diff --git a/plugins/sphinx/ico.png b/plugins/sphinx/ico.png new file mode 100644 index 000000000..9ddb87aa3 Binary files /dev/null and b/plugins/sphinx/ico.png differ diff --git a/plugins/sphinx/index.html b/plugins/sphinx/index.html new file mode 100755 index 000000000..4af4424b3 --- /dev/null +++ b/plugins/sphinx/index.html @@ -0,0 +1,18 @@ +
+
+
+

服务

+

自启动

+

配置修改

+

日志

+
+
+
+
+
+
+ \ No newline at end of file diff --git a/plugins/sphinx/index.py b/plugins/sphinx/index.py new file mode 100755 index 000000000..f50457221 --- /dev/null +++ b/plugins/sphinx/index.py @@ -0,0 +1,218 @@ +# coding:utf-8 + +import sys +import io +import os +import time + +sys.path.append(os.getcwd() + "/class/core") +import public + +app_debug = False +if public.isAppleSystem(): + app_debug = True + + +def getPluginName(): + return 'sphinx' + + +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 getConf(): + path = getPluginDir() + "/config/redis.conf" + return path + + +def getInitDTpl(): + path = getPluginDir() + "/init.d/" + getPluginName() + ".tpl" + return path + + +def getArgs(): + args = sys.argv[2:] + 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 status(): + data = public.execShell( + "ps -ef|grep redis |grep -v grep | grep -v python | awk '{print $2}'") + if data[0] == '': + return 'stop' + return 'start' + + +def initDreplace(): + + file_tpl = getInitDTpl() + service_path = os.path.dirname(os.getcwd()) + + initD_path = getServerDir() + '/init.d' + if not os.path.exists(initD_path): + os.mkdir(initD_path) + file_bin = initD_path + '/' + getPluginName() + + # initd replace + content = public.readFile(file_tpl) + content = content.replace('{$SERVER_PATH}', service_path) + public.writeFile(file_bin, content) + public.execShell('chmod +x ' + file_bin) + + # config replace + conf_content = public.readFile(getConf()) + conf_content = conf_content.replace('{$SERVER_PATH}', service_path) + public.writeFile(getServerDir() + '/redis.conf', conf_content) + + return file_bin + + +def start(): + file = initDreplace() + data = public.execShell(file + ' start') + if data[1] == '': + return 'ok' + return 'fail' + + +def stop(): + file = initDreplace() + data = public.execShell(file + ' stop') + if data[1] == '': + return 'ok' + return 'fail' + + +def restart(): + file = initDreplace() + data = public.execShell(file + ' restart') + if data[1] == '': + return 'ok' + return 'fail' + + +def reload(): + file = initDreplace() + data = public.execShell(file + ' reload') + if data[1] == '': + return 'ok' + return 'fail' + + +def runInfo(): + cmd = getServerDir() + "/bin/redis-cli info" + data = public.execShell(cmd)[0] + res = [ + 'tcp_port', + 'uptime_in_days', # 已运行天数 + 'connected_clients', # 连接的客户端数量 + 'used_memory', # Redis已分配的内存总量 + 'used_memory_rss', # Redis占用的系统内存总量 + 'used_memory_peak', # Redis所用内存的高峰值 + 'mem_fragmentation_ratio', # 内存碎片比率 + 'total_connections_received', # 运行以来连接过的客户端的总数量 + 'total_commands_processed', # 运行以来执行过的命令的总数量 + 'instantaneous_ops_per_sec', # 服务器每秒钟执行的命令数量 + 'keyspace_hits', # 查找数据库键成功的次数 + 'keyspace_misses', # 查找数据库键失败的次数 + 'latest_fork_usec' # 最近一次 fork() 操作耗费的毫秒数 + ] + data = data.split("\n") + result = {} + for d in data: + if len(d) < 3: + continue + t = d.strip().split(':') + if not t[0] in res: + continue + result[t[0]] = t[1] + return public.getJson(result) + + +def initdStatus(): + if not app_debug: + os_name = public.getOs() + if os_name == 'darwin': + return "Apple Computer does not support" + initd_bin = getInitDFile() + if os.path.exists(initd_bin): + return 'ok' + return 'fail' + + +def initdInstall(): + import shutil + if not app_debug: + os_name = public.getOs() + if os_name == 'darwin': + return "Apple Computer does not support" + + source_bin = initDreplace() + initd_bin = getInitDFile() + shutil.copyfile(source_bin, initd_bin) + public.execShell('chmod +x ' + initd_bin) + return 'ok' + + +def initdUinstall(): + if not app_debug: + os_name = public.getOs() + if os_name == 'darwin': + return "Apple Computer does not support" + initd_bin = getInitDFile() + os.remove(initd_bin) + return 'ok' + + +def runLog(): + return getServerDir() + '/data/redis.log' + +if __name__ == "__main__": + func = sys.argv[1] + if func == 'status': + print status() + elif func == 'start': + print start() + elif func == 'stop': + print stop() + elif func == 'restart': + print restart() + elif func == 'reload': + print reload() + elif func == 'initd_status': + print initdStatus() + elif func == 'initd_install': + print initdInstall() + elif func == 'initd_uninstall': + print initdUinstall() + elif func == 'run_info': + print runInfo() + elif func == 'conf': + print getConf() + elif func == 'run_log': + print runLog() + else: + print 'error' diff --git a/plugins/sphinx/info.json b/plugins/sphinx/info.json new file mode 100755 index 000000000..87238bd7f --- /dev/null +++ b/plugins/sphinx/info.json @@ -0,0 +1,17 @@ +{ + "sort": 7, + "ps": "简单高效的全文搜索引擎", + "name": "sphinx", + "title": "sphinx", + "shell": "install.sh", + "versions":["4.0"], + "updates":["4.0.11"], + "tip": "soft", + "checks": "server/sphinx", + "display": 1, + "author": "midoks", + "date": "2017-04-01", + "home": "http://sphinxsearch.com/", + "type": 0, + "pid": "5" +} \ No newline at end of file diff --git a/plugins/sphinx/install.sh b/plugins/sphinx/install.sh new file mode 100755 index 000000000..aca61f0c9 --- /dev/null +++ b/plugins/sphinx/install.sh @@ -0,0 +1,35 @@ +#!/bin/bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin +export PATH + +curPath=`pwd` +rootPath=$(dirname "$curPath") +rootPath=$(dirname "$rootPath") +serverPath=$(dirname "$rootPath") + + +install_tmp=${rootPath}/tmp/bt_install.pl + + +Install_sphinx() +{ + + echo '正在安装脚本文件...' > $install_tmp + mkdir -p $serverPath/sphinx + + echo '4.0' > $serverPath/sphinx/version.pl + echo '安装完成' > $install_tmp +} + +Uninstall_sphinx() +{ + rm -rf $serverPath/sphinx + echo "Uninstall_sphinx" > $install_tmp +} + +action=$1 +if [ "${1}" == 'install' ];then + Install_sphinx +else + Uninstall_sphinx +fi diff --git a/plugins/sphinx/js/sphinx.js b/plugins/sphinx/js/sphinx.js new file mode 100755 index 000000000..784349ab9 --- /dev/null +++ b/plugins/sphinx/js/sphinx.js @@ -0,0 +1,479 @@ + +function str2Obj(str){ + var data = {}; + kv = str.split('&'); + for(i in kv){ + v = kv[i].split('='); + data[v[0]] = v[1]; + } + return data; +} + +function phpPost(method, version, args,callback){ + var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 }); + + var req_data = {}; + req_data['name'] = 'php'; + req_data['func'] = method; + req_data['version'] = version; + + if (typeof(args) == 'string'){ + req_data['args'] = JSON.stringify(str2Obj(args)); + } else { + req_data['args'] = JSON.stringify(args); + } + + $.post('/plugins/run', req_data, function(data) { + layer.close(loadT); + if (!data.status){ + layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']}); + return; + } + + if(typeof(callback) == 'function'){ + callback(data); + } + },'json'); +} + + +//配置修改 +function phpSetConfig(version) { + phpPost('get_php_conf', version,'',function(data){ + // console.log(data); + var rdata = $.parseJSON(data.data); + // console.log(rdata); + var mlist = ''; + for (var i = 0; i < rdata.length; i++) { + var w = '70' + if (rdata[i].name == 'error_reporting') w = '250'; + var ibody = ''; + switch (rdata[i].type) { + case 0: + var selected_1 = (rdata[i].value == 1) ? 'selected' : ''; + var selected_0 = (rdata[i].value == 0) ? 'selected' : ''; + ibody = '' + break; + case 1: + var selected_1 = (rdata[i].value == 'On') ? 'selected' : ''; + var selected_0 = (rdata[i].value == 'Off') ? 'selected' : ''; + ibody = '' + break; + } + mlist += '

