@@ -1722,103 +1722,103 @@ def sh(cmd, t=30):
17221722
17231723 elif action == 'switch_version' :
17241724 ver = d .get ('version' , '' )
1725- if mod_id == 'redis' and ver :
1726- # Stop redis, install specific version from redis.io, restart
1725+ if not ver :
1726+ return jsonify ({'ok' : False , 'error' : 'No version specified' }), 400
1727+
1728+ # Build the switch script per module
1729+ script = None
1730+ ver_check_cmd = None # command to get new version string after switch
1731+
1732+ if mod_id == 'redis' :
17271733 script = (
1728- 'systemctl stop redis-server 2>/dev/null || systemctl stop redis 2>/dev/null; '
1734+ 'systemctl stop redis-server 2>/dev/null || systemctl stop redis 2>/dev/null && '
17291735 'curl -fsSL https://packages.redis.io/gpg | gpg --batch --yes --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg && '
17301736 'echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/redis.list && '
17311737 'apt-get update -o APT::Update::Error-Mode=any 2>/dev/null && '
1732- 'apt-get install -y --allow-downgrades redis-server=' + ver + '.* 2>/dev/null || '
1733- 'apt-get install -y redis-server && '
1738+ f'apt-get install -y --allow-downgrades redis-server={ ver } .* 2>/dev/null || apt-get install -y redis-server && '
17341739 'systemctl start redis-server 2>/dev/null || systemctl start redis'
17351740 )
1736- out = sh ( script , t = 120 )
1737- new_ver = sh ( "redis-server --version 2>/dev/null | grep -oP '[0-9]+[.][0-9]+[.][0-9]+'" ) or ''
1738- return jsonify ({ 'ok' : True , 'output' : out , 'version' : new_ver })
1739- elif mod_id in ( ' pure-ftpd' , 'pure_ftpd' ) and ver :
1740- out = sh ( 'apt-get install -y pure-ftpd=' + ver + ' 2>/dev/null || apt-get install -y pure-ftpd 2>&1' , t = 60 )
1741- return jsonify ({ 'ok' : True , 'output' : out })
1742- elif mod_id == 'mariadb' and ver :
1741+ ver_check_cmd = "redis-server --version 2>/dev/null | grep -oP '[0-9]+[.][0-9]+[.][0-9]+'"
1742+
1743+ elif mod_id in ( 'pure-ftpd' , 'pure_ftpd' ):
1744+ script = f'apt-get install -y pure-ftpd= { ver } 2>/dev/null || apt-get install -y pure-ftpd'
1745+ ver_check_cmd = "pure-ftpd --version 2>/dev/null | grep -oP '[0-9]+[.][0-9]+[.][0-9]+' | head -1"
1746+
1747+ elif mod_id == 'mariadb' :
17431748 script = (
17441749 'export DEBIAN_FRONTEND=noninteractive && '
1745- 'systemctl stop mariadb 2>/dev/null; '
1746- 'curl -fsSL https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | bash -s -- --mariadb-server-version=' + ver + ' && '
1750+ 'systemctl stop mariadb 2>/dev/null && '
1751+ f 'curl -fsSL https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | bash -s -- --mariadb-server-version={ ver } && '
17471752 'apt-get update -qq && '
17481753 'apt-get install -y mariadb-server && '
17491754 'systemctl start mariadb'
17501755 )
1751- out = sh (script , t = 300 )
1752- new_ver = sh ("mariadb --version 2>/dev/null | grep -oP '[0-9]+[.][0-9]+[.][0-9]+' | head -1" ) or ''
1753- return jsonify ({'ok' : True , 'output' : out , 'version' : new_ver })
1756+ ver_check_cmd = "mariadb --version 2>/dev/null | grep -oP '[0-9]+[.][0-9]+[.][0-9]+' | head -1"
17541757
1755- elif mod_id == 'postgresql' and ver :
1758+ elif mod_id == 'mysql' :
1759+ script = (
1760+ 'export DEBIAN_FRONTEND=noninteractive && '
1761+ f'apt-get install -y --allow-downgrades mysql-server={ ver } * 2>/dev/null || '
1762+ 'apt-get install -y mysql-server && '
1763+ 'systemctl restart mysql'
1764+ )
1765+ ver_check_cmd = "mysql --version 2>/dev/null | grep -oP '[0-9]+[.][0-9]+[.][0-9]+' | head -1"
1766+
1767+ elif mod_id == 'postgresql' :
17561768 script = (
17571769 'export DEBIAN_FRONTEND=noninteractive && '
17581770 'rm -f /usr/share/keyrings/postgresql.gpg /etc/apt/sources.list.d/pgdg.list && '
17591771 'curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc -o /tmp/pg.asc && '
17601772 'gpg --batch --no-tty --dearmor -o /usr/share/keyrings/postgresql.gpg /tmp/pg.asc && '
1761- 'echo "deb [signed-by=/usr/share/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list && '
1773+ f 'echo "deb [signed-by=/usr/share/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list && '
17621774 'apt-get update -qq && '
1763- 'apt-get install -y postgresql-' + ver + ' && '
1775+ f 'apt-get install -y postgresql-{ ver } && '
17641776 'systemctl restart postgresql'
17651777 )
1766- out = sh (script , t = 300 )
1767- new_ver = sh ("psql --version 2>/dev/null | grep -oP '[0-9]+[.][0-9]+' | head -1" ) or ''
1768- return jsonify ({'ok' : True , 'output' : out , 'version' : new_ver })
1778+ ver_check_cmd = "psql --version 2>/dev/null | grep -oP '[0-9]+[.][0-9]+' | head -1"
17691779
1770- elif mod_id == 'mongodb' and ver :
1780+ elif mod_id == 'mongodb' :
17711781 script = (
17721782 'export DEBIAN_FRONTEND=noninteractive && '
1773- 'systemctl stop mongod 2>/dev/null; '
1774- 'rm -f /usr/share/keyrings/mongodb-server-*.gpg /etc/apt/sources.list.d/mongodb*.list && '
1775- 'curl -fsSL https://www.mongodb.org/static/pgp/server-' + ver + ' .asc -o /tmp/mongo.asc && '
1776- 'gpg --batch --no-tty --dearmor -o /usr/share/keyrings/mongodb-server-' + ver + ' .gpg /tmp/mongo.asc && '
1777- 'echo "deb [signed-by=/usr/share/keyrings/mongodb-server-' + ver + ' .gpg] https://repo.mongodb.org/apt/ubuntu $(lsb_release -cs)/mongodb-org/' + ver + ' multiverse" > /etc/apt/sources.list.d/mongodb-org-' + ver + ' .list && '
1783+ 'systemctl stop mongod 2>/dev/null && '
1784+ f 'rm -f /usr/share/keyrings/mongodb-server-*.gpg /etc/apt/sources.list.d/mongodb*.list && '
1785+ f 'curl -fsSL https://www.mongodb.org/static/pgp/server-{ ver } .asc -o /tmp/mongo.asc && '
1786+ f 'gpg --batch --no-tty --dearmor -o /usr/share/keyrings/mongodb-server-{ ver } .gpg /tmp/mongo.asc && '
1787+ f 'echo "deb [signed-by=/usr/share/keyrings/mongodb-server-{ ver } .gpg] https://repo.mongodb.org/apt/ubuntu $(lsb_release -cs)/mongodb-org/{ ver } multiverse" > /etc/apt/sources.list.d/mongodb-org-{ ver } .list && '
17781788 'apt-get update -qq && '
17791789 'apt-get install -y mongodb-org && '
17801790 'systemctl start mongod'
17811791 )
1782- out = sh (script , t = 300 )
1783- new_ver = sh ("mongod --version 2>/dev/null | grep -oP '[0-9]+[.][0-9]+[.][0-9]+' | head -1" ) or ''
1784- return jsonify ({'ok' : True , 'output' : out , 'version' : new_ver })
1792+ ver_check_cmd = "mongod --version 2>/dev/null | grep -oP '[0-9]+[.][0-9]+[.][0-9]+' | head -1"
17851793
1786- elif mod_id == 'apache2' and ver :
1794+ elif mod_id == 'apache2' :
17871795 script = (
17881796 'export DEBIAN_FRONTEND=noninteractive && '
1789- 'add-apt-repository -y ppa:ondrej/apache2 2>/dev/null; '
1797+ 'add-apt-repository -y ppa:ondrej/apache2 2>/dev/null && '
17901798 'apt-get update -qq && '
1791- 'apt-get install -y --allow-downgrades apache2=' + ver + '-* 2>/dev/null || '
1792- 'apt-get install -y apache2 && '
1799+ f'apt-get install -y --allow-downgrades apache2={ ver } -* 2>/dev/null || apt-get install -y apache2 && '
17931800 'systemctl restart apache2'
17941801 )
1795- out = sh (script , t = 180 )
1796- new_ver = sh ("apache2 -v 2>/dev/null | grep -oP '[0-9]+[.][0-9]+[.][0-9]+' | head -1" ) or ''
1797- return jsonify ({'ok' : True , 'output' : out , 'version' : new_ver })
1802+ ver_check_cmd = "apache2 -v 2>/dev/null | grep -oP '[0-9]+[.][0-9]+[.][0-9]+' | head -1"
17981803
1799- elif mod_id == 'nodejs' and ver :
1804+ elif mod_id == 'nodejs' :
18001805 script = (
18011806 'export DEBIAN_FRONTEND=noninteractive && '
1802- 'curl -fsSL https://deb.nodesource.com/setup_' + ver + ' .x | bash - && '
1807+ f 'curl -fsSL https://deb.nodesource.com/setup_{ ver } .x | bash - && '
18031808 'apt-get install -y nodejs'
18041809 )
1805- out = sh (script , t = 180 )
1806- new_ver = sh ("node --version 2>/dev/null" ) or ''
1807- return jsonify ({'ok' : True , 'output' : out , 'version' : new_ver })
1810+ ver_check_cmd = "node --version 2>/dev/null"
18081811
1809- elif mod_id == 'bind9' and ver :
1812+ elif mod_id == 'bind9' :
18101813 script = (
18111814 'export DEBIAN_FRONTEND=noninteractive && '
18121815 + ('add-apt-repository -y ppa:isc/bind && apt-get update -qq && ' if ver == '9.20' else 'apt-get update -qq && ' ) +
18131816 'apt-get install -y bind9 bind9utils && '
18141817 '(systemctl restart named 2>/dev/null || systemctl restart bind9 2>/dev/null)'
18151818 )
1816- out = sh (script , t = 180 )
1817- new_ver = sh ("named -v 2>/dev/null | grep -oP '[0-9]+[.][0-9]+[.][0-9]+' | head -1" ) or ''
1818- return jsonify ({'ok' : True , 'output' : out , 'version' : new_ver })
1819+ ver_check_cmd = "named -v 2>/dev/null | grep -oP '[0-9]+[.][0-9]+[.][0-9]+' | head -1"
18191820
1820- elif mod_id == 'nginx' and ver :
1821- # Switch nginx repo based on channel (stable/mainline)
1821+ elif mod_id == 'nginx' :
18221822 repo = 'http://nginx.org/packages/ubuntu' if ver == 'stable' else 'http://nginx.org/packages/mainline/ubuntu'
18231823 script = (
18241824 f'echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] { repo } $(lsb_release -cs) nginx" '
@@ -1827,22 +1827,48 @@ def sh(cmd, t=30):
18271827 'apt-get install -y nginx && '
18281828 'systemctl reload nginx 2>/dev/null || systemctl restart nginx 2>/dev/null'
18291829 )
1830- out = sh (script , t = 120 )
1831- new_ver = sh ("nginx -v 2>&1 | grep -oP '[0-9]+[.][0-9]+[.][0-9]+'" ) or ''
1832- return jsonify ({'ok' : True , 'output' : out , 'version' : new_ver })
1833- elif mod_id == 'openlitespeed' and ver :
1830+ ver_check_cmd = "nginx -v 2>&1 | grep -oP '[0-9]+[.][0-9]+[.][0-9]+'"
1831+
1832+ elif mod_id == 'openlitespeed' :
18341833 script = (
1835- 'systemctl stop lsws 2>/dev/null; '
1834+ 'systemctl stop lsws 2>/dev/null && '
18361835 'wget -q https://repo.litespeed.sh -O ls_repo.sh && bash ls_repo.sh && '
18371836 '(apt-get update -o APT::Update::Error-Mode=any 2>/dev/null; true) && '
1838- f'apt-get install -y --allow-downgrades openlitespeed={ ver } 2>/dev/null || '
1839- 'apt-get install -y openlitespeed && '
1837+ f'apt-get install -y --allow-downgrades openlitespeed={ ver } 2>/dev/null || apt-get install -y openlitespeed && '
18401838 'systemctl start lsws'
18411839 )
1842- out = sh (script , t = 120 )
1843- new_ver = sh ("cat /usr/local/lsws/VERSION 2>/dev/null | grep -oP '[0-9]+[.][0-9]+[.][0-9]+'" ) or ''
1844- return jsonify ({'ok' : True , 'output' : out , 'version' : new_ver })
1845- return jsonify ({'ok' : False , 'error' : 'Version switch not supported for ' + mod_id })
1840+ ver_check_cmd = "cat /usr/local/lsws/VERSION 2>/dev/null | grep -oP '[0-9]+[.][0-9]+[.][0-9]+'"
1841+
1842+ if not script :
1843+ return jsonify ({'ok' : False , 'error' : f'Version switch not supported for { mod_id } ' }), 400
1844+
1845+ # Run as a streaming job — same system as install/uninstall
1846+ job_id = str (uuid .uuid4 ())[:8 ]
1847+ _jobs [job_id ] = {'status' :'running' ,'lines' :[],'done' :False ,'success' :False ,'installed' :True }
1848+
1849+ def run_switch ():
1850+ mod_name = mod ['name' ] if mod else mod_id
1851+ _jobs [job_id ]['lines' ].append (f'[VortexPanel] Switching { mod_name } to version { ver } ...' )
1852+ proc = subprocess .Popen (
1853+ f'DEBIAN_FRONTEND=noninteractive { script } 2>&1' ,
1854+ shell = True , stdout = subprocess .PIPE , stderr = subprocess .STDOUT , text = True , bufsize = 1
1855+ )
1856+ for line in proc .stdout :
1857+ _jobs [job_id ]['lines' ].append (line .rstrip ())
1858+ proc .wait ()
1859+ success = proc .returncode == 0
1860+ new_ver = sh (ver_check_cmd ) if ver_check_cmd else ver
1861+ _jobs [job_id ]['lines' ].append (
1862+ f'[VortexPanel] { "✓ Switched to " + new_ver + " successfully!" if success else "⚠ Switch may have failed — check output above." } '
1863+ )
1864+ _jobs [job_id ].update ({
1865+ 'done' : True , 'success' : success , 'status' : 'done' ,
1866+ 'installed' : True , 'installedVer' : new_ver ,
1867+ })
1868+ panel_cache .invalidate ('modules_list' )
1869+
1870+ threading .Thread (target = run_switch , daemon = True ).start ()
1871+ return jsonify ({'ok' : True , 'job_id' : job_id , 'action' : 'switch_version' })
18461872
18471873 elif action == 'setup_private_dns' :
18481874 networks = d .get ('networks' , '127.0.0.1;' )
0 commit comments