diff --git a/data/db.py b/class/db.py
similarity index 100%
rename from data/db.py
rename to class/db.py
diff --git a/class/public.py b/class/public.py
index 32eade083..82f170058 100755
--- a/class/public.py
+++ b/class/public.py
@@ -13,16 +13,15 @@ import re
import hashlib
-def getRunDir():
- return os.getcwd()
-
-runDir = getRunDir()
-print runDir + "/class/"
-sys.path.append(runDir + "/class/")
+sys.path.append(os.getcwd() + "/class/")
import db
from random import Random
-from flask import jsonify
+# from flask import jsonify
+
+
+def getRunDir():
+ return os.getcwd()
def M(table):
diff --git a/class/system.py b/class/system.py
new file mode 100755
index 000000000..99e6d55cd
--- /dev/null
+++ b/class/system.py
@@ -0,0 +1,634 @@
+#coding: utf-8
+# +-------------------------------------------------------------------
+# | 宝塔Linux面板 x3
+# +-------------------------------------------------------------------
+# | Copyright (c) 2015-2016 宝塔软件(http://bt.cn) All rights reserved.
+# +-------------------------------------------------------------------
+# | Author: 黄文良 <287962566@qq.com>
+# +-------------------------------------------------------------------
+import psutil,web,time,os,public,re
+class system:
+ setupPath = None;
+ pids = None
+ def __init__(self):
+ self.setupPath = '/www/server';
+
+ def GetConcifInfo(self,get=None):
+ #取环境配置信息
+ if not hasattr(web.ctx.session, 'config'):
+ web.ctx.session.config = public.M('config').where("id=?",('1',)).field('webserver,sites_path,backup_path,status,mysql_root').find();
+ if not hasattr(web.ctx.session.config,'email'):
+ web.ctx.session.config['email'] = public.M('users').where("id=?",('1',)).getField('email');
+ data = {}
+ data = web.ctx.session.config
+ data['webserver'] = web.ctx.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);
+ tmp['setup'] = os.path.exists(vfile);
+ tmp['status'] = pstatus;
+ tmp['phpversion'] = phpversion;
+ tmp['port'] = phpport;
+ tmp['auth'] = pauth;
+ data['phpmyadmin'] = tmp;
+
+ tmp = {}
+ tmp['setup'] = os.path.exists('/etc/init.d/tomcat');
+ tmp['status'] = False
+ if tmp['setup']:
+ if os.path.exists('/www/server/tomcat/logs/catalina-daemon.pid'):
+ tmp['status'] = self.getPid('jsvc')
+ if not tmp['status']:
+ tmp['status'] = self.getPid('java')
+ 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
+
+
+ #名取PID
+ def getPid(self,pname):
+ try:
+ if not self.pids: self.pids = psutil.pids()
+ for pid in self.pids:
+ if psutil.Process(pid).name() == pname: return True;
+ return False
+ except: return False
+
+ #检测指定进程是否存活
+ def checkProcess(self,pid):
+ try:
+ if not self.pids: self.pids = psutil.pids()
+ if int(pid) in self.pids: return True
+ return False;
+ except: return False
+
+
+ def GetPanelInfo(self,get=None):
+ #取面板配置
+ address = public.GetLocalIp()
+ try:
+ try:
+ port = web.ctx.host.split(':')[1]
+ except:
+ port = public.readFile('data/port.pl')
+ except:
+ port = '8888';
+ domain = ''
+ if os.path.exists('data/domain.conf'):
+ domain = public.readFile('data/domain.conf');
+
+ autoUpdate = ''
+ if os.path.exists('data/autoUpdate.pl'): autoUpdate = 'checked';
+ limitip = ''
+ if os.path.exists('data/limitip.conf'): limitip = public.readFile('data/limitip.conf');
+
+ templates = []
+ for template in os.listdir('templates/'):
+ if os.path.isdir('templates/' + template): templates.append(template);
+ template = public.readFile('data/templates.pl');
+
+ check502 = '';
+ if os.path.exists('data/502Task.pl'): check502 = 'checked';
+ return {'port':port,'address':address,'domain':domain,'auto':autoUpdate,'502':check502,'limitip':limitip,'templates':templates,'template':template}
+
+ def GetPHPConfig(self,version):
+ #取PHP配置
+ file = self.setupPath + "/php/"+version+"/etc/php.ini"
+ phpini = public.readFile(file)
+ file = self.setupPath + "/php/"+version+"/etc/php-fpm.conf"
+ phpfpm = public.readFile(file)
+ data = {}
+ try:
+ rep = "upload_max_filesize\s*=\s*([0-9]+)M"
+ tmp = re.search(rep,phpini).groups()
+ data['max'] = tmp[0]
+ except:
+ data['max'] = '50'
+ try:
+ rep = "request_terminate_timeout\s*=\s*([0-9]+)\n"
+ tmp = re.search(rep,phpfpm).groups()
+ data['maxTime'] = tmp[0]
+ except:
+ data['maxTime'] = 0
+
+ try:
+ rep = ur"\n;*\s*cgi\.fix_pathinfo\s*=\s*([0-9]+)\s*\n"
+ tmp = re.search(rep,phpini).groups()
+
+ if tmp[0] == '1':
+ data['pathinfo'] = True
+ else:
+ data['pathinfo'] = False
+ except:
+ data['pathinfo'] = False
+
+ return data
+
+
+ def GetSystemTotal(self,get,interval = 1):
+ #取系统统计信息
+ data = self.GetMemInfo();
+ cpu = self.GetCpuInfo(interval);
+ data['cpuNum'] = cpu[1];
+ data['cpuRealUsed'] = cpu[0];
+ data['time'] = self.GetBootTime();
+ data['system'] = self.GetSystemVersion();
+ data['isuser'] = public.M('users').where('username=?',('admin',)).count();
+ data['version'] = web.ctx.session.version;
+ return data
+
+ def GetLoadAverage(self,get):
+ c = os.getloadavg()
+ data = {};
+ data['one'] = float(c[0]);
+ data['five'] = float(c[1]);
+ data['fifteen'] = float(c[2]);
+ data['max'] = psutil.cpu_count() * 2;
+ data['limit'] = data['max'];
+ data['safe'] = data['max'] * 0.75;
+ return data;
+
+ def GetAllInfo(self,get):
+ data = {}
+ data['load_average'] = self.GetLoadAverage(get);
+ data['title'] = self.GetTitle();
+ data['network'] = self.GetNetWorkApi(get);
+ data['panel_status'] = not os.path.exists('/www/server/panel/data/close.pl');
+ import firewalls
+ ssh_info = firewalls.firewalls().GetSshInfo(None)
+ data['enable_ssh_status'] = ssh_info['status']
+ data['disable_ping_status'] = not ssh_info['ping']
+ data['time'] = self.GetBootTime();
+ #data['system'] = self.GetSystemVersion();
+ #data['mem'] = self.GetMemInfo();
+ data['version'] = web.ctx.session.version;
+ return data;
+
+ def GetTitle(self):
+ titlePl = 'data/title.pl';
+ title = '宝塔Linux面板';
+ if os.path.exists(titlePl): title = public.readFile(titlePl).strip();
+ return title;
+
+ def GetSystemVersion(self):
+ #取操作系统版本
+ import public
+ version = public.readFile('/etc/redhat-release')
+ if not version:
+ version = public.readFile('/etc/issue').strip().split("\n")[0].replace('\\n','').replace('\l','').strip();
+ else:
+ version = version.replace('release ','').strip();
+ return version
+
+ def GetBootTime(self):
+ #取系统启动时间
+ import public,math
+ conf = public.readFile('/proc/uptime').split()
+ tStr = float(conf[0])
+ min = tStr / 60;
+ hours = min / 60;
+ days = math.floor(hours / 24);
+ hours = math.floor(hours - (days * 24));
+ min = math.floor(min - (days * 60 * 24) - (hours * 60));
+ return public.getMsg('SYS_BOOT_TIME',(str(int(days)),str(int(hours)),str(int(min))))
+
+ def GetCpuInfo(self,interval = 1):
+ #取CPU信息
+ cpuCount = psutil.cpu_count()
+ used = psutil.cpu_percent(interval=interval)
+ return used,cpuCount
+
+ def GetMemInfo(self,get=None):
+ #取内存信息
+ mem = psutil.virtual_memory()
+ memInfo = {'memTotal':mem.total/1024/1024,'memFree':mem.free/1024/1024,'memBuffers':mem.buffers/1024/1024,'memCached':mem.cached/1024/1024}
+ memInfo['memRealUsed'] = memInfo['memTotal'] - memInfo['memFree'] - memInfo['memBuffers'] - memInfo['memCached']
+ return memInfo
+
+ def GetDiskInfo(self,get=None):
+ return self.GetDiskInfo2();
+ #取磁盘分区信息
+ diskIo = psutil.disk_partitions();
+ diskInfo = []
+
+ for disk in diskIo:
+ if disk[1] == '/mnt/cdrom':continue;
+ if disk[1] == '/boot':continue;
+ tmp = {}
+ tmp['path'] = disk[1]
+ tmp['size'] = psutil.disk_usage(disk[1])
+ diskInfo.append(tmp)
+ return diskInfo
+
+ def GetDiskInfo2(self):
+ #取磁盘分区信息
+ temp = public.ExecShell("df -h -P|grep '/'|grep -v tmpfs")[0];
+ tempInodes = public.ExecShell("df -i -P|grep '/'|grep -v tmpfs")[0];
+ temp1 = temp.split('\n');
+ tempInodes1 = tempInodes.split('\n');
+ diskInfo = [];
+ n = 0
+ cuts = ['/mnt/cdrom','/boot','/boot/efi','/dev','/dev/shm','/run/lock','/run','/run/shm','/run/user'];
+ for tmp in temp1:
+ n += 1
+ inodes = tempInodes1[n-1].split();
+ disk = tmp.split();
+ if len(disk) < 5: continue;
+ if disk[1].find('M') != -1: continue;
+ if disk[1].find('K') != -1: continue;
+ if len(disk[5].split('/')) > 4: continue;
+ if disk[5] in cuts: continue;
+ arr = {}
+ arr['path'] = disk[5];
+ tmp1 = [disk[1],disk[2],disk[3],disk[4]];
+ arr['size'] = tmp1;
+ arr['inodes'] = [inodes[1],inodes[2],inodes[3],inodes[4]]
+ if disk[5] == '/':
+ bootLog = '/tmp/panelBoot.pl';
+ if disk[2].find('M') != -1:
+ if os.path.exists(bootLog): os.system('rm -f ' + bootLog);
+ else:
+ if not os.path.exists(bootLog): os.system('sleep 1 && /etc/init.d/bt reload &');
+ diskInfo.append(arr);
+ return diskInfo;
+
+ #清理系统垃圾
+ def ClearSystem(self,get):
+ count = total = 0;
+ tmp_total,tmp_count = self.ClearMail();
+ count += tmp_count;
+ total += tmp_total;
+ tmp_total,tmp_count = self.ClearOther();
+ count += tmp_count;
+ total += tmp_total;
+ return count,total
+
+ #清理邮件日志
+ def ClearMail(self):
+ rpath = '/var/spool';
+ total = count = 0;
+ import shutil
+ con = ['cron','anacron','mail'];
+ for d in os.listdir(rpath):
+ if d in con: continue;
+ dpath = rpath + '/' + d
+ time.sleep(0.2);
+ num = size = 0;
+ for n in os.listdir(dpath):
+ filename = dpath + '/' + n
+ fsize = os.path.getsize(filename);
+ size += fsize
+ if os.path.isdir(filename):
+ shutil.rmtree(filename)
+ else:
+ os.remove(filename)
+ print '\t\033[1;32m[OK]\033[0m'
+ num += 1
+ total += size;
+ count += num;
+ return total,count
+
+ #清理其它
+ def ClearOther(self):
+ clearPath = [
+ {'path':'/www/server/panel','find':'testDisk_'},
+ {'path':'/www/wwwlogs','find':'log'},
+ {'path':'/tmp','find':'panelBoot.pl'},
+ {'path':'/www/server/panel/install','find':'.rpm'}
+ ]
+
+ total = count = 0;
+ for c in clearPath:
+ for d in os.listdir(c['path']):
+ if d.find(c['find']) == -1: continue;
+ filename = c['path'] + '/' + d;
+ fsize = os.path.getsize(filename);
+ total += fsize
+ if os.path.isdir(filename):
+ shutil.rmtree(filename)
+ else:
+ os.remove(filename)
+ count += 1;
+ public.serviceReload();
+ os.system('echo > /tmp/panelBoot.pl');
+ return total,count
+
+ def GetNetWork(self,get=None):
+ #return self.GetNetWorkApi(get);
+ #取网络流量信息
+ try:
+ networkIo = psutil.net_io_counters()[:4]
+ if not hasattr(web.ctx.session,'otime'):
+ web.ctx.session.up = networkIo[0]
+ web.ctx.session.down = networkIo[1]
+ web.ctx.session.otime = time.time();
+
+ ntime = time.time();
+ networkInfo = {}
+ networkInfo['upTotal'] = networkIo[0]
+ networkInfo['downTotal'] = networkIo[1]
+ networkInfo['up'] = round(float(networkIo[0] - web.ctx.session.up) / 1024 / (ntime - web.ctx.session.otime),2)
+ networkInfo['down'] = round(float(networkIo[1] - web.ctx.session.down) / 1024 / (ntime - web.ctx.session.otime),2)
+ networkInfo['downPackets'] =networkIo[3]
+ networkInfo['upPackets'] =networkIo[2]
+
+ web.ctx.session.up = networkIo[0]
+ web.ctx.session.down = networkIo[1]
+ web.ctx.session.otime = ntime;
+
+ networkInfo['cpu'] = self.GetCpuInfo()
+ networkInfo['load'] = self.GetLoadAverage(get);
+ return networkInfo
+ except:
+ return None
+
+
+ def GetNetWorkApi(self,get=None):
+ #取网络流量信息
+ try:
+ tmpfile = 'data/network.temp';
+ networkIo = psutil.net_io_counters()[:4]
+
+ if not os.path.exists(tmpfile):
+ public.writeFile(tmpfile,str(networkIo[0])+'|'+str(networkIo[1])+'|' + str(int(time.time())));
+
+ lastValue = public.readFile(tmpfile).split('|');
+
+ ntime = time.time();
+ networkInfo = {}
+ networkInfo['upTotal'] = networkIo[0]
+ networkInfo['downTotal'] = networkIo[1]
+ networkInfo['up'] = round(float(networkIo[0] - int(lastValue[0])) / 1024 / (ntime - int(lastValue[2])),2)
+ networkInfo['down'] = round(float(networkIo[1] - int(lastValue[1])) / 1024 / (ntime - int(lastValue[2])),2)
+ networkInfo['downPackets'] =networkIo[3]
+ networkInfo['upPackets'] =networkIo[2]
+
+ public.writeFile(tmpfile,str(networkIo[0])+'|'+str(networkIo[1])+'|' + str(int(time.time())));
+
+ #networkInfo['cpu'] = self.GetCpuInfo(0.1)
+ return networkInfo
+ except:
+ return None
+
+ def GetNetWorkOld(self):
+ #取网络流量信息
+ import time;
+ pnet = public.readFile('/proc/net/dev');
+ rep = '([^\s]+):[\s]{0,}(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)';
+ pnetall = re.findall(rep,pnet);
+ networkInfo = {}
+ networkInfo['upTotal'] = networkInfo['downTotal'] = networkInfo['up'] = networkInfo['down'] = networkInfo['downPackets'] = networkInfo['upPackets'] = 0;
+ for pnetInfo in pnetall:
+ if pnetInfo[0] == 'io': continue;
+ networkInfo['downTotal'] += int(pnetInfo[1]);
+ networkInfo['downPackets'] += int(pnetInfo[2]);
+ networkInfo['upTotal'] += int(pnetInfo[9]);
+ networkInfo['upPackets'] += int(pnetInfo[10]);
+
+ if not hasattr(web.ctx.session,'otime'):
+ web.ctx.session.up = networkInfo['upTotal']
+ web.ctx.session.down = networkInfo['downTotal']
+ web.ctx.session.otime = time.time();
+ ntime = time.time();
+ tmpDown = networkInfo['downTotal'] - web.ctx.session.down;
+ tmpUp = networkInfo['upTotal'] - web.ctx.session.up;
+ networkInfo['down'] = str(round(float(tmpDown) / 1024 / (ntime - web.ctx.session.otime),2));
+ networkInfo['up'] = str(round(float(tmpUp) / 1024 / (ntime - web.ctx.session.otime),2));
+ if networkInfo['down'] < 0: networkInfo['down'] = 0;
+ if networkInfo['up'] < 0: networkInfo['up'] = 0;
+
+ web.ctx.session.up = networkInfo['upTotal'];
+ web.ctx.session.down = networkInfo['downTotal'];
+ web.ctx.session.otime = ntime;
+ networkInfo['cpu'] = self.GetCpuInfo()
+ return networkInfo;
+
+ 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');
+ public.ExecShell('pkill -9 httpd');
+
+ 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",'
'),));
+
+ if get.type == 'restart':
+ public.ExecShell('pkill -9 httpd');
+ public.ExecShell('/etc/init.d/httpd start');
+
+ #检查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",'
'),));
+
+ #执行
+ 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': return public.returnMsg(False, '
警告消息:
' + result[1].replace('\n','
'));
+ return public.returnMsg(True,'SYS_EXEC_SUCCESS');
+
+ def RestartServer(self,get):
+ if not public.IsRestart(): return public.returnMsg(False,'EXEC_ERR_TASK');
+ public.ExecShell("sync && /etc/init.d/bt stop && init 6 &");
+ return public.returnMsg(True,'SYS_REBOOT');
+
+ #释放内存
+ def ReMemory(self,get):
+ os.system('sync');
+ scriptFile = 'script/rememory.sh'
+ if not os.path.exists(scriptFile):
+ public.downloadFile(web.ctx.session.home + '/script/rememory.sh',scriptFile);
+ public.ExecShell("/bin/bash " + self.setupPath + '/panel/' + scriptFile);
+ return self.GetMemInfo();
+
+ #重启面板
+ def ReWeb(self,get):
+ #if not public.IsRestart(): return public.returnMsg(False,'EXEC_ERR_TASK');
+ public.ExecShell('/etc/init.d/bt restart &');
+ return True
+
+ #修复面板
+ def RepPanel(self,get):
+ vp = '';
+ if public.readFile('/www/server/panel/class/common.py').find('checkSafe') != -1: vp = '_pro';
+ public.ExecShell("wget -O update.sh " + public.get_url() + "/install/update"+vp+".sh && bash update.sh");
+ if hasattr(web.ctx.session,'getCloudPlugin'): del(web.ctx.session['getCloudPlugin']);
+ return True;
+
+ #升级到专业版
+ def UpdatePro(self,get):
+ public.ExecShell("wget -O update.sh " + public.get_url() + "/install/update_pro.sh && bash update.sh pro");
+ if hasattr(web.ctx.session,'getCloudPlugin'): del(web.ctx.session['getCloudPlugin']);
+ return True;
+
+
+
+
+
+
\ No newline at end of file
diff --git a/data/default.db b/data/default.db
index d673496b5..966364cdc 100755
Binary files a/data/default.db and b/data/default.db differ
diff --git a/task.py b/task.py
new file mode 100755
index 000000000..0700a534d
--- /dev/null
+++ b/task.py
@@ -0,0 +1,526 @@
+# coding: utf-8
+
+#------------------------------
+# 计划任务
+#------------------------------
+import sys
+import os
+import json
+# import psutil
+import time
+
+sys.path.append(os.getcwd() + "/class/")
+reload(sys)
+sys.setdefaultencoding('utf-8')
+import db
+import public
+
+
+global pre, timeoutCount, logPath, isTask, oldEdate, isCheck
+pre = 0
+timeoutCount = 0
+isCheck = 0
+oldEdate = None
+logPath = '/tmp/panelExec.log'
+isTask = '/tmp/panelTask.pl'
+
+
+class MyBad():
+ _msg = None
+
+ def __init__(self, msg):
+ self._msg = msg
+
+ def __repr__(self):
+ return self._msg
+
+
+def ExecShell(cmdstring, cwd=None, timeout=None, shell=True):
+ try:
+ global logPath
+ import shlex
+ import datetime
+ import subprocess
+ import time
+
+ if timeout:
+ end_time = datetime.datetime.now() + datetime.timedelta(seconds=timeout)
+
+ sub = subprocess.Popen(cmdstring + ' > ' + logPath + ' 2>&1',
+ cwd=cwd, stdin=subprocess.PIPE, shell=shell, bufsize=4096)
+
+ while sub.poll() is None:
+ time.sleep(0.1)
+
+ return sub.returncode
+ except:
+ return None
+
+
+def DownloadFile(url, filename):
+ # 下载文件
+ try:
+ import urllib
+ import socket
+ socket.setdefaulttimeout(10)
+ urllib.urlretrieve(url, filename=filename, reporthook=DownloadHook)
+ os.system('chown www.www ' + filename)
+ WriteLogs('done')
+ except:
+ WriteLogs('done')
+
+
+def DownloadHook(count, blockSize, totalSize):
+ # 下载文件进度回调
+ global pre
+ used = count * blockSize
+ pre1 = int((100.0 * used / totalSize))
+ if pre == pre1:
+ return
+ speed = {'total': totalSize, 'used': used, 'pre': pre}
+ WriteLogs(json.dumps(speed))
+ pre = pre1
+
+
+def WriteLogs(logMsg):
+ # 写输出日志
+ try:
+ global logPath
+ fp = open(logPath, 'w+')
+ fp.write(logMsg)
+ fp.close()
+ except:
+ pass
+
+
+def startTask():
+ # 任务队列
+ global isTask
+ # import time
+ # import public
+ try:
+ while True:
+ try:
+ if os.path.exists(isTask):
+ sql = db.Sql()
+ sql.table('tasks').where(
+ "status=?", ('-1',)).setField('status', '0')
+ taskArr = sql.table('tasks').where("status=?", ('0',)).field(
+ 'id,type,execstr').order("id asc").select()
+ for value in taskArr:
+ start = int(time.time())
+ if not sql.table('tasks').where("id=?", (value['id'],)).count():
+ continue
+ sql.table('tasks').where("id=?", (value['id'],)).save(
+ 'status,start', ('-1', start))
+ if value['type'] == 'download':
+ argv = value['execstr'].split('|bt|')
+ DownloadFile(argv[0], argv[1])
+ elif value['type'] == 'execshell':
+ ExecShell(value['execstr'])
+ end = int(time.time())
+ sql.table('tasks').where("id=?", (value['id'],)).save(
+ 'status,end', ('1', end))
+ if(sql.table('tasks').where("status=?", ('0')).count() < 1):
+ os.system('rm -f ' + isTask)
+ except:
+ pass
+ siteEdate()
+ mainSafe()
+ time.sleep(2)
+ except:
+ time.sleep(60)
+ startTask()
+
+
+def mainSafe():
+ global isCheck
+ try:
+ if isCheck < 100:
+ isCheck += 1
+ return True
+ isCheck = 0
+ isStart = public.ExecShell(
+ "ps aux |grep 'python main.py'|grep -v grep|awk '{print $2}'")[0]
+ if not isStart:
+ os.system('/etc/init.d/bt start')
+ isStart = public.ExecShell(
+ "ps aux |grep 'python main.py'|grep -v grep|awk '{print $2}'")[0]
+ public.WriteLog('守护程序', '面板服务程序启动成功 -> PID: ' + isStart)
+ except:
+ time.sleep(30)
+ mainSafe()
+
+
+def siteEdate():
+ # 网站到期处理
+ global oldEdate
+ try:
+ if not oldEdate:
+ oldEdate = public.readFile('data/edate.pl')
+ if not oldEdate:
+ oldEdate = '0000-00-00'
+ mEdate = time.strftime('%Y-%m-%d', time.localtime())
+ if oldEdate == mEdate:
+ return False
+ edateSites = public.M('sites').where('edate>? AND edate AND (status=? OR status=?)',
+ ('0000-00-00', mEdate, 1, u'正在运行')).field('id,name').select()
+ import panelSite
+ siteObject = panelSite.panelSite()
+ for site in edateSites:
+ get = MyBad('')
+ get.id = site['id']
+ get.name = site['name']
+ siteObject.SiteStop(get)
+ oldEdate = mEdate
+ public.writeFile('data/edate.pl', mEdate)
+ except:
+ pass
+
+
+def systemTask():
+ # 系统监控任务
+ try:
+ import system
+ import psutil
+ import time
+ sm = system.system()
+ filename = 'data/control.conf'
+ sql = db.Sql().dbfile('system')
+ csql = '''CREATE TABLE IF NOT EXISTS `load_average` (
+ `id` INTEGER PRIMARY KEY AUTOINCREMENT,
+ `pro` REAL,
+ `one` REAL,
+ `five` REAL,
+ `fifteen` REAL,
+ `addtime` INTEGER
+)'''
+ sql.execute(csql, ())
+ cpuIo = cpu = {}
+ cpuCount = psutil.cpu_count()
+ used = count = 0
+ reloadNum = 0
+ network_up = network_down = diskio_1 = diskio_2 = networkInfo = cpuInfo = diskInfo = None
+ while True:
+ if not os.path.exists(filename):
+ time.sleep(10)
+ continue
+
+ day = 30
+ try:
+ day = int(public.readFile(filename))
+ if day < 1:
+ time.sleep(10)
+ continue
+ except:
+ day = 30
+
+ tmp = {}
+ # 取当前CPU Io
+ tmp['used'] = psutil.cpu_percent(interval=1)
+
+ if not cpuInfo:
+ tmp['mem'] = GetMemUsed()
+ cpuInfo = tmp
+
+ if cpuInfo['used'] < tmp['used']:
+ tmp['mem'] = GetMemUsed()
+ cpuInfo = tmp
+
+ # 取当前网络Io
+ networkIo = psutil.net_io_counters()[:4]
+ if not network_up:
+ network_up = networkIo[0]
+ network_down = networkIo[1]
+ tmp = {}
+ tmp['upTotal'] = networkIo[0]
+ tmp['downTotal'] = networkIo[1]
+ tmp['up'] = round(float((networkIo[0] - network_up) / 1024), 2)
+ tmp['down'] = round(float((networkIo[1] - network_down) / 1024), 2)
+ tmp['downPackets'] = networkIo[3]
+ tmp['upPackets'] = networkIo[2]
+
+ network_up = networkIo[0]
+ network_down = networkIo[1]
+
+ if not networkInfo:
+ networkInfo = tmp
+ if (tmp['up'] + tmp['down']) > (networkInfo['up'] + networkInfo['down']):
+ networkInfo = tmp
+
+ # 取磁盘Io
+ if os.path.exists('/proc/diskstats'):
+ diskio_2 = psutil.disk_io_counters()
+ if not diskio_1:
+ diskio_1 = diskio_2
+ tmp = {}
+ tmp['read_count'] = diskio_2.read_count - diskio_1.read_count
+ tmp['write_count'] = diskio_2.write_count - diskio_1.write_count
+ tmp['read_bytes'] = diskio_2.read_bytes - diskio_1.read_bytes
+ tmp['write_bytes'] = diskio_2.write_bytes - diskio_1.write_bytes
+ tmp['read_time'] = diskio_2.read_time - diskio_1.read_time
+ tmp['write_time'] = diskio_2.write_time - diskio_1.write_time
+
+ if not diskInfo:
+ diskInfo = tmp
+ else:
+ diskInfo['read_count'] += tmp['read_count']
+ diskInfo['write_count'] += tmp['write_count']
+ diskInfo['read_bytes'] += tmp['read_bytes']
+ diskInfo['write_bytes'] += tmp['write_bytes']
+ diskInfo['read_time'] += tmp['read_time']
+ diskInfo['write_time'] += tmp['write_time']
+
+ diskio_1 = diskio_2
+
+ # print diskInfo
+
+ if count >= 12:
+ try:
+ addtime = int(time.time())
+ deltime = addtime - (day * 86400)
+
+ data = (cpuInfo['used'], cpuInfo['mem'], addtime)
+ sql.table('cpuio').add('pro,mem,addtime', data)
+ sql.table('cpuio').where("addtime", (deltime,)).delete()
+
+ data = (networkInfo['up'] / 5, networkInfo['down'] / 5, networkInfo['upTotal'], networkInfo[
+ 'downTotal'], networkInfo['downPackets'], networkInfo['upPackets'], addtime)
+ sql.table('network').add(
+ 'up,down,total_up,total_down,down_packets,up_packets,addtime', data)
+ sql.table('network').where(
+ "addtime", (deltime,)).delete()
+ if os.path.exists('/proc/diskstats'):
+ data = (diskInfo['read_count'], diskInfo['write_count'], diskInfo['read_bytes'], diskInfo[
+ 'write_bytes'], diskInfo['read_time'], diskInfo['write_time'], addtime)
+ sql.table('diskio').add(
+ 'read_count,write_count,read_bytes,write_bytes,read_time,write_time,addtime', data)
+ sql.table('diskio').where(
+ "addtime", (deltime,)).delete()
+
+ # LoadAverage
+ load_average = sm.GetLoadAverage(None)
+ lpro = round(
+ (load_average['one'] / load_average['max']) * 100, 2)
+ if lpro > 100:
+ lpro = 100
+ sql.table('load_average').add('pro,one,five,fifteen,addtime', (lpro, load_average[
+ 'one'], load_average['five'], load_average['fifteen'], addtime))
+
+ lpro = None
+ load_average = None
+ cpuInfo = None
+ networkInfo = None
+ diskInfo = None
+ count = 0
+ reloadNum += 1
+ if reloadNum > 1440:
+ if os.path.exists('data/ssl.pl'):
+ os.system(
+ '/etc/init.d/bt restart > /dev/null 2>&1')
+ reloadNum = 0
+ except Exception, ex:
+ print str(ex)
+ del(tmp)
+
+ time.sleep(5)
+ count += 1
+ except Exception, ex:
+ print str(ex)
+ time.sleep(30)
+ systemTask()
+
+
+def GetMemUsed():
+ # 取内存使用率
+ try:
+ import psutil
+ mem = psutil.virtual_memory()
+ memInfo = {'memTotal': mem.total / 1024 / 1024, 'memFree': mem.free / 1024 / 1024,
+ 'memBuffers': mem.buffers / 1024 / 1024, 'memCached': mem.cached / 1024 / 1024}
+ tmp = memInfo['memTotal'] - memInfo['memFree'] - \
+ memInfo['memBuffers'] - memInfo['memCached']
+ tmp1 = memInfo['memTotal'] / 100
+ return (tmp / tmp1)
+ except:
+ return 1
+
+# 检查502错误
+
+
+def check502():
+ try:
+ phpversions = ['53', '54', '55', '56', '70', '71', '72']
+ for version in phpversions:
+ if not os.path.exists('/etc/init.d/php-fpm-' + version):
+ continue
+ if checkPHPVersion(version):
+ continue
+ if startPHPVersion(version):
+ public.WriteLog('PHP守护程序', '检测到PHP-' + version + '处理异常,已自动修复!')
+ except:
+ pass
+
+
+def startPHPVersion(version):
+ # 处理指定PHP版本
+ try:
+ fpm = '/etc/init.d/php-fpm-' + version
+ if not os.path.exists(fpm):
+ return False
+
+ # 尝试重载服务
+ os.system(fpm + ' reload')
+ if checkPHPVersion(version):
+ return True
+
+ # 尝试重启服务
+ cgi = '/tmp/php-cgi-' + version
+ pid = '/www/server/php' + version + '/php-fpm.pid'
+ os.system('pkill -9 php-fpm-' + version)
+ time.sleep(0.5)
+ if not os.path.exists(cgi):
+ os.system('rm -f ' + cgi)
+ if not os.path.exists(pid):
+ os.system('rm -f ' + pid)
+ os.system(fpm + ' start')
+ if checkPHPVersion(version):
+ return True
+
+ # 检查是否正确启动
+ if os.path.exists(cgi):
+ return True
+ except:
+ return True
+
+
+def checkPHPVersion(version):
+ # 检查指定PHP版本
+ try:
+ url = 'http://127.0.0.1/phpfpm_' + version + '_status'
+ result = public.httpGet(url)
+ # 检查nginx
+ if result.find('Bad Gateway') != -1:
+ return False
+ # 检查Apache
+ if result.find('Service Unavailable') != -1:
+ return False
+ if result.find('Not Found') != -1:
+ CheckPHPINFO()
+
+ # 检查Web服务是否启动
+ if result.find('Connection refused') != -1:
+ global isTask
+ if os.path.exists(isTask):
+ isStatus = public.readFile(isTask)
+ if isStatus == 'True':
+ return True
+ filename = '/etc/init.d/nginx'
+ if os.path.exists(filename):
+ os.system(filename + ' start')
+ filename = '/etc/init.d/httpd'
+ if os.path.exists(filename):
+ os.system(filename + ' start')
+
+ return True
+ except:
+ return True
+
+
+def CheckPHPINFO():
+ # 检测PHPINFO配置
+ php_versions = ['53', '54', '55', '56', '70', '71', '72']
+ setupPath = '/www/server'
+ path = setupPath + '/panel/vhost/nginx/phpinfo.conf'
+ if not os.path.exists(path):
+ opt = ""
+ for version in php_versions:
+ opt += "\n\tlocation /" + version + \
+ " {\n\t\tinclude enable-php-" + version + ".conf;\n\t}"
+
+ phpinfoBody = '''server
+{
+ listen 80;
+ server_name 127.0.0.2;
+ allow 127.0.0.1;
+ index phpinfo.php index.html index.php;
+ root /www/server/phpinfo;
+%s
+}''' % (opt,)
+ public.writeFile(path, phpinfoBody)
+
+ path = setupPath + '/panel/vhost/apache/phpinfo.conf'
+ if not os.path.exists(path):
+ opt = ""
+ for version in php_versions:
+ opt += """\n