diff --git a/plugins/caddy/check.sh b/plugins/caddy/check.sh new file mode 100755 index 000000000..4cb2277cc --- /dev/null +++ b/plugins/caddy/check.sh @@ -0,0 +1,35 @@ +#!/bin/bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin +export PATH + +# OpenResty服务名称 +service_name="caddy" + +# 检查OpenResty是否正在运行 +if systemctl is-active --quiet "$service_name"; then + # 检查是否存在僵尸进程 + zombie_processes=$(ps -ef | grep -i caddy | grep -v grep | awk '{print $2}' | xargs ps -o state= -p 2>/dev/null | grep -c Z) + if [ "$zombie_processes" -gt 0 ]; then + echo "kill caddy 僵尸进程" + ps -ef|grep caddy| grep -v grep| awk '{print $2}' | xargs kill -9 + echo "检测到OpenResty僵尸进程,正在重启服务..." + systemctl restart "$service_name" + echo "服务已重启" + else + echo "OpenResty运行正常" + fi +else + echo "kill caddy" + ps -ef|grep caddy| grep -v grep| awk '{print $2}' | xargs kill -9 + echo "caddy未运行,正在启动服务..." + systemctl start "$service_name" + echo "服务已启动" +fi + +NGINX_IDS=`ps -ef|grep caddy | grep -v grep| awk '{print $2}'` +if [ "$NGINX_IDS" == "" ];then + ps -ef|grep caddy| grep -v grep| awk '{print $2}' | xargs kill -9 + systemctl start "$service_name" + echo "caddy未运行,正在启动服务..." +fi + diff --git a/plugins/caddy/conf/Caddyfile b/plugins/caddy/conf/Caddyfile new file mode 100644 index 000000000..98594e3a2 --- /dev/null +++ b/plugins/caddy/conf/Caddyfile @@ -0,0 +1,13 @@ +:8080 { + # Set this path to your site's directory. + root * /tmp + + # Enable the static file server. + file_server + + # Another common task is to set up a reverse proxy: + # reverse_proxy localhost:8080 + + # Or serve a PHP site through php-fpm: + # php_fastcgi localhost:9000 +} \ No newline at end of file diff --git a/plugins/caddy/ico.png b/plugins/caddy/ico.png new file mode 100644 index 000000000..91071011e Binary files /dev/null and b/plugins/caddy/ico.png differ diff --git a/plugins/caddy/index.html b/plugins/caddy/index.html new file mode 100755 index 000000000..92cba9ba6 --- /dev/null +++ b/plugins/caddy/index.html @@ -0,0 +1,24 @@ +
+ +
+
+

服务

+

自启动

+

配置修改

+

负载状态

+

性能调整

+

错误日志

+

维护功能

