def __write_passwd(self, name, user, passwd, focre=True): auth_pass = self.rsyn_path + '/secrets/' + name + '.db' if os.path.exists(auth_pass) and focre: return True public.writeFile(auth_pass, user + ':' + passwd) public.ExecShell("chmod 600 " + auth_pass) return True
def SetupPackage(self, get): name = get.dname site_name = get.site_name php_version = get.php_version #取基础信息 find = public.M('sites').where( 'name=?', (site_name, )).field('id,path,name').find() if not 'path' in find: return public.returnMsg(False, '网站不存在!') path = find['path'] if path.replace('//', '/') == '/': return public.returnMsg(False, '危险的网站根目录!') #获取包信息 pinfo = self.GetPackageInfo(name) id = pinfo['id'] if not pinfo: return public.returnMsg(False, '指定软件包不存在!') #检查本地包 self.WriteLogs( json.dumps({ 'name': '正在校验软件包...', 'total': 0, 'used': 0, 'pre': 0, 'speed': 0 })) pack_path = self.__panelPath + '/package' if not os.path.exists(pack_path): os.makedirs(pack_path, 384) packageZip = pack_path + '/' + name + '.zip' isDownload = False if os.path.exists(packageZip): md5str = self.GetFileMd5(packageZip) if md5str != pinfo['versions'][0]['md5']: isDownload = True else: isDownload = True #下载文件 if isDownload: self.WriteLogs( json.dumps({ 'name': '正在下载文件 ...', 'total': 0, 'used': 0, 'pre': 0, 'speed': 0 })) if pinfo['versions'][0]['download']: self.DownloadFile( 'http://www.bt.cn/api/Pluginother/get_file?fname=' + pinfo['versions'][0]['download'], packageZip) if not os.path.exists(packageZip): return public.returnMsg(False, '文件下载失败!' + packageZip) pinfo = self.set_temp_file(packageZip, path) if not pinfo: return public.returnMsg(False, '在安装包中找不到【宝塔自动部署配置文件】') #设置权限 self.WriteLogs( json.dumps({ 'name': '设置权限', 'total': 0, 'used': 0, 'pre': 0, 'speed': 0 })) os.system('chmod -R 755 ' + path) os.system('chown -R www.www ' + path) if pinfo['chmod']: for chm in pinfo['chmod']: os.system('chmod -R ' + str(chm['mode']) + ' ' + (path + '/' + chm['path']).replace('//', '/')) #安装PHP扩展 self.WriteLogs( json.dumps({ 'name': '安装必要的PHP扩展', 'total': 0, 'used': 0, 'pre': 0, 'speed': 0 })) import files mfile = files.files() if type(pinfo['php_ext']) != list: pinfo['php_ext'] = pinfo['php_ext'].strip().split(',') for ext in pinfo['php_ext']: if ext == 'pathinfo': import config con = config.config() get.version = php_version get.type = 'on' con.setPathInfo(get) else: get.name = ext get.version = php_version get.type = '1' mfile.InstallSoft(get) #解禁PHP函数 if 'enable_functions' in pinfo: try: if type(pinfo['enable_functions']) == str: pinfo['enable_functions'] = pinfo[ 'enable_functions'].strip().split(',') php_f = public.GetConfigValue( 'setup_path') + '/php/' + php_version + '/etc/php.ini' php_c = public.readFile(php_f) rep = "disable_functions\s*=\s{0,1}(.*)\n" tmp = re.search(rep, php_c).groups() disable_functions = tmp[0].split(',') for fun in pinfo['enable_functions']: fun = fun.strip() if fun in disable_functions: disable_functions.remove(fun) disable_functions = ','.join(disable_functions) php_c = re.sub( rep, 'disable_functions = ' + disable_functions + "\n", php_c) public.writeFile(php_f, php_c) public.phpReload(php_version) except: pass #执行额外shell进行依赖安装 self.WriteLogs( json.dumps({ 'name': '执行额外SHELL', 'total': 0, 'used': 0, 'pre': 0, 'speed': 0 })) if os.path.exists(path + '/install.sh'): os.system('cd ' + path + ' && bash ' + 'install.sh ' + find['name'] + " &> install.log") os.system('rm -f ' + path + '/install.sh') #是否执行Composer if os.path.exists(path + '/composer.json'): self.WriteLogs( json.dumps({ 'name': '执行Composer', 'total': 0, 'used': 0, 'pre': 0, 'speed': 0 })) if not os.path.exists(path + '/composer.lock'): execPHP = '/www/server/php/' + php_version + '/bin/php' if execPHP: if public.get_url().find('125.88'): os.system( 'cd ' + path + ' && ' + execPHP + ' /usr/bin/composer config repo.packagist composer https://packagist.phpcomposer.com' ) import panelSite phpini = '/www/server/php/' + php_version + '/etc/php.ini' phpiniConf = public.readFile(phpini) phpiniConf = phpiniConf.replace( 'proc_open,proc_get_status,', '') public.writeFile(phpini, phpiniConf) os.system( 'nohup cd ' + path + ' && ' + execPHP + ' /usr/bin/composer install -vvv > /tmp/composer.log 2>&1 &' ) #写伪静态 self.WriteLogs( json.dumps({ 'name': '设置伪静态', 'total': 0, 'used': 0, 'pre': 0, 'speed': 0 })) swfile = path + '/nginx.rewrite' if os.path.exists(swfile): rewriteConf = public.readFile(swfile) dwfile = self.__panelPath + '/vhost/rewrite/' + site_name + '.conf' public.writeFile(dwfile, rewriteConf) swfile = path + '/.htaccess' if os.path.exists(swfile): swpath = (path + '/' + pinfo['run_path'] + '/.htaccess').replace( '//', '/') if pinfo['run_path'] != '/' and not os.path.exists(swpath): public.writeFile(swpath, public.readFile(swfile)) #删除伪静态文件 public.ExecShell("rm -f " + path + '/*.rewrite') #删除多余文件 rm_file = path + '/index.html' if os.path.exists(rm_file): rm_file_body = public.readFile(rm_file) if rm_file_body.find('panel-heading') != -1: os.remove(rm_file) #设置运行目录 self.WriteLogs( json.dumps({ 'name': '设置运行目录', 'total': 0, 'used': 0, 'pre': 0, 'speed': 0 })) if pinfo['run_path'] != '/': import panelSite siteObj = panelSite.panelSite() mobj = obj() mobj.id = find['id'] mobj.runPath = pinfo['run_path'] siteObj.SetSiteRunPath(mobj) #导入数据 self.WriteLogs( json.dumps({ 'name': '导入数据库', 'total': 0, 'used': 0, 'pre': 0, 'speed': 0 })) if os.path.exists(path + '/import.sql'): databaseInfo = public.M('databases').where( 'pid=?', (find['id'], )).field('username,password').find() if databaseInfo: os.system('/www/server/mysql/bin/mysql -u' + databaseInfo['username'] + ' -p' + databaseInfo['password'] + ' ' + databaseInfo['username'] + ' < ' + path + '/import.sql') os.system('rm -f ' + path + '/import.sql') siteConfigFile = (path + '/' + pinfo['db_config']).replace( '//', '/') if os.path.exists(siteConfigFile): siteConfig = public.readFile(siteConfigFile) siteConfig = siteConfig.replace('BT_DB_USERNAME', databaseInfo['username']) siteConfig = siteConfig.replace('BT_DB_PASSWORD', databaseInfo['password']) siteConfig = siteConfig.replace('BT_DB_NAME', databaseInfo['username']) public.writeFile(siteConfigFile, siteConfig) #清理文件和目录 self.WriteLogs( json.dumps({ 'name': '清理多余的文件', 'total': 0, 'used': 0, 'pre': 0, 'speed': 0 })) if type(pinfo['remove_file']) == str: pinfo['remove_file'] = pinfo['remove_file'].strip().split(',') print(pinfo['remove_file']) for f_path in pinfo['remove_file']: if not f_path: continue filename = (path + '/' + f_path).replace('//', '/') if os.path.exists(filename): if not os.path.isdir(filename): if f_path.find('.user.ini') != -1: public.ExecShell("chattr -i " + filename) os.remove(filename) else: public.ExecShell("rm -rf " + filename) public.serviceReload() if id: self.depTotal(id) self.WriteLogs( json.dumps({ 'name': '准备部署', 'total': 0, 'used': 0, 'pre': 0, 'speed': 0 })) return public.returnMsg(True, pinfo)
def bt_cli(u_input=0): raw_tip = "===============================================" if not u_input: print("===============宝塔面板命令行==================") print("(1) 重启面板服务 (8) 改面板端口") print("(2) 停止面板服务 (9) 清除面板缓存") print("(3) 启动面板服务 (10) 清除登录限制") print("(4) 重载面板服务 (11) 取消入口限制") print("(5) 修改面板密码 (12) 取消域名绑定限制") print("(6) 修改面板用户名 (13) 取消IP访问限制") print("(7) 强制修改MySQL密码 (14) 查看面板默认信息") print("(22) 显示面板错误日志 (15) 清理系统垃圾") print("(23) 关闭BasicAuth认证 (16) 修复面板(检查错误并更新面板文件到最新版)") print("(24) 关闭谷歌认证 (17) 设置日志切割是否压缩") print("(25) 设置是否保存文件历史副本 (18) 设置是否自动备份面板") print("(0) 取消") print(raw_tip) try: u_input = input("请输入命令编号:") if sys.version_info[0] == 3: u_input = int(u_input) except: u_input = 0 nums = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 22, 23, 24, 25 ] if not u_input in nums: print(raw_tip) print("已取消!") exit() print(raw_tip) print("正在执行(%s)..." % u_input) print(raw_tip) if u_input == 1: os.system("/etc/init.d/bt restart") elif u_input == 2: os.system("/etc/init.d/bt stop") elif u_input == 3: os.system("/etc/init.d/bt start") elif u_input == 4: os.system("/etc/init.d/bt reload") elif u_input == 5: if sys.version_info[0] == 2: input_pwd = raw_input("请输入新的面板密码:") else: input_pwd = input("请输入新的面板密码:") set_panel_pwd(input_pwd.strip(), True) elif u_input == 6: if sys.version_info[0] == 2: input_user = raw_input("请输入新的面板用户名(>5位):") else: input_user = input("请输入新的面板用户名(>5位):") set_panel_username(input_user.strip()) elif u_input == 7: if sys.version_info[0] == 2: input_mysql = raw_input("请输入新的MySQL密码:") else: input_mysql = input("请输入新的MySQL密码:") if not input_mysql: print("|-错误,不能设置空密码") return if len(input_mysql) < 8: print("|-错误,长度不能少于8位") return import re rep = "^[\w@\._]+$" if not re.match(rep, input_mysql): print("|-错误,密码中不能包含特殊符号") return print(input_mysql) set_mysql_root(input_mysql.strip()) elif u_input == 8: input_port = input("请输入新的面板端口:") if sys.version_info[0] == 3: input_port = int(input_port) if not input_port: print("|-错误,未输入任何有效端口") return if input_port in [80, 443, 21, 20, 22]: print("|-错误,请不要使用常用端口作为面板端口") return old_port = int(public.readFile('data/port.pl')) if old_port == input_port: print("|-错误,与面板当前端口一致,无需修改") return is_exists = public.ExecShell("lsof -i:%s|grep LISTEN|grep -v grep" % input_port) if len(is_exists[0]) > 5: print("|-错误,指定端口已被其它应用占用") return public.writeFile('data/port.pl', str(input_port)) if os.path.exists("/usr/bin/firewall-cmd"): os.system( "firewall-cmd --permanent --zone=public --add-port=%s/tcp" % input_port) os.system("firewall-cmd --reload") elif os.path.exists("/etc/sysconfig/iptables"): os.system( "iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport %s -j ACCEPT" % input_port) os.system("service iptables save") else: os.system("ufw allow %s" % input_port) os.system("ufw reload") os.system("/etc/init.d/bt reload") print("|-已将面板端口修改为:%s" % input_port) print( "|-若您的服务器提供商是[阿里云][腾讯云][华为云]或其它开启了[安全组]的服务器,请在安全组放行[%s]端口才能访问面板" % input_port) elif u_input == 9: sess_file = '/dev/shm/session.db' if os.path.exists(sess_file): os.remove(sess_file) os.system("/etc/init.d/bt reload") elif u_input == 10: os.system("/etc/init.d/bt reload") elif u_input == 11: auth_file = 'data/admin_path.pl' if os.path.exists(auth_file): os.remove(auth_file) os.system("/etc/init.d/bt reload") print("|-已取消入口限制") elif u_input == 12: auth_file = 'data/domain.conf' if os.path.exists(auth_file): os.remove(auth_file) os.system("/etc/init.d/bt reload") print("|-已取消域名访问限制") elif u_input == 13: auth_file = 'data/limitip.conf' if os.path.exists(auth_file): os.remove(auth_file) os.system("/etc/init.d/bt reload") print("|-已取消IP访问限制") elif u_input == 14: os.system("/etc/init.d/bt default") elif u_input == 15: ClearSystem() elif u_input == 16: os.system("curl http://download.bt.cn/install/update6.sh|bash") elif u_input == 17: l_path = '/www/server/panel/data/log_not_gzip.pl' if os.path.exists(l_path): print("|-检测到已关闭gzip压缩功能,正在开启...") os.remove(l_path) print("|-已开启gzip压缩") else: print("|-检测到已开启gzip压缩功能,正在关闭...") public.writeFile(l_path, 'True') print("|-已关闭gzip压缩") elif u_input == 18: l_path = '/www/server/panel/data/not_auto_backup.pl' if os.path.exists(l_path): print("|-检测到已关闭面板自动备份功能,正在开启...") os.remove(l_path) print("|-已开启面板自动备份功能") else: print("|-检测到已开启面板自动备份功能,正在关闭...") public.writeFile(l_path, 'True') print("|-已开关闭面板自动备份功能") elif u_input == 22: os.system('tail -100 /www/server/panel/logs/error.log') elif u_input == 23: filename = '/www/server/panel/config/basic_auth.json' if os.path.exists(filename): os.remove(filename) os.system('bt reload') print("|-已关闭BasicAuth认证") elif u_input == 24: filename = '/www/server/panel/data/two_step_auth.txt' if os.path.exists(filename): os.remove(filename) print("|-已关闭谷歌认证") elif u_input == 25: l_path = '/www/server/panel/data/not_file_history.pl' if os.path.exists(l_path): print("|-检测到已关闭文件副本功能,正在开启...") os.remove(l_path) print("|-已开启文件副本功能") else: print("|-检测到已开启文件副本功能,正在关闭...") public.writeFile(l_path, 'True') print("|-已开关闭文件副本功能")
def ServiceAdmin(self, get=None): #服务管理 if get.name == 'mysqld': public.CheckMyCnf() if get.name == 'phpmyadmin': import ajax get.status = 'True' ajax.ajax().setPHPMyAdmin(get) return public.returnMsg(True, 'SYS_EXEC_SUCCESS') #检查httpd配置文件 if get.name == 'apache' or get.name == 'httpd': get.name = 'httpd' if not os.path.exists(self.setupPath + '/apache/bin/apachectl'): return public.returnMsg(True, 'SYS_NOT_INSTALL_APACHE') vhostPath = self.setupPath + '/panel/vhost/apache' if not os.path.exists(vhostPath): public.ExecShell('mkdir ' + vhostPath) public.ExecShell('/etc/init.d/httpd start') if get.type == 'start': public.ExecShell('/etc/init.d/httpd stop') self.kill_port() result = public.ExecShell('ulimit -n 10240 && ' + self.setupPath + '/apache/bin/apachectl -t') if result[1].find('Syntax OK') == -1: public.WriteLog("TYPE_SOFT", 'SYS_EXEC_ERR', (str(result), )) return public.returnMsg(False, 'SYS_CONF_APACHE_ERR', (result[1].replace("\n", '<br>'), )) if get.type == 'restart': public.ExecShell('pkill -9 httpd') public.ExecShell('/etc/init.d/httpd start') time.sleep(0.5) #检查nginx配置文件 elif get.name == 'nginx': vhostPath = self.setupPath + '/panel/vhost/rewrite' if not os.path.exists(vhostPath): public.ExecShell('mkdir ' + vhostPath) vhostPath = self.setupPath + '/panel/vhost/nginx' if not os.path.exists(vhostPath): public.ExecShell('mkdir ' + vhostPath) public.ExecShell('/etc/init.d/nginx start') result = public.ExecShell('ulimit -n 10240 && nginx -t -c ' + self.setupPath + '/nginx/conf/nginx.conf') if result[1].find('perserver') != -1: limit = self.setupPath + '/nginx/conf/nginx.conf' nginxConf = public.readFile(limit) limitConf = "limit_conn_zone $binary_remote_addr zone=perip:10m;\n\t\tlimit_conn_zone $server_name zone=perserver:10m;" nginxConf = nginxConf.replace( "#limit_conn_zone $binary_remote_addr zone=perip:10m;", limitConf) public.writeFile(limit, nginxConf) public.ExecShell('/etc/init.d/nginx start') return public.returnMsg(True, 'SYS_CONF_NGINX_REP') if result[1].find('proxy') != -1: import panelSite panelSite.panelSite().CheckProxy(get) public.ExecShell('/etc/init.d/nginx start') return public.returnMsg(True, 'SYS_CONF_NGINX_REP') #return result if result[1].find('successful') == -1: public.WriteLog("TYPE_SOFT", 'SYS_EXEC_ERR', (str(result), )) return public.returnMsg(False, 'SYS_CONF_NGINX_ERR', (result[1].replace("\n", '<br>'), )) if get.type == 'start': self.kill_port() time.sleep(0.5) if get.name == 'redis': redis_init = '/etc/init.d/redis' if os.path.exists(redis_init): init_body = public.ReadFile(redis_init) if init_body.find('pkill -9 redis') == -1: public.ExecShell("wget -O " + redis_init + " " + public.get_url() + '/init/redis.init') public.ExecShell("chmod +x " + redis_init) #执行 execStr = "/etc/init.d/" + get.name + " " + get.type if execStr == '/etc/init.d/pure-ftpd reload': execStr = self.setupPath + '/pure-ftpd/bin/pure-pw mkdb ' + self.setupPath + '/pure-ftpd/etc/pureftpd.pdb' if execStr == '/etc/init.d/pure-ftpd start': os.system('pkill -9 pure-ftpd') if execStr == '/etc/init.d/tomcat reload': execStr = '/etc/init.d/tomcat stop && /etc/init.d/tomcat start' if execStr == '/etc/init.d/tomcat restart': execStr = '/etc/init.d/tomcat stop && /etc/init.d/tomcat start' if get.name != 'mysqld': result = public.ExecShell(execStr) else: os.system(execStr) result = [] result.append('') result.append('') if result[1].find('nginx.pid') != -1: public.ExecShell('pkill -9 nginx && sleep 1') public.ExecShell('/etc/init.d/nginx start') if get.type != 'test': public.WriteLog("TYPE_SOFT", 'SYS_EXEC_SUCCESS', (execStr, )) if len(result[1] ) > 1 and get.name != 'pure-ftpd' and get.name != 'redis': return public.returnMsg( False, '<p>警告消息: <p>' + result[1].replace('\n', '<br>')) return public.returnMsg(True, 'SYS_EXEC_SUCCESS')
def kill_port(self): public.ExecShell('pkill -9 httpd') public.ExecShell('pkill -9 nginx') public.ExecShell("kill -9 $(lsof -i :80|grep LISTEN|awk '{print $2}')") return True
def GetShell(self, param): #try: type = param['sType'] if type == 'toFile': shell = param.sFile else: head = "#!/bin/bash\nPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin\nexport PATH\n" python_bin = public.get_python_bin() if public.get_webserver() == 'nginx': log = '.log' elif public.get_webserver() == 'apache': log = '-access_log' else: log = '_ols.access_log' if type in [ 'site', 'path' ] and param['sBody'] != 'undefined' and len(param['sBody']) > 1: exports = param['sBody'].replace("\r\n", "\n").replace("\n", ",") head += "BT_EXCLUDE=\"" + exports.strip( ) + "\"\nexport BT_EXCLUDE\n" wheres = { 'path': head + python_bin + " " + public.GetConfigValue('setup_path') + "/panel/script/backup.py path " + param['sName'] + " " + str(param['save']), 'site': head + python_bin + " " + public.GetConfigValue('setup_path') + "/panel/script/backup.py site " + param['sName'] + " " + str(param['save']), 'database': head + python_bin + " " + public.GetConfigValue('setup_path') + "/panel/script/backup.py database " + param['sName'] + " " + str(param['save']), 'logs': head + python_bin + " " + public.GetConfigValue('setup_path') + "/panel/script/logsBackup " + param['sName'] + log + " " + str(param['save']), 'rememory': head + "/bin/bash " + public.GetConfigValue('setup_path') + '/panel/script/rememory.sh', 'webshell': head + python_bin + " " + public.GetConfigValue('setup_path') + '/panel/class/webshell_check.py site ' + param['sName'] + ' ' + param['urladdress'] } if param['backupTo'] != 'localhost': cfile = public.GetConfigValue( 'setup_path') + "/panel/plugin/" + param[ 'backupTo'] + "/" + param['backupTo'] + "_main.py" if not os.path.exists(cfile): cfile = public.GetConfigValue( 'setup_path' ) + "/panel/script/backup_" + param['backupTo'] + ".py" wheres = { 'path': head + python_bin + " " + cfile + " path " + param['sName'] + " " + str(param['save']), 'site': head + python_bin + " " + cfile + " site " + param['sName'] + " " + str(param['save']), 'database': head + python_bin + " " + cfile + " database " + param['sName'] + " " + str(param['save']), 'logs': head + python_bin + " " + public.GetConfigValue('setup_path') + "/panel/script/logsBackup " + param['sName'] + log + " " + str(param['save']), 'rememory': head + "/bin/bash " + public.GetConfigValue('setup_path') + '/panel/script/rememory.sh', 'webshell': head + python_bin + " " + public.GetConfigValue('setup_path') + '/panel/class/webshell_check.py site ' + param['sName'] + ' ' + param['urladdress'] } try: shell = wheres[type] except: if type == 'toUrl': shell = head + "curl -sS --connect-timeout 10 -m 3600 '" + param[ 'urladdress'] + "'" else: shell = head + param['sBody'].replace("\r\n", "\n") shell += ''' echo "----------------------------------------------------------------------------" endDate=`date +"%Y-%m-%d %H:%M:%S"` echo "★[$endDate] Successful" echo "----------------------------------------------------------------------------" ''' cronPath = public.GetConfigValue('setup_path') + '/cron' if not os.path.exists(cronPath): public.ExecShell('mkdir -p ' + cronPath) if not 'echo' in param: cronName = public.md5(public.md5(str(time.time()) + '_bt')) else: cronName = param['echo'] file = cronPath + '/' + cronName public.writeFile(file, self.CheckScript(shell)) public.ExecShell('chmod 750 ' + file) return cronName
try: from flask_sqlalchemy import SQLAlchemy app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////dev/shm/session.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True sdb = SQLAlchemy(app) app.config['SESSION_TYPE'] = 'sqlalchemy' app.config['SESSION_SQLALCHEMY'] = sdb app.config['SESSION_SQLALCHEMY_TABLE'] = 'session' s_sqlite = True except: app.config['SESSION_TYPE'] = 'filesystem' app.config['SESSION_FILE_DIR'] = r'/dev/shm/session_py' + str(sys.version_info[0]) app.config['SESSION_FILE_THRESHOLD'] = 2048 app.config['SESSION_FILE_MODE'] = 384 s_sqlite = False public.ExecShell("pip install flask_sqlalchemy &") app.config['SESSION_PERMANENT'] = True app.config['SESSION_USE_SIGNER'] = True app.config['SESSION_KEY_PREFIX'] = 'BT_:' app.config['SESSION_COOKIE_NAME'] = "BT_PANEL_6" app.config['PERMANENT_SESSION_LIFETIME'] = 86400 * 7 Session(app) if s_sqlite: sdb.create_all() from datetime import datetime import socket comm = common.panelAdmin() method_all = ['GET','POST']
def UpdatePanel(self, get): try: if not public.IsRestart(): return public.returnMsg(False, 'EXEC_ERR_TASK') import json if int(session['config']['status']) == 0: public.HttpGet( public.GetConfigValue('home') + '/Api/SetupCount?type=Linux') public.M('config').where("id=?", ('1', )).setField('status', 1) #取回远程版本信息 if 'updateInfo' in session and hasattr(get, 'check') == False: updateInfo = session['updateInfo'] else: logs = '' import psutil, system, sys mem = psutil.virtual_memory() import panelPlugin mplugin = panelPlugin.panelPlugin() mplugin.ROWS = 10000 panelsys = system.system() data = {} data['sites'] = str(public.M('sites').count()) data['ftps'] = str(public.M('ftps').count()) data['databases'] = str(public.M('databases').count()) data['system'] = panelsys.GetSystemVersion() + '|' + str( mem.total / 1024 / 1024) + 'MB|' + str(public.getCpuType()) + '*' + str( psutil.cpu_count()) + '|' + str( public.get_webserver()) + '|' + session['version'] data['system'] += '||' + self.GetInstalleds( mplugin.getPluginList(None)) data['logs'] = logs data['oem'] = '' data['intrusion'] = 0 data['uid'] = self.get_uid() #msg = public.getMsg('PANEL_UPDATE_MSG'); data['o'] = '' filename = '/www/server/panel/data/o.pl' if os.path.exists(filename): data['o'] = str(public.readFile(filename)) sUrl = public.GetConfigValue('home') + '/api/panel/updateLinux' updateInfo = json.loads(public.httpPost(sUrl, data)) if not updateInfo: return public.returnMsg(False, "CONNECT_ERR") #updateInfo['msg'] = msg; session['updateInfo'] = updateInfo #检查是否需要升级 if updateInfo['is_beta'] == 1: if updateInfo['beta']['version'] == session['version']: return public.returnMsg(False, updateInfo) else: if updateInfo['version'] == session['version']: return public.returnMsg(False, updateInfo) #是否执行升级程序 if (updateInfo['force'] == True or hasattr(get, 'toUpdate') == True or os.path.exists('data/autoUpdate.pl') == True): if updateInfo['is_beta'] == 1: updateInfo['version'] = updateInfo['beta']['version'] setupPath = public.GetConfigValue('setup_path') uptype = 'update' httpUrl = public.get_url() if httpUrl: updateInfo[ 'downUrl'] = httpUrl + '/install/' + uptype + '/LinuxPanel-' + updateInfo[ 'version'] + '.zip' public.downloadFile(updateInfo['downUrl'], 'panel.zip') if os.path.getsize('panel.zip') < 1048576: return public.returnMsg(False, "PANEL_UPDATE_ERR_DOWN") public.ExecShell('unzip -o panel.zip -d ' + setupPath + '/') import compileall if os.path.exists('/www/server/panel/runserver.py'): public.ExecShell('rm -f /www/server/panel/*.pyc') if os.path.exists('/www/server/panel/class/common.py'): public.ExecShell('rm -f /www/server/panel/class/*.pyc') if os.path.exists('panel.zip'): os.remove("panel.zip") session['version'] = updateInfo['version'] if 'getCloudPlugin' in session: del (session['getCloudPlugin']) if updateInfo['is_beta'] == 1: self.to_beta() public.ExecShell("/etc/init.d/bt start") public.writeFile('data/restart.pl', 'True') return public.returnMsg(True, 'PANEL_UPDATE', (updateInfo['version'], )) #输出新版本信息 data = { 'status': True, 'version': updateInfo['version'], 'updateMsg': updateInfo['updateMsg'] } public.ExecShell('rm -rf /www/server/phpinfo/*') return public.returnMsg(True, updateInfo) except Exception as ex: return public.returnMsg(False, "CONNECT_ERR")
def GetDirSize(self,get): get.path = get.path.encode('utf-8'); import web tmp = public.ExecShell('du -sbh '+ get.path) return tmp[0].split()[0]
certificate_pem, _, _ = _do_request(order['certificate'], err_msg="Certificate download failed") log.info("Certificate signed!") return certificate_pem if __name__ == "__main__": # 文件验证调用脚本 os.chdir("/www/server/panel") sys.path.append("class/") import public data = json.loads(sys.argv[1]) print (data) sitedomain = data['siteName'] path = data['path'] public.ExecShell("mkdir -p {}".format(path)) KEY_PREFIX = os.path.join(path, "privkey") ACCOUNT_KEY = os.path.join(path, "letsencrypt-account.key") DOMAIN_KEY = os.path.join(path, "privkey.pem") DOMAIN_DIR = data['sitePath'] DOMAINS = data['DOMAINS'] DOMAIN_PEM = KEY_PREFIX + ".pem" DOMAIN_CSR = KEY_PREFIX + ".csr" DOMAIN_CRT = KEY_PREFIX + ".crt" DOMAIN_CHAINED_CRT = os.path.join(path, "fullchain.pem") if not os.path.isfile(ACCOUNT_KEY): public.ExecShell('''openssl genrsa 4096 > "{}" '''.format(ACCOUNT_KEY)) print ("Generate account key...") if not os.path.isfile(DOMAIN_KEY): public.ExecShell('''openssl genrsa 2048 > "{}" '''.format(DOMAIN_KEY)) print ("Generate domain key...")
def get_lines(self, args): if not os.path.exists(args.filename): return public.returnMsg(False, '指定日志文件不存在!') s_body = public.ExecShell("tail -n {} {}".format( args.num, args.filename))[0] return public.returnMsg(True, s_body)
def request_post(self, post): if not hasattr(post, 'username') or not hasattr(post, 'password'): return public.returnJson(False, 'LOGIN_USER_EMPTY'), json_header self.error_num(False) if self.limit_address('?') < 1: return public.returnJson(False, 'LOGIN_ERR_LIMIT'), json_header post.username = post.username.strip() public.chdck_salt() sql = db.Sql() user_list = sql.table('users').field( 'id,username,password,salt').select() userInfo = None for u_info in user_list: if public.md5(u_info['username']) == post.username: userInfo = u_info if 'code' in session: if session['code'] and not 'is_verify_password' in session: if not hasattr(post, 'code'): return public.returnJson( False, 'Verification code can not be empty!'), json_header if not public.checkCode(post.code): public.WriteLog('TYPE_LOGIN', 'LOGIN_ERR_CODE', ('****', '****', public.GetClientIp())) return public.returnJson(False, 'CODE_ERR'), json_header try: if not userInfo['salt']: public.chdck_salt() userInfo = sql.table('users').where( 'id=?', (userInfo['id'], )).field('id,username,password,salt').find() password = public.md5(post.password.strip() + userInfo['salt']) if public.md5( userInfo['username'] ) != post.username or userInfo['password'] != password: public.WriteLog('TYPE_LOGIN', 'LOGIN_ERR_PASS', ('****', '******', public.GetClientIp())) num = self.limit_address('+') return public.returnJson(False, 'LOGIN_USER_ERR', (str(num), )), json_header _key_file = "/www/server/panel/data/two_step_auth.txt" #登陆告警 public.login_send_body("Userinfo", userInfo['username'], public.GetClientIp(), str(request.environ.get('REMOTE_PORT'))) if hasattr(post, 'vcode'): if self.limit_address('?', v="vcode") < 1: return public.returnJson( False, 'You have failed verification many times, forbidden for 10 minutes' ), json_header import pyotp secret_key = public.readFile(_key_file) if not secret_key: return public.returnJson( False, "Did not find the key, please close Google verification on the command line and trun on again" ), json_header t = pyotp.TOTP(secret_key) result = t.verify(post.vcode) if not result: if public.sync_date(): result = t.verify(post.vcode) if not result: num = self.limit_address('++', v="vcode") return public.returnJson( False, 'Invalid Verification code. You have [{}] times left to try!' .format(num)), json_header now = int(time.time()) public.writeFile( "/www/server/panel/data/dont_vcode_ip.txt", json.dumps({ "client_ip": public.GetClientIp(), "add_time": now })) self.limit_address('--', v="vcode") self.set_cdn_host(post) return self._set_login_session(userInfo) acc_client_ip = self.check_two_step_auth() if not os.path.exists(_key_file) or acc_client_ip: self.set_cdn_host(post) return self._set_login_session(userInfo) self.limit_address('-') session['is_verify_password'] = True return "1" except Exception as ex: stringEx = str(ex) if stringEx.find('unsupported') != -1 or stringEx.find('-1') != -1: public.ExecShell("rm -f /tmp/sess_*") public.ExecShell("rm -f /www/wwwlogs/*log") public.ServiceReload() return public.returnJson(False, 'USER_INODE_ERR'), json_header public.WriteLog('TYPE_LOGIN', 'LOGIN_ERR_PASS', ('****', '******', public.GetClientIp())) num = self.limit_address('+') return public.returnJson(False, 'LOGIN_USER_ERR', (str(num), )), json_header
def to_new_version(self, get=None): if not os.path.exists(self.rsyn_path + 'secrets'): os.mkdir(self.rsyn_path + 'secrets') if not os.path.exists(self.rsyn_file): os.mknod(self.rsyn_file) data_conf = '''uid = root gid = root use chroot = yes port = 873 hosts allow = log file = /var/log/rsyncd.log pid file = /var/run/rsyncd.pid ''' public.ExecShell('echo "%s" > %s' % (data_conf, self.rsyn_file)) self.rsyn_conf = {} with open(self.rsyn_file, "r") as conf: section = 'is_global' self.rsyn_conf[section] = {} for row in conf: if not re.match("^[\s]*?#", row) and row != "\n": is_section = re.findall("\[(.*?)\]", row) if is_section: section = is_section[0] self.rsyn_conf[section] = {} else: try: info = row.split('=') key = info[0].strip() value = info[1].strip() if section == 'is_global' and key in [ "log file", "pid file", "uid", "gid", "use chroot" ]: continue if key == "secrets file": passwd = re.findall(":(\w+)", public.readFile(value))[0] self.rsyn_conf[section]["passwd"] = passwd continue if key == "auth users": continue key = "user" if key == "hosts allow": key = "ip" value = value.replace(",", "\n") if key == "dont commpress": key = "dont_commpress" value = value.replace(' *.', ',')[2:] key = key.replace(" ", "_") self.rsyn_conf[section][key] = value except: pass if not 'port' in self.rsyn_conf['is_global'].keys(): self.rsyn_conf['is_global']['port'] = 873 if not 'ip' in self.rsyn_conf['is_global'].keys(): self.rsyn_conf['is_global']['ip'] = '' data = self.get_rsync_conf(None) data['global']['port'] = self.rsyn_conf['is_global']['port'] del (self.rsyn_conf['is_global']) for k in self.rsyn_conf.keys(): auth_pass = self.rsyn_path + '/secrets/' + k + '.db' com = True for m in data['modules']: if m['name'] == k: com = False break if not com: continue module = { 'name': k, 'path': self.rsyn_conf[k]['path'], 'password': self.rsyn_conf[k]['passwd'], 'comment': self.rsyn_conf[k]['comment'], 'read only': 'false', 'ignore errors': True, 'auth users': k, 'secrets file': auth_pass, 'addtime': time.time() } data['modules'].insert(0, module) serverDict = public.readFile(self.rsyn_path + '/serverdict.json') if serverDict: serverDict = json.loads(serverDict) for k in serverDict.keys(): del (serverDict[k]['cron_info']['id']) tmp = k.split('_') sclient = { 'model': 'default.rsync', 'name': k, 'ip': tmp[0], 'password': public.readFile(self.rsyn_path + '/sclient/' + k + '.db'), 'path': serverDict[k]['path'], 'to': '', 'exclude': [], 'delete': 'false', 'realtime': serverDict[k]['inotify_info'], 'delay': 3, 'rsync': { 'bwlimit': '200', 'port': str(serverDict[k]['port']), 'compress': 'true', 'archive': 'true', 'verbose': 'true' }, 'ps': '', 'cron': serverDict[k]['cron_info'], 'addtime': time.time() } data['client'].insert(0, sclient) os.remove(self.rsyn_path + '/serverdict.json') public.writeFile(self.rsyn_path + '/config.json', json.dumps(data))
def __write_lsync_pass(self, name, passwd, focre=True): auth_pass = self.rsyn_path + '/sclient/' + name + '_pass' if os.path.exists(auth_pass) and focre: return True public.writeFile(auth_pass, passwd) public.ExecShell("chmod 600 " + auth_pass) return True
def GetReplicateStatus(self, get): conf = public.readFile(self.datafile) status_list = [] if os.path.exists(self.datafile) and conf != "": conf = json.loads(conf) # 兼容旧版本设置 if not isinstance(conf["slave_ip"], list): conf["slave_ip"] = [conf["slave_ip"]] conf["slave_port"] = [str(conf["slave_port"])] conf["slave_id"] = [int(conf["master_id"]) + 1] public.writeFile(self.datafile, json.dumps(conf)) try: slaveip = conf["slave_ip"] slaveport = conf["slave_port"] if "master_ip" in conf.keys(): slavestatus = pm.panelMysql().query("show slave status")[0] Slave_IO_Running = slavestatus[10] Slave_SQL_Running = slavestatus[11] master_ip = conf["master_ip"] slave_ip = "local" else: for i in slaveip: master_ip = "local" slave_ip = i if not self.CheckPort(slave_ip, slaveport[slaveip.index(i)]): status = { "Slave_IO_Running": "no", "Slave_SQL_Running": "no", "master_ip": master_ip, "slave_ip": slave_ip, "slavestatus": slavestatus, "replicate_dbs": conf["replicate_dbs"], "slave_port": slaveport[slaveip.index(i)] } status_list.append(status) continue # return public.returnMsg(False, '无法访问从服务器<br>请确认安全组是否已经放行<br>Mysql端口:%s' % i+":"+slaveport[slaveip.index(i)]) slavestatus = public.ExecShell( "mysql -h%s -P%s --connect_timeout=3 -u%s -p%s -e 'show slave status\G'" % (i, slaveport[slaveip.index(i)], "user" + conf["slave_user"], "pass" + conf["slave_pass"]))[0] Slave_IO_Running = "Slave_IO_Running:\s+(\w+)" Slave_SQL_Running = "Slave_SQL_Running:\s+(\w+)" if not slavestatus: Slave_IO_Running = "no" Slave_SQL_Running = "no" else: Slave_IO_Running = re.search( Slave_IO_Running, slavestatus).group(1) Slave_SQL_Running = re.search( Slave_SQL_Running, slavestatus).group(1) status = { "Slave_IO_Running": Slave_IO_Running, "Slave_SQL_Running": Slave_SQL_Running, "master_ip": master_ip, "slave_ip": slave_ip, "slavestatus": slavestatus, "replicate_dbs": conf["replicate_dbs"], "slave_port": slaveport[slaveip.index(i)] } status_list.append(status) except: slavestatus = "" Slave_IO_Running = "no" Slave_SQL_Running = "no" master_ip = "" slave_ip = "" else: return public.returnMsg(True, "获取成功") if not status_list: status_list = [{ "Slave_IO_Running": Slave_IO_Running, "Slave_SQL_Running": Slave_SQL_Running, "master_ip": master_ip, "slave_ip": slave_ip, "slavestatus": slavestatus, "replicate_dbs": conf["replicate_dbs"] }] return public.returnMsg(True, status_list)
def GetSearch(self,get): if not os.path.exists(get.path): return public.returnMsg(False,'DIR_NOT_EXISTS'); return public.ExecShell("find "+get.path+" -name '*"+get.search+"*'");
def FixReplicate(self, get): file = "%s/plugin/masterslave/data.json" % self.setpath conf = json.loads(public.readFile(file)) status = self.GetReplicateStatus(get) slave_ip = get.slave_ip if status: status_list = status["msg"] for status in status_list: if status["slave_ip"] == slave_ip: if status["Slave_IO_Running"] != "Yes" or status[ "Slave_SQL_Running"] != "Yes": mversion = pm.panelMysql().query( "select version()")[0][0].split("-")[0] Last_IO_Errno = re.search( "Last_IO_Errno:\s+(\d+)", status["slavestatus"]).group(1) if Last_IO_Errno == "1236": if "5.5" in mversion: errormsg = re.search( "Last_IO_Error:\s+(.+)", status["slavestatus"]).group(1) rep = "(mysql-bin\.\d+)\'\s\w{2}\s(\d+)" errormsg = re.search(rep, errormsg) errmysqlbin = errormsg.group(1) errlogpos = errormsg.group(2) os.system( "/www/server/mysql/bin/mysqlbinlog /www/server/data/%s|grep 'end_log_pos' > /www/server/data/btfix.log" % errmysqlbin) mpos = public.ExecShell( "tail -n 1 /www/server/data/btfix.log|awk '{print $7}'" )[0].split("\n")[0] print(mpos) if int(mpos) < int(errlogpos): change_sql = 'stop slave;change master to MASTER_LOG_FILE="%s",MASTER_LOG_POS=%s;start slave' % ( errmysqlbin, mpos) print(change_sql) print( self.__ExceSql( status["slave_ip"], status["slave_port"], "user" + conf["slave_user"], "pass" + conf["slave_pass"], change_sql)) status = self.GetReplicateStatus(get) status = status["msg"] if status[ "Slave_IO_Running"] == "Yes" and status[ "Slave_SQL_Running"] == "Yes": os.system( "rm -f /www/server/data/btfix.log") print("修复成功") return public.returnMsg(True, "修复成功") else: print("修复失败") return public.returnMsg(True, "修复失败") # 主键冲突处理 last_sql_errno = re.search( "Last_SQL_Errno:\s+(\d+)", status["slavestatus"]).group(1) if last_sql_errno == "1062": while True: errormsg = re.search( "Last_SQL_Error:\s+(.*)", status["slavestatus"]).group(1) primary = "entry\s'(\w+)'" defdb = "database:\s'(\w*)'" db_tb = "(insert|INSERT)\s+(into|INTO)\s+(`|)([\w\_\-\.]+)(`|)" primary = re.search(primary, errormsg).group(1) try: defdb = re.search(defdb, errormsg).group(1) except: defdb = "" db_tb = re.search(db_tb, errormsg).group(4) print(primary, defdb, db_tb) if defdb: db_tb = defdb + "." + db_tb.split(".")[-1] sql = "desc %s" % db_tb result = pm.panelMysql().query(sql) for i in result: if "PRI" in i: prikey = i[0] sql = 'delete from %s where %s=%s;stop slave;start slave;' % ( db_tb, prikey, primary) print(sql) a = self.__ExceSql(status["slave_ip"], status["slave_port"], "user" + conf["slave_user"], "pass" + conf["slave_pass"], sql) print(a) status_list = self.GetReplicateStatus( get)["msg"] for status in status_list: if status["slave_ip"] == slave_ip: last_sql_errno = re.search( "Last_SQL_Errno:\s+(\d+)", status["slavestatus"]).group(1) if last_sql_errno != "1062": return public.returnMsg( True, "修复成功") else: return public.returnMsg(False, "无法修复") else: print("同步正常无需修复") return public.returnMsg(True, "同步正常无需修复") else: return public.returnMsg(False, "获取主从状态失败")
def syncDate(self, get): dateStr = public.HttpGet( public.GetConfigValue('home') + '/api/index/get_date') result = public.ExecShell('date -s "%s"' % dateStr) public.WriteLog("TYPE_PANEL", "DATE_SUCCESS") return public.returnMsg(True, "DATE_SUCCESS")
def StartTask(self, get): echo = public.M('crontab').where('id=?', (get.id, )).getField('echo') execstr = public.GetConfigValue('setup_path') + '/cron/' + echo public.ExecShell('chmod +x ' + execstr) public.ExecShell('nohup ' + execstr + ' >> ' + execstr + '.log 2>&1 &') return public.returnMsg(True, 'CRONTAB_TASK_EXEC')
def backupDatabase(self, name, count): sql = db.Sql() path = sql.table('databases').where('name=?', (name, )).getField('path') startTime = time.time() if not path: endDate = time.strftime('%Y/%m/%d %X', time.localtime()) log = "数据库[" + name + "]不存在!" print "★[" + endDate + "] " + log print "----------------------------------------------------------------------------" return backup_path = sql.table('config').where( "id=?", (1, )).getField('backup_path') + '/database' if not os.path.exists(backup_path): public.ExecShell("mkdir -p " + backup_path) filename = backup_path + "/Db_" + name + "_" + time.strftime( '%Y%m%d_%H%M%S', time.localtime()) + ".sql.gz" import re mysql_root = sql.table('config').where("id=?", (1, )).getField('mysql_root') mycnf = public.readFile('/etc/my.cnf') rep = "\[mysqldump\]\nuser=root" sea = "[mysqldump]\n" subStr = sea + "user=root\npassword="******"\n" mycnf = mycnf.replace(sea, subStr) if len(mycnf) > 100: public.writeFile('/etc/my.cnf', mycnf) public.ExecShell( "/www/server/mysql/bin/mysqldump --opt --default-character-set=utf8 " + name + " | gzip > " + filename) if not os.path.exists(filename): endDate = time.strftime('%Y/%m/%d %X', time.localtime()) log = "数据库[" + name + "]备份失败!" print "★[" + endDate + "] " + log print "----------------------------------------------------------------------------" return mycnf = public.readFile('/etc/my.cnf') mycnf = mycnf.replace(subStr, sea) if len(mycnf) > 100: public.writeFile('/etc/my.cnf', mycnf) endDate = time.strftime('%Y/%m/%d %X', time.localtime()) outTime = time.time() - startTime pid = sql.table('databases').where('name=?', (name, )).getField('id') sql.table('backup').add('type,name,pid,filename,addtime,size', (1, os.path.basename(filename), pid, filename, endDate, os.path.getsize(filename))) log = "数据库[" + name + "]备份成功,用时[" + str(round(outTime, 2)) + "]秒" public.WriteLog('计划任务', log) print "★[" + endDate + "] " + log print "|---保留最新的[" + count + "]份备份" print "|---文件名:" + filename #清理多余备份 backups = sql.table('backup').where( 'type=? and pid=?', ('1', pid)).field('id,filename').select() num = len(backups) - int(count) if num > 0: for backup in backups: public.ExecShell("rm -f " + backup['filename']) sql.table('backup').where('id=?', (backup['id'], )).delete() num -= 1 print "|---已清理过期备份文件:" + backup['filename'] if num < 1: break
def GetConcifInfo(self, get=None): #取环境配置信息 if not 'config' in session: session['config'] = public.M('config').where( "id=?", ('1', )).field('webserver,sites_path,backup_path,status,mysql_root' ).find() if not 'email' in session['config']: session['config']['email'] = public.M('users').where( "id=?", ('1', )).getField('email') data = {} data = session['config'] data['webserver'] = session['config']['webserver'] #PHP版本 phpVersions = ('52', '53', '54', '55', '56', '70', '71', '72', '73', '74') data['php'] = [] for version in phpVersions: tmp = {} tmp['setup'] = os.path.exists(self.setupPath + '/php/' + version + '/bin/php') if tmp['setup']: phpConfig = self.GetPHPConfig(version) tmp['version'] = version tmp['max'] = phpConfig['max'] tmp['maxTime'] = phpConfig['maxTime'] tmp['pathinfo'] = phpConfig['pathinfo'] tmp['status'] = os.path.exists('/tmp/php-cgi-' + version + '.sock') data['php'].append(tmp) tmp = {} data['webserver'] = '' serviceName = 'nginx' tmp['setup'] = False phpversion = "54" phpport = '888' pstatus = False pauth = False if os.path.exists(self.setupPath + '/nginx'): data['webserver'] = 'nginx' serviceName = 'nginx' tmp['setup'] = os.path.exists(self.setupPath + '/nginx/sbin/nginx') configFile = self.setupPath + '/nginx/conf/nginx.conf' try: if os.path.exists(configFile): conf = public.readFile(configFile) rep = "listen\s+([0-9]+)\s*;" rtmp = re.search(rep, conf) if rtmp: phpport = rtmp.groups()[0] if conf.find('AUTH_START') != -1: pauth = True if conf.find(self.setupPath + '/stop') == -1: pstatus = True configFile = self.setupPath + '/nginx/conf/enable-php.conf' conf = public.readFile(configFile) rep = "php-cgi-([0-9]+)\.sock" rtmp = re.search(rep, conf) if rtmp: phpversion = rtmp.groups()[0] except: pass elif os.path.exists(self.setupPath + '/apache'): data['webserver'] = 'apache' serviceName = 'httpd' tmp['setup'] = os.path.exists(self.setupPath + '/apache/bin/httpd') configFile = self.setupPath + '/apache/conf/extra/httpd-vhosts.conf' try: if os.path.exists(configFile): conf = public.readFile(configFile) rep = "php-cgi-([0-9]+)\.sock" rtmp = re.search(rep, conf) if rtmp: phpversion = rtmp.groups()[0] rep = "Listen\s+([0-9]+)\s*\n" rtmp = re.search(rep, conf) if rtmp: phpport = rtmp.groups()[0] if conf.find('AUTH_START') != -1: pauth = True if conf.find(self.setupPath + '/stop') == -1: pstatus = True except: pass tmp['type'] = data['webserver'] tmp['version'] = public.readFile(self.setupPath + '/' + data['webserver'] + '/version.pl') tmp['status'] = False result = public.ExecShell('/etc/init.d/' + serviceName + ' status') if result[0].find('running') != -1: tmp['status'] = True data['web'] = tmp tmp = {} vfile = self.setupPath + '/phpmyadmin/version.pl' tmp['version'] = public.readFile(vfile) if tmp['version']: tmp['version'] = tmp['version'].strip() tmp['setup'] = os.path.exists(vfile) tmp['status'] = pstatus tmp['phpversion'] = phpversion.strip() tmp['port'] = phpport tmp['auth'] = pauth data['phpmyadmin'] = tmp tmp = {} tmp['setup'] = os.path.exists('/etc/init.d/tomcat') tmp['status'] = tmp['setup'] #if public.ExecShell('ps -aux|grep tomcat|grep -v grep')[0] == "": tmp['status'] = False tmp['version'] = public.readFile(self.setupPath + '/tomcat/version.pl') data['tomcat'] = tmp tmp = {} tmp['setup'] = os.path.exists(self.setupPath + '/mysql/bin/mysql') tmp['version'] = public.readFile(self.setupPath + '/mysql/version.pl') tmp['status'] = os.path.exists('/tmp/mysql.sock') data['mysql'] = tmp tmp = {} tmp['setup'] = os.path.exists(self.setupPath + '/redis/runtest') tmp['status'] = os.path.exists('/var/run/redis_6379.pid') data['redis'] = tmp tmp = {} tmp['setup'] = os.path.exists('/usr/local/memcached/bin/memcached') tmp['status'] = os.path.exists('/var/run/memcached.pid') data['memcached'] = tmp tmp = {} tmp['setup'] = os.path.exists(self.setupPath + '/pure-ftpd/bin/pure-pw') tmp['version'] = public.readFile(self.setupPath + '/pure-ftpd/version.pl') tmp['status'] = os.path.exists('/var/run/pure-ftpd.pid') data['pure-ftpd'] = tmp data['panel'] = self.GetPanelInfo() data['systemdate'] = public.ExecShell( 'date +"%Y-%m-%d %H:%M:%S %Z %z"')[0].strip() return data
def SetMaster(self, get): if not self.GetPort(get): print(self.GetPort(get)) return public.returnMsg(False, '请确定数据库是否已经开启') iprep = "(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})\.(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})\.(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})\.(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})" if re.search(iprep, get.slave_ip): slave_ip = re.search(iprep, get.slave_ip).group() else: print('请输入正确的IP地址') return public.returnMsg(False, '请输入正确的IP地址') ip = self.GetLocalIP() for i in ip: if i == slave_ip: return public.returnMsg(False, '不能输入本机的IP') try: slave_port = int(get.slave_port) if slave_port >= 65535 or slave_port < 1: return public.returnMsg(False, '请输入正确的端口号') except: return public.returnMsg(False, '请输入正确的端口号') if not self.CheckBinLog(): return public.returnMsg(False, '请先开启Mysql二进制日志') if not self.CheckPort(slave_ip, slave_port): return public.returnMsg( False, '无法访问从服务器<br>请确认安全组是否已经放行<br>Mysql端口:%s' % slave_port) mconf = public.readFile(self.__mfile) masterinfo = self.GetMasterInfo(get) masterinfo["replicate_dbs"] = json.loads(get.replicate_dbs) dbmsg = [] if masterinfo["replicate_dbs"][0] == "alldatabases": for i in self.GetDbs(get): if i != "mysql": d = public.M('databases').where('name=?', ('%s' % i, )).find() dbmsg.append(d) else: for i in masterinfo["replicate_dbs"]: d = public.M('databases').where('name=?', (i, )).find() dbmsg.append(d) masterinfo["slave_ip"] = [slave_ip] masterinfo["slave_port"] = [str(slave_port)] masterinfo["replicate_dbs_info"] = dbmsg addconf = """ log-slave-updates=true enforce-gtid-consistency=true gtid-mode=on """ if masterinfo["replicate_dbs"][0] == "alldatabases": masterinfo["slave_ips"] = public.M('config').where( 'id=?', (1, )).getField('mysql_root') print(masterinfo["master_version"]) if "5.5" not in masterinfo["master_version"] and not re.match( "10", masterinfo["master_version"]): print(masterinfo["master_version"]) if not re.search("gtid-mode=on", mconf): mconf = re.sub("\[mysqld\]", "[mysqld]" + addconf, mconf) public.writeFile(self.__mfile, mconf) self.WriteLog("重启mysql") pid_old = public.ExecShell( "ps aux|grep 'mysql.sock'|awk 'NR==1 {print $2}'" )[0].split("\n")[0] self.WriteLog("旧PID %s" % pid_old) pid_new = pid_old public.writeFile("/tmp/mysqlpid", "") for i in range(10): if i == 0: os.system("/etc/init.d/mysqld restart &") time.sleep(10) pid_new = public.ExecShell( "ps aux|grep 'mysql.sock'|awk 'NR==1 {print $2}'" )[0].split("\n")[0] self.WriteLog("新PID %s" % pid_new) if pid_old == pid_new: time.sleep(10) pid_new = public.ExecShell( "ps aux|grep 'mysql.sock'|awk 'NR==1 {print $2}'" )[0].split("\n")[0] else: public.writeFile("/tmp/mysqlpid", "ok") break time.sleep(1) self.CreateSalveUser(masterinfo, slave_ip) keys = base64.b64encode(json.dumps(masterinfo)) public.writeFile(self.datafile, json.dumps(masterinfo)) return keys
def RestartServer(self, get): if not public.IsRestart(): return public.returnMsg(False, 'EXEC_ERR_TASK') public.ExecShell("sync && init 6 &") return public.returnMsg(True, 'SYS_REBOOT')
def SetSpeed(self): data = public.getSpeed() bakpath = "/www/backup/database/masterslave.sql" if data["title"] == "导入数据库": self.SetTotalSpeed({"total": "80"}) conffile = "%s/plugin/masterslave/data.json" % self.setpath masterinfo = json.loads(public.readFile(conffile)) public.writeSpeed(data["title"], 1, data["total"]) while True: data = public.getSpeed() time.sleep(1) if public.ExecShell("ps aux|grep 'mysql -uroot -p'|wc -l" )[0].split("\n")[0] == "2": public.writeSpeed(data["title"], data["total"], data["total"]) break if data["used"] < data["total"]: if masterinfo["replicate_dbs"][0] == "alldatabases": used = float(pm.panelMysql().query( "select concat(round(sum(data_length/1024/1024),2),'MB') as data from information_schema.tables" )[0][0].split("M")[0]) else: used = 0 try: for i in masterinfo["replicate_dbs"]: used += float(pm.panelMysql().query( "select concat(round(sum(data_length/1024/1024),2),'MB') as data from tables where table_schema='%s'" % i)[0][0].split("M")[0]) except: used = data["total"] public.writeSpeed(data["title"], int(used), data["total"]) else: public.writeSpeed(data["title"], data["total"], data["total"]) break if data["title"] == "备份数据库": self.SetTotalSpeed({"total": "30"}) while True: data = public.getSpeed() time.sleep(1) if public.ExecShell("ps aux|grep 'mysqldump -h'|wc -l" )[0].split("\n")[0] == "2": public.writeSpeed(data["title"], data["total"], data["total"]) break if data["used"] < data["total"]: # used = int(public.ExecShell("du -sm |awk '{print $1}'" % bakpath)[0].split("M")[0]) used = int( public.ExecShell("du -sm %s|awk '{print $1}'" % bakpath)[0].split("\n")[0]) if used > data["total"]: used = data["total"] public.writeSpeed(data["title"], int(used), data["total"]) else: public.writeSpeed(data["title"], data["total"], data["total"]) if data["title"] == "重启数据库": self.SetTotalSpeed({"total": "99"}) n = 0 while True: data = public.getSpeed() time.sleep(1) if n == 100: break if public.readFile("/tmp/mysqlpid"): public.writeSpeed(data["title"], data["total"], data["total"]) self.SetTotalSpeed({"total": "100"}) os.system("rm -f /tmp/mysqlpid") break n += 1
def UpdatePanel(self, get): #return public.returnMsg(False,'演示服务器,禁止此操作!'); try: if not public.IsRestart(): return public.returnMsg(False, 'EXEC_ERR_TASK') import web, json if int(web.ctx.session.config['status']) == 0: public.httpGet(web.ctx.session.home + '/Api/SetupCount?type=Linux') public.M('config').where("id=?", ('1', )).setField('status', 1) #取回远程版本信息 if hasattr(web.ctx.session, 'updateInfo') == True and hasattr( get, 'check') == False: updateInfo = web.ctx.session.updateInfo else: login_temp = 'data/login.temp' if os.path.exists(login_temp): logs = public.readFile(login_temp) os.remove(login_temp) else: logs = '' import psutil, panelPlugin, system mem = psutil.virtual_memory() mplugin = panelPlugin.panelPlugin() mplugin.ROWS = 10000 panelsys = system.system() data = {} data['sites'] = str(public.M('sites').count()) data['ftps'] = str(public.M('ftps').count()) data['databases'] = str(public.M('databases').count()) data['system'] = panelsys.GetSystemVersion() + '|' + str( mem.total / 1024 / 1024) + 'MB|' + public.getCpuType() + '*' + str( psutil.cpu_count()) + '|' + public.get_webserver( ) + '|' + web.ctx.session.version data['system'] += '||' + self.GetInstalleds( mplugin.getPluginList(None)) data['logs'] = logs data['oem'] = '' msg = public.getMsg('PANEL_UPDATE_MSG') sUrl = web.ctx.session.home + '/Api/updateLinux' betaIs = 'data/beta.pl' betaStr = public.readFile(betaIs) if betaStr: if betaStr.strip() != 'False': sUrl = web.ctx.session.home + '/Api/updateLinuxBeta' msg = public.getMsg('PANEL_UPDATE_MSG_TEST') betaIs = 'plugin/beta/config.conf' betaStr = public.readFile(betaIs) if betaStr: if betaStr.strip() != 'False': sUrl = web.ctx.session.home + '/Api/updateLinuxBeta' msg = public.getMsg('PANEL_UPDATE_MSG_TEST') updateInfo = json.loads(public.httpPost(sUrl, data)) if not updateInfo: return public.returnMsg(False, "CONNECT_ERR") updateInfo['msg'] = msg web.ctx.session.updateInfo = updateInfo #检查是否需要升级 if updateInfo['version'] == web.ctx.session.version: try: return public.returnMsg(False, updateInfo['msg']) except: return public.returnMsg(False, 'PANEL_UPDATE_ERR_NEW') #是否执行升级程序 if (updateInfo['force'] == True or hasattr(get, 'toUpdate') == True or os.path.exists('data/autoUpdate.pl') == True): setupPath = web.ctx.session.setupPath uptype = 'update' betaIs = 'plugin/beta/config.conf' betaStr = public.readFile(betaIs) if betaStr: if betaStr.strip() != 'False': uptype = 'updateTest' betaIs = 'data/beta.pl' betaStr = public.readFile(betaIs) if betaStr: if betaStr.strip() != 'False': uptype = 'updateTest' httpUrl = public.get_url() if httpUrl: updateInfo[ 'downUrl'] = httpUrl + '/install/' + uptype + '/LinuxPanel-' + updateInfo[ 'version'] + '.zip' public.downloadFile(updateInfo['downUrl'], 'panel.zip') if os.path.getsize('panel.zip') < 1048576: return public.returnMsg(False, "PANEL_UPDATE_ERR_DOWN") public.ExecShell('unzip -o panel.zip -d ' + setupPath + '/') import compileall if os.path.exists(setupPath + '/panel/main.py'): public.ExecShell('rm -f ' + setupPath + '/panel/*.pyc') if os.path.exists(setupPath + '/panel/class/common.py'): public.ExecShell('rm -f ' + setupPath + '/panel/class/*.pyc') compileall.compile_dir(setupPath + '/panel') compileall.compile_dir(setupPath + '/panel/class') public.ExecShell('rm -f panel.zip') web.ctx.session.version = updateInfo['version'] return public.returnMsg(True, 'PANEL_UPDATE', (updateInfo['version'], )) #输出新版本信息 data = { 'status': True, 'version': updateInfo['version'], 'updateMsg': updateInfo['updateMsg'] } public.ExecShell('rm -rf /www/server/phpinfo/*') return data except Exception, ex: return public.returnMsg(False, "CONNECT_ERR")
def BackUpMasterDbs(self, get): import MySQLdb bakpath = "/www/backup/database" # 是否为ip iprep = "(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})\.(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})\.(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})\.(2(5[0-5]{1}|[0-4]\d{1})|[0-1]?\d{1,2})" if re.search(iprep, get.master_ip): master_ip = re.search(iprep, get.master_ip).group() else: print('请输入正确的IP地址') return public.returnMsg(False, '请输入正确的IP地址') ip = self.GetLocalIP() for i in ip: if i == master_ip: return public.returnMsg(False, '不能输入本机的IP') # 解码 masterinfo = json.loads(base64.b64decode(get.keys)) masterinfo["master_ip"] = master_ip # slave_version = pm.panelMysql().query("select version()")[0][0].split("-")[0] slave_version = self.GetVersion() masterinfo["slave_version"] = slave_version # 写入data.json供设置速度使用 self.WriteLog(json.dumps(masterinfo)) public.writeFile(self.datafile, json.dumps(masterinfo)) if not self.CheckPort(master_ip, masterinfo["master_port"]): return public.returnMsg( False, '无法访问从服务器<br>请确认安全组是否已经放行<br>Mysql端口:%s' % masterinfo["master_port"]) if slave_version in masterinfo["master_version"]: try: master_port = int(masterinfo["master_port"]) except Exception as e: return public.returnMsg(False, e) try: db = MySQLdb.connect(host=masterinfo["master_ip"], port=master_port, user="******", passwd=masterinfo["btmysql"], charset="utf8") cur = db.cursor() except: return public.returnMsg( False, '无法连接主服务器,请确定主服务器 IP端口是否正确,安全组是否已经放行Mysql端口') # 开始备份 backsqlpath = "%s/masterslave.sql" % (bakpath) backsh = "nohup mysqldump -h%s -P%s -u%s -p%s --master-data=2 --skip-lock-tables --single-transaction %s%s 1> %s 2>/dev/null&" if masterinfo["replicate_dbs"][0] == "alldatabases": print("Starting backup of databases alldatabases") self.WriteLog("开始备份数据库") # 统计数据库大小 cur.execute( "select concat(round(sum(data_length/1024/1024),2),'MB') as data from information_schema.tables" ) total_db = int(float(cur.fetchall()[0][0].split("M")[0])) print(total_db) if total_db == 0: total_db = 2 public.writeSpeed("备份数据库", 1, total_db) # 开始备份数据库 try: self.WriteLog("备份数据库 %s" % "alldatabases") error = public.ExecShell( backsh % (masterinfo["master_ip"], masterinfo["master_port"], "btmysql", masterinfo["btmysql"], "--all-databases", "", backsqlpath))[1] if "error" in error or "not exist" in error: return public.returnMsg( False, '数据库备份失败 %s\n错误信息:%s\n ,请检测主库是否有问题' % ("alldatabases", error)) except: self.WriteLog("备份失败 %s" % "alldatabases") return public.returnMsg(False, '数据库备份失败 %s' % "alldatabases") threading.Thread(target=self.SetSpeed()).start() else: total_db = 1 replicate_dbs = "" cur.execute("use information_schema") for d in masterinfo["replicate_dbs"]: replicate_dbs += " %s " % d # 统计数据库大小 cur.execute( "select concat(round(sum(data_length/1024/1024),2),'MB') as data from tables where table_schema='%s'" % d) a = cur.fetchall()[0][0] if a: total_db += float(a.split("M")[0]) print(total_db) public.writeSpeed("备份数据库", 1, int(total_db)) print("Starting backup of databases %s" % replicate_dbs) # 开始备份数据库 try: self.WriteLog("备份数据库 %s" % replicate_dbs) error = public.ExecShell( backsh % (masterinfo["master_ip"], masterinfo["master_port"], "btmysql", masterinfo["btmysql"], "--databases", replicate_dbs, backsqlpath))[1] if "error" in error or "not exist" in error: return public.returnMsg( False, '数据库备份失败 %s\n错误信息:%s\n ,请检测主库是否有问题' % ("replicate_dbs", error)) except: self.WriteLog("备份失败 %s" % replicate_dbs) return public.returnMsg(False, '数据库备份失败 %s' % replicate_dbs) threading.Thread(target=self.SetSpeed()).start() self.WriteLog("备份成功") masterlogdata = public.ExecShell("head -n 50 %s" % backsqlpath) try: masterlogdata = masterlogdata[0] rep = "CHANGE MASTER TO MASTER_LOG_FILE='([\w\-\.]+)',\s*MASTER_LOG_POS=(\d+);" logfile = re.search(rep, masterlogdata).group(1) logpos = re.search(rep, masterlogdata).group(2) except: return public.returnMsg(False, '获取Master信息失败') try: gtid = self.__ExceSql('SELECT BINLOG_GTID_POS("%s", %s)' % (logfile, logpos), masterinfo=masterinfo)[0].split("\n")[1] except: gtid = "" db.close() public.writeFile("%s/log.txt" % bakpath, str([logfile, logpos])) masterinfo["logfile"] = logfile masterinfo["logpos"] = logpos masterinfo["gtid"] = gtid masterinfo["backsqlpath"] = backsqlpath public.writeFile("%s/plugin/masterslave/data.json" % self.setpath, json.dumps(masterinfo)) public.writeFile("/tmp/mysql.log", masterinfo, "a+") return masterinfo else: self.WriteLog("mysql版本不一致 主版本%s 从版本%s" % (masterinfo["master_version"], slave_version)) return public.returnMsg( False, 'mysql版本不一致 主版本%s 从版本%s' % (masterinfo["master_version"], slave_version))
def GetApacheStatus(self): process_cpu = {} apacheconf = "%s/apache/conf/httpd.conf" % (self.setupPath) confcontent = public.readFile(apacheconf) rep = "#Include conf/extra/httpd-info.conf" if re.search(rep, confcontent): confcontent = re.sub(rep, "Include conf/extra/httpd-info.conf", confcontent) public.writeFile(apacheconf, confcontent) public.serviceReload() result = public.HttpGet('http://127.0.0.1/server-status?auto') try: workermen = int( public.ExecShell( "ps aux|grep httpd|grep 'start'|awk '{memsum+=$6};END {print memsum}'" )[0]) / 1024 except: return public.returnMsg(False, "Get worker RAM False") for proc in psutil.process_iter(): if proc.name() == "httpd": self.GetProcessCpuPercent(proc.pid, process_cpu) time.sleep(0.5) data = {} # 计算启动时间 Uptime = re.search("ServerUptimeSeconds:\s+(.*)", result) if not Uptime: return public.returnMsg(False, "Get worker Uptime False") Uptime = int(Uptime.group(1)) min = Uptime / 60 hours = min / 60 days = math.floor(hours / 24) hours = math.floor(hours - (days * 24)) min = math.floor(min - (days * 60 * 24) - (hours * 60)) #格式化重启时间 restarttime = re.search("RestartTime:\s+(.*)", result) if not restarttime: return public.returnMsg(False, "Get worker Restart Time False") restarttime = restarttime.group(1) rep = "\w+,\s([\w-]+)\s([\d\:]+)\s\w+" date = re.search(rep, restarttime) if not date: return public.returnMsg(False, "Get worker date False") date = date.group(1) timedetail = re.search(rep, restarttime) if not timedetail: return public.returnMsg(False, "Get worker time detail False") timedetail = timedetail.group(2) monthen = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ] n = 0 for m in monthen: if m in date: date = re.sub(m, str(n + 1), date) n += 1 date = date.split("-") date = "%s-%s-%s" % (date[2], date[1], date[0]) reqpersec = re.search("ReqPerSec:\s+(.*)", result) if not reqpersec: return public.returnMsg(False, "Get worker reqpersec False") reqpersec = reqpersec.group(1) if re.match("^\.", reqpersec): reqpersec = "%s%s" % (0, reqpersec) data["RestartTime"] = "%s %s" % (date, timedetail) data["UpTime"] = "%s day %s hour %s minute" % (str( int(days)), str(int(hours)), str(int(min))) total_acc = re.search("Total Accesses:\s+(\d+)", result) if not total_acc: return public.returnMsg(False, "Get worker TotalAccesses False") data["TotalAccesses"] = total_acc.group(1) total_kb = re.search("Total kBytes:\s+(\d+)", result) if not total_kb: return public.returnMsg(False, "Get worker TotalKBytes False") data["TotalKBytes"] = total_kb.group(1) data["ReqPerSec"] = round(float(reqpersec), 2) busywork = re.search("BusyWorkers:\s+(\d+)", result) if not busywork: return public.returnMsg(False, "Get worker BusyWorkers False") data["BusyWorkers"] = busywork.group(1) idlework = re.search("IdleWorkers:\s+(\d+)", result) if not idlework: return public.returnMsg(False, "Get worker IdleWorkers False") data["IdleWorkers"] = idlework.group(1) data["workercpu"] = round(float(process_cpu["httpd"]), 2) data["workermem"] = "%s%s" % (int(workermen), "MB") return data
def SetSlave(self, get): if not self.GetPort(get): return public.returnMsg(False, '请确定数据库是否已经开启') if not self.CheckBinLog(): return public.returnMsg(False, '请先开启Mysql二进制日志') sconf = public.readFile(self.__mfile) # 备份需要同步的数据库 masterinfo = self.BackUpMasterDbs(get) try: bkstatus = masterinfo["msg"] except: bkstatus = False if bkstatus: return bkstatus __dbpass = public.M('config').where('id=?', (1, )).getField('mysql_root') slave_version = masterinfo["slave_version"] create_replicate_sql = "" # Mysql5.5版本 if "5.5" in slave_version: create_replicate_sql += "CHANGE MASTER TO MASTER_HOST='%s',MASTER_PORT=%s,MASTER_USER='******',MASTER_PASSWORD='******',MASTER_LOG_FILE='%s',MASTER_LOG_POS=%s" % ( masterinfo["master_ip"], masterinfo["master_port"], masterinfo["slave_user"], masterinfo["slave_pass"], masterinfo["logfile"], masterinfo["logpos"]) # Mysql5.6+版本 addconf = """ log-slave-updates=true enforce-gtid-consistency=true gtid-mode=on""" if "5.5" not in slave_version and not re.match("10", slave_version): if not re.search("gtid-mode=on", sconf): sconf = re.sub("\[mysqld\]", "[mysqld]" + addconf, sconf) create_replicate_sql += "CHANGE MASTER TO MASTER_HOST='%s',MASTER_PORT=%s,MASTER_USER='******',MASTER_PASSWORD='******',MASTER_AUTO_POSITION = 1" % ( masterinfo["master_ip"], masterinfo["master_port"], masterinfo["slave_user"], masterinfo["slave_pass"]) # 构造要同步的数据库配置 replicate_dbs = "" if masterinfo["replicate_dbs"][0] != "alldatabases": for d in masterinfo["replicate_dbs"]: replicate_dbs += "\nreplicate-wild-do-table = %s.%s" % (d, "%") else: sconf = re.sub("replicate-wild-do-table\s*=\s*[\w\%\.\_\-]+", "", sconf) print(replicate_dbs) try: serverid = masterinfo["slave_id"] except: serverid = [int(masterinfo["master_id"]) + 1] localip = public.ExecShell("ip a")[0] netip = public.readFile("%s/data/iplist.txt") index = 0 try: for i in masterinfo["slave_ip"]: if i in localip or i in netip: index += masterinfo["slave_ip"].index("i") break if not index: return public.returnMsg(False, '主库没有设置该主机为从服务器,请先设置主服务器后再配置从库') except: pass serverid = serverid[index] if not re.search("replicate-wild-do-table", sconf): sconf = re.sub("server-id\s*=\s*\d+", "server-id = %s%s" % (serverid, replicate_dbs), sconf) public.writeFile(self.__mfile, sconf) # 导入主库数据库 try: pid_old = public.ExecShell( "ps aux|grep 'mysql.sock'|awk 'NR==1 {print $2}'")[0].split( "\n")[0] self.WriteLog("旧PID %s" % pid_old) pid_new = pid_old public.writeFile("/tmp/mysqlpid", "") for i in range(10): if i == 1: os.system("/etc/init.d/mysqld restart &") time.sleep(10) pid_new = public.ExecShell( "ps aux|grep 'mysql.sock'|awk 'NR==1 {print $2}'" )[0].split("\n")[0] self.WriteLog("新PID %s" % pid_new) if pid_old == pid_new: time.sleep(10) pid_new = public.ExecShell( "ps aux|grep 'mysql.sock'|awk 'NR==1 {print $2}'" )[0].split("\n")[0] else: public.writeFile("/tmp/mysqlpid", "ok") break pm.panelMysql().execute("stop slave") pm.panelMysql().execute("reset master") pm.panelMysql().execute("reset slave all") self.WriteLog("开始导入数据库") speed = public.getSpeed() public.writeSpeed("导入数据库", 1, speed["total"]) error = public.ExecShell( "nohup /usr/bin/mysql -uroot -p%s < %s &" % (__dbpass, masterinfo["backsqlpath"])) self.WriteLog(str(error)) except Exception as e: self.WriteLog("导入数据库失败 %s" % e) return public.ReturnMsg(False, "导入失败") threading.Thread(target=self.SetSpeed()).start() self.WriteLog("导入数据库完成") self.WriteLog("删除备份的数据库文件") os.system("rm -f %s" % masterinfo["backsqlpath"]) os.system("rm -f /tmp/mysqlpid") self.WriteLog("重启mysql") pid_old = public.ExecShell( "ps aux|grep 'mysql.sock'|awk 'NR==1 {print $2}'")[0].split( "\n")[0] self.WriteLog("旧PID %s" % pid_old) pid_new = "" public.writeFile("/tmp/mysqlpid", "") restart = 0 for i in range(10): if i == 1: os.system("/etc/init.d/mysqld restart &") time.sleep(10) pid_new = public.ExecShell( "ps aux|grep 'mysql.sock'|awk 'NR==1 {print $2}'" )[0].split("\n")[0] self.WriteLog("新PID %s" % pid_new) if pid_old == pid_new: time.sleep(10) pid_new = public.ExecShell( "ps aux|grep 'mysql.sock'|awk 'NR==1 {print $2}'" )[0].split("\n")[0] else: public.writeFile("/tmp/mysqlpid", "ok") restart += 1 break if restart == 0: return public.ReturnMsg(False, "导入数据后重启失败") public.writeSpeed("重启数据库", int(1), int(2)) threading.Thread(target=self.SetSpeed()).start() self.WriteLog("mysql重启完成") # 写入同步的数据库到面板数据库 for i in masterinfo["replicate_dbs_info"]: if not i: continue localdb = public.M('databases').where('name=?', (i[2], )).select() if not localdb: public.M('databases').add(("name,username,password,accept,ps"), (i[2], i[3], i[4], i[5], i[6])) # 完整复制将主root密码写入到从的面板 if masterinfo["replicate_dbs"][0] == "alldatabases": self.WriteLog("因为是完整同步,修改从库面板密码为主库") public.M('config').where('id=?', (1, )).setField('mysql_root', masterinfo["slave_ips"]) result = str(pm.panelMysql().query("select version()")[0]) self.WriteLog(result) if result == "1045": public.M('config').where('id=?', (1, )).setField( 'mysql_root', __dbpass) # Mairadb10.*版本 if re.match("10", slave_version): set_slave_pos_sql = "SET GLOBAL gtid_slave_pos='%s'" % masterinfo[ "gtid"] # 需要在数据重启后配置 pm.panelMysql().query(set_slave_pos_sql) create_replicate_sql += "CHANGE MASTER TO MASTER_HOST='%s',MASTER_PORT=%s,MASTER_USER='******',MASTER_PASSWORD='******',master_use_gtid=slave_pos" % ( masterinfo["master_ip"], masterinfo["master_port"], masterinfo["slave_user"], masterinfo["slave_pass"]) self.WriteLog("停止从服务") pm.panelMysql().query("stop slave") self.WriteLog("修改从服务器的主服务器信息") pm.panelMysql().query(create_replicate_sql) self.WriteLog("启动从服务") pm.panelMysql().query("start slave") time.sleep(2) self.WriteLog("获取从状态") slavestatus = pm.panelMysql().query("show slave status")[0] self.WriteLog(str(slavestatus)) self.WriteLog("创建Slave监控用户") create_status_user = "******" % ( "user" + masterinfo["slave_user"], masterinfo["master_ip"], "pass" + masterinfo["slave_pass"]) grant_status_user = "******" % ( "user" + masterinfo["slave_user"], masterinfo["master_ip"]) pm.panelMysql().execute(create_status_user) pm.panelMysql().execute(grant_status_user) n = 0 try: for i in slavestatus: if i == "Yes": n += 1 except: return public.returnMsg(False, '获取主从状态失败') if n == 2: print("设置成功") self.WriteLog("删除btmysql用户") self.__ExceSql('delete from mysql.user where user="******"', masterinfo=masterinfo) if masterinfo["replicate_dbs"][0] != "alldatabases": self.WriteLog("删除从btmysql用户") pm.panelMysql().execute( "delete from mysql.user where user='******'") self.WriteLog("设置成功") os.system("rm -f %s" % self.totalspeedfile) return public.returnMsg(True, '设置成功') else: self.WriteLog("设置失败") os.system("rm -f %s" % self.totalspeedfile) return public.returnMsg(True, '设置失败')
import urlparse from urlparse import urljoin import urllib2 import cryptography.hazmat import cryptography.hazmat.backends import cryptography.hazmat.primitives.serialization else: # python3 from urllib.parse import urlparse from urllib.parse import urljoin import cryptography import platform import hmac try: import requests except: public.ExecShell('pip install requests') import requests try: import OpenSSL except: public.ExecShell('pip install pyopenssl') import OpenSSL import random import datetime import logging from hashlib import sha1 os.chdir("/www/server/panel") sys.path.append("class/") import public caa_value = '0 issue "letsencrypt.org"'
def rsync_service(self, get): s_cmd = "/etc/init.d/rsynd " + get.state public.ExecShell(s_cmd) self.__check_port_appect(get) self.__write_logs(s_cmd + '已执行') return public.returnMsg(True, '操作成功!')