' + rdata[i].name + '' + ibody + ', ' + rdata[i].ps + '

' + } + var phpCon = '
\ + ' + mlist + '\ +
\ +
' + $(".soft-man-con").html(phpCon); + }); +} + + +//提交PHP配置 +function submitConf(version) { + var data = { + version: version, + display_errors: $("select[name='display_errors']").val(), + 'cgi.fix_pathinfo': $("select[name='cgi.fix_pathinfo']").val(), + 'date.timezone': $("input[name='date.timezone']").val(), + short_open_tag: $("select[name='short_open_tag']").val(), + asp_tags: $("select[name='asp_tags']").val() || 'On', + safe_mode: $("select[name='safe_mode']").val(), + max_execution_time: $("input[name='max_execution_time']").val(), + max_input_time: $("input[name='max_input_time']").val(), + memory_limit: $("input[name='memory_limit']").val(), + post_max_size: $("input[name='post_max_size']").val(), + file_uploads: $("select[name='file_uploads']").val(), + upload_max_filesize: $("input[name='upload_max_filesize']").val(), + max_file_uploads: $("input[name='max_file_uploads']").val(), + default_socket_timeout: $("input[name='default_socket_timeout']").val(), + error_reporting: $("input[name='error_reporting']").val() || 'On' + }; + + phpPost('submit_php_conf', version, data, function(ret_data){ + var rdata = $.parseJSON(ret_data.data); + // console.log(rdata); + layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 }); + }); +} + + + +//php上传限制 +function phpUploadLimitReq(version){ + phpPost('get_limit_conf', version, '', function(ret_data){ + var rdata = $.parseJSON(ret_data.data); + phpUploadLimit(version,rdata['max']); + }); +} + +function phpUploadLimit(version,max){ + var LimitCon = '