+
+
+
+
+
+ +
+ + \ No newline at end of file diff --git a/plugins/caddy/index.py b/plugins/caddy/index.py new file mode 100755 index 000000000..fdd445a91 --- /dev/null +++ b/plugins/caddy/index.py @@ -0,0 +1,442 @@ +# coding:utf-8 + +import sys +import io +import os +import time +import threading +import subprocess +import re + + +web_dir = os.getcwd() + "/web" +if os.path.exists(web_dir): + sys.path.append(web_dir) + os.chdir(web_dir) + +import core.mw as mw + +app_debug = False +if mw.isAppleSystem(): + app_debug = True + + +def getPluginName(): + return 'caddy' + + +def getPluginDir(): + return mw.getPluginDir() + '/' + getPluginName() + + +def getServerDir(): + return mw.getServerDir() + '/' + getPluginName() + + +def getInitDFile(): + current_os = mw.getOs() + if current_os == 'darwin': + return '/tmp/' + getPluginName() + + if current_os.startswith('freebsd'): + return '/etc/rc.d/' + getPluginName() + + return '/etc/init.d/' + getPluginName() + + +def getArgs(): + args = sys.argv[2:] + # print(args) + tmp = {} + args_len = len(args) + + if args_len == 1: + t = args[0].strip('{').strip('}') + t = t.split(':',2) + tmp[t[0]] = t[1] + elif args_len > 1: + for i in range(len(args)): + t = args[i].split(':',2) + tmp[t[0]] = t[1] + # print(tmp) + return tmp + + +def checkArgs(data, ck=[]): + for i in range(len(ck)): + if not ck[i] in data: + return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!')) + return (True, mw.returnJson(True, 'ok')) + + +def getConf(): + path = getServerDir() + "/Caddyfile" + return path + + +def getConfTpl(): + path = getPluginDir() + '/conf/Caddyfile' + return path + + +def getInitDTpl(): + path = getPluginDir() + "/init.d/caddy.tpl" + return path + +def initDreplace(): + file_tpl = getInitDTpl() + service_path = mw.getServerDir() + initD_path = getServerDir() + '/init.d' + + # init.d + file_bin = initD_path + '/' + getPluginName() + + if not os.path.exists(initD_path): + os.mkdir(initD_path) + + # initd replace + content = mw.readFile(file_tpl) + content = content.replace('{$SERVER_PATH}', service_path) + mw.writeFile(file_bin, content) + mw.execShell('chmod +x ' + file_bin) + + caddy_file = getConf() + if not os.path.exists(caddy_file): + caddy_file_tpl = getConfTpl() + content = mw.readFile(systemServiceTpl) + content = content.replace('{$SERVER_PATH}', service_path) + mw.writeFile(caddy_file, content) + + # systemd + # /usr/lib/systemd/system + systemDir = mw.systemdCfgDir() + systemService = systemDir + '/caddy.service' + if os.path.exists(systemDir) and not os.path.exists(systemService): + systemServiceTpl = getPluginDir() + '/init.d/caddy.service.tpl' + se_content = mw.readFile(systemServiceTpl) + se_content = se_content.replace('{$SERVER_PATH}', service_path) + mw.writeFile(systemService, se_content) + mw.execShell('systemctl daemon-reload') + + return file_bin + + +def status(): + cmd = "ps -ef|grep 'caddy run' |grep -v grep | grep -v python | awk '{print $2}'" + data = mw.execShell(cmd) + if data[0] == '': + return 'stop' + return 'start' + + +def caddyOp(method): + file = initDreplace() + + current_os = mw.getOs() + if current_os == "darwin": + data = mw.execShell(file + ' ' + method) + if data[1] == '': + return 'ok' + return data[1] + + if current_os.startswith("freebsd"): + data = mw.execShell('service caddy ' + method) + if data[1] == '': + return 'ok' + return data[1] + + data = mw.execShell('systemctl ' + method + ' caddy') + if data[1] == '': + return 'ok' + return data[1] + +def start(): + return caddyOp('start') + + +def stop(): + r = caddyOp('stop') + pid_file = getPidFile() + if os.path.exists(pid_file): + os.remove(pid_file) + return r + + +def restart(): + return restyOp_restart() + + +def reload(): + confReplace() + return caddyOp('reload') + + +def initdStatus(): + current_os = mw.getOs() + if current_os == 'darwin': + return "Apple Computer does not support" + + if current_os.startswith('freebsd'): + initd_bin = getInitDFile() + if os.path.exists(initd_bin): + return 'ok' + + shell_cmd = 'systemctl status caddy | grep loaded | grep "enabled;"' + data = mw.execShell(shell_cmd) + if data[0] == '': + return 'fail' + return 'ok' + + +def initdInstall(): + current_os = mw.getOs() + if current_os == 'darwin': + return "Apple Computer does not support" + + # freebsd initd install + if current_os.startswith('freebsd'): + import shutil + source_bin = initDreplace() + initd_bin = getInitDFile() + shutil.copyfile(source_bin, initd_bin) + mw.execShell('chmod +x ' + initd_bin) + mw.execShell('sysrc ' + getPluginName() + '_enable="YES"') + return 'ok' + + mw.execShell('systemctl enable caddy') + return 'ok' + + +def initdUinstall(): + current_os = mw.getOs() + if current_os == 'darwin': + return "Apple Computer does not support" + + if current_os.startswith('freebsd'): + initd_bin = getInitDFile() + os.remove(initd_bin) + mw.execShell('sysrc ' + getPluginName() + '_enable="NO"') + return 'ok' + + mw.execShell('systemctl disable caddy') + return 'ok' + + +def runInfo(): + op_status = status() + if op_status == 'stop': + return mw.returnJson(False, "未启动!") + + +def errorLogPath(): + return getServerDir() + '/nginx/logs/error.log' + + +def getCfg(): + cfg = getConf() + content = mw.readFile(cfg) + + unitrep = "[kmgKMG]" + cfg_args = [ + {"name": "worker_processes", "ps": "处理进程,auto表示自动,数字表示进程数", 'type': 2}, + {"name": "worker_connections", "ps": "最大并发链接数", 'type': 2}, + {"name": "keepalive_timeout", "ps": "连接超时时间", 'type': 2}, + {"name": "zstd", "ps": "是否开启zstd压缩传输", 'type': 1}, + {"name": "brotli", "ps": "是否开启brotli压缩传输", 'type': 1}, + {"name": "gzip", "ps": "是否开启gzip压缩传输", 'type': 1}, + {"name": "gzip_min_length", "ps": "最小压缩文件", 'type': 2}, + {"name": "gzip_comp_level", "ps": "压缩率", 'type': 2}, + {"name": "client_max_body_size", "ps": "最大上传文件", 'type': 2}, + {"name": "server_names_hash_bucket_size", + "ps": "服务器名字的hash表大小", 'type': 2}, + {"name": "client_header_buffer_size", "ps": "客户端请求头buffer大小", 'type': 2}, + ] + + # {"name": "client_body_buffer_size", "ps": "请求主体缓冲区"} + rdata = [] + for i in cfg_args: + rep = r"(%s)\s+(\w+)" % i["name"] + k = re.search(rep, content) + if not k: + return mw.returnJson(False, "获取 key {} 失败".format(k)) + k = k.group(1) + v = re.search(rep, content) + if not v: + return mw.returnJson(False, "获取 value {} 失败".format(v)) + v = v.group(2) + + if re.search(unitrep, v): + u = str.upper(v[-1]) + v = v[:-1] + if len(u) == 1: + psstr = u + "B," + i["ps"] + else: + psstr = u + "," + i["ps"] + else: + u = "" + + kv = {"name": k, "value": v, "unit": u, + "ps": i["ps"], "type": i["type"]} + rdata.append(kv) + + return mw.returnJson(True, "ok", rdata) + +def replaceChar(value, index, new_char): + return value[:index] + new_char + value[index+1:] + +def makeWorkerCpuAffinity(val): + if val == "auto": + return "auto" + + if mw.isNumber(val): + core_num = int(val) + default_core_str = "0"*core_num + core_num_arr = [] + for x in range(core_num): + t = replaceChar(default_core_str, x , "1") + core_num_arr.append(t) + return " ".join(core_num_arr) + + return 'auto' + +def setCfg(): + + args = getArgs() + data = checkArgs(args, [ + 'worker_processes', 'worker_connections', 'keepalive_timeout','zstd','brotli', + 'gzip', 'gzip_min_length', 'gzip_comp_level', 'client_max_body_size', + 'server_names_hash_bucket_size', 'client_header_buffer_size' + ]) + if not data[0]: + return data[1] + + cfg = getConf() + mw.backFile(cfg) + content = mw.readFile(cfg) + + unitrep = "[kmgKMG]" + cfg_args = [ + {"name": "worker_processes", "ps": "处理进程,auto表示自动,数字表示进程数", 'type': 2}, + {"name": "worker_connections", "ps": "最大并发链接数", 'type': 2}, + {"name": "keepalive_timeout", "ps": "连接超时时间", 'type': 2}, + {"name": "zstd", "ps": "是否开启zstd压缩传输", 'type': 1}, + {"name": "brotli", "ps": "是否开启brotli压缩传输", 'type': 1}, + {"name": "gzip", "ps": "是否开启压缩传输", 'type': 1}, + {"name": "gzip_min_length", "ps": "最小压缩文件", 'type': 2}, + {"name": "gzip_comp_level", "ps": "压缩率", 'type': 2}, + {"name": "client_max_body_size", "ps": "最大上传文件", 'type': 2}, + {"name": "server_names_hash_bucket_size", + "ps": "服务器名字的hash表大小", 'type': 2}, + {"name": "client_header_buffer_size", "ps": "客户端请求头buffer大小", 'type': 2}, + ] + + # print(args) + for k, v in args.items(): + # print(k, v) + rep = r"%s\s+[^kKmMgG\;\n]+" % k + if k == "worker_processes" or k == "gzip": + if not re.search(r"auto|on|off|\d+", v): + return mw.returnJson(False, '参数值错误') + elif k == "zstd" or k == "brotli": + if not re.search(r"auto|on|off|\d+", v): + return mw.returnJson(False, '参数值错误') + else: + if not re.search(r"\d+", v): + return mw.returnJson(False, '参数值错误,请输入数字整数') + + if k == "worker_processes" : + k_wca = "worker_cpu_affinity" + rep_wca = r"%s\s+[^\;\n]+" % k_wca + v_wca = makeWorkerCpuAffinity(v) + newconf = "%s %s" % (k_wca, v_wca) + content = re.sub(rep_wca, newconf, content) + + + if re.search(rep, content): + newconf = "%s %s" % (k, v) + content = re.sub(rep, newconf, content) + elif re.search(rep, content): + newconf = "%s %s" % (k, v) + content = re.sub(rep, newconf, content) + + mw.writeFile(cfg, content) + isError = mw.checkWebConfig() + if (isError != True): + mw.restoreFile(cfg) + return mw.returnJson(False, 'ERROR: 配置出错
' + isError.replace("\n", '
') + '
') + + mw.restartWeb() + return mw.returnJson(True, '设置成功') + + +def cronAddCheck(): + try: + import tool_task + tool_task.createBgTask() + return mw.returnJson(True, '添加检查任务成功') + except Exception as e: + return mw.returnJson(False, '添加检查任务失败:'+str(e)) + +def cronDelCheck(): + try: + import tool_task + tool_task.removeBgTask() + return mw.returnJson(True, '删除检查任务成功') + except Exception as e: + return mw.returnJson(False, '删除检查任务失败:'+str(e)) + +def cronCheck(): + return 'ok' + + +def installPreInspection(): + return 'ok' + + +if __name__ == "__main__": + + version = '1.27.1' + version_pl = getServerDir() + "/version.pl" + if os.path.exists(version_pl): + version = mw.readFile(version_pl) + + + 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 == 'install_pre_inspection': + print(installPreInspection()) + elif func == 'conf': + print(getConf()) + elif func == 'get_os': + print(getOs()) + elif func == 'run_info': + print(runInfo()) + elif func == 'error_log': + print(errorLogPath()) + elif func == 'get_cfg': + print(getCfg()) + elif func == 'set_cfg': + print(setCfg()) + elif func == 'check': + print(cronCheck()) + elif func == 'cron_add_check': + print(cronAddCheck()) + elif func == 'cron_del_check': + print(cronDelCheck()) + else: + print('error') diff --git a/plugins/caddy/info.json b/plugins/caddy/info.json new file mode 100755 index 000000000..97a69c069 --- /dev/null +++ b/plugins/caddy/info.json @@ -0,0 +1,18 @@ +{ + "sort": 0, + "title":"caddy", + "tip":"soft", + "name":"caddy", + "type":"其他插件", + "ps":"一款功能强大、企业级、开源 Web 服务器,具有用 Go 编写的自动 HTTPS", + "shell":"install.sh", + "install_pre_inspection":true, + "checks":"server/caddy", + "path":"server/caddy", + "author":"caddyserver", + "home":"https://caddyserver.com/", + "date":"2026-04-11", + "pid": "1", + "versions": ["2.11"], + "updates": ["2.11.2"] +} \ No newline at end of file diff --git a/plugins/caddy/init.d/caddy.service.tpl b/plugins/caddy/init.d/caddy.service.tpl new file mode 100644 index 000000000..724eb30d7 --- /dev/null +++ b/plugins/caddy/init.d/caddy.service.tpl @@ -0,0 +1,36 @@ +# caddy.service +# +# For using Caddy with a config file. +# +# Make sure the ExecStart and ExecReload commands are correct +# for your installation. +# +# See https://caddyserver.com/docs/install for instructions. +# +# WARNING: This service does not use the --resume flag, so if you +# use the API to make changes, they will be overwritten by the +# Caddyfile next time the service is restarted. If you intend to +# use Caddy's API to configure it, add the --resume flag to the +# `caddy run` command or use the caddy-api.service file instead. + +[Unit] +Description=Caddy +Documentation=https://caddyserver.com/docs/ +After=network.target network-online.target +Requires=network-online.target + +[Service] +Type=notify +User=caddy +Group=caddy +ExecStart={$SERVER_PATH}/caddy/bin/caddy run --environ --config {$SERVER_PATH}/caddy/Caddyfile +ExecReload={$SERVER_PATH}/caddy/bin/caddy reload --config {$SERVER_PATH}/caddy/Caddyfile --force +TimeoutStopSec=5s +LimitNOFILE=1048576 +LimitNPROC=512 +PrivateTmp=true +ProtectSystem=full +AmbientCapabilities=CAP_NET_BIND_SERVICE + +[Install] +WantedBy=multi-user.target diff --git a/plugins/caddy/init.d/caddy.tpl b/plugins/caddy/init.d/caddy.tpl new file mode 100644 index 000000000..e89186483 --- /dev/null +++ b/plugins/caddy/init.d/caddy.tpl @@ -0,0 +1,111 @@ +#!/bin/sh +# +# /etc/rc.d/init.d/caddy +# +# Runs the caddy +# +# +# chkconfig: - 85 15 +# + +### BEGIN INIT INFO +# Provides: caddy +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Should-Start: caddy +# Should-Stop: caddy +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start caddy at boot time. +# Description: Control caddy. +### END INIT INFO + +# Source function library. +if [ -f /etc/init.d/functions ];then + . /etc/init.d/functions +fi + +if [ -f /etc/rc.d/init.d/functions ];then + . /etc/rc.d/init.d/functions +fi + +# Default values +export HOME={$HOME_DIR} +export USER={$RUN_USER} +NAME=caddy +CADDY_HOME={$SERVER_PATH}/caddy +CADDY_PATH=${CADDY_HOME}/bin/$NAME +CADDY_USER={$RUN_USER} +SERVICENAME="caddy" +LOCKFILE=/tmp/caddy.lock +LOGPATH=${CADDY_HOME}/log +LOGFILE=${LOGPATH}/caddy.log +RETVAL=0 + +if [ -d $LOGPATH ];then + mkdir -p $LOGPATH +fi + +[ -r /etc/sysconfig/$NAME ] && . /etc/sysconfig/$NAME +DAEMON_OPTS="--check $NAME" +[ ! -z "$CADDY_USER" ] && DAEMON_OPTS="$DAEMON_OPTS --user=${CADDY_USER}" + +status(){ + isStart=`ps -ef|grep 'caddy run' |grep -v grep|awk '{print $2}'` + if [ "$isStart" == '' ];then + echo -e "${SERVICENAME} not running" + else + echo -e "${SERVICENAME}(pid $(echo $isStart)) already running" + fi +} + +start() { + isStart=`ps -ef | grep 'caddy run' | grep -v grep | awk '{print $2}'` + if [ "$isStart" != '' ];then + echo "${SERVICENAME}(pid $(echo $isStart)) already running" + return $RETVAL + fi + + cd ${CADDY_HOME} + echo -e "starting ${SERVICENAME}: \c" + ${CADDY_PATH} run --environ --config ${CADDY_HOME}/Caddyfile > ${LOGFILE} 2>&1 & + RETVAL=$? + [ $RETVAL = 0 ] && touch ${LOCKFILE} && echo -e "\033[32mdone\033[0m" + return $RETVAL +} + +stop() { + pids=`ps -ef | grep 'caddy run' | grep -v grep | awk '{print $2}'` + arr=($pids) + echo -e "stopping caddy... \c" + for p in ${arr[@]} + do + kill -9 $p + done + echo -e "\033[32mdone\033[0m" +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + status) + status + ;; + restart) + stop + start + ;; + reload) + stop + start + ;; + *) + echo "Usage: ${NAME} {start|stop|status|restart}" + exit 1 + ;; +esac +exit $RETVAL diff --git a/plugins/caddy/install.sh b/plugins/caddy/install.sh new file mode 100755 index 000000000..cf40b02da --- /dev/null +++ b/plugins/caddy/install.sh @@ -0,0 +1,76 @@ +#!/bin/bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin +export PATH + +# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/caddy && bash install.sh install 1.21.4 +# cd /www/server/mdserver-web/plugins/caddy && bash install.sh install 1.21.4 +# cd /www/server/mdserver-web/plugins/caddy && bash install.sh install 1.29.2 +# cd /www/server/mdserver-web/plugins/caddy && bash install.sh upgrade 1.29.2 + +# curl -I -H "Accept-Encoding: br" http://localhost +# curl -I -H "Accept-Encoding: zstd" http://localhost +# curl --http3 -v https://www.xxx.com + +# cd /www/server/mdserver-web && python3 plugins/caddy/index.py run_info + +curPath=`pwd` +rootPath=$(dirname "$curPath") +rootPath=$(dirname "$rootPath") +serverPath=$(dirname "$rootPath") + +sysName=`uname` +action=$1 +type=$2 + +VERSION=$2 +openrestyDir=${serverPath}/source/caddy + +if id www &> /dev/null ;then + echo "www uid is `id -u www`" + echo "www shell is `grep "^www:" /etc/passwd |cut -d':' -f7 `" +else + groupadd www + useradd -g www -s /bin/bash www +fi + +if [ "${action}" == "upgrade" ];then + sh -x $curPath/versions/$2/install.sh $1 + + echo "${VERSION}" > $serverPath/caddy/version.pl + + #初始化 + cd ${rootPath} && python3 ${rootPath}/plugins/caddy/index.py start + cd ${rootPath} && python3 ${rootPath}/plugins/caddy/index.py initd_install + exit 0 +fi + + +if [ "${2}" == "" ];then + echo '缺少安装脚本版本...' + exit 0 +fi + +if [ "${action}" == "uninstall" ];then + if [ -f /usr/lib/systemd/system/caddy.service ] || [ -f /lib/systemd/system/caddy.service ];then + systemctl stop caddy + rm -rf /usr/systemd/system/caddy.service + rm -rf /lib/systemd/system/caddy.service + systemctl daemon-reload + fi + + if [ -f $serverPath/caddy/init.d/caddy ];then + $serverPath/caddy/init.d/caddy stop + fi + + rm -rf $serverPath/caddy +fi + +sh -x $curPath/versions/$2/install.sh $1 + +if [ "${action}" == "install" ] && [ -d $serverPath/caddy ];then + echo "${VERSION}" > $serverPath/caddy/version.pl + + #初始化 + cd ${rootPath} && python3 ${rootPath}/plugins/caddy/index.py start + cd ${rootPath} && python3 ${rootPath}/plugins/caddy/index.py initd_install +fi diff --git a/plugins/caddy/js/caddy.js b/plugins/caddy/js/caddy.js new file mode 100755 index 000000000..3eccb9fce --- /dev/null +++ b/plugins/caddy/js/caddy.js @@ -0,0 +1,238 @@ +function caddyPost(method, args, callback){ + var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 }); + $.post('/plugins/run', {name:'caddy', func:method, args:JSON.stringify(args)}, 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 orPluginService(_name, version){ + var data = {name:_name, func:'status'} + if ( typeof(version) != 'undefined' ){ + data['version'] = version; + } else { + version = ''; + } + + caddyPost('status', data, function(data){ + if (data.data == 'start'){ + orPluginSetService(_name, true, version); + } else { + orPluginSetService(_name, false, version); + } + }); +} + +function orPluginSetService(_name ,status, version){ + var serviceCon ='

