@whyour/qinglong 0.15.6 → 0.17.0
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 +1 -0
- package/docker/310.Dockerfile +6 -1
- package/docker/Dockerfile +2 -1
- package/docker/docker-entrypoint.sh +1 -0
- package/docker/front.conf +16 -0
- package/other.config.js +13 -0
- package/package.json +3 -3
- package/sample/config.sample.sh +19 -8
- package/sample/notify.js +49 -32
- package/sample/notify.py +286 -145
- package/shell/check.sh +1 -0
- package/shell/share.sh +13 -1
- package/shell/update.sh +34 -22
- package/static/build/api/dependence.js +12 -0
- package/static/build/config/index.js +1 -0
- package/static/build/config/util.js +26 -23
- package/static/build/data/dependence.js +1 -0
- package/static/build/loaders/server.js +0 -21
- package/static/build/loaders/update.js +79 -0
- package/static/build/services/dependence.js +35 -4
- package/static/build/services/notify.js +4 -13
- package/static/build/services/system.js +17 -32
- package/static/build/shared/pLimit.js +18 -5
- package/static/build/update.js +29 -0
- package/static/dist/{419.f9258e2f.async.js → 419.71c3c9c2.async.js} +1 -1
- package/static/dist/{833.c59c5023.async.js → 833.ea0fd669.async.js} +1 -1
- package/static/dist/8430.0291dda0.async.js +1 -0
- package/static/dist/index.html +1 -1
- package/static/dist/{layouts__index.817c948a.async.js → layouts__index.a51b2768.async.js} +1 -1
- package/static/dist/{src__pages__crontab__detail.7d1c2d15.async.js → src__pages__crontab__detail.2ab4f3e8.async.js} +1 -1
- package/static/dist/{src__pages__crontab__index.5aece157.async.js → src__pages__crontab__index.719429ac.async.js} +1 -1
- package/static/dist/src__pages__dependence__index.52fca7ba.async.js +1 -0
- package/static/dist/src__pages__dependence__logModal.baba01d6.async.js +1 -0
- package/static/dist/src__pages__dependence__type.860703e8.async.js +1 -0
- package/static/dist/{src__pages__log__index.757b3471.async.js → src__pages__log__index.44c6a008.async.js} +1 -1
- package/static/dist/{src__pages__script__index.ed44bc1b.async.js → src__pages__script__index.2a8d8477.async.js} +1 -1
- package/static/dist/src__pages__setting__checkUpdate.43e62d05.async.js +1 -0
- package/static/dist/src__pages__setting__dependence.28193e94.async.js +1 -0
- package/static/dist/src__pages__setting__index.7ab054fb.async.js +1 -0
- package/static/dist/src__pages__setting__other.2c4534ef.async.js +1 -0
- package/static/dist/src__pages__setting__progress.7d65aebf.async.js +1 -0
- package/static/dist/{umi.889d3656.js → umi.3bb00f35.js} +1 -1
- package/version.yaml +8 -12
- package/static/dist/8008.89ba3d06.async.js +0 -1
- package/static/dist/src__pages__dependence__index.27d29203.async.js +0 -1
- package/static/dist/src__pages__dependence__logModal.b44459a9.async.js +0 -1
- package/static/dist/src__pages__setting__checkUpdate.42020a45.async.js +0 -1
- package/static/dist/src__pages__setting__dependence.2efb8ee3.async.js +0 -1
- package/static/dist/src__pages__setting__index.3e2ad723.async.js +0 -1
- package/static/dist/src__pages__setting__other.a029d99a.async.js +0 -1
- package/static/dist/src__pages__setting__progress.65e2e878.async.js +0 -1
package/shell/check.sh
CHANGED
package/shell/share.sh
CHANGED
|
@@ -298,7 +298,7 @@ git_clone_scripts() {
|
|
|
298
298
|
|
|
299
299
|
set_proxy "$proxy"
|
|
300
300
|
|
|
301
|
-
git clone --depth=1 $part_cmd $url $dir
|
|
301
|
+
git clone -q --depth=1 $part_cmd $url $dir
|
|
302
302
|
exit_status=$?
|
|
303
303
|
|
|
304
304
|
unset_proxy
|
|
@@ -310,6 +310,11 @@ random_range() {
|
|
|
310
310
|
echo $((RANDOM % ($end - $beg) + $beg))
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
+
delete_pm2() {
|
|
314
|
+
cd $dir_root
|
|
315
|
+
pm2 delete ecosystem.config.js
|
|
316
|
+
}
|
|
317
|
+
|
|
313
318
|
reload_pm2() {
|
|
314
319
|
cd $dir_root
|
|
315
320
|
restore_env_vars
|
|
@@ -317,6 +322,13 @@ reload_pm2() {
|
|
|
317
322
|
pm2 startOrGracefulReload ecosystem.config.js
|
|
318
323
|
}
|
|
319
324
|
|
|
325
|
+
reload_update() {
|
|
326
|
+
cd $dir_root
|
|
327
|
+
restore_env_vars
|
|
328
|
+
pm2 flush &>/dev/null
|
|
329
|
+
pm2 startOrGracefulReload other.config.js
|
|
330
|
+
}
|
|
331
|
+
|
|
320
332
|
diff_time() {
|
|
321
333
|
local format="$1"
|
|
322
334
|
local begin_time="$2"
|
package/shell/update.sh
CHANGED
|
@@ -34,7 +34,6 @@ output_list_add_drop() {
|
|
|
34
34
|
if [[ -s $list ]]; then
|
|
35
35
|
echo -e "检测到有${type}的定时任务:"
|
|
36
36
|
cat $list
|
|
37
|
-
echo
|
|
38
37
|
fi
|
|
39
38
|
}
|
|
40
39
|
|
|
@@ -45,7 +44,7 @@ del_cron() {
|
|
|
45
44
|
local path=$2
|
|
46
45
|
local detail=""
|
|
47
46
|
local ids=""
|
|
48
|
-
echo -e "开始尝试自动删除失效的定时任务..."
|
|
47
|
+
echo -e "\n开始尝试自动删除失效的定时任务..."
|
|
49
48
|
for cron in $(cat $list_drop); do
|
|
50
49
|
local id=$(cat $list_crontab_user | grep -E "$cmd_task.* $cron" | perl -pe "s|.*ID=(.*) $cmd_task.* $cron\.*|\1|" | head -1 | awk -F " " '{print $1}')
|
|
51
50
|
if [[ $ids ]]; then
|
|
@@ -76,7 +75,7 @@ del_cron() {
|
|
|
76
75
|
add_cron() {
|
|
77
76
|
local list_add=$1
|
|
78
77
|
local path=$2
|
|
79
|
-
echo -e "开始尝试自动添加定时任务..."
|
|
78
|
+
echo -e "\n开始尝试自动添加定时任务..."
|
|
80
79
|
local detail=""
|
|
81
80
|
cd $dir_scripts
|
|
82
81
|
for file in $(cat $list_add); do
|
|
@@ -86,19 +85,20 @@ add_cron() {
|
|
|
86
85
|
cron_line=$(
|
|
87
86
|
perl -ne "{
|
|
88
87
|
print if /.*([\d\*]*[\*-\/,\d]*[\d\*] ){4,5}[\d\*]*[\*-\/,\d]*[\d\*]( |,|\").*$file_name/
|
|
89
|
-
}" $file |
|
|
88
|
+
}" $file 2>/dev/null |
|
|
90
89
|
perl -pe "{
|
|
91
90
|
s|[^\d\*]*(([\d\*]*[\*-\/,\d]*[\d\*] ){4,5}[\d\*]*[\*-\/,\d]*[\d\*])( \|,\|\").*/?$file_name.*|\1|g;
|
|
92
91
|
s|\*([\d\*])(.*)|\1\2|g;
|
|
93
92
|
s| | |g;
|
|
94
|
-
}" | sort -u | head -1
|
|
93
|
+
}" 2>/dev/null | sort -u | head -1
|
|
95
94
|
)
|
|
96
|
-
cron_name=$(grep "new Env" $file | awk -F "\(" '{print $2}' | awk -F "\)" '{print $1}' | sed 's:.*\('\''\|"\)\([^"'\'']*\)\('\''\|"\).*:\2:' | sed 's:"::g' | sed "s:'::g" | head -1)
|
|
97
|
-
[[ -z $cron_name ]] && cron_name="$file_name"
|
|
98
95
|
[[ -z $cron_line ]] && cron_line=$(grep "cron:" $file | awk -F ":" '{print $2}' | head -1 | xargs)
|
|
99
96
|
[[ -z $cron_line ]] && cron_line=$(grep "cron " $file | awk -F "cron \"" '{print $2}' | awk -F "\" " '{print $1}' | head -1 | xargs)
|
|
100
97
|
[[ -z $cron_line ]] && cron_line="$default_cron"
|
|
101
|
-
|
|
98
|
+
cron_name=$(grep "new Env" $file | awk -F "\(" '{print $2}' | awk -F "\)" '{print $1}' | sed 's:.*\('\''\|"\)\([^"'\'']*\)\('\''\|"\).*:\2:' | sed 's:"::g' | sed "s:'::g" | head -1)
|
|
99
|
+
[[ -z $cron_name ]] && cron_name=$(grep "name:" $file | awk -F ":" '{print $2}' | head -1 | xargs)
|
|
100
|
+
[[ -z $cron_name ]] && cron_name=$(basename "$file_name")
|
|
101
|
+
result=$(add_cron_api "${cron_line}:${cmd_task} ${file}:${cron_name}:${SUB_ID}")
|
|
102
102
|
echo -e "$result"
|
|
103
103
|
if [[ $detail ]]; then
|
|
104
104
|
detail="${detail}${result}\n"
|
|
@@ -135,10 +135,10 @@ update_repo() {
|
|
|
135
135
|
git_clone_scripts "${formatUrl}" ${repo_path} "${branch}" "${proxy}"
|
|
136
136
|
|
|
137
137
|
if [[ $exit_status -eq 0 ]]; then
|
|
138
|
-
echo -e "
|
|
138
|
+
echo -e "拉取 ${uniq_path} 成功...\n"
|
|
139
139
|
diff_scripts "$repo_path" "$author" "$path" "$blackword" "$dependence" "$extensions" "$autoAddCron" "$autoDelCron"
|
|
140
140
|
else
|
|
141
|
-
echo -e "
|
|
141
|
+
echo -e "拉取 ${uniq_path} 失败,请检查日志...\n"
|
|
142
142
|
fi
|
|
143
143
|
}
|
|
144
144
|
|
|
@@ -195,7 +195,7 @@ update_raw() {
|
|
|
195
195
|
[[ -z $cron_line ]] && cron_line=$(grep "cron:" $raw_file_name | awk -F ":" '{print $2}' | head -1 | xargs)
|
|
196
196
|
[[ -z $cron_line ]] && cron_line=$(grep "cron " $raw_file_name | awk -F "cron \"" '{print $2}' | awk -F "\" " '{print $1}' | head -1 | xargs)
|
|
197
197
|
[[ -z $cron_line ]] && cron_line="$default_cron"
|
|
198
|
-
result=$(add_cron_api "$cron_line:$cmd_task $filename:$cron_name:$SUB_ID")
|
|
198
|
+
result=$(add_cron_api "${cron_line}:${cmd_task} ${filename}:${cron_name}:${SUB_ID}")
|
|
199
199
|
echo -e "$result\n"
|
|
200
200
|
notify_api "新增任务通知" "\n$result"
|
|
201
201
|
# update_cron_api "$cron_line:$cmd_task $filename:$cron_name:$cron_id"
|
|
@@ -231,22 +231,25 @@ usage() {
|
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
reload_qinglong() {
|
|
234
|
+
delete_pm2
|
|
235
|
+
|
|
234
236
|
local reload_target="${1}"
|
|
235
237
|
local primary_branch="master"
|
|
236
|
-
if [[ "${QL_BRANCH}" == "develop" ]]; then
|
|
237
|
-
primary_branch="
|
|
238
|
+
if [[ "${QL_BRANCH}" == "develop" ]] || [[ "${QL_BRANCH}" == "debian" ]] || [[ "${QL_BRANCH}" == "debian-dev" ]]; then
|
|
239
|
+
primary_branch="${QL_BRANCH}"
|
|
238
240
|
fi
|
|
239
241
|
|
|
240
242
|
if [[ "$reload_target" == 'system' ]]; then
|
|
241
|
-
|
|
243
|
+
rm -rf ${dir_root}/back ${dir_root}/cli ${dir_root}/docker ${dir_root}/sample ${dir_root}/shell ${dir_root}/src
|
|
244
|
+
mv -f ${dir_tmp}/qinglong-${primary_branch}/* ${dir_root}/
|
|
242
245
|
rm -rf $dir_static/*
|
|
243
|
-
|
|
246
|
+
mv -f ${dir_tmp}/qinglong-static-${primary_branch}/* ${dir_static}/
|
|
244
247
|
cp -f $file_config_sample $dir_config/config.sample.sh
|
|
245
248
|
fi
|
|
246
249
|
|
|
247
250
|
if [[ "$reload_target" == 'data' ]]; then
|
|
248
|
-
rm -rf ${dir_root}/data
|
|
249
|
-
|
|
251
|
+
rm -rf ${dir_root}/data/*
|
|
252
|
+
mv -f ${dir_tmp}/data/* ${dir_root}/data/
|
|
250
253
|
fi
|
|
251
254
|
|
|
252
255
|
reload_pm2
|
|
@@ -258,7 +261,7 @@ update_qinglong() {
|
|
|
258
261
|
local mirror="gitee"
|
|
259
262
|
local downloadQLUrl="https://gitee.com/whyour/qinglong/repository/archive"
|
|
260
263
|
local downloadStaticUrl="https://gitee.com/whyour/qinglong-static/repository/archive"
|
|
261
|
-
local githubStatus=$(curl -s -m 2 -IL "https://google.com" | grep 200)
|
|
264
|
+
local githubStatus=$(curl -s --noproxy "*" -m 2 -IL "https://google.com" | grep 200)
|
|
262
265
|
if [[ ! -z $githubStatus ]]; then
|
|
263
266
|
mirror="github"
|
|
264
267
|
downloadQLUrl="https://github.com/whyour/qinglong/archive/refs/heads"
|
|
@@ -310,9 +313,12 @@ check_update_dep() {
|
|
|
310
313
|
echo -e "更新包下载成功..."
|
|
311
314
|
|
|
312
315
|
if [[ "$needRestart" == 'true' ]]; then
|
|
313
|
-
|
|
316
|
+
delete_pm2
|
|
317
|
+
|
|
318
|
+
rm -rf ${dir_root}/back ${dir_root}/cli ${dir_root}/docker ${dir_root}/sample ${dir_root}/shell ${dir_root}/src
|
|
319
|
+
mv -f ${dir_tmp}/qinglong-${primary_branch}/* ${dir_root}/
|
|
314
320
|
rm -rf $dir_static/*
|
|
315
|
-
|
|
321
|
+
mv -f ${dir_tmp}/qinglong-static-${primary_branch}/* ${dir_static}/
|
|
316
322
|
cp -f $file_config_sample $dir_config/config.sample.sh
|
|
317
323
|
|
|
318
324
|
reload_pm2
|
|
@@ -417,9 +423,15 @@ gen_list_repo() {
|
|
|
417
423
|
fi
|
|
418
424
|
|
|
419
425
|
for file in ${files}; do
|
|
426
|
+
dirPath=$(dirname "$file")
|
|
420
427
|
filename=$(basename "$file")
|
|
421
|
-
|
|
422
|
-
|
|
428
|
+
filePath="${uniq_path}/${filename}"
|
|
429
|
+
if [[ $dirPath ]] && [[ $dirPath != '.' ]]; then
|
|
430
|
+
mkdir -p "${dir_scripts}/${uniq_path}/${dirPath}"
|
|
431
|
+
filePath="${uniq_path}/${dirPath}/${filename}"
|
|
432
|
+
fi
|
|
433
|
+
cp -f $file "${dir_scripts}/$filePath"
|
|
434
|
+
echo "$filePath" >>"$dir_list_tmp/${uniq_path}_scripts.list"
|
|
423
435
|
# cron_id=$(cat $list_crontab_user | grep -E "$cmd_task.* ${uniq_path}_${filename}" | perl -pe "s|.*ID=(.*) $cmd_task.* ${uniq_path}_${filename}\.*|\1|" | head -1 | awk -F " " '{print $1}')
|
|
424
436
|
# if [[ $cron_id ]]; then
|
|
425
437
|
# result=$(update_cron_command_api "$cmd_task ${uniq_path}/${filename}:$cron_id")
|
|
@@ -111,5 +111,17 @@ exports.default = (app) => {
|
|
|
111
111
|
return next(e);
|
|
112
112
|
}
|
|
113
113
|
});
|
|
114
|
+
route.put('/cancel', (0, celebrate_1.celebrate)({
|
|
115
|
+
body: celebrate_1.Joi.array().items(celebrate_1.Joi.number().required()),
|
|
116
|
+
}), async (req, res, next) => {
|
|
117
|
+
try {
|
|
118
|
+
const dependenceService = typedi_1.Container.get(dependence_1.default);
|
|
119
|
+
await dependenceService.cancel(req.body);
|
|
120
|
+
return res.send({ code: 200 });
|
|
121
|
+
}
|
|
122
|
+
catch (e) {
|
|
123
|
+
return next(e);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
114
126
|
};
|
|
115
127
|
//# sourceMappingURL=dependence.js.map
|
|
@@ -56,6 +56,7 @@ exports.default = {
|
|
|
56
56
|
port: parseInt(process.env.BACK_PORT, 10),
|
|
57
57
|
cronPort: parseInt(process.env.CRON_PORT, 10),
|
|
58
58
|
publicPort: parseInt(process.env.PUBLIC_PORT, 10),
|
|
59
|
+
updatePort: parseInt(process.env.UPDATE_PORT, 10),
|
|
59
60
|
secret: process.env.SECRET || (0, share_1.createRandomString)(16, 32),
|
|
60
61
|
logs: {
|
|
61
62
|
level: process.env.LOG_LEVEL || 'silly',
|
|
@@ -352,30 +352,33 @@ function parseHeaders(headers) {
|
|
|
352
352
|
return parsed;
|
|
353
353
|
}
|
|
354
354
|
exports.parseHeaders = parseHeaders;
|
|
355
|
-
function
|
|
355
|
+
function parseString(input, valueFormatFn) {
|
|
356
|
+
const regex = /(\w+):\s*((?:(?!\n\w+:).)*)/g;
|
|
357
|
+
const matches = {};
|
|
358
|
+
let match;
|
|
359
|
+
while ((match = regex.exec(input)) !== null) {
|
|
360
|
+
const [, key, value] = match;
|
|
361
|
+
const _key = key.trim();
|
|
362
|
+
if (!_key || matches[_key]) {
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
let _value = value.trim();
|
|
366
|
+
try {
|
|
367
|
+
_value = valueFormatFn ? valueFormatFn(_value) : _value;
|
|
368
|
+
const jsonValue = JSON.parse(_value);
|
|
369
|
+
matches[_key] = jsonValue;
|
|
370
|
+
}
|
|
371
|
+
catch (error) {
|
|
372
|
+
matches[_key] = _value;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return matches;
|
|
376
|
+
}
|
|
377
|
+
function parseBody(body, contentType, valueFormatFn) {
|
|
356
378
|
if (contentType === 'text/plain' || !body) {
|
|
357
379
|
return body;
|
|
358
380
|
}
|
|
359
|
-
const parsed =
|
|
360
|
-
let key;
|
|
361
|
-
let val;
|
|
362
|
-
let i;
|
|
363
|
-
body &&
|
|
364
|
-
body.split('\n').forEach(function parser(line) {
|
|
365
|
-
i = line.indexOf(':');
|
|
366
|
-
key = line.substring(0, i).trim();
|
|
367
|
-
val = line.substring(i + 1).trim();
|
|
368
|
-
if (!key || parsed[key]) {
|
|
369
|
-
return;
|
|
370
|
-
}
|
|
371
|
-
try {
|
|
372
|
-
const jsonValue = JSON.parse(val);
|
|
373
|
-
parsed[key] = jsonValue;
|
|
374
|
-
}
|
|
375
|
-
catch (error) {
|
|
376
|
-
parsed[key] = val;
|
|
377
|
-
}
|
|
378
|
-
});
|
|
381
|
+
const parsed = parseString(body, valueFormatFn);
|
|
379
382
|
switch (contentType) {
|
|
380
383
|
case 'multipart/form-data':
|
|
381
384
|
return Object.keys(parsed).reduce((p, c) => {
|
|
@@ -416,8 +419,8 @@ async function killTask(pid) {
|
|
|
416
419
|
}
|
|
417
420
|
}
|
|
418
421
|
exports.killTask = killTask;
|
|
419
|
-
async function getPid(
|
|
420
|
-
const taskCommand = `ps -eo pid,command | grep "${
|
|
422
|
+
async function getPid(cmd) {
|
|
423
|
+
const taskCommand = `ps -eo pid,command | grep "${cmd}" | grep -v grep | awk '{print $1}' | head -1 | xargs echo -n`;
|
|
421
424
|
const pid = await promiseExec(taskCommand);
|
|
422
425
|
return pid ? Number(pid) : undefined;
|
|
423
426
|
}
|
|
@@ -27,6 +27,7 @@ var DependenceStatus;
|
|
|
27
27
|
DependenceStatus[DependenceStatus["removed"] = 4] = "removed";
|
|
28
28
|
DependenceStatus[DependenceStatus["removeFailed"] = 5] = "removeFailed";
|
|
29
29
|
DependenceStatus[DependenceStatus["queued"] = 6] = "queued";
|
|
30
|
+
DependenceStatus[DependenceStatus["cancelled"] = 7] = "cancelled";
|
|
30
31
|
})(DependenceStatus || (exports.DependenceStatus = DependenceStatus = {}));
|
|
31
32
|
var DependenceTypes;
|
|
32
33
|
(function (DependenceTypes) {
|
|
@@ -8,27 +8,6 @@ const sock_1 = __importDefault(require("./sock"));
|
|
|
8
8
|
exports.default = async ({ server }) => {
|
|
9
9
|
await (0, sock_1.default)({ server });
|
|
10
10
|
logger_1.default.info('✌️ Sock loaded');
|
|
11
|
-
let exitTime = 0;
|
|
12
|
-
let timer;
|
|
13
|
-
process.on('SIGINT', (singal) => {
|
|
14
|
-
logger_1.default.warn(`Server need close, singal ${singal}`);
|
|
15
|
-
console.warn(`Server need close, singal ${singal}`);
|
|
16
|
-
exitTime++;
|
|
17
|
-
if (exitTime >= 3) {
|
|
18
|
-
logger_1.default.warn('Forcing server close');
|
|
19
|
-
console.warn('Forcing server close');
|
|
20
|
-
clearTimeout(timer);
|
|
21
|
-
process.exit(1);
|
|
22
|
-
}
|
|
23
|
-
server.close(() => {
|
|
24
|
-
if (timer) {
|
|
25
|
-
clearTimeout(timer);
|
|
26
|
-
}
|
|
27
|
-
timer = setTimeout(() => {
|
|
28
|
-
process.exit();
|
|
29
|
-
}, 15000);
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
11
|
process.on('uncaughtException', (error) => {
|
|
33
12
|
logger_1.default.error('Uncaught exception:', error);
|
|
34
13
|
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const body_parser_1 = __importDefault(require("body-parser"));
|
|
7
|
+
const celebrate_1 = require("celebrate");
|
|
8
|
+
const cors_1 = __importDefault(require("cors"));
|
|
9
|
+
const express_jwt_1 = __importDefault(require("express-jwt"));
|
|
10
|
+
const typedi_1 = __importDefault(require("typedi"));
|
|
11
|
+
const config_1 = __importDefault(require("../config"));
|
|
12
|
+
const system_1 = __importDefault(require("../services/system"));
|
|
13
|
+
const logger_1 = __importDefault(require("./logger"));
|
|
14
|
+
exports.default = ({ app }) => {
|
|
15
|
+
app.set('trust proxy', 'loopback');
|
|
16
|
+
app.use((0, cors_1.default)());
|
|
17
|
+
app.use(body_parser_1.default.json({ limit: '50mb' }));
|
|
18
|
+
app.use(body_parser_1.default.urlencoded({ limit: '50mb', extended: true }));
|
|
19
|
+
app.use((0, express_jwt_1.default)({
|
|
20
|
+
secret: config_1.default.secret,
|
|
21
|
+
algorithms: ['HS384'],
|
|
22
|
+
}));
|
|
23
|
+
app.put('/api/reload', async (req, res, next) => {
|
|
24
|
+
try {
|
|
25
|
+
const systemService = typedi_1.default.get(system_1.default);
|
|
26
|
+
const result = await systemService.reloadSystem();
|
|
27
|
+
res.send(result);
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
logger_1.default.error('🔥 error: %o', e);
|
|
31
|
+
return next(e);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
app.put('/api/system', async (req, res, next) => {
|
|
35
|
+
try {
|
|
36
|
+
const systemService = typedi_1.default.get(system_1.default);
|
|
37
|
+
const result = await systemService.reloadSystem('system');
|
|
38
|
+
res.send(result);
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
logger_1.default.error('🔥 error: %o', e);
|
|
42
|
+
return next(e);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
app.put('/api/data', async (req, res, next) => {
|
|
46
|
+
try {
|
|
47
|
+
const systemService = typedi_1.default.get(system_1.default);
|
|
48
|
+
const result = await systemService.reloadSystem('data');
|
|
49
|
+
res.send(result);
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
logger_1.default.error('🔥 error: %o', e);
|
|
53
|
+
return next(e);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
app.use((req, res, next) => {
|
|
57
|
+
const err = new Error('Not Found');
|
|
58
|
+
err['status'] = 404;
|
|
59
|
+
next(err);
|
|
60
|
+
});
|
|
61
|
+
app.use((0, celebrate_1.errors)());
|
|
62
|
+
app.use((err, req, res, next) => {
|
|
63
|
+
if (err.name === 'UnauthorizedError') {
|
|
64
|
+
return res
|
|
65
|
+
.status(err.status)
|
|
66
|
+
.send({ code: 401, message: err.message })
|
|
67
|
+
.end();
|
|
68
|
+
}
|
|
69
|
+
return next(err);
|
|
70
|
+
});
|
|
71
|
+
app.use((err, req, res, next) => {
|
|
72
|
+
res.status(err.status || 500);
|
|
73
|
+
res.json({
|
|
74
|
+
code: err.status || 500,
|
|
75
|
+
message: err.message,
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -80,8 +80,11 @@ let DependenceService = class DependenceService {
|
|
|
80
80
|
async removeDb(ids) {
|
|
81
81
|
await dependence_1.DependenceModel.destroy({ where: { id: ids } });
|
|
82
82
|
}
|
|
83
|
-
async dependencies({ searchValue, type }, sort =
|
|
83
|
+
async dependencies({ searchValue, type, status, }, sort = [], query = {}) {
|
|
84
84
|
let condition = Object.assign(Object.assign({}, query), { type: dependence_1.DependenceTypes[type] });
|
|
85
|
+
if (status) {
|
|
86
|
+
condition.status = status.split(',').map(Number);
|
|
87
|
+
}
|
|
85
88
|
if (searchValue) {
|
|
86
89
|
const encodeText = encodeURI(searchValue);
|
|
87
90
|
const reg = {
|
|
@@ -93,7 +96,7 @@ let DependenceService = class DependenceService {
|
|
|
93
96
|
condition = Object.assign(Object.assign({}, condition), { name: reg });
|
|
94
97
|
}
|
|
95
98
|
try {
|
|
96
|
-
const result = await this.find(condition);
|
|
99
|
+
const result = await this.find(condition, sort);
|
|
97
100
|
return result;
|
|
98
101
|
}
|
|
99
102
|
catch (error) {
|
|
@@ -111,6 +114,24 @@ let DependenceService = class DependenceService {
|
|
|
111
114
|
this.installDependenceOneByOne(docs, true, true);
|
|
112
115
|
return docs;
|
|
113
116
|
}
|
|
117
|
+
async cancel(ids) {
|
|
118
|
+
const docs = await dependence_1.DependenceModel.findAll({ where: { id: ids } });
|
|
119
|
+
for (const doc of docs) {
|
|
120
|
+
pLimit_1.default.removeQueuedDependency(doc);
|
|
121
|
+
const depInstallCommand = dependence_1.InstallDependenceCommandTypes[doc.type];
|
|
122
|
+
const depUnInstallCommand = dependence_1.unInstallDependenceCommandTypes[doc.type];
|
|
123
|
+
const installCmd = `${depInstallCommand} ${doc.name.trim()}`;
|
|
124
|
+
const unInstallCmd = `${depUnInstallCommand} ${doc.name.trim()}`;
|
|
125
|
+
const pids = await Promise.all([
|
|
126
|
+
(0, util_1.getPid)(installCmd),
|
|
127
|
+
(0, util_1.getPid)(unInstallCmd),
|
|
128
|
+
]);
|
|
129
|
+
for (const pid of pids) {
|
|
130
|
+
pid && (await (0, util_1.killTask)(pid));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
await dependence_1.DependenceModel.update({ status: dependence_1.DependenceStatus.cancelled }, { where: { id: ids } });
|
|
134
|
+
}
|
|
114
135
|
async find(query, sort = []) {
|
|
115
136
|
const docs = await dependence_1.DependenceModel.findAll({
|
|
116
137
|
where: Object.assign({}, query),
|
|
@@ -133,9 +154,13 @@ let DependenceService = class DependenceService {
|
|
|
133
154
|
});
|
|
134
155
|
}
|
|
135
156
|
installOrUninstallDependency(dependency, isInstall = true, force = false) {
|
|
136
|
-
return pLimit_1.default.
|
|
157
|
+
return pLimit_1.default.runDependeny(dependency, () => {
|
|
137
158
|
return new Promise(async (resolve) => {
|
|
138
159
|
var _a;
|
|
160
|
+
if (pLimit_1.default.firstDependencyId !== dependency.id) {
|
|
161
|
+
return resolve(null);
|
|
162
|
+
}
|
|
163
|
+
pLimit_1.default.removeQueuedDependency(dependency);
|
|
139
164
|
const depIds = [dependency.id];
|
|
140
165
|
const status = isInstall
|
|
141
166
|
? dependence_1.DependenceStatus.installing
|
|
@@ -249,7 +274,13 @@ let DependenceService = class DependenceService {
|
|
|
249
274
|
? dependence_1.DependenceStatus.installFailed
|
|
250
275
|
: dependence_1.DependenceStatus.removeFailed;
|
|
251
276
|
}
|
|
252
|
-
await dependence_1.DependenceModel.
|
|
277
|
+
const docs = await dependence_1.DependenceModel.findAll({ where: { id: depIds } });
|
|
278
|
+
const _docIds = docs
|
|
279
|
+
.filter((x) => x.status !== dependence_1.DependenceStatus.cancelled)
|
|
280
|
+
.map((x) => x.id);
|
|
281
|
+
if (_docIds.length > 0) {
|
|
282
|
+
await dependence_1.DependenceModel.update({ status }, { where: { id: _docIds } });
|
|
283
|
+
}
|
|
253
284
|
// 如果删除依赖成功或者强制删除
|
|
254
285
|
if ((isSucceed || force) && !isInstall) {
|
|
255
286
|
this.removeDb(depIds);
|
|
@@ -561,16 +561,17 @@ let NotificationService = class NotificationService {
|
|
|
561
561
|
}
|
|
562
562
|
}
|
|
563
563
|
async webhook() {
|
|
564
|
+
var _a;
|
|
564
565
|
const { webhookUrl, webhookBody, webhookHeaders, webhookMethod, webhookContentType, } = this.params;
|
|
565
|
-
|
|
566
|
-
if (!formatUrl && !formatBody) {
|
|
566
|
+
if (!webhookUrl.includes('$title') && !webhookBody.includes('$title')) {
|
|
567
567
|
throw new Error('Url 或者 Body 中必须包含 $title');
|
|
568
568
|
}
|
|
569
569
|
const headers = (0, util_1.parseHeaders)(webhookHeaders);
|
|
570
|
-
const body = (0, util_1.parseBody)(
|
|
570
|
+
const body = (0, util_1.parseBody)(webhookBody, webhookContentType, (v) => { var _a; return (_a = v === null || v === void 0 ? void 0 : v.replaceAll('$title', this.title)) === null || _a === void 0 ? void 0 : _a.replaceAll('$content', this.content); });
|
|
571
571
|
const bodyParam = this.formatBody(webhookContentType, body);
|
|
572
572
|
const options = Object.assign(Object.assign(Object.assign({ method: webhookMethod, headers }, this.gotOption), { allowGetBody: true }), bodyParam);
|
|
573
573
|
try {
|
|
574
|
+
const formatUrl = (_a = webhookUrl === null || webhookUrl === void 0 ? void 0 : webhookUrl.replaceAll('$title', encodeURIComponent(this.title))) === null || _a === void 0 ? void 0 : _a.replaceAll('$content', encodeURIComponent(this.content));
|
|
574
575
|
const res = await (0, got_1.default)(formatUrl, options);
|
|
575
576
|
if (String(res.statusCode).startsWith('20')) {
|
|
576
577
|
return true;
|
|
@@ -597,16 +598,6 @@ let NotificationService = class NotificationService {
|
|
|
597
598
|
}
|
|
598
599
|
return {};
|
|
599
600
|
}
|
|
600
|
-
formatNotifyContent(url, body) {
|
|
601
|
-
var _a, _b;
|
|
602
|
-
if (!url.includes('$title') && !body.includes('$title')) {
|
|
603
|
-
return {};
|
|
604
|
-
}
|
|
605
|
-
return {
|
|
606
|
-
formatUrl: (_a = url === null || url === void 0 ? void 0 : url.replaceAll('$title', encodeURIComponent(this.title))) === null || _a === void 0 ? void 0 : _a.replaceAll('$content', encodeURIComponent(this.content)),
|
|
607
|
-
formatBody: (_b = body === null || body === void 0 ? void 0 : body.replaceAll('$title', this.title)) === null || _b === void 0 ? void 0 : _b.replaceAll('$content', this.content),
|
|
608
|
-
};
|
|
609
|
-
}
|
|
610
601
|
};
|
|
611
602
|
__decorate([
|
|
612
603
|
(0, typedi_1.Inject)((type) => user_1.default),
|
|
@@ -15,23 +15,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
15
15
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
16
|
};
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
const cross_spawn_1 = require("cross-spawn");
|
|
19
|
+
const fs_1 = __importDefault(require("fs"));
|
|
20
|
+
const got_1 = __importDefault(require("got"));
|
|
21
|
+
const sum_1 = __importDefault(require("lodash/sum"));
|
|
22
|
+
const path_1 = __importDefault(require("path"));
|
|
18
23
|
const typedi_1 = require("typedi");
|
|
19
24
|
const winston_1 = __importDefault(require("winston"));
|
|
20
25
|
const config_1 = __importDefault(require("../config"));
|
|
26
|
+
const const_1 = require("../config/const");
|
|
27
|
+
const util_1 = require("../config/util");
|
|
28
|
+
const dependence_1 = require("../data/dependence");
|
|
21
29
|
const system_1 = require("../data/system");
|
|
30
|
+
const pLimit_1 = __importDefault(require("../shared/pLimit"));
|
|
22
31
|
const notify_1 = __importDefault(require("./notify"));
|
|
23
32
|
const schedule_1 = __importDefault(require("./schedule"));
|
|
24
|
-
const cross_spawn_1 = require("cross-spawn");
|
|
25
33
|
const sock_1 = __importDefault(require("./sock"));
|
|
26
|
-
const got_1 = __importDefault(require("got"));
|
|
27
|
-
const util_1 = require("../config/util");
|
|
28
|
-
const const_1 = require("../config/const");
|
|
29
|
-
const pLimit_1 = __importDefault(require("../shared/pLimit"));
|
|
30
|
-
const tar_1 = __importDefault(require("tar"));
|
|
31
|
-
const path_1 = __importDefault(require("path"));
|
|
32
|
-
const fs_1 = __importDefault(require("fs"));
|
|
33
|
-
const sum_1 = __importDefault(require("lodash/sum"));
|
|
34
|
-
const dependence_1 = require("../data/dependence");
|
|
35
34
|
let SystemService = class SystemService {
|
|
36
35
|
constructor(logger, scheduleService, sockService) {
|
|
37
36
|
this.logger = logger;
|
|
@@ -112,7 +111,10 @@ let SystemService = class SystemService {
|
|
|
112
111
|
}
|
|
113
112
|
let command = `cd && ${cmd}`;
|
|
114
113
|
const docs = await dependence_1.DependenceModel.findAll({
|
|
115
|
-
where: {
|
|
114
|
+
where: {
|
|
115
|
+
type: dependence_1.DependenceTypes.nodejs,
|
|
116
|
+
status: dependence_1.DependenceStatus.installed,
|
|
117
|
+
},
|
|
116
118
|
});
|
|
117
119
|
if (docs.length > 0) {
|
|
118
120
|
command += ` && pnpm i -g`;
|
|
@@ -258,24 +260,7 @@ let SystemService = class SystemService {
|
|
|
258
260
|
async reloadSystem(target) {
|
|
259
261
|
const cmd = `real_time=true ql reload ${target || ''}`;
|
|
260
262
|
const cp = (0, cross_spawn_1.spawn)(cmd, { shell: '/bin/bash' });
|
|
261
|
-
cp.
|
|
262
|
-
this.sockService.sendMessage({
|
|
263
|
-
type: 'reloadSystem',
|
|
264
|
-
message: data.toString(),
|
|
265
|
-
});
|
|
266
|
-
});
|
|
267
|
-
cp.stderr.on('data', (data) => {
|
|
268
|
-
this.sockService.sendMessage({
|
|
269
|
-
type: 'reloadSystem',
|
|
270
|
-
message: data.toString(),
|
|
271
|
-
});
|
|
272
|
-
});
|
|
273
|
-
cp.on('error', (err) => {
|
|
274
|
-
this.sockService.sendMessage({
|
|
275
|
-
type: 'reloadSystem',
|
|
276
|
-
message: JSON.stringify(err),
|
|
277
|
-
});
|
|
278
|
-
});
|
|
263
|
+
cp.unref();
|
|
279
264
|
return { code: 200 };
|
|
280
265
|
}
|
|
281
266
|
async notify({ title, content }) {
|
|
@@ -317,7 +302,7 @@ let SystemService = class SystemService {
|
|
|
317
302
|
}
|
|
318
303
|
async exportData(res) {
|
|
319
304
|
try {
|
|
320
|
-
await
|
|
305
|
+
await (0, util_1.promiseExec)(`cd ${config_1.default.rootPath} && tar -zcvf ${config_1.default.dataTgzFile} data/`);
|
|
321
306
|
res.download(config_1.default.dataTgzFile);
|
|
322
307
|
}
|
|
323
308
|
catch (error) {
|
|
@@ -327,8 +312,8 @@ let SystemService = class SystemService {
|
|
|
327
312
|
async importData() {
|
|
328
313
|
try {
|
|
329
314
|
await (0, util_1.promiseExec)(`rm -rf ${path_1.default.join(config_1.default.tmpPath, 'data')}`);
|
|
330
|
-
await
|
|
331
|
-
return { code: 200 };
|
|
315
|
+
const res = await (0, util_1.promiseExec)(`cd ${config_1.default.tmpPath} && tar -zxvf data.tgz`);
|
|
316
|
+
return { code: 200, data: res };
|
|
332
317
|
}
|
|
333
318
|
catch (error) {
|
|
334
319
|
return { code: 400, message: error.message };
|
|
@@ -14,10 +14,16 @@ class TaskLimit {
|
|
|
14
14
|
get cronLimitPendingCount() {
|
|
15
15
|
return this.cronLimit.size;
|
|
16
16
|
}
|
|
17
|
+
get firstDependencyId() {
|
|
18
|
+
return [...this.queuedDependencyIds.values()][0];
|
|
19
|
+
}
|
|
17
20
|
constructor() {
|
|
18
|
-
this.
|
|
21
|
+
this.dependenyLimit = new p_queue_cjs_1.default({ concurrency: 1 });
|
|
22
|
+
this.queuedDependencyIds = new Set([]);
|
|
19
23
|
this.updateLogLimit = new p_queue_cjs_1.default({ concurrency: 1 });
|
|
20
|
-
this.cronLimit = new p_queue_cjs_1.default({
|
|
24
|
+
this.cronLimit = new p_queue_cjs_1.default({
|
|
25
|
+
concurrency: Math.max(os_1.default.cpus().length, 4),
|
|
26
|
+
});
|
|
21
27
|
this.setCustomLimit();
|
|
22
28
|
this.handleEvents();
|
|
23
29
|
}
|
|
@@ -31,7 +37,7 @@ class TaskLimit {
|
|
|
31
37
|
this.cronLimit.on('completed', (param) => {
|
|
32
38
|
logger_1.default.info(`[schedule][任务处理成功] 参数 ${JSON.stringify(param)}`);
|
|
33
39
|
});
|
|
34
|
-
this.cronLimit.on('error', error => {
|
|
40
|
+
this.cronLimit.on('error', (error) => {
|
|
35
41
|
logger_1.default.error(`[schedule][任务处理错误] 参数 ${JSON.stringify(error)}`);
|
|
36
42
|
});
|
|
37
43
|
this.cronLimit.on('next', () => {
|
|
@@ -41,6 +47,11 @@ class TaskLimit {
|
|
|
41
47
|
logger_1.default.info(`[schedule][任务队列] 空闲中...`);
|
|
42
48
|
});
|
|
43
49
|
}
|
|
50
|
+
removeQueuedDependency(dependency) {
|
|
51
|
+
if (this.queuedDependencyIds.has(dependency.id)) {
|
|
52
|
+
this.queuedDependencyIds.delete(dependency.id);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
44
55
|
async setCustomLimit(limit) {
|
|
45
56
|
var _a;
|
|
46
57
|
if (limit) {
|
|
@@ -58,8 +69,10 @@ class TaskLimit {
|
|
|
58
69
|
async runWithCronLimit(fn, options) {
|
|
59
70
|
return this.cronLimit.add(fn, options);
|
|
60
71
|
}
|
|
61
|
-
|
|
62
|
-
|
|
72
|
+
runDependeny(dependency, fn, options) {
|
|
73
|
+
this.queuedDependencyIds.add(dependency.id);
|
|
74
|
+
fn.dependency = dependency;
|
|
75
|
+
return this.dependenyLimit.add(fn, options);
|
|
63
76
|
}
|
|
64
77
|
updateDepLog(fn, options) {
|
|
65
78
|
return this.updateLogLimit.add(fn, options);
|