@whyour/qinglong 2.20.2-3 → 2.21.0-10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +5 -0
- package/AGENTS.md +43 -0
- package/README-en.md +11 -0
- package/README.md +11 -0
- package/back/protos/api.proto +3 -0
- package/deploy/kubernetes/README.md +81 -0
- package/deploy/kubernetes/base/kustomization.yaml +5 -0
- package/deploy/kubernetes/base/qinglong.yaml +95 -0
- package/deploy/kubernetes/overlays/example/kustomization.yaml +10 -0
- package/docker/Dockerfile +51 -69
- package/docker/Dockerfile.310 +94 -0
- package/docker/Dockerfile.debian +120 -0
- package/docker/{310.Dockerfile → Dockerfile.debian310} +13 -5
- package/docker/docker-entrypoint.sh +95 -3
- package/docs/PROJECT_ARCHITECTURE.md +550 -0
- package/package.json +29 -28
- package/sample/config.sample.sh +19 -3
- package/sample/notify.js +145 -9
- package/sample/notify.py +110 -11
- package/shell/api.sh +51 -21
- package/shell/bot.sh +30 -16
- package/shell/check.sh +21 -19
- package/shell/lang/en.sh +105 -0
- package/shell/lang/zh.sh +105 -0
- package/shell/otask.sh +117 -28
- package/shell/preload/client.js +20 -2
- package/shell/preload/esm-loader.mjs +41 -0
- package/shell/preload/sitecustomize.js +36 -0
- package/shell/pub.sh +8 -8
- package/shell/rmlog.sh +5 -5
- package/shell/share.sh +50 -31
- package/shell/start.sh +40 -27
- package/shell/task.sh +10 -2
- package/shell/update.sh +22 -22
- package/static/build/api/config.js +17 -7
- package/static/build/api/cron.js +40 -3
- package/static/build/api/dashboard.js +344 -0
- package/static/build/api/env.js +40 -2
- package/static/build/api/index.js +2 -0
- package/static/build/api/log.js +15 -5
- package/static/build/api/script.js +34 -9
- package/static/build/api/system.js +22 -8
- package/static/build/api/user.js +6 -5
- package/static/build/app.js +22 -19
- package/static/build/config/const.js +8 -6
- package/static/build/config/container.js +12 -0
- package/static/build/config/grpcCerts.js +150 -0
- package/static/build/config/index.js +6 -4
- package/static/build/config/util.js +69 -18
- package/static/build/data/cron.js +3 -1
- package/static/build/data/cronStats.js +59 -0
- package/static/build/data/env.js +2 -0
- package/static/build/data/notify.js +18 -1
- package/static/build/data/runningInstance.js +57 -0
- package/static/build/data/sock.js +1 -0
- package/static/build/loaders/app.js +7 -7
- package/static/build/loaders/db.js +8 -2
- package/static/build/loaders/deps.js +1 -22
- package/static/build/loaders/express.js +19 -15
- package/static/build/loaders/initData.js +20 -2
- package/static/build/loaders/initFile.js +3 -1
- package/static/build/loaders/initTask.js +3 -2
- package/static/build/loaders/server.js +1 -1
- package/static/build/protos/api.js +23 -1
- package/static/build/schedule/addCron.js +67 -10
- package/static/build/schedule/api.js +1 -1
- package/static/build/schedule/client.js +9 -1
- package/static/build/schedule/delCron.js +11 -1
- package/static/build/schedule/health.js +1 -1
- package/static/build/services/config.js +19 -5
- package/static/build/services/cron.js +198 -38
- package/static/build/services/dependence.js +19 -18
- package/static/build/services/env.js +31 -3
- package/static/build/services/grpc.js +32 -6
- package/static/build/services/http.js +33 -18
- package/static/build/services/notify.js +87 -8
- package/static/build/services/open.js +2 -1
- package/static/build/services/sshKey.js +6 -3
- package/static/build/services/subscription.js +8 -5
- package/static/build/services/system.js +34 -9
- package/static/build/services/user.js +39 -13
- package/static/build/shared/auth.js +7 -1
- package/static/build/shared/i18n.js +160 -0
- package/static/build/shared/pLimit.js +15 -3
- package/static/build/shared/runCron.js +5 -0
- package/static/build/shared/store.js +7 -0
- package/static/build/validation/schedule.js +10 -0
- package/static/dist/1089.0ecc5383.async.js +1 -0
- package/static/dist/1147.62793604.async.js +1 -0
- package/static/dist/1192.4e5740f2.async.js +1 -0
- package/static/dist/1214.c6469b53.async.js +1 -0
- package/static/dist/134.54df9e38.async.js +1 -0
- package/static/dist/1352.96a77e1d.async.js +1 -0
- package/static/dist/{1765.d8e002d7.async.js → 1765.5ac01a93.async.js} +1 -1
- package/static/dist/1836.f0b74cf1.async.js +1 -0
- package/static/dist/{1885.e0d00d2d.async.js → 1885.e1ea09f6.async.js} +1 -1
- package/static/dist/1967.3f3945d0.async.js +1 -0
- package/static/dist/{2096.383c1047.async.js → 2096.6d98fd12.async.js} +1 -1
- package/static/dist/2208.85285476.async.js +1 -0
- package/static/dist/2286.f371c743.async.js +1 -0
- package/static/dist/2476.4e9b0992.async.js +1 -0
- package/static/dist/2537.2b262ee0.async.js +1 -0
- package/static/dist/{255.12f03ab2.async.js → 255.8a80b983.async.js} +1 -1
- package/static/dist/2635.d4c59d23.async.js +1 -0
- package/static/dist/2808.cdc0995c.async.js +1 -0
- package/static/dist/{2821.be3dc88e.async.js → 2821.651f31e5.async.js} +1 -1
- package/static/dist/2986.4c49eef7.async.js +1 -0
- package/static/dist/300.08ac9875.async.js +1 -0
- package/static/dist/3191.545ab873.async.js +1 -0
- package/static/dist/3714.8d6dba9e.async.js +1 -0
- package/static/dist/3906.a5eee612.async.js +1 -0
- package/static/dist/{6541.a6d499de.async.js → 3948.4fe809fd.async.js} +1 -1
- package/static/dist/{5171.7fc6d0a2.async.js → 4573.16f19278.async.js} +1 -1
- package/static/dist/{4859.93e63ea6.async.js → 4859.6592cebb.async.js} +1 -1
- package/static/dist/4887.8e3ae573.async.js +1 -0
- package/static/dist/{4902.54ecbdb5.async.js → 4902.555f92ab.async.js} +1 -1
- package/static/dist/{4934.1ca6b6b0.async.js → 4934.f3539d08.async.js} +1 -1
- package/static/dist/5077.cbd111cd.async.js +1 -0
- package/static/dist/{6247.b550d996.async.js → 5157.7c5af144.async.js} +1 -1
- package/static/dist/{540.481d4708.async.js → 540.19ddf020.async.js} +1 -1
- package/static/dist/{5970.10ac4f16.async.js → 5970.d3a6e7bd.async.js} +1 -1
- package/static/dist/{6013.2d7bb12a.async.js → 6013.4e38de36.async.js} +1 -1
- package/static/dist/{6016.9c379049.async.js → 6016.1e6574b6.async.js} +1 -1
- package/static/dist/{6035.5889ddc7.async.js → 6035.32ebfad9.async.js} +1 -1
- package/static/dist/6339.ab305e96.async.js +1 -0
- package/static/dist/6569.55177f6a.async.js +1 -0
- package/static/dist/6610.c111af7e.async.js +1 -0
- package/static/dist/{3034.6413c38e.async.js → 6638.87a163d2.async.js} +1 -1
- package/static/dist/{6646.5fc37228.async.js → 6646.95e92533.async.js} +1 -1
- package/static/dist/6665.1d099ad1.async.js +1 -0
- package/static/dist/{7355.b7c0562f.async.js → 7355.f9f263d8.async.js} +1 -1
- package/static/dist/{7384.065ccae2.async.js → 7384.1bb449d5.async.js} +1 -1
- package/static/dist/7441.ee1bf2bb.async.js +1 -0
- package/static/dist/{7508.a31662a3.async.js → 7508.7dcee91c.async.js} +1 -1
- package/static/dist/{7802.6b73f16a.async.js → 7802.34255805.async.js} +1 -1
- package/static/dist/{7984.e6bb9378.async.js → 7984.594296a5.async.js} +1 -1
- package/static/dist/{5653.4fce7ce8.async.js → 8033.5cb31493.async.js} +1 -1
- package/static/dist/8147.2fb55202.async.js +1 -0
- package/static/dist/8187.48c130d6.async.js +1 -0
- package/static/dist/8495.d53e15ca.async.js +1 -0
- package/static/dist/8587.315b06c0.async.js +1 -0
- package/static/dist/8826.db34ad8d.async.js +1 -0
- package/static/dist/{2742.4852aac8.async.js → 8865.ed665d31.async.js} +1 -1
- package/static/dist/901.7ee5c6d3.async.js +1 -0
- package/static/dist/9271.231db2ce.async.js +1 -0
- package/static/dist/9323.a33f47da.async.js +1 -0
- package/static/dist/{9730.30083c91.async.js → 9730.801665a3.async.js} +1 -1
- package/static/dist/{9761.627ca3b5.async.js → 9761.360a19d8.async.js} +1 -1
- package/static/dist/index.html +2 -2
- package/static/dist/layouts__index.a7a2bfe0.async.js +1 -0
- package/static/dist/layouts__index.adf0692f.chunk.css +1 -0
- package/static/dist/preload_helper.3048fe5b.js +1 -0
- package/static/dist/{src__pages__config__index.622b6ee8.async.js → src__pages__config__index.a22ff7dc.async.js} +1 -1
- package/static/dist/{src__pages__crontab__const.323d5124.async.js → src__pages__crontab__const.aba07deb.async.js} +1 -1
- package/static/dist/src__pages__crontab__detail.b98f0084.async.js +1 -0
- package/static/dist/src__pages__crontab__index.68e78a33.async.js +1 -0
- package/static/dist/{src__pages__crontab__logModal.5e6a4bf2.async.js → src__pages__crontab__logModal.831d5e4b.async.js} +1 -1
- package/static/dist/src__pages__crontab__modal.f7041c7c.async.js +1 -0
- package/static/dist/src__pages__crontab__type.d7af36e5.async.js +1 -0
- package/static/dist/{src__pages__crontab__viewCreateModal.ffcf7a24.async.js → src__pages__crontab__viewCreateModal.4d589f66.async.js} +1 -1
- package/static/dist/{src__pages__crontab__viewManageModal.c2724575.async.js → src__pages__crontab__viewManageModal.0e317746.async.js} +1 -1
- package/static/dist/src__pages__dashboard__index.58177357.async.js +1 -0
- package/static/dist/src__pages__dependence__index.b7bbc795.async.js +1 -0
- package/static/dist/{src__pages__dependence__logModal.f123e2ac.async.js → src__pages__dependence__logModal.0681830b.async.js} +1 -1
- package/static/dist/src__pages__dependence__modal.f7bb47ba.async.js +1 -0
- package/static/dist/src__pages__env__editNameModal.48715576.async.js +1 -0
- package/static/dist/src__pages__env__index.452cdc47.async.js +1 -0
- package/static/dist/src__pages__env__modal.e1234834.async.js +1 -0
- package/static/dist/src__pages__error__index.dedb2b90.async.js +1 -0
- package/static/dist/src__pages__initialization__index.22620a77.async.js +1 -0
- package/static/dist/src__pages__log__index.9c66639f.async.js +1 -0
- package/static/dist/{src__pages__login__index.cd6e3152.async.js → src__pages__login__index.8c813eb1.async.js} +1 -1
- package/static/dist/{src__pages__script__components__UnsupportedFilePreview__index.39074c68.async.js → src__pages__script__components__UnsupportedFilePreview__index.c347a13a.async.js} +1 -1
- package/static/dist/src__pages__script__editNameModal.532a3044.async.js +1 -0
- package/static/dist/src__pages__script__index.1fc20f22.async.js +1 -0
- package/static/dist/src__pages__script__renameModal.5cdde919.async.js +1 -0
- package/static/dist/src__pages__script__saveModal.5ffed35f.async.js +1 -0
- package/static/dist/src__pages__script__setting.1a82c6d7.async.js +1 -0
- package/static/dist/src__pages__setting__appModal.43b7758a.async.js +1 -0
- package/static/dist/src__pages__setting__checkUpdate.34d773f2.async.js +1 -0
- package/static/dist/src__pages__setting__dependence.9c04c79a.async.js +1 -0
- package/static/dist/src__pages__setting__index.7e070838.async.js +1 -0
- package/static/dist/src__pages__setting__notification.bac481c2.async.js +1 -0
- package/static/dist/src__pages__setting__other.707cfafe.async.js +1 -0
- package/static/dist/src__pages__setting__security.b7235753.async.js +1 -0
- package/static/dist/src__pages__setting__systemLog.b81a8c1d.async.js +1 -0
- package/static/dist/{src__pages__subscription__logModal.0caa7283.async.js → src__pages__subscription__logModal.3864b37f.async.js} +1 -1
- package/static/dist/src__pages__subscription__modal.562448e2.async.js +1 -0
- package/static/dist/{umi.ef8199a4.js → umi.a54a59f6.js} +1 -1
- package/version.yaml +33 -4
- package/sample/notify.py.save +0 -1010
- package/static/dist/105.85a5c47a.async.js +0 -1
- package/static/dist/1083.f86ce804.async.js +0 -1
- package/static/dist/1147.32f41a88.async.js +0 -1
- package/static/dist/1352.ab6da08e.async.js +0 -1
- package/static/dist/1690.f0290540.async.js +0 -1
- package/static/dist/1742.6cbe5aca.async.js +0 -1
- package/static/dist/2208.8e3a7325.async.js +0 -1
- package/static/dist/3191.70bc19db.async.js +0 -1
- package/static/dist/5312.74b95311.async.js +0 -1
- package/static/dist/5691.931f59c5.async.js +0 -1
- package/static/dist/6159.55cb068a.async.js +0 -1
- package/static/dist/7025.f4080d63.async.js +0 -1
- package/static/dist/739.6be5552a.async.js +0 -1
- package/static/dist/7571.4f6240b1.async.js +0 -1
- package/static/dist/786.59fc381c.async.js +0 -1
- package/static/dist/8317.c44c1ebd.async.js +0 -1
- package/static/dist/8826.0291edfd.async.js +0 -1
- package/static/dist/955.3c9481f7.async.js +0 -1
- package/static/dist/layouts__index.1fce90e0.chunk.css +0 -1
- package/static/dist/layouts__index.8dcf1576.async.js +0 -1
- package/static/dist/preload_helper.116a62f6.js +0 -1
- package/static/dist/src__pages__crontab__detail.b07f0c0a.async.js +0 -1
- package/static/dist/src__pages__crontab__index.2e2e1096.async.js +0 -1
- package/static/dist/src__pages__crontab__modal.4d8c2a22.async.js +0 -1
- package/static/dist/src__pages__crontab__type.db7c1858.async.js +0 -1
- package/static/dist/src__pages__dependence__index.3d87ceac.async.js +0 -1
- package/static/dist/src__pages__dependence__modal.631ffb5b.async.js +0 -1
- package/static/dist/src__pages__env__editNameModal.ff85ef8c.async.js +0 -1
- package/static/dist/src__pages__env__index.a0a2fece.async.js +0 -1
- package/static/dist/src__pages__env__modal.d1004662.async.js +0 -1
- package/static/dist/src__pages__error__index.1bc3c90b.async.js +0 -1
- package/static/dist/src__pages__initialization__index.8b1cbaf9.async.js +0 -1
- package/static/dist/src__pages__log__index.cf00c9af.async.js +0 -1
- package/static/dist/src__pages__script__editNameModal.53424d49.async.js +0 -1
- package/static/dist/src__pages__script__index.e65df827.async.js +0 -1
- package/static/dist/src__pages__script__renameModal.4bbe7fb1.async.js +0 -1
- package/static/dist/src__pages__script__saveModal.cf449f3c.async.js +0 -1
- package/static/dist/src__pages__script__setting.b345d59a.async.js +0 -1
- package/static/dist/src__pages__setting__appModal.03faec89.async.js +0 -1
- package/static/dist/src__pages__setting__checkUpdate.46efe057.async.js +0 -1
- package/static/dist/src__pages__setting__dependence.4495c7b6.async.js +0 -1
- package/static/dist/src__pages__setting__index.6919c399.async.js +0 -1
- package/static/dist/src__pages__setting__notification.d6a3884f.async.js +0 -1
- package/static/dist/src__pages__setting__other.0d931d6f.async.js +0 -1
- package/static/dist/src__pages__setting__security.91cb545f.async.js +0 -1
- package/static/dist/src__pages__setting__systemLog.1d433a48.async.js +0 -1
- package/static/dist/src__pages__subscription__modal.0b84f6cf.async.js +0 -1
package/shell/otask.sh
CHANGED
|
@@ -24,7 +24,13 @@ random_delay() {
|
|
|
24
24
|
done
|
|
25
25
|
|
|
26
26
|
local delay_second=$(($(gen_random_num "$random_delay_max") + 1))
|
|
27
|
-
|
|
27
|
+
local start_time
|
|
28
|
+
if [[ $is_macos -eq 1 ]]; then
|
|
29
|
+
start_time=$(date -v "+${delay_second}S" "+%Y-%m-%d %H:%M:%S")
|
|
30
|
+
else
|
|
31
|
+
start_time=$(date -d "+${delay_second} seconds" "+%Y-%m-%d %H:%M:%S")
|
|
32
|
+
fi
|
|
33
|
+
t '任务随机延迟 %s 秒,将于 %s 开始,配置文件参数 RandomDelay 置空可取消延迟\n' "$delay_second" "$start_time"
|
|
28
34
|
sleep $delay_second
|
|
29
35
|
fi
|
|
30
36
|
}
|
|
@@ -83,6 +89,61 @@ clear_non_sh_env() {
|
|
|
83
89
|
fi
|
|
84
90
|
}
|
|
85
91
|
|
|
92
|
+
append_node_dependency_path() {
|
|
93
|
+
export PREV_NODE_PATH="${NODE_PATH:=}"
|
|
94
|
+
|
|
95
|
+
# 用户依赖目录加入 NODE_PATH,替代 symlink 到 node_modules 的方式
|
|
96
|
+
export NODE_PATH="${NODE_PATH:+${NODE_PATH}:}${dir_dep}"
|
|
97
|
+
|
|
98
|
+
local pnpm_global_path=$(pnpm root -g 2>/dev/null)
|
|
99
|
+
if [[ -n "$pnpm_global_path" ]]; then
|
|
100
|
+
export QL_NODE_GLOBAL_PATH="$pnpm_global_path"
|
|
101
|
+
export NODE_PATH="${NODE_PATH:+${NODE_PATH}:}${pnpm_global_path}"
|
|
102
|
+
fi
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
enter_script_workdir() {
|
|
106
|
+
local use_dot_prefix="$1"
|
|
107
|
+
|
|
108
|
+
# 如果定时任务显式指定了工作目录,优先使用
|
|
109
|
+
if [[ -n "${work_dir:=}" ]]; then
|
|
110
|
+
local _target_dir
|
|
111
|
+
if [[ "${work_dir}" == /* ]]; then
|
|
112
|
+
_target_dir="${work_dir}"
|
|
113
|
+
else
|
|
114
|
+
_target_dir="${dir_scripts}/${work_dir}"
|
|
115
|
+
fi
|
|
116
|
+
if [[ -d "${_target_dir}" ]]; then
|
|
117
|
+
cd "${_target_dir}"
|
|
118
|
+
if [[ ${file_param} =~ "/" ]]; then
|
|
119
|
+
local script_name="${file_param##*/}"
|
|
120
|
+
if [[ "${use_dot_prefix}" == "true" ]]; then
|
|
121
|
+
file_param="./${script_name}"
|
|
122
|
+
else
|
|
123
|
+
file_param="${script_name}"
|
|
124
|
+
fi
|
|
125
|
+
fi
|
|
126
|
+
return
|
|
127
|
+
fi
|
|
128
|
+
t '警告:工作目录不存在 %s' "${_target_dir}"
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
cd $dir_scripts
|
|
132
|
+
if [[ ${file_param} =~ "/" ]]; then
|
|
133
|
+
local script_dir="${file_param%/*}"
|
|
134
|
+
local script_name="${file_param##*/}"
|
|
135
|
+
|
|
136
|
+
if [[ -d ${script_dir} ]]; then
|
|
137
|
+
cd ${script_dir}
|
|
138
|
+
if [[ "${use_dot_prefix}" == "true" ]]; then
|
|
139
|
+
file_param="./${script_name}"
|
|
140
|
+
else
|
|
141
|
+
file_param="${script_name}"
|
|
142
|
+
fi
|
|
143
|
+
fi
|
|
144
|
+
fi
|
|
145
|
+
}
|
|
146
|
+
|
|
86
147
|
## 正常运行单个脚本,$1:传入参数
|
|
87
148
|
run_normal() {
|
|
88
149
|
local file_param=$1
|
|
@@ -90,12 +151,7 @@ run_normal() {
|
|
|
90
151
|
random_delay "$file_param"
|
|
91
152
|
fi
|
|
92
153
|
|
|
93
|
-
|
|
94
|
-
local relative_path="${file_param%/*}"
|
|
95
|
-
if [[ ${file_param} != /* ]] && [[ ! -z ${relative_path} ]] && [[ ${file_param} =~ "/" ]]; then
|
|
96
|
-
cd ${relative_path}
|
|
97
|
-
file_param=${file_param/$relative_path\//}
|
|
98
|
-
fi
|
|
154
|
+
enter_script_workdir
|
|
99
155
|
|
|
100
156
|
if [[ $isJsOrPythonFile == 'false' ]]; then
|
|
101
157
|
clear_non_sh_env
|
|
@@ -120,7 +176,7 @@ run_concurrent() {
|
|
|
120
176
|
local env_param="$2"
|
|
121
177
|
local num_param=$(echo "$3" | perl -pe "s|.*$2(.*)|\1|" | awk '{$1=$1};1')
|
|
122
178
|
if [[ ! $env_param ]]; then
|
|
123
|
-
|
|
179
|
+
t '\n缺少并发运行的环境变量参数'
|
|
124
180
|
exit 1
|
|
125
181
|
fi
|
|
126
182
|
|
|
@@ -128,12 +184,7 @@ run_concurrent() {
|
|
|
128
184
|
time=$(date "+$mtime_format")
|
|
129
185
|
single_log_time=$(format_log_time "$mtime_format" "$time")
|
|
130
186
|
|
|
131
|
-
|
|
132
|
-
local relative_path="${file_param%/*}"
|
|
133
|
-
if [[ ! -z ${relative_path} ]] && [[ ${file_param} =~ "/" ]]; then
|
|
134
|
-
cd ${relative_path}
|
|
135
|
-
file_param=${file_param/$relative_path\//}
|
|
136
|
-
fi
|
|
187
|
+
enter_script_workdir
|
|
137
188
|
|
|
138
189
|
local j=0
|
|
139
190
|
for i in ${array_run[@]}; do
|
|
@@ -162,7 +213,7 @@ run_designated() {
|
|
|
162
213
|
local env_param="$2"
|
|
163
214
|
local num_param=$(echo "$3" | perl -pe "s|.*$2(.*)|\1|" | awk '{$1=$1};1')
|
|
164
215
|
if [[ ! $env_param ]]; then
|
|
165
|
-
|
|
216
|
+
t '\n缺少单独运行的参数 task xxx.js desi Test'
|
|
166
217
|
exit 1
|
|
167
218
|
fi
|
|
168
219
|
|
|
@@ -182,12 +233,7 @@ run_designated() {
|
|
|
182
233
|
clear_non_sh_env
|
|
183
234
|
fi
|
|
184
235
|
|
|
185
|
-
|
|
186
|
-
local relative_path="${file_param%/*}"
|
|
187
|
-
if [[ ! -z ${relative_path} ]] && [[ ${file_param} =~ "/" ]]; then
|
|
188
|
-
cd ${relative_path}
|
|
189
|
-
file_param=${file_param/$relative_path\//}
|
|
190
|
-
fi
|
|
236
|
+
enter_script_workdir
|
|
191
237
|
|
|
192
238
|
envParam="${env_param}" numParam="${num_param}" $timeoutCmd $which_program $file_param "${script_params[@]}"
|
|
193
239
|
}
|
|
@@ -196,14 +242,53 @@ run_designated() {
|
|
|
196
242
|
run_else() {
|
|
197
243
|
local file_param="$1"
|
|
198
244
|
|
|
199
|
-
|
|
200
|
-
local
|
|
201
|
-
if [[
|
|
202
|
-
|
|
203
|
-
|
|
245
|
+
# 判断 file_param 本身是否是脚本文件
|
|
246
|
+
local is_file_script="false"
|
|
247
|
+
if [[ "$file_param" == *.js || "$file_param" == *.mjs ||
|
|
248
|
+
"$file_param" == *.py || "$file_param" == *.pyc ||
|
|
249
|
+
"$file_param" == *.sh || "$file_param" == *.ts ]]; then
|
|
250
|
+
is_file_script="true"
|
|
204
251
|
fi
|
|
205
252
|
|
|
206
|
-
|
|
253
|
+
if [[ "$is_file_script" != "true" ]]; then
|
|
254
|
+
# file_param 不是脚本,从后续参数中查找脚本路径来确定工作目录
|
|
255
|
+
local script_for_dir=""
|
|
256
|
+
for arg in "$@"; do
|
|
257
|
+
if [[ "$arg" == *.js || "$arg" == *.mjs ||
|
|
258
|
+
"$arg" == *.py || "$arg" == *.pyc ||
|
|
259
|
+
"$arg" == *.sh || "$arg" == *.ts ]]; then
|
|
260
|
+
script_for_dir="$arg"
|
|
261
|
+
break
|
|
262
|
+
fi
|
|
263
|
+
done
|
|
264
|
+
|
|
265
|
+
if [[ -n "$script_for_dir" ]]; then
|
|
266
|
+
local saved_file_param="$file_param"
|
|
267
|
+
file_param="$script_for_dir"
|
|
268
|
+
enter_script_workdir true
|
|
269
|
+
local adjusted_script="$file_param"
|
|
270
|
+
file_param="$saved_file_param"
|
|
271
|
+
|
|
272
|
+
shift
|
|
273
|
+
local new_args=()
|
|
274
|
+
for arg in "$@"; do
|
|
275
|
+
if [[ "$arg" == "$script_for_dir" ]]; then
|
|
276
|
+
new_args+=("$adjusted_script")
|
|
277
|
+
else
|
|
278
|
+
new_args+=("$arg")
|
|
279
|
+
fi
|
|
280
|
+
done
|
|
281
|
+
set -- "${new_args[@]}"
|
|
282
|
+
else
|
|
283
|
+
# 没有找到脚本参数,只 cd 到 scripts 目录
|
|
284
|
+
enter_script_workdir true
|
|
285
|
+
shift
|
|
286
|
+
fi
|
|
287
|
+
else
|
|
288
|
+
# file_param 本身就是脚本,直接用 enter_script_workdir 处理
|
|
289
|
+
enter_script_workdir true
|
|
290
|
+
shift
|
|
291
|
+
fi
|
|
207
292
|
|
|
208
293
|
clear_non_sh_env
|
|
209
294
|
$timeoutCmd $which_program $file_param "$@"
|
|
@@ -242,7 +327,7 @@ check_nounset() {
|
|
|
242
327
|
}
|
|
243
328
|
|
|
244
329
|
main() {
|
|
245
|
-
if [[ $1 == *.js ]] || [[ $1 == *.py ]] || [[ $1 == *.pyc ]] || [[ $1 == *.sh ]] || [[ $1 == *.ts ]]; then
|
|
330
|
+
if [[ $1 == *.js ]] || [[ $1 == *.mjs ]] || [[ $1 == *.py ]] || [[ $1 == *.pyc ]] || [[ $1 == *.sh ]] || [[ $1 == *.ts ]]; then
|
|
246
331
|
if [[ $1 == *.sh ]]; then
|
|
247
332
|
timeoutCmd=""
|
|
248
333
|
fi
|
|
@@ -278,15 +363,19 @@ main() {
|
|
|
278
363
|
|
|
279
364
|
handle_task_start "${task_shell_params[@]}"
|
|
280
365
|
check_file "${task_shell_params[@]}"
|
|
366
|
+
append_node_dependency_path
|
|
281
367
|
if [[ $isJsOrPythonFile == 'false' ]]; then
|
|
282
368
|
run_task_before "${task_shell_params[@]}"
|
|
283
369
|
fi
|
|
284
370
|
set_u_on="false"
|
|
285
371
|
check_nounset
|
|
286
372
|
main "${task_shell_params[@]}"
|
|
373
|
+
_task_exit_code=$?
|
|
287
374
|
if [[ "$set_u_on" == 'true' ]]; then
|
|
288
375
|
set -u
|
|
289
376
|
fi
|
|
377
|
+
export NODE_PATH="${PREV_NODE_PATH}"
|
|
378
|
+
unset QL_NODE_GLOBAL_PATH
|
|
290
379
|
if [[ $isJsOrPythonFile == 'true' ]]; then
|
|
291
380
|
export NODE_OPTIONS="${PREV_NODE_OPTIONS}"
|
|
292
381
|
export PYTHONPATH="${PREV_PYTHONPATH}"
|
package/shell/preload/client.js
CHANGED
|
@@ -1,11 +1,29 @@
|
|
|
1
1
|
const grpc = require('@grpc/grpc-js');
|
|
2
2
|
const protoLoader = require('@grpc/proto-loader');
|
|
3
|
+
const { readFileSync } = require('fs');
|
|
3
4
|
const { join } = require('path');
|
|
4
5
|
|
|
5
6
|
class GrpcClient {
|
|
7
|
+
static #certDir = join(
|
|
8
|
+
process.env.QL_DATA_DIR || join(process.env.QL_DIR, 'data'),
|
|
9
|
+
'config/grpc',
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
static #loadTlsCredentials() {
|
|
13
|
+
try {
|
|
14
|
+
return grpc.credentials.createSsl(
|
|
15
|
+
readFileSync(join(GrpcClient.#certDir, 'ca.crt')),
|
|
16
|
+
readFileSync(join(GrpcClient.#certDir, 'client.key')),
|
|
17
|
+
readFileSync(join(GrpcClient.#certDir, 'client.crt')),
|
|
18
|
+
);
|
|
19
|
+
} catch {
|
|
20
|
+
return grpc.credentials.createInsecure();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
6
24
|
static #config = {
|
|
7
25
|
protoPath: join(process.env.QL_DIR, 'back/protos/api.proto'),
|
|
8
|
-
serverAddress: `
|
|
26
|
+
serverAddress: `localhost:${process.env.GRPC_PORT || '5500'}`,
|
|
9
27
|
protoOptions: {
|
|
10
28
|
keepCase: true,
|
|
11
29
|
longs: String,
|
|
@@ -58,7 +76,7 @@ class GrpcClient {
|
|
|
58
76
|
|
|
59
77
|
this.#client = new apiProto.Api(
|
|
60
78
|
serverAddress,
|
|
61
|
-
|
|
79
|
+
GrpcClient.#loadTlsCredentials(),
|
|
62
80
|
grpcOptions,
|
|
63
81
|
);
|
|
64
82
|
} catch (error) {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
|
|
4
|
+
const builtinModules = [
|
|
5
|
+
'assert', 'buffer', 'child_process', 'cluster', 'crypto', 'dgram', 'dns',
|
|
6
|
+
'events', 'fs', 'http', 'https', 'net', 'os', 'path', 'process', 'querystring',
|
|
7
|
+
'readline', 'stream', 'string_decoder', 'timers', 'tls', 'tty', 'url', 'util',
|
|
8
|
+
'v8', 'zlib',
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
function isBareSpecifier(specifier) {
|
|
12
|
+
return !specifier.startsWith('.') &&
|
|
13
|
+
!specifier.startsWith('/') &&
|
|
14
|
+
!specifier.startsWith('file:') &&
|
|
15
|
+
!specifier.startsWith('node:') &&
|
|
16
|
+
!builtinModules.includes(specifier) &&
|
|
17
|
+
!builtinModules.includes(specifier.split('/')[0]);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function resolve(specifier, context, nextResolve) {
|
|
21
|
+
if (!isBareSpecifier(specifier)) {
|
|
22
|
+
return nextResolve(specifier, context);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// 解析优先级:全局 pnpm > 系统全局
|
|
26
|
+
const bases = [
|
|
27
|
+
process.env.QL_NODE_GLOBAL_PATH,
|
|
28
|
+
'/usr/local/lib/node_modules',
|
|
29
|
+
].filter(Boolean);
|
|
30
|
+
|
|
31
|
+
for (const base of bases) {
|
|
32
|
+
if (existsSync(join(base, specifier))) {
|
|
33
|
+
return nextResolve(specifier, {
|
|
34
|
+
...context,
|
|
35
|
+
parentURL: new URL(`${join(base, specifier)}/`, 'file://').href,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return nextResolve(specifier, context);
|
|
41
|
+
}
|
|
@@ -1,7 +1,41 @@
|
|
|
1
1
|
const { execSync } = require('child_process');
|
|
2
|
+
const Module = require('module');
|
|
3
|
+
const path = require('path');
|
|
2
4
|
const client = require('./client.js');
|
|
3
5
|
require(`./env.js`);
|
|
4
6
|
|
|
7
|
+
// 注册 ESM loader,使全局安装的包也可通过 import 导入
|
|
8
|
+
try {
|
|
9
|
+
Module.register(new URL('esm-loader.mjs', `file://${__dirname}/`).href);
|
|
10
|
+
} catch (_) {}
|
|
11
|
+
|
|
12
|
+
function preferGlobalNodeModules() {
|
|
13
|
+
const { QL_NODE_GLOBAL_PATH } = process.env;
|
|
14
|
+
if (!QL_NODE_GLOBAL_PATH || Module._qlGlobalPathPatched) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const originalResolveFilename = Module._resolveFilename;
|
|
19
|
+
Module._resolveFilename = function (request, parent, isMain, options) {
|
|
20
|
+
if (
|
|
21
|
+
!Module.builtinModules.includes(request) &&
|
|
22
|
+
!request.startsWith('node:') &&
|
|
23
|
+
!request.startsWith('.') &&
|
|
24
|
+
!path.isAbsolute(request)
|
|
25
|
+
) {
|
|
26
|
+
try {
|
|
27
|
+
return originalResolveFilename.call(this, request, parent, isMain, {
|
|
28
|
+
...options,
|
|
29
|
+
paths: [QL_NODE_GLOBAL_PATH],
|
|
30
|
+
});
|
|
31
|
+
} catch (error) {}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return originalResolveFilename.call(this, request, parent, isMain, options);
|
|
35
|
+
};
|
|
36
|
+
Module._qlGlobalPathPatched = true;
|
|
37
|
+
}
|
|
38
|
+
|
|
5
39
|
function expandRange(rangeStr, max) {
|
|
6
40
|
const tempRangeStr = rangeStr
|
|
7
41
|
.trim()
|
|
@@ -113,6 +147,8 @@ try {
|
|
|
113
147
|
return;
|
|
114
148
|
}
|
|
115
149
|
|
|
150
|
+
preferGlobalNodeModules();
|
|
151
|
+
|
|
116
152
|
process.on('SIGTERM', (code) => {
|
|
117
153
|
process.exit(15);
|
|
118
154
|
});
|
package/shell/pub.sh
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
echo -e "开始发布"
|
|
3
3
|
|
|
4
|
-
echo -e "切换
|
|
5
|
-
git branch -D
|
|
6
|
-
git checkout -b
|
|
7
|
-
git push --set-upstream origin
|
|
4
|
+
echo -e "切换master分支"
|
|
5
|
+
git branch -D master
|
|
6
|
+
git checkout -b master
|
|
7
|
+
git push --set-upstream origin master -f
|
|
8
8
|
|
|
9
9
|
echo -e "更新cdn文件"
|
|
10
10
|
ts-node-transpile-only sample/tool.ts
|
|
11
11
|
|
|
12
12
|
string=$(cat version.yaml | grep "version" | egrep "[^ ]*" -o | egrep "\d\.*")
|
|
13
13
|
version="v$string"
|
|
14
|
-
echo -e "当前版本$version
|
|
14
|
+
echo -e "当前版本$version"
|
|
15
15
|
|
|
16
16
|
echo -e "删除已经存在的本地tag"
|
|
17
|
-
git tag -d "$version
|
|
17
|
+
git tag -d "$version" &>/dev/null
|
|
18
18
|
|
|
19
19
|
echo -e "删除已经存在的远程tag"
|
|
20
|
-
git push origin :refs/tags/$version
|
|
20
|
+
git push origin :refs/tags/$version &>/dev/null
|
|
21
21
|
|
|
22
22
|
echo -e "创建新tag"
|
|
23
|
-
git tag -a "$version
|
|
23
|
+
git tag -a "$version" -m "release $version"
|
|
24
24
|
|
|
25
25
|
echo -e "提交tag"
|
|
26
26
|
git push --tags
|
package/shell/rmlog.sh
CHANGED
|
@@ -22,12 +22,12 @@ remove_js_log() {
|
|
|
22
22
|
if [[ $diff_time -gt $((${days} * 86400)) ]]; then
|
|
23
23
|
local log_path=$(echo "$log" | sed "s,${dir_log}/,,g")
|
|
24
24
|
local result=$(find_cron_api "log_path=$log_path")
|
|
25
|
-
|
|
25
|
+
t '查询文件 %s' "$log_path"
|
|
26
26
|
if [[ -z $result ]]; then
|
|
27
|
-
|
|
27
|
+
t '删除中~'
|
|
28
28
|
rm -vf $log
|
|
29
29
|
else
|
|
30
|
-
|
|
30
|
+
t '正在被 %s 使用,跳过~' "$result"
|
|
31
31
|
fi
|
|
32
32
|
fi
|
|
33
33
|
done
|
|
@@ -43,8 +43,8 @@ remove_empty_dir() {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
if [[ ${days} ]]; then
|
|
46
|
-
|
|
46
|
+
t '查找旧日志文件中...\n'
|
|
47
47
|
remove_js_log
|
|
48
48
|
remove_empty_dir
|
|
49
|
-
|
|
49
|
+
t '删除旧日志执行完毕\n'
|
|
50
50
|
fi
|
package/shell/share.sh
CHANGED
|
@@ -65,17 +65,7 @@ link_name=(
|
|
|
65
65
|
)
|
|
66
66
|
|
|
67
67
|
init_env() {
|
|
68
|
-
|
|
69
|
-
export NODE_PATH="/usr/local/bin:/usr/local/lib/node_modules${pnpm_global_path:+:${pnpm_global_path}}"
|
|
70
|
-
|
|
71
|
-
# 如果存在 pnpm 全局路径,创建软链接
|
|
72
|
-
if [[ -n "$pnpm_global_path" ]]; then
|
|
73
|
-
# 确保目标目录存在
|
|
74
|
-
mkdir -p "${dir_root}/node_modules"
|
|
75
|
-
# 链接全局模块到项目的 node_modules
|
|
76
|
-
ln -sf "${pnpm_global_path}/"* "${dir_root}/node_modules/" 2>/dev/null || true
|
|
77
|
-
fi
|
|
78
|
-
|
|
68
|
+
export NODE_PATH="/usr/local/bin:/usr/local/lib/node_modules"
|
|
79
69
|
export PYTHONUNBUFFERED=1
|
|
80
70
|
}
|
|
81
71
|
|
|
@@ -88,6 +78,16 @@ load_ql_envs() {
|
|
|
88
78
|
|
|
89
79
|
import_config() {
|
|
90
80
|
[[ -f $file_config_user ]] && . $file_config_user
|
|
81
|
+
[[ -f $dir_preload/lang_env.sh ]] && . $dir_preload/lang_env.sh
|
|
82
|
+
|
|
83
|
+
# 加载语言包(bash 4+ 支持 declare -A,不兼容时回退输出中文 key)
|
|
84
|
+
local lang=${QL_LANG:-zh}
|
|
85
|
+
local lang_file="$dir_shell/lang/${lang}.sh"
|
|
86
|
+
if [[ ${BASH_VERSINFO[0]} -ge 4 ]] && [[ -f $lang_file ]]; then
|
|
87
|
+
. $lang_file
|
|
88
|
+
elif [[ ${BASH_VERSINFO[0]} -ge 4 ]]; then
|
|
89
|
+
. "$dir_shell/lang/zh.sh"
|
|
90
|
+
fi
|
|
91
91
|
|
|
92
92
|
load_ql_envs
|
|
93
93
|
command_timeout_time=${CommandTimeoutTime:-""}
|
|
@@ -101,6 +101,18 @@ import_config() {
|
|
|
101
101
|
fi
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
t() {
|
|
105
|
+
local key="$1"
|
|
106
|
+
shift
|
|
107
|
+
local msg
|
|
108
|
+
if declare -p LANG_MESSAGES &>/dev/null; then
|
|
109
|
+
msg="${LANG_MESSAGES["$key"]}"
|
|
110
|
+
fi
|
|
111
|
+
[[ -z $msg ]] && msg="$key"
|
|
112
|
+
# shellcheck disable=SC2059
|
|
113
|
+
printf "$msg\n" "$@"
|
|
114
|
+
}
|
|
115
|
+
|
|
104
116
|
set_proxy() {
|
|
105
117
|
local proxy="$1"
|
|
106
118
|
if [[ $proxy ]]; then
|
|
@@ -235,7 +247,7 @@ npm_install_2() {
|
|
|
235
247
|
local dir_work=$1
|
|
236
248
|
|
|
237
249
|
cd $dir_work
|
|
238
|
-
|
|
250
|
+
t '安装 %s 依赖包...\n' "$dir_work"
|
|
239
251
|
npm_install_sub
|
|
240
252
|
cd $dir_current
|
|
241
253
|
}
|
|
@@ -254,7 +266,7 @@ git_clone_scripts() {
|
|
|
254
266
|
local branch="$3"
|
|
255
267
|
local proxy="$4"
|
|
256
268
|
[[ $branch ]] && local part_cmd="-b $branch "
|
|
257
|
-
|
|
269
|
+
t '开始拉取仓库 %s 到 %s\n' "${uniq_path}" "$dir"
|
|
258
270
|
|
|
259
271
|
set_proxy "$proxy"
|
|
260
272
|
|
|
@@ -287,18 +299,18 @@ reload_pm2() {
|
|
|
287
299
|
return 0
|
|
288
300
|
else
|
|
289
301
|
local exit_code=$?
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
302
|
+
t '警告: PM2 启动失败 (退出码: %s),可能是由于硬件不兼容' "$exit_code"
|
|
303
|
+
t '正在尝试直接使用 Node.js 启动服务...'
|
|
304
|
+
|
|
293
305
|
# Kill any existing node processes for qinglong
|
|
294
306
|
pkill -f "node.*static/build/app.js" 2>/dev/null || true
|
|
295
|
-
|
|
307
|
+
|
|
296
308
|
# Start node directly in the background
|
|
297
309
|
nohup node static/build/app.js > $dir_log/qinglong.log 2>&1 &
|
|
298
310
|
local node_pid=$!
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
311
|
+
|
|
312
|
+
t '已使用 Node.js 直接启动服务 (PID: %s)' "$node_pid"
|
|
313
|
+
t '注意: 使用此模式时,部分 PM2 管理功能将不可用'
|
|
302
314
|
return 0
|
|
303
315
|
fi
|
|
304
316
|
}
|
|
@@ -370,16 +382,16 @@ handle_task_start() {
|
|
|
370
382
|
error_message=", 任务状态更新失败(${error})"
|
|
371
383
|
fi
|
|
372
384
|
fi
|
|
373
|
-
|
|
385
|
+
t '## 开始执行... %s\n' "${begin_time}${error_message}"
|
|
374
386
|
}
|
|
375
387
|
|
|
376
388
|
run_task_before() {
|
|
377
389
|
. $file_task_before "$@"
|
|
378
390
|
|
|
379
391
|
if [[ ${task_before:=} ]]; then
|
|
380
|
-
|
|
392
|
+
t '执行前置命令\n'
|
|
381
393
|
eval "${task_before%;}"
|
|
382
|
-
|
|
394
|
+
t '\n执行前置命令结束\n'
|
|
383
395
|
fi
|
|
384
396
|
}
|
|
385
397
|
|
|
@@ -387,9 +399,9 @@ run_task_after() {
|
|
|
387
399
|
. $file_task_after "$@"
|
|
388
400
|
|
|
389
401
|
if [[ ${task_after:=} ]]; then
|
|
390
|
-
|
|
402
|
+
t '\n执行后置命令\n'
|
|
391
403
|
eval "${task_after%;}"
|
|
392
|
-
|
|
404
|
+
t '\n执行后置命令结束'
|
|
393
405
|
fi
|
|
394
406
|
}
|
|
395
407
|
|
|
@@ -398,18 +410,25 @@ handle_task_end() {
|
|
|
398
410
|
local end_time=$(format_time "$time_format" "$etime")
|
|
399
411
|
local end_timestamp=$(format_timestamp "$time_format" "$etime")
|
|
400
412
|
local diff_time=$(($end_timestamp - $begin_timestamp))
|
|
401
|
-
local
|
|
402
|
-
[[ "${MANUAL:=}" == "true" ]] && suffix="(手动停止)"
|
|
403
|
-
|
|
413
|
+
local exit_code="${_task_exit_code:-0}"
|
|
404
414
|
[[ "$diff_time" == 0 ]] && diff_time=1
|
|
405
415
|
|
|
406
416
|
if [[ $ID ]]; then
|
|
407
|
-
local error=$(update_cron "\"$ID\"" "1" "$$" "$log_path" "$begin_timestamp" "$diff_time")
|
|
417
|
+
local error=$(update_cron "\"$ID\"" "1" "$$" "$log_path" "$begin_timestamp" "$diff_time" "$exit_code")
|
|
408
418
|
if [[ $error ]]; then
|
|
409
|
-
error_message=",
|
|
419
|
+
error_message=", 状态更新失败(${error})"
|
|
410
420
|
fi
|
|
411
421
|
fi
|
|
412
|
-
|
|
422
|
+
|
|
423
|
+
record_cron_stat "$ID" "${exit_code:-0}" "$diff_time"
|
|
424
|
+
|
|
425
|
+
if [[ "${MANUAL:=}" == "true" ]]; then
|
|
426
|
+
t '\n## 已停止 🛑... %s 耗时 %s 秒%s' "$end_time" "$diff_time" "${error_message:=} "
|
|
427
|
+
elif [[ $exit_code -eq 0 ]]; then
|
|
428
|
+
t '\n## 完成 ✅... %s 耗时 %s 秒%s' "$end_time" "$diff_time" "${error_message:=} "
|
|
429
|
+
else
|
|
430
|
+
t '\n## 失败 ❌(退出码 %s)... %s 耗时 %s 秒%s' "$exit_code" "$end_time" "$diff_time" "${error_message:=} "
|
|
431
|
+
fi
|
|
413
432
|
}
|
|
414
433
|
|
|
415
434
|
init_env
|
package/shell/start.sh
CHANGED
|
@@ -12,23 +12,23 @@ if [[ ! $QL_DIR ]]; then
|
|
|
12
12
|
elif [[ -d "$pnpm_dir/@whyour/qinglong" ]]; then
|
|
13
13
|
QL_DIR="$pnpm_dir/@whyour/qinglong"
|
|
14
14
|
else
|
|
15
|
-
|
|
15
|
+
t '未找到 qinglong 模块,请先执行 npm i -g @whyour/qinglong 安装'
|
|
16
16
|
fi
|
|
17
17
|
|
|
18
18
|
if [[ $QL_DIR ]]; then
|
|
19
|
-
|
|
19
|
+
t '请先手动设置 export QL_DIR=%s,环境变量,并手动添加到系统环境变量,然后再次执行命令 qinglong 启动服务' "$QL_DIR"
|
|
20
20
|
fi
|
|
21
21
|
|
|
22
22
|
exit 1
|
|
23
23
|
fi
|
|
24
24
|
|
|
25
25
|
if [[ ! $QL_DATA_DIR ]]; then
|
|
26
|
-
|
|
26
|
+
t '请先手动设置数据存储目录 export QL_DATA_DIR 环境变量,目录必须以斜杠开头的绝对路径,并且以 /data 结尾,例如 /ql/data 并手动添加到系统环境变量'
|
|
27
27
|
exit 1
|
|
28
28
|
fi
|
|
29
29
|
|
|
30
30
|
if [[ $QL_DATA_DIR != */data ]]; then
|
|
31
|
-
|
|
31
|
+
t 'QL_DATA_DIR 必须以 /data 结尾,例如 /ql/data,如果有历史数据,请新建 data 目录,把历史数据放到 data 目录中'
|
|
32
32
|
exit 1
|
|
33
33
|
fi
|
|
34
34
|
|
|
@@ -36,31 +36,44 @@ command="$1"
|
|
|
36
36
|
|
|
37
37
|
if [[ $command != "reload" ]]; then
|
|
38
38
|
# 安装依赖
|
|
39
|
-
os_name
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
tzdata \
|
|
49
|
-
perl \
|
|
50
|
-
openssl \
|
|
51
|
-
jq \
|
|
52
|
-
nginx \
|
|
53
|
-
openssh \
|
|
54
|
-
procps \
|
|
55
|
-
netcat-openbsd
|
|
56
|
-
elif [[ $os_name == 'debian' ]] || [[ $os_name == 'ubuntu' ]]; then
|
|
57
|
-
apt-get update
|
|
58
|
-
apt-get install -y git curl wget tzdata perl openssl jq nginx procps netcat-openbsd openssh-client
|
|
59
|
-
else
|
|
60
|
-
echo -e "暂不支持此系统部署 $os_name"
|
|
61
|
-
exit 1
|
|
39
|
+
os_name="${QL_OS_TYPE:-}"
|
|
40
|
+
if [ -z "$os_name" ]; then
|
|
41
|
+
os_name=$(source /etc/os-release && echo "$ID")
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
# 非 root 用户使用 sudo
|
|
45
|
+
SUDO=""
|
|
46
|
+
if [ "$(id -u)" -ne 0 ]; then
|
|
47
|
+
SUDO="sudo"
|
|
62
48
|
fi
|
|
63
49
|
|
|
50
|
+
case "$os_name" in
|
|
51
|
+
alpine)
|
|
52
|
+
$SUDO apk update
|
|
53
|
+
$SUDO apk add -f bash \
|
|
54
|
+
coreutils \
|
|
55
|
+
git \
|
|
56
|
+
curl \
|
|
57
|
+
wget \
|
|
58
|
+
tzdata \
|
|
59
|
+
perl \
|
|
60
|
+
openssl \
|
|
61
|
+
jq \
|
|
62
|
+
nginx \
|
|
63
|
+
openssh \
|
|
64
|
+
procps \
|
|
65
|
+
netcat-openbsd
|
|
66
|
+
;;
|
|
67
|
+
debian|ubuntu)
|
|
68
|
+
$SUDO apt-get update
|
|
69
|
+
$SUDO apt-get install -y git curl wget tzdata perl openssl jq nginx procps netcat-openbsd openssh-client
|
|
70
|
+
;;
|
|
71
|
+
*)
|
|
72
|
+
t '暂不支持此系统部署 %s' "$os_name"
|
|
73
|
+
exit 1
|
|
74
|
+
;;
|
|
75
|
+
esac
|
|
76
|
+
|
|
64
77
|
npm install -g pnpm@8.3.1 pm2 ts-node
|
|
65
78
|
fi
|
|
66
79
|
|