当前状态:'+(status ? '开启' : '关闭' )+ + '

\ + \ + \ + \ +
'; + $(".soft-man-con").html(serviceCon); +} + + +function orPluginOpService(a, b, v,request_callback) { + + var c = "name=" + a + "&func=" + b; + if(v != ''){ + c = c + '&version='+v; + } + + var d = ""; + + switch(b) { + case "stop":d = '停止';break; + case "start":d = '启动';break; + case "restart":d = '重启';break; + case "reload":d = '重载';break; + } + layer.confirm( msgTpl('您真的要{1}{2}{3}服务吗?', [d,a,v]), {icon:3,closeBtn: 2}, function() { + caddyPost('get_os',{},function(data){ + var rdata = $.parseJSON(data.data); + if (!rdata['auth']){ + layer.prompt({title: '检查到权限不足,需要输入密码!', formType: 1},function(pwd, index){ + + layer.close(index); + var data = {'pwd':pwd}; + c += '&args='+JSON.stringify(data); + orPluginOpServiceOp(a,b,c,d,a,v,request_callback); + }); + } else { + orPluginOpServiceOp(a,b,c,d,a,v,request_callback); + + } + }); + }) +} + +function orPluginOpServiceOp(a,b,c,d,a,v,request_callback){ + + var request_path = "/plugins/run"; + if (request_callback == 'yes'){ + request_path = "/plugins/callback"; + } + + var e = layer.msg(msgTpl('正在{1}{2}{3}服务,请稍候...',[d,a,v]), {icon: 16,time: 0}); + $.post(request_path, c, function(g) { + layer.close(e); + + var f = g.data == 'ok' ? msgTpl('{1}{2}服务已{3}',[a,v,d]) : msgTpl('{1}{2}服务{3}失败!',[a,v,d]); + layer.msg(f, {icon: g.data == 'ok' ? 1 : 2}); + + if( b != "reload" && g.data == 'ok' ) { + if ( b == 'start' ) { + orPluginSetService(a, true, v); + } else if ( b == 'stop' ){ + orPluginSetService(a, false, v); + } + } + + if( g.status && g.data != 'ok' ) { + layer.msg(g.data, {icon: 2,time: 10000,shade: 0.3}); + } + + },'json').error(function() { + layer.close(e); + layer.msg('操作异常!', {icon: 2}); + }); +} + + +//查看Nginx负载状态 +function getOpStatus() { + var loadT = layer.msg('正在处理,请稍后...', { icon: 16, time: 0, shade: 0.3 }); + $.post('/plugins/run', {name:'openresty', func:'run_info'}, function(data) { + layer.close(loadT); + try { + var rdata = $.parseJSON(data.data); + if ('status' in rdata && !rdata.status){ + showMsg(rdata.msg, function(){}, null,3000); + return; + } + + var con = "
\ + \ + \ + \ + \ + \ + \ + \ +
活动连接(Active connections)" + rdata.active + "
总连接次数(accepts)" + rdata.accepts + "
总握手次数(handled)" + rdata.handled + "
总请求数(requests)" + rdata.requests + "
请求数(Reading)" + rdata.Reading + "
响应数(Writing)" + rdata.Writing + "
驻留进程(Waiting)" + rdata.Waiting + "
"; + $(".soft-man-con").html(con); + }catch(err){ + showMsg(data.data, function(){}, null,3000); + } + },'json'); +} + + +function setOpCfg(){ + caddyPost('get_cfg', {}, function(data){ + var rdata = $.parseJSON(data.data); + var rdata = rdata.data; + // console.log(rdata); + + var mlist = ''; + for (var i = 0; i < rdata.length; i++) { + var w = '70' + 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].unit+"" +', ' + rdata[i].ps + '

