# coding:utf-8 import sys import io import os import time import re import json import shutil reload(sys) sys.setdefaultencoding('utf8') sys.path.append(os.getcwd() + "/class/core") sys.path.append("/usr/local/lib/python2.7/site-packages") import public app_debug = False if public.isAppleSystem(): app_debug = True def getPluginName(): return 'php' def getPluginDir(): return public.getPluginDir() + '/' + getPluginName() def getServerDir(): return public.getServerDir() + '/' + getPluginName() def getInitDFile(): if app_debug: return '/tmp/' + getPluginName() return '/etc/init.d/' + getPluginName() def getArgs(): args = sys.argv[3:] tmp = {} args_len = len(args) if args_len == 1: t = args[0].strip('{').strip('}') t = t.split(':') tmp[t[0]] = t[1] elif args_len > 1: for i in range(len(args)): t = args[i].split(':') tmp[t[0]] = t[1] return tmp def checkArgs(data, ck=[]): for i in range(len(ck)): if not ck[i] in data: return (False, public.returnJson(False, '参数:(' + ck[i] + ')没有!')) return (True, public.returnJson(True, 'ok')) def getConf(version): path = getServerDir() + '/' + version + '/etc/php.ini' return path def status(version): cmd = "ps -ef|grep 'php/" + version + \ "' |grep -v grep | grep -v python | awk '{print $2}'" data = public.execShell(cmd) if data[0] == '': return 'stop' return 'start' def contentReplace(content, version): service_path = public.getServerDir() content = content.replace('{$ROOT_PATH}', public.getRootDir()) content = content.replace('{$SERVER_PATH}', service_path) content = content.replace('{$PHP_VERSION}', version) if public.isAppleSystem(): # user = public.execShell( # "who | sed -n '2, 1p' |awk '{print $1}'")[0].strip() content = content.replace('{$PHP_USER}', 'nobody') content = content.replace('{$PHP_GROUP}', 'nobody') rep = 'listen.owner\s*=\s*(.+)\r?\n' val = ';listen.owner = nobody\n' content = re.sub(rep, val, content) rep = 'listen.group\s*=\s*(.+)\r?\n' val = ';listen.group = nobody\n' content = re.sub(rep, val, content) rep = 'user\s*=\s*(.+)\r?\n' val = ';user = nobody\n' content = re.sub(rep, val, content) rep = r'[^\.]group\s*=\s*(.+)\r?\n' val = ';group = nobody\n' content = re.sub(rep, val, content) else: content = content.replace('{$PHP_USER}', 'www') content = content.replace('{$PHP_GROUP}', 'www') return content def makeOpenrestyConf(): if public.isInstalledWeb(): d_pathinfo = public.getServerDir() + '/openresty/nginx/conf/pathinfo.conf' if not os.path.exists(d_pathinfo): s_pathinfo = getPluginDir() + '/conf/pathinfo.conf' shutil.copyfile(s_pathinfo, d_pathinfo) info = getPluginDir() + '/info.json' content = public.readFile(info) content = json.loads(content) versions = content['versions'] tpl = getPluginDir() + '/conf/enable-php.conf' tpl_content = public.readFile(tpl) for x in range(len(versions)): desc_file = public.getServerDir() + '/openresty/nginx/conf/enable-php-' + \ versions[x] + '.conf' if not os.path.exists(desc_file): w_content = contentReplace(tpl_content, versions[x]) public.writeFile(desc_file, w_content) def phpFpmReplace(version): desc_php_fpm = getServerDir() + '/' + version + '/etc/php-fpm.conf' if not os.path.exists(desc_php_fpm): tpl_php_fpm = getPluginDir() + '/conf/php-fpm.conf' content = public.readFile(tpl_php_fpm) content = contentReplace(content, version) public.writeFile(desc_php_fpm, content) def phpFpmWwwReplace(version): service_php_fpm_dir = getServerDir() + '/' + version + '/etc/php-fpm.d/' if not os.path.exists(service_php_fpm_dir): os.mkdir(service_php_fpm_dir) service_php_fpmwww = service_php_fpm_dir + '/www.conf' if not os.path.exists(service_php_fpmwww): tpl_php_fpmwww = getPluginDir() + '/conf/www.conf' content = public.readFile(tpl_php_fpmwww) content = contentReplace(content, version) public.writeFile(service_php_fpmwww, content) def makePhpIni(version): d_ini = public.getServerDir() + '/php/' + version + '/etc/php.ini' if not os.path.exists(d_ini): s_ini = getPluginDir() + '/conf/php' + version + '.ini' shutil.copyfile(s_ini, d_ini) def initReplace(version): makeOpenrestyConf() makePhpIni(version) initD_path = getServerDir() + '/init.d' if not os.path.exists(initD_path): os.mkdir(initD_path) file_bin = initD_path + '/php' + version if not os.path.exists(file_bin): file_tpl = getPluginDir() + '/init.d/php.tpl' content = public.readFile(file_tpl) content = contentReplace(content, version) public.writeFile(file_bin, content) public.execShell('chmod +x ' + file_bin) phpFpmWwwReplace(version) phpFpmReplace(version) session_path = '/tmp/session' if not os.path.exists(session_path): os.mkdir(session_path) if not public.isAppleSystem(): public.execShell('chmod -R www:www' + session_path) return file_bin def phpOp(version, method): file = initReplace(version) data = public.execShell(file + ' ' + method) if data[1] == '': return 'ok' return data[1] def start(version): return phpOp(version, 'start') def stop(version): return phpOp(version, 'stop') def restart(version): return phpOp(version, 'restart') def reload(version): return phpOp(version, 'reload') def fpmLog(version): return getServerDir() + '/' + version + '/var/log/php-fpm.log' def fpmSlowLog(version): return getServerDir() + '/' + version + '/var/log/www-slow.log' def getPhpConf(version): gets = [ {'name': 'short_open_tag', 'type': 1, 'ps': '短标签支持'}, {'name': 'asp_tags', 'type': 1, 'ps': 'ASP标签支持'}, {'name': 'max_execution_time', 'type': 2, 'ps': '最大脚本运行时间'}, {'name': 'max_input_time', 'type': 2, 'ps': '最大输入时间'}, {'name': 'memory_limit', 'type': 2, 'ps': '脚本内存限制'}, {'name': 'post_max_size', 'type': 2, 'ps': 'POST数据最大尺寸'}, {'name': 'file_uploads', 'type': 1, 'ps': '是否允许上传文件'}, {'name': 'upload_max_filesize', 'type': 2, 'ps': '允许上传文件的最大尺寸'}, {'name': 'max_file_uploads', 'type': 2, 'ps': '允许同时上传文件的最大数量'}, {'name': 'default_socket_timeout', 'type': 2, 'ps': 'Socket超时时间'}, {'name': 'error_reporting', 'type': 3, 'ps': '错误级别'}, {'name': 'display_errors', 'type': 1, 'ps': '是否输出详细错误信息'}, {'name': 'cgi.fix_pathinfo', 'type': 0, 'ps': '是否开启pathinfo'}, {'name': 'date.timezone', 'type': 3, 'ps': '时区'} ] phpini = public.readFile(getServerDir() + '/' + version + '/etc/php.ini') result = [] for g in gets: rep = g['name'] + '\s*=\s*([0-9A-Za-z_& ~]+)(\s*;?|\r?\n)' tmp = re.search(rep, phpini) if not tmp: continue g['value'] = tmp.groups()[0] result.append(g) return public.getJson(result) def submitPhpConf(version): gets = ['display_errors', 'cgi.fix_pathinfo', 'date.timezone', 'short_open_tag', 'asp_tags', 'max_execution_time', 'max_input_time', 'memory_limit', 'post_max_size', 'file_uploads', 'upload_max_filesize', 'max_file_uploads', 'default_socket_timeout', 'error_reporting'] args = getArgs() filename = getServerDir() + '/' + version + '/etc/php.ini' phpini = public.readFile(filename) for g in gets: if g in args: rep = g + '\s*=\s*(.+)\r?\n' val = g + ' = ' + args[g] + '\n' phpini = re.sub(rep, val, phpini) public.writeFile(filename, phpini) public.execShell(getServerDir() + '/init.d/php' + version + ' reload') return public.returnJson(True, '设置成功') def getLimitConf(version): fileini = getServerDir() + "/" + version + "/etc/php.ini" phpini = public.readFile(fileini) filefpm = getServerDir() + "/" + version + "/etc/php-fpm.conf" phpfpm = public.readFile(filefpm) # print fileini, filefpm 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 = r"\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 public.getJson(data) def setMaxTime(version): args = getArgs() data = checkArgs(args, ['time']) if not data[0]: return data[1] time = args['time'] if int(time) < 30 or int(time) > 86400: return public.returnJson(False, '请填写30-86400间的值!') filefpm = getServerDir() + "/" + version + "/etc/php-fpm.conf" conf = public.readFile(filefpm) rep = "request_terminate_timeout\s*=\s*([0-9]+)\n" conf = re.sub(rep, "request_terminate_timeout = " + time + "\n", conf) public.writeFile(filefpm, conf) fileini = getServerDir() + "/" + version + "/etc/php.ini" phpini = public.readFile(fileini) rep = "max_execution_time\s*=\s*([0-9]+)\r?\n" phpini = re.sub(rep, "max_execution_time = " + time + "\n", phpini) rep = "max_input_time\s*=\s*([0-9]+)\r?\n" phpini = re.sub(rep, "max_input_time = " + time + "\n", phpini) public.writeFile(fileini, phpini) return public.returnJson(True, '设置成功!') def setMaxSize(version): args = getArgs() if not 'max' in args: return 'missing time args!' max = args['max'] if int(max) < 2: return public.returnJson(False, '上传大小限制不能小于2MB!') path = getServerDir() + '/' + version + '/etc/php.ini' conf = public.readFile(path) rep = u"\nupload_max_filesize\s*=\s*[0-9]+M" conf = re.sub(rep, u'\nupload_max_filesize = ' + max + 'M', conf) rep = u"\npost_max_size\s*=\s*[0-9]+M" conf = re.sub(rep, u'\npost_max_size = ' + max + 'M', conf) public.writeFile(path, conf) # if public.get_webserver() == 'nginx': # path = web.ctx.session.setupPath + '/nginx/conf/nginx.conf' # conf = public.readFile(path) # rep = "client_max_body_size\s+([0-9]+)m" # tmp = re.search(rep, conf).groups() # if int(tmp[0]) < int(max): # conf = re.sub(rep, 'client_max_body_size ' + max + 'm', conf) # public.writeFile(path, conf) public.writeLog("TYPE_PHP", "PHP_UPLOAD_MAX", (version, max)) return public.returnJson(True, '设置成功!') def getFpmConfig(version): filefpm = getServerDir() + '/' + version + '/etc/php-fpm.d/www.conf' conf = public.readFile(filefpm) data = {} rep = "\s*pm.max_children\s*=\s*([0-9]+)\s*" tmp = re.search(rep, conf).groups() data['max_children'] = tmp[0] rep = "\s*pm.start_servers\s*=\s*([0-9]+)\s*" tmp = re.search(rep, conf).groups() data['start_servers'] = tmp[0] rep = "\s*pm.min_spare_servers\s*=\s*([0-9]+)\s*" tmp = re.search(rep, conf).groups() data['min_spare_servers'] = tmp[0] rep = "\s*pm.max_spare_servers \s*=\s*([0-9]+)\s*" tmp = re.search(rep, conf).groups() data['max_spare_servers'] = tmp[0] rep = "\s*pm\s*=\s*(\w+)\s*" tmp = re.search(rep, conf).groups() data['pm'] = tmp[0] return public.getJson(data) def setFpmConfig(version): args = getArgs() # if not 'max' in args: # return 'missing time args!' version = args['version'] max_children = args['max_children'] start_servers = args['start_servers'] min_spare_servers = args['min_spare_servers'] max_spare_servers = args['max_spare_servers'] pm = args['pm'] file = getServerDir() + '/' + version + '/etc/php-fpm.d/www.conf' conf = public.readFile(file) rep = "\s*pm.max_children\s*=\s*([0-9]+)\s*" conf = re.sub(rep, "\npm.max_children = " + max_children, conf) rep = "\s*pm.start_servers\s*=\s*([0-9]+)\s*" conf = re.sub(rep, "\npm.start_servers = " + start_servers, conf) rep = "\s*pm.min_spare_servers\s*=\s*([0-9]+)\s*" conf = re.sub(rep, "\npm.min_spare_servers = " + min_spare_servers, conf) rep = "\s*pm.max_spare_servers \s*=\s*([0-9]+)\s*" conf = re.sub(rep, "\npm.max_spare_servers = " + max_spare_servers + "\n", conf) rep = "\s*pm\s*=\s*(\w+)\s*" conf = re.sub(rep, "\npm = " + pm + "\n", conf) public.writeFile(file, conf) reload(version) public.writeLog("TYPE_PHP", 'PHP_CHILDREN', (version, max_children, start_servers, min_spare_servers, max_spare_servers)) return public.returnJson(True, '设置成功') def checkFpmStatusFile(version): if public.isInstalledWeb(): desc_file = public.getServerDir( ) + '/openresty/nginx/conf/php_status/phpfpm_status_' + version + '.conf' if not os.path.exists(desc_file): tpl = getPluginDir() + '/conf/phpfpm_status.conf' content = public.readFile(tpl) content = contentReplace(content, version) public.writeFile(desc_file, content) public.restartWeb() def getFpmStatus(version): checkFpmStatusFile(version) result = public.httpGet( 'http://127.0.0.1/phpfpm_status_' + version + '?json') tmp = json.loads(result) fTime = time.localtime(int(tmp['start time'])) tmp['start time'] = time.strftime('%Y-%m-%d %H:%M:%S', fTime) return public.getJson(tmp) def getDisableFunc(version): filename = public.getServerDir() + '/php/' + version + '/etc/php.ini' if not os.path.exists(filename): return public.returnJson(False, '指定PHP版本不存在!') phpini = public.readFile(filename) data = {} rep = "disable_functions\s*=\s{0,1}(.*)\n" tmp = re.search(rep, phpini).groups() data['disable_functions'] = tmp[0] return public.getJson(data) def setDisableFunc(version): filename = public.getServerDir() + '/php/' + version + '/etc/php.ini' if not os.path.exists(filename): return public.returnJson(False, '指定PHP版本不存在!') args = getArgs() disable_functions = args['disable_functions'] phpini = public.readFile(filename) rep = "disable_functions\s*=\s*.*\n" phpini = re.sub(rep, 'disable_functions = ' + disable_functions + "\n", phpini) public.writeLog('TYPE_PHP', 'PHP_DISABLE_FUNCTION', (version, disable_functions)) public.writeFile(filename, phpini) reload(version) return public.returnJson(True, '设置成功!') def checkPhpinfoFile(v): if public.isInstalledWeb(): desc_file = public.getServerDir() + '/openresty/nginx/conf/php_status/phpinfo_' + \ str(v) + '.conf' if not os.path.exists(desc_file): tpl = getPluginDir() + '/conf/phpinfo.conf' content = public.readFile(tpl) content = contentReplace(content, v) public.writeFile(desc_file, content) public.restartWeb() def getPhpinfo(v): checkPhpinfoFile(v) sPath = public.getRootDir() + '/phpinfo/' + str(v) # public.execShell("rm -rf " + public.getRootDir() + '/phpinfo') public.execShell("mkdir -p " + sPath) public.writeFile(sPath + '/phpinfo.php', '') # print 'http://127.0.0.1/' + str(v) + '/phpinfo.php' phpinfo = public.httpGet('http://127.0.0.1/' + str(v) + '/phpinfo.php') public.writeFile('/tmp/phpinfo.txt', phpinfo) # os.system("rm -rf " + public.getRootDir() + '/phpinfo') return '' def getLibConf(version): fname = public.getServerDir() + '/php/' + version + '/etc/php.ini' if not os.path.exists(fname): return public.returnJson(False, '指定PHP版本不存在!') phpini = public.readFile(fname) libpath = getPluginDir() + '/versions/phplib.conf' phplib = json.loads(public.readFile(libpath)) libs = [] tasks = public.M('tasks').where( "status!=?", ('1',)).field('status,name').select() for lib in phplib: lib['task'] = '1' for task in tasks: tmp = public.getStrBetween('[', ']', task['name']) if not tmp: continue tmp1 = tmp.split('-') if tmp1[0].lower() == lib['name'].lower(): lib['task'] = task['status'] lib['phpversions'] = [] lib['phpversions'].append(tmp1[1]) if phpini.find(lib['check']) == -1: lib['status'] = False else: lib['status'] = True libs.append(lib) return public.returnJson(True, 'OK!', libs) def installLib(version): args = getArgs() data = checkArgs(args, ['name']) if not data[0]: return data[1] name = args['name'] execstr = "cd " + getPluginDir() + '/versions/' + version + " && /bin/bash " + \ name + '.sh' + ' install ' + version rettime = time.strftime('%Y-%m-%d %H:%M:%S') insert_info = (None, '安装[' + name + '-' + version + ']', 'execshell', '0', rettime, execstr) public.M('tasks').add('id,name,type,status,addtime,execstr', insert_info) return public.returnJson(True, '已将下载任务添加到队列!') def uninstallLib(version): args = getArgs() data = checkArgs(args, ['name']) if not data[0]: return data[1] name = args['name'] execstr = "cd " + getPluginDir() + '/versions/' + version + " && /bin/bash " + \ name + '.sh' + ' uninstall ' + version rettime = time.strftime('%Y-%m-%d %H:%M:%S') insert_info = (None, '安装[' + name + '-' + version + ']', 'execshell', '0', rettime, execstr) public.M('tasks').add('id,name,type,status,addtime,execstr', insert_info) return public.returnJson(True, '已将卸载载任务添加到队列!') if __name__ == "__main__": if len(sys.argv) < 3: print 'missing parameters' exit(0) func = sys.argv[1] version = sys.argv[2] if func == 'status': print status(version) elif func == 'start': print start(version) elif func == 'stop': print stop(version) elif func == 'restart': print restart(version) elif func == 'reload': print reload(version) elif func == 'fpm_log': print fpmLog(version) elif func == 'fpm_slow_log': print fpmSlowLog(version) elif func == 'conf': print getConf(version) elif func == 'get_php_conf': print getPhpConf(version) elif func == 'submit_php_conf': print submitPhpConf(version) elif func == 'get_limit_conf': print getLimitConf(version) elif func == 'set_max_time': print setMaxTime(version) elif func == 'set_max_size': print setMaxSize(version) elif func == 'get_fpm_conf': print getFpmConfig(version) elif func == 'set_fpm_conf': print setFpmConfig(version) elif func == 'get_fpm_status': print getFpmStatus(version) elif func == 'get_disable_func': print getDisableFunc(version) elif func == 'set_disable_func': print setDisableFunc(version) elif func == 'get_phpinfo': print getPhpinfo(version) elif func == 'get_lib_conf': print getLibConf(version) elif func == 'install_lib': print installLib(version) elif func == 'uninstall_lib': print uninstallLib(version) else: print "fail"