MB

'; + $(".soft-man-con").html(LimitCon); +} + + +//php超时限制 +function phpTimeLimitReq(version){ + phpPost('get_limit_conf', version, '', function(ret_data){ + var rdata = $.parseJSON(ret_data.data); + phpTimeLimit(version,rdata['maxTime']); + }); +} + +function phpTimeLimit(version, max) { + var LimitCon = '

'; + $(".soft-man-con").html(LimitCon); +} + +//设置超时限制 +function setPHPMaxTime(version) { + var max = $(".phpTimeLimit").val(); + phpPost('set_max_time',version,{'time':max},function(data){ + var rdata = $.parseJSON(data.data); + layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 }); + }); +} +//设置PHP上传限制 +function setPHPMaxSize(version) { + max = $(".phpUploadLimit").val(); + if (max < 2) { + alert(max); + layer.msg('上传大小限制不能小于2M', { icon: 2 }); + return; + } + + phpPost('set_max_size',version,{'max':max},function(data){ + var rdata = $.parseJSON(data.data); + layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 }); + }); +} + + +function getFpmConfig(version){ + phpPost('get_fpm_conf', version, {}, function(data){ + // console.log(data); + var rdata = $.parseJSON(data.data); + // console.log(rdata); + var limitList = "" + + "" + + "" + + "" + + "" + + "" + + "" + var pms = [{ 'name': 'static', 'title': '静态' }, { 'name': 'dynamic', 'title': '动态' }]; + var pmList = ''; + for (var i = 0; i < pms.length; i++) { + pmList += ''; + } + var body = "
" + + "

并发方案:

" + + "

运行模式:*PHP-FPM运行模式

" + + "

max_children:*允许创建的最大子进程数

" + + "