'; + } + var con = '
\ + ' + mlist + '\ +
\ + \ + \ +
\ +
' + $(".soft-man-con").html(con); + }); +} + +function submitConf() { + var data = { + worker_processes: $("input[name='worker_processes']").val(), + worker_connections: $("input[name='worker_connections']").val(), + keepalive_timeout: $("input[name='keepalive_timeout']").val(), + zstd: $("select[name='zstd']").val() || 'on', + brotli: $("select[name='brotli']").val() || 'on', + gzip: $("select[name='gzip']").val() || 'on', + gzip_min_length: $("input[name='gzip_min_length']").val(), + gzip_comp_level: $("input[name='gzip_comp_level']").val(), + client_max_body_size: $("input[name='client_max_body_size']").val(), + server_names_hash_bucket_size: $("input[name='server_names_hash_bucket_size']").val(), + client_header_buffer_size: $("input[name='client_header_buffer_size']").val(), + }; + + // console.log(data); + caddyPost('set_cfg', data, function(rdata){ + var rdata = $.parseJSON(rdata.data); + // console.log(rdata); + layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 }); + }); +} + +function otherFunc(){ + var con = '

\ + \ + \ +

'; + $(".soft-man-con").html(con); +} + +function cronAddCheck(){ + caddyPost('cron_add_check', {}, function(data){ + var rdata = $.parseJSON(data.data); + layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 }); + }); +} + +function cronDelCheck(){ + caddyPost('cron_del_check', {}, function(data){ + var rdata = $.parseJSON(data.data); + layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 }); + }); +} + + + + + + + + + + + + diff --git a/plugins/caddy/tool_task.py b/plugins/caddy/tool_task.py new file mode 100644 index 000000000..f20ba8348 --- /dev/null +++ b/plugins/caddy/tool_task.py @@ -0,0 +1,124 @@ +# coding:utf-8 + +import sys +import io +import os +import time +import json + +web_dir = os.getcwd() + "/web" +if os.path.exists(web_dir): + sys.path.append(web_dir) + os.chdir(web_dir) + +import core.mw as mw +from utils.crontab import crontab as MwCrontab + + +app_debug = False +if mw.isAppleSystem(): + app_debug = True + + +def getPluginName(): + return 'caddy' + + +def getPluginDir(): + return mw.getPluginDir() + '/' + getPluginName() + + +def getServerDir(): + return mw.getServerDir() + '/' + getPluginName() + + +def getTaskConf(): + conf = getServerDir() + "/task_config.json" + return conf + + +def getConfigData(): + conf = getTaskConf() + if os.path.exists(conf): + return json.loads(mw.readFile(getTaskConf())) + return { + "task_id": -1, + "period": "minute-n", + "where1": "3", + "hour": "0", + "minute": "0", + } + + +def createBgTask(): + removeBgTask() + createBgTaskByName(getPluginName()) + + +def createBgTaskByName(name): + args = getConfigData() + _name = "[caddy]检查任务" + res = mw.M("crontab").field("id, name").where("name=?", (_name,)).find() + if res: + return True + + if "task_id" in args and args["task_id"] > 0: + res = mw.M("crontab").field("id, name").where( + "id=?", (args["task_id"],)).find() + if res and res["id"] == args["task_id"]: + print("计划任务已经存在!") + return True + + mw_dir = mw.getPanelDir() + cmd = ''' +mw_dir=%s +rname=%s +plugin_path=%s +script_path=%s +''' % (mw_dir, name, getServerDir(), getPluginDir()) + cmd += 'echo "bash $script_path/check.sh"' + "\n" + cmd += 'cd $mw_dir && bash $script_path/check.sh' + "\n" + + params = { + 'name': _name, + 'type': args['period'], + 'week': "", + 'where1': args['where1'], + 'hour': args['hour'], + 'minute': args['minute'], + 'save': "", + 'backup_to': "", + 'stype': "toShell", + 'sname': '', + 'sbody': cmd, + 'url_address': '', + } + + task_id = MwCrontab.instance().add(params) + if task_id > 0: + args["task_id"] = task_id + args["name"] = name + mw.writeFile(getTaskConf(), json.dumps(args)) + + +def removeBgTask(): + cfg = getConfigData() + if "task_id" in cfg and cfg["task_id"] > 0: + res = mw.M("crontab").field("id, name").where( + "id=?", (cfg["task_id"],)).find() + if res and res["id"] == cfg["task_id"]: + data = MwCrontab.instance().delete(cfg["task_id"]) + if data["status"]: + cfg["task_id"] = -1 + mw.writeFile(getTaskConf(), json.dumps(cfg)) + return True + return False + + +if __name__ == "__main__": + if len(sys.argv) > 1: + action = sys.argv[1] + if action == "remove": + removeBgTask() + elif action == "add": + createBgTask() diff --git a/plugins/caddy/versions/2.11/install.sh b/plugins/caddy/versions/2.11/install.sh new file mode 100644 index 000000000..e97027b78 --- /dev/null +++ b/plugins/caddy/versions/2.11/install.sh @@ -0,0 +1,87 @@ +#!/bin/bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin +export PATH + +# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/caddy && bash install.sh install 2.11 +# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/caddy && bash install.sh upgrade 2.11 +# cd /www/server/mdserver-web/plugins/caddy && bash install.sh install 2.11 + +curPath=`pwd` +rootPath=$(dirname "$curPath") +rootPath=$(dirname "$rootPath") +serverPath=$(dirname "$rootPath") + +sysName=`uname` +action=$1 +type=$2 + +OS=`uname` +OSNAME='' +case $(uname) in + Darwin) OSNAME="mac" ;; + Linux) OSNAME="linux" ;; +esac + +ARCH=`uname -m` +ARCH_NAME='' +case $(uname -m) in + i386) ARCH_NAME="386" ;; + i686) ARCH_NAME="386" ;; + x86_64) ARCH_NAME="amd64" ;; + arm) ARCH_NAME="arm64" ;; + arm64) ARCH_NAME="arm64" ;; +esac + +VERSION=2.11.2 + +caddyDir=${serverPath}/source/caddy + +Install_App() +{ + if [ "${action}" == "install" ];then + if [ -d $serverPath/caddy ];then + exit 0 + fi + fi + + mkdir -p ${caddyDir} + # mkdir -p ${serverPath}/caddy + echo 'install scripts ...' + + FILE_NAME="caddy_${VERSION}_${OSNAME}_${ARCH_NAME}.tar.gz" + + if [ ! -f ${caddyDir}/${FILE_NAME} ];then + wget --no-check-certificate -O ${caddyDir}/${FILE_NAME} "https://github.com/caddyserver/caddy/releases/download/v${VERSION}/${FILE_NAME}" + fi + + + echo "cd $serverPath/source/caddy/caddy && tar -zxvf ${caddyDir}/$FILE_NAME" + + mkdir -p cd $serverPath/source/caddy/caddy + cd $serverPath/source/caddy/caddy && tar -zxvf ${caddyDir}/$FILE_NAME + if [ "$OSNAME" == "mac" ];then + xattr -cr caddy + fi + + if [ ! -f $serverPath/caddy/bin ];then + mkdir -p $serverPath/caddy/bin + mv $serverPath/source/caddy/caddy/* $serverPath/caddy/bin + chmod +x $serverPath/caddy/bin/caddy + fi + + echo 'Installation of caddy completed' +} + +Uninstall_App() +{ + echo 'Uninstalling caddy completed' +} + +action=$1 +if [ "${1}" == "install" ];then + Install_App +elif [ "${1}" == "upgrade" ];then + Install_App +else + Uninstall_App +fi