mirror of https://github.com/midoks/mdserver-web
parent
9aad09be9a
commit
f766039139
@ -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 |
||||
|
||||
@ -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 |
||||
} |
||||
|
After Width: | Height: | Size: 3.5 KiB |
@ -0,0 +1,24 @@ |
||||
<div class="bt-form"> |
||||
<!-- <div class='plugin_version'></div> --> |
||||
<div class="bt-w-main"> |
||||
<div class="bt-w-menu"> |
||||
<p class="bgw" onclick="orPluginService('caddy',$('.plugin_version').attr('version'));">服务</p> |
||||
<p onclick="pluginInitD('caddy', $('.plugin_version').attr('version'));">自启动</p> |
||||
<p onclick="pluginConfig('caddy');">配置修改</p> |
||||
<p onclick="getOpStatus();">负载状态</p> |
||||
<p onclick="setOpCfg();">性能调整</p> |
||||
<p onclick="pluginLogs('caddy');">错误日志</p> |
||||
<p onclick="otherFunc();">维护功能</p> |
||||
</div> |
||||
<div class="bt-w-con pd15"> |
||||
<div class="soft-man-con"></div> |
||||
</div> |
||||
</div> |
||||
|
||||
</div> |
||||
|
||||
<script type="text/javascript"> |
||||
$.getScript( "/plugins/file?name=caddy&f=js/caddy.js", function(){ |
||||
orPluginService('caddy'); |
||||
}); |
||||
</script> |
||||
@ -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: 配置出错<br><a style="color:red;">' + isError.replace("\n", '<br>') + '</a>') |
||||
|
||||
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') |
||||
@ -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"] |
||||
} |
||||
@ -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 |
||||
@ -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 |
||||
@ -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 |
||||
@ -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 ='<p class="status">当前状态:<span>'+(status ? '开启' : '关闭' )+ |
||||
'</span><span style="color: '+ |
||||
(status?'#20a53a;':'red;')+ |
||||
' margin-left: 3px;" class="glyphicon ' + (status?'glyphicon glyphicon-play':'glyphicon-pause')+'"></span></p><div class="sfm-opt">\ |
||||
<button class="btn btn-default btn-sm" onclick="orPluginOpService(\''+_name+'\',\''+(status?'stop':'start')+'\',\''+version+'\')">'+(status?'停止':'启动')+'</button>\ |
||||
<button class="btn btn-default btn-sm" onclick="orPluginOpService(\''+_name+'\',\'restart\',\''+version+'\',\'yes\')">重启</button>\ |
||||
<button class="btn btn-default btn-sm" onclick="orPluginOpService(\''+_name+'\',\'reload\',\''+version+'\')">重载配置</button>\ |
||||
</div>'; |
||||
$(".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 = "<div><table class='table table-hover table-bordered'>\ |
||||
<tr><th>活动连接(Active connections)</th><td>" + rdata.active + "</td></tr>\ |
||||
<tr><th>总连接次数(accepts)</th><td>" + rdata.accepts + "</td></tr>\ |
||||
<tr><th>总握手次数(handled)</th><td>" + rdata.handled + "</td></tr>\ |
||||
<tr><th>总请求数(requests)</th><td>" + rdata.requests + "</td></tr>\ |
||||
<tr><th>请求数(Reading)</th><td>" + rdata.Reading + "</td></tr>\ |
||||
<tr><th>响应数(Writing)</th><td>" + rdata.Writing + "</td></tr>\ |
||||
<tr><th>驻留进程(Waiting)</th><td>" + rdata.Waiting + "</td></tr>\ |
||||
</table></div>"; |
||||
$(".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 = '<input style="width: ' + w + 'px;" class="bt-input-text mr5" name="' + rdata[i].name + '" value="' + rdata[i].value + '" type="text" >'; |
||||
switch (rdata[i].type) { |
||||
case 0: |
||||
var selected_1 = (rdata[i].value == 1) ? 'selected' : ''; |
||||
var selected_0 = (rdata[i].value == 0) ? 'selected' : ''; |
||||
ibody = '<select class="bt-input-text mr5" name="' + rdata[i].name + '" style="width: ' + w + 'px;">\ |
||||
<option value="1" ' + selected_1 + '>开启</option>\ |
||||
<option value="0" ' + selected_0 + '>关闭</option>\ |
||||
</select>'; |
||||
break; |
||||
case 1: |
||||
var selected_1 = (rdata[i].value == 'on') ? 'selected' : ''; |
||||
var selected_0 = (rdata[i].value == 'off') ? 'selected' : ''; |
||||
ibody = '<select class="bt-input-text mr5" name="' + rdata[i].name + '" style="width: ' + w + 'px;">\ |
||||
<option value="on" ' + selected_1 + '>开启</option>\ |
||||
<option value="off" ' + selected_0 + '>关闭</option>\ |
||||
</select>'; |
||||
break; |
||||
} |
||||
mlist += '<p style="margin-top:15px;"><span>' + rdata[i].name + '</span>' + ibody + "<b class='unit c9'>"+rdata[i].unit+"</b>" +', <font class="c9">' + rdata[i].ps + '</font></p>'; |
||||
} |
||||
var con = '<style>.conf_p p{margin-bottom: 2px}</style><div class="conf_p" style="margin-bottom:0">\ |
||||
' + mlist + '\ |
||||
<div style="margin-top:10px; padding-right:15px" class="text-right">\ |
||||
<button class="btn btn-success btn-sm mr5" onclick="setOpCfg()">刷新</button>\ |
||||
<button class="btn btn-success btn-sm" onclick="submitConf()">保存</button>\ |
||||
</div>\ |
||||
</div>' |
||||
$(".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 = '<p class="conf_p" style="text-align:center;">\ |
||||
<button class="btn btn-default btn-sm" onclick="cronAddCheck()">添加检查任务</button> \ |
||||
<button class="btn btn-default btn-sm" onclick="cronDelCheck()">删除检查任务</button>\ |
||||
</p>'; |
||||
$(".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 }); |
||||
}); |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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() |
||||
@ -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 |
||||
Loading…
Reference in new issue