start_servers: *起始进程数(服务启动后初始进程数量)

" + + "

min_spare_servers: *最小空闲进程数(清理空闲进程后的保留数量)

" + + "

max_spare_servers: *最大空闲进程数(当空闲进程达到此值时清理)

" + + "
" + + "
"; + + $(".soft-man-con").html(body); + $("select[name='limit']").change(function() { + var type = $(this).val(); + var max_children = rdata.max_children; + var start_servers = rdata.start_servers; + var min_spare_servers = rdata.min_spare_servers; + var max_spare_servers = rdata.max_spare_servers; + switch (type) { + case '1': + max_children = 30; + start_servers = 5; + min_spare_servers = 5; + max_spare_servers = 20; + break; + case '2': + max_children = 50; + start_servers = 15; + min_spare_servers = 15; + max_spare_servers = 35; + break; + case '3': + max_children = 100; + start_servers = 20; + min_spare_servers = 20; + max_spare_servers = 70; + break; + case '4': + max_children = 200; + start_servers = 25; + min_spare_servers = 25; + max_spare_servers = 150; + break; + case '5': + max_children = 300; + start_servers = 30; + min_spare_servers = 30; + max_spare_servers = 180; + break; + case '6': + max_children = 500; + start_servers = 35; + min_spare_servers = 35; + max_spare_servers = 250; + break; + } + + $("input[name='max_children']").val(max_children); + $("input[name='start_servers']").val(start_servers); + $("input[name='min_spare_servers']").val(min_spare_servers); + $("input[name='max_spare_servers']").val(max_spare_servers); + }); + }); +} + +function setFpmConfig(version){ + var max_children = Number($("input[name='max_children']").val()); + var start_servers = Number($("input[name='start_servers']").val()); + var min_spare_servers = Number($("input[name='min_spare_servers']").val()); + var max_spare_servers = Number($("input[name='max_spare_servers']").val()); + var pm = $("select[name='pm']").val(); + + if (max_children < max_spare_servers) { + layer.msg('max_spare_servers 不能大于 max_children', { icon: 2 }); + return; + } + + if (min_spare_servers > start_servers) { + layer.msg('min_spare_servers 不能大于 start_servers', { icon: 2 }); + return; + } + + if (max_spare_servers < min_spare_servers) { + layer.msg('min_spare_servers 不能大于 max_spare_servers', { icon: 2 }); + return; + } + + if (max_children < start_servers) { + layer.msg('start_servers 不能大于 max_children', { icon: 2 }); + return; + } + + if (max_children < 1 || start_servers < 1 || min_spare_servers < 1 || max_spare_servers < 1) { + layer.msg('配置值不能小于1', { icon: 2 }); + return; + } + + var data = { + version:version, + max_children:max_children, + start_servers:start_servers, + min_spare_servers:min_spare_servers, + max_spare_servers:max_spare_servers, + pm:pm, + }; + phpPost('set_fpm_conf', version, data, function(ret_data){ + var rdata = $.parseJSON(ret_data.data); + layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 }); + }); +} + + +function getFpmStatus(version){ + phpPost('get_fpm_status', version, '', function(ret_data){ + var rdata = $.parseJSON(ret_data.data); + var con = "
\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
应用池(pool)" + rdata.pool + "
进程管理方式(process manager)" + ((rdata['process manager'] == 'dynamic') ? '动态' : '静态') + "
启动日期(start time)" + rdata['start time'] + "
请求数(accepted conn)" + rdata['accepted conn'] + "
请求队列(listen queue)" + rdata['listen queue'] + "
最大等待队列(max listen queue)" + rdata['max listen queue'] + "
socket队列长度(listen queue len)" + rdata['listen queue len'] + "
空闲进程数量(idle processes)" + rdata['idle processes'] + "
活跃进程数量(active processes)" + rdata['active processes'] + "
总进程数量(total processes)" + rdata['total processes'] + "
最大活跃进程数量(max active processes)" + rdata['max active processes'] + "
到达进程上限次数(max children reached)" + rdata['max children reached'] + "
慢请求数量(slow requests)" + rdata['slow requests'] + "
"; + $(".soft-man-con").html(con); + $(".GetPHPStatus td,.GetPHPStatus th").css("padding", "7px"); + }); +} + +//禁用函数 +function disableFunc(version) { + phpPost('get_disable_func', version,'',function(data){ + var rdata = $.parseJSON(data.data); + var disable_functions = rdata.disable_functions.split(','); + var dbody = '' + for (var i = 0; i < disable_functions.length; i++) { + if (disable_functions[i] == '') continue; + dbody += "" + disable_functions[i] + "删除"; + } + + var con = "
" + + "" + + "" + + "
" + + "
" + + "" + + "" + dbody + "" + + "
名称操作
"; + + con += ''; + + $(".soft-man-con").html(con); + }); +} +//设置禁用函数 +function setDisableFunc(version, act, fs) { + var fsArr = fs.split(','); + if (act == 1) { + var functions = $("#disable_function_val").val(); + for (var i = 0; i < fsArr.length; i++) { + if (functions == fsArr[i]) { + layer.msg(lan.soft.fun_msg, { icon: 5 }); + return; + } + } + fs += ',' + functions; + msg = '添加成功'; + } else { + + fs = ''; + for (var i = 0; i < fsArr.length; i++) { + if (act == fsArr[i]) continue; + fs += fsArr[i] + ',' + } + msg = '删除成功'; + fs = fs.substr(0, fs.length - 1); + } + + var data = { + 'version':version, + 'disable_functions':fs, + }; + + phpPost('set_disable_func', version,data,function(data){ + var rdata = $.parseJSON(data.data); + showMsg(rdata.status ? msg : rdata.msg, function(){ + disableFunc(version); + } ,{ icon: rdata.status ? 1 : 2 }); + }); +} + + +//phpinfo +function getPhpinfo(version) { + var con = ''; + $(".soft-man-con").html(con); +} + +//获取PHPInfo +function getPHPInfo(version) { + phpPost('get_phpinfo', version, '', function(data){ + var rdata = data.data; + layer.open({ + type: 1, + title: "PHP-" + version + "-PHPINFO", + area: ['90%', '90%'], + closeBtn: 2, + shadeClose: true, + content: rdata + }); + }); +} + +function phpLibConfig(version){ + + phpPost('get_lib_conf', version, '', function(data){ + var rdata = $.parseJSON(data.data); + var libs = rdata.data; + + var body = ''; + var opt = ''; + for (var i = 0; i < libs.length; i++) { + if (libs[i].versions.indexOf(version) == -1){ + continue; + } + + if (libs[i]['task'] == '-1' && libs[i].phpversions.indexOf(version) != -1) { + opt = '安装' + } else if (libs[i]['task'] == '0' && libs[i].phpversions.indexOf(version) != -1) { + opt = '等待安装...' + } else if (libs[i].status) { + opt = '卸载' + } else { + opt = '安装' + } + + body += '' + + '' + libs[i].name + '' + + '' + libs[i].type + '' + + '' + libs[i].msg + '' + + '' + + '' + opt + '' + + ''; + } + + + var con = '
' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + body + '' + + '
名称类型说明状态操作
' + + '
' + + ''; + $('.soft-man-con').html(con); + }); + +} + +//安装扩展 +function installPHPLib(version, name, title, pathinfo) { + layer.confirm('您真的要安装{1}吗?'.replace('{1}', name), { icon: 3, closeBtn: 2 }, function() { + name = name.toLowerCase(); + var data = "name=" + name + "&version=" + version + "&type=1"; + + phpPost('install_lib', version, data, function(data){ + var rdata = $.parseJSON(data.data); + layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 }); + getTaskCount(); + phpLibConfig(version); + }); + }); +} + +//卸载扩展 +function uninstallPHPLib(version, name, title, pathinfo) { + layer.confirm('您真的要安装{1}吗?'.replace('{1}', name), { icon: 3, closeBtn: 2 }, function() { + name = name.toLowerCase(); + var data = 'name=' + name + '&version=' + version; + phpPost('uninstall_lib', version, data, function(data){ + var rdata = $.parseJSON(data.data); + layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 }); + getTaskCount(); + phpLibConfig(version); + }); + }); +} \ No newline at end of file