Compare commits

...

18 Commits

Author SHA1 Message Date
whyour 1377fe31aa 更新版本 v2.15.14 2023-05-15 23:44:42 +08:00
whyour 3d1cf6bf2e 修改群晖名称 2023-05-15 23:44:32 +08:00
whyour 6ac755b478 修复后端 html 缓存 2023-05-15 22:34:06 +08:00
whyour e70fa83074 修复获取配置文件参数 2023-05-14 20:53:45 +08:00
whyour 41521f1d08 修复 token 任务脚本路径,容器启动 bot 2023-05-13 01:10:49 +08:00
whyour 8b7bef097c 修复拉取仓库逻辑 2023-05-12 18:28:01 +08:00
whyour 618756d4a9 修复设置代理时,服务启动失败 2023-05-10 23:17:05 +08:00
whyour 70d0c71414 修复错误日志样式 2023-05-10 23:01:51 +08:00
whyour 65eb9c806d 更新 sqlite 2023-05-10 21:58:11 +08:00
whyour 50718ba714 修复 public 服务转发 2023-05-10 01:07:46 +08:00
whyour 7c3bb90d12 修复删除依赖和移动环境变量接口数据结构 2023-05-08 21:29:25 +08:00
whyour f66390eabd 修改初始系统状态逻辑已经错误页面 2023-05-07 23:40:37 +08:00
whyour 481646501c 修复订阅更新仓库失败 2023-05-06 22:58:05 +08:00
whyour 5baa8e4391 增加 pm2 平滑重启 2023-05-06 00:09:03 +08:00
whyour 3d11210aeb pnpm 版本降至 8.3.1 2023-05-05 00:26:23 +08:00
whyour e1863407f2 修复 npm 源判断 2023-05-04 22:23:55 +08:00
whyour 0c28b63ab7 修改容器启动流程 2023-05-04 22:07:39 +08:00
whyour 8b8bd279c6 修复 nginx 转发stream接口失效,停止运行命令支持 pid 参数 2023-05-04 21:28:14 +08:00
33 changed files with 3262 additions and 2868 deletions
+2 -2
View File
@@ -45,7 +45,7 @@ jobs:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
with:
version: latest
version: '8.3.1'
- uses: actions/setup-node@v3
with:
@@ -99,7 +99,7 @@ jobs:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
with:
version: latest
version: '8.3.1'
- uses: actions/setup-node@v3
with:
cache: 'pnpm'
+1 -1
View File
@@ -198,7 +198,7 @@ $ git clone git@github.com:whyour/qinglong.git
$ cd qinglong
$ cp .env.example .env
# Recommended use pnpm https://pnpm.io/zh/installation
$ npm install -g pnpm
$ npm install -g pnpm@8.3.1
$ pnpm install
$ pnpm start
```
+1 -1
View File
@@ -197,7 +197,7 @@ $ git clone git@github.com:whyour/qinglong.git
$ cd qinglong
$ cp .env.example .env
# 推荐使用 pnpm https://pnpm.io/zh/installation
$ npm install -g pnpm
$ npm install -g pnpm@8.3.1
$ pnpm install
$ pnpm start
```
+4 -3
View File
@@ -5,6 +5,7 @@ import { Logger } from 'winston';
import config from '../config';
import * as fs from 'fs';
import { celebrate, Joi } from 'celebrate';
import { join } from 'path';
const route = Router();
export default (app: Router) => {
@@ -41,11 +42,11 @@ export default (app: Router) => {
}
if (req.params.file.includes('sample')) {
content = getFileContentByName(
`${config.samplePath}${req.params.file}`,
join(config.samplePath, req.params.file),
);
} else {
content = getFileContentByName(
`${config.configPath}${req.params.file}`,
join(config.configPath, req.params.file),
);
}
res.send({ code: 200, data: content });
@@ -70,7 +71,7 @@ export default (app: Router) => {
if (config.blackFileList.includes(name)) {
res.send({ code: 403, message: '文件无法访问' });
}
const path = `${config.configPath}${name}`;
const path = join(config.configPath, name);
fs.writeFileSync(path, content);
res.send({ code: 200, message: '保存成功' });
} catch (e) {
+3 -3
View File
@@ -94,7 +94,7 @@ export default (app: Router) => {
path += '/';
}
if (!path.startsWith('/')) {
path = `${config.scriptPath}${path}`;
path = join(config.scriptPath, path);
}
if (config.writePathList.every((x) => !path.startsWith(x))) {
return res.send({
@@ -124,7 +124,7 @@ export default (app: Router) => {
if (fs.existsSync(originFilePath)) {
fs.copyFileSync(
originFilePath,
`${config.bakPath}${originFilename.replace(/\//g, '')}`,
join(config.bakPath, originFilename.replace(/\//g, '')),
);
if (filename !== originFilename) {
fs.unlinkSync(originFilePath);
@@ -207,7 +207,7 @@ export default (app: Router) => {
let { filename } = req.body as {
filename: string;
};
const filePath = `${config.scriptPath}${filename}`;
const filePath = join(config.scriptPath, filename);
// const stats = fs.statSync(filePath);
// res.set({
// 'Content-Type': 'application/octet-stream', //告诉浏览器这是一个二进制文件
+5 -1
View File
@@ -170,6 +170,9 @@ export default (app: Router) => {
await systemService.run(
{ ...req.body, logPath },
{
onStart: async (cp, startTime) => {
res.setHeader('QL-Task-Pid', `${cp.pid}`);
},
onEnd: async (cp, endTime, diff) => {
res.end();
},
@@ -195,7 +198,8 @@ export default (app: Router) => {
'/command-stop',
celebrate({
body: Joi.object({
command: Joi.string().required(),
command: Joi.string().optional(),
pid: Joi.number().optional(),
}),
}),
async (req: Request, res: Response, next: NextFunction) => {
+1
View File
@@ -18,6 +18,7 @@ async function startServer() {
const server = app
.listen(config.port, () => {
Logger.debug(`✌️ 后端服务启动成功!`);
process.send?.('ready');
})
.on('error', (err) => {
Logger.error(err);
+2 -1
View File
@@ -1,9 +1,10 @@
import { Sequelize, Transaction } from 'sequelize';
import config from '../config/index';
import { join } from 'path';
export const sequelize = new Sequelize({
dialect: 'sqlite',
storage: `${config.dbPath}database.sqlite`,
storage: join(config.dbPath, 'database.sqlite'),
logging: false,
retry: {
max: 10,
+23 -1
View File
@@ -14,19 +14,41 @@ import handler from 'serve-handler';
import * as Sentry from '@sentry/node';
import { EnvModel } from '../data/env';
import { errors } from 'celebrate';
import path from 'path';
import { createProxyMiddleware } from 'http-proxy-middleware';
export default ({ app }: { app: Application }) => {
app.enable('trust proxy');
app.use(cors());
app.use(`${config.api.prefix}/static`, express.static(config.uploadPath));
app.use(
'/api/public',
createProxyMiddleware({
target: `http://localhost:${config.publicPort}/api`,
changeOrigin: true,
pathRewrite: { '/api/public': '' },
}),
);
app.use((req, res, next) => {
if (req.path.startsWith('/api') || req.path.startsWith('/open')) {
next();
} else {
return handler(req, res, {
public: 'static/dist',
public: path.join(config.rootPath, 'static/dist'),
rewrites: [{ source: '**', destination: '/index.html' }],
headers: [
{
source: 'index.html',
headers: [
{
key: 'Cache-Control',
value: 'no-cache',
},
],
},
],
});
}
});
+4 -2
View File
@@ -4,6 +4,7 @@ import ScheduleService from '../services/schedule';
import SubscriptionService from '../services/subscription';
import config from '../config';
import { fileExist } from '../config/util';
import { join } from 'path';
export default async () => {
const systemService = Container.get(SystemService);
@@ -11,8 +12,9 @@ export default async () => {
const subscriptionService = Container.get(SubscriptionService);
// 生成内置token
let tokenCommand = `tsx ${config.rootPath}/back/token.ts`;
const tokenFile = `${config.rootPath}static/build/token.js`;
let tokenCommand = `tsx ${join(config.rootPath, 'back/token.ts')}`;
const tokenFile = join(config.rootPath, 'static/build/token.js');
if (await fileExist(tokenFile)) {
tokenCommand = `node ${tokenFile}`;
}
+8 -2
View File
@@ -9,8 +9,14 @@ export default async ({ server }: { server: Server }) => {
process.on('SIGINT', () => {
Logger.info('✌️ Server need close');
server.close(() => {
Logger.info('✌️ Server closed');
process.exit(0);
setTimeout(() => {
process.exit();
}, 10000);
});
setTimeout(() => {
console.log('Forcing server close !!!');
process.exit(1);
}, 15000);
});
};
+3 -3
View File
@@ -1,5 +1,4 @@
import express from 'express';
import { exec } from 'child_process';
import Logger from './loaders/logger';
import config from './config';
import { HealthClient } from './protos/health';
@@ -14,9 +13,9 @@ const client = new HealthClient(
app.get('/api/health', (req, res) => {
client.check({ service: 'cron' }, (err, response) => {
if (err) {
return res.status(500).send({ error: err });
return res.status(500).send({ code: 500, error: err });
}
return res.status(200).send({ data: response });
return res.status(200).send({ code: 200, data: response });
});
});
@@ -26,6 +25,7 @@ app
await require('./loaders/db').default();
Logger.debug(`✌️ 公共服务启动成功!`);
process.send?.('ready');
})
.on('error', (err) => {
Logger.error(err);
+1
View File
@@ -16,5 +16,6 @@ server.bindAsync(
() => {
server.start();
Logger.debug(`✌️ 定时服务启动成功!`);
process.send?.('ready');
},
);
+13 -4
View File
@@ -190,13 +190,22 @@ export default class SystemService {
);
}
public async stop({ command }: { command: string }) {
public async stop({ command, pid }: { command: string; pid: number }) {
if (!pid && !command) {
return { code: 400, message: '参数错误' };
}
if (pid) {
await killTask(pid);
return { code: 200 };
}
if (!command.startsWith(TASK_COMMAND)) {
command = `${TASK_COMMAND} ${command}`;
}
const pid = await getPid(command);
if (pid) {
await killTask(pid);
const _pid = await getPid(command);
if (_pid) {
await killTask(_pid);
return { code: 200 };
} else {
return { code: 400, message: '任务未找到' };
+20 -11
View File
@@ -1,6 +1,11 @@
import { Service, Inject } from 'typedi';
import winston from 'winston';
import { createRandomString, getNetIp, getPlatform } from '../config/util';
import {
createRandomString,
fileExist,
getNetIp,
getPlatform,
} from '../config/util';
import config from '../config';
import * as fs from 'fs';
import jwt from 'jsonwebtoken';
@@ -205,17 +210,16 @@ export default class UserService {
}
private initAuthInfo() {
const newPassword = createRandomString(16, 22);
fs.writeFileSync(
config.authConfigFile,
JSON.stringify({
username: 'admin',
password: newPassword,
password: 'admin',
}),
);
return {
code: 100,
message: '已初始化密码,请前往auth.json查看并重新登录',
message: '未找到认证文件,重新初始化',
};
}
@@ -240,13 +244,18 @@ export default class UserService {
return { code: 200, data: avatar, message: '更新成功' };
}
public getUserInfo(): Promise<any> {
return new Promise((resolve) => {
fs.readFile(config.authConfigFile, 'utf8', (err, data) => {
if (err) console.log(err);
resolve(JSON.parse(data));
});
});
public async getUserInfo(): Promise<any> {
const authFileExist = await fileExist(config.authConfigFile);
if (!authFileExist) {
fs.writeFileSync(
config.authConfigFile,
JSON.stringify({
username: 'admin',
password: 'admin',
}),
);
}
return this.getAuthInfo();
}
public initTwoFactor() {
+6 -5
View File
@@ -3,9 +3,9 @@ COPY package.json .npmrc pnpm-lock.yaml /tmp/build/
RUN set -x \
&& apk update \
&& apk add nodejs npm git \
&& npm i -g pnpm \
&& npm i -g pnpm@8.3.1 \
&& cd /tmp/build \
&& pnpm install --prod
&& pnpm --registry https://registry.npmmirror.com install --prod
FROM python:3.10-alpine
@@ -29,7 +29,6 @@ RUN set -x \
&& apk upgrade \
&& apk --no-cache add -f bash \
coreutils \
moreutils \
git \
curl \
wget \
@@ -41,6 +40,7 @@ RUN set -x \
jq \
openssh \
procps \
netcat-openbsd \
npm \
&& rm -rf /var/cache/apk/* \
&& apk update \
@@ -49,7 +49,8 @@ RUN set -x \
&& git config --global user.email "qinglong@@users.noreply.github.com" \
&& git config --global user.name "qinglong" \
&& git config --global http.postBuffer 524288000 \
&& npm install -g pnpm \
&& npm install -g pnpm@8.3.1 \
&& cd && pnpm config set registry https://registry.npmmirror.com \
&& pnpm add -g pm2 tsx \
&& rm -rf /root/.pnpm-store \
&& rm -rf /root/.local/share/pnpm/store \
@@ -71,7 +72,7 @@ COPY --from=builder /tmp/build/node_modules/. /ql/node_modules/
WORKDIR ${QL_DIR}
HEALTHCHECK --interval=5s --timeout=2s --retries=10 \
HEALTHCHECK --interval=5s --timeout=2s --retries=20 \
CMD curl -sf http://127.0.0.1:5400/api/health || exit 1
ENTRYPOINT ["./docker/docker-entrypoint.sh"]
+14 -18
View File
@@ -10,12 +10,21 @@ echo -e "======================1. 检测配置文件========================\n"
make_dir /etc/nginx/conf.d
make_dir /run/nginx
init_nginx
fix_config
pm2 l &>/dev/null
pm2 flush &>/dev/null
echo -e "======================2. 安装依赖========================\n"
patch_version
if [[ $PipMirror ]]; then
pip3 config set global.index-url $PipMirror
fi
current_npm_registry=$(cd && pnpm config get registry)
is_equal_registry=$(echo $current_npm_registry | grep "${NpmMirror}")
if [[ "$is_equal_registry" == "" ]]; then
cd && pnpm config set registry $NpmMirror
pnpm install -g
fi
update_depend
echo
@@ -23,36 +32,23 @@ echo -e "======================3. 启动nginx========================\n"
nginx -s reload 2>/dev/null || nginx -c /etc/nginx/nginx.conf
echo -e "nginx启动成功...\n"
echo -e "======================4. 启动面板监控========================\n"
pm2 delete public &>/dev/null
pm2 start $dir_static/build/public.js -n public --source-map-support --time
echo -e "监控服务启动成功...\n"
echo -e "======================5. 启动主服务========================\n"
pm2 delete panel &>/dev/null
pm2 start $dir_static/build/app.js -n panel --source-map-support --time
echo -e "主服务启动成功...\n"
echo -e "======================6. 启动定时服务========================\n"
pm2 delete schedule &>/dev/null
pm2 start $dir_static/build/schedule/index.js -n schedule --source-map-support --time
echo -e "定时任务启动成功...\n"
echo -e "======================4. 启动pm2服务========================\n"
reload_pm2
if [[ $AutoStartBot == true ]]; then
echo -e "======================7. 启动bot========================\n"
echo -e "======================5. 启动bot========================\n"
nohup ql -l bot >$dir_log/bot.log 2>&1 &
echo -e "bot后台启动中...\n"
fi
if [[ $EnableExtraShell == true ]]; then
echo -e "======================8. 执行自定义脚本========================\n"
echo -e "====================6. 执行自定义脚本========================\n"
nohup ql -l extra >$dir_log/extra.log 2>&1 &
echo -e "自定义脚本后台执行中...\n"
fi
echo -e "############################################################\n"
echo -e "容器启动成功..."
echo -e "\n请先访问5700端口,登录成功面板之后再执行添加定时任务..."
echo -e "############################################################\n"
crond -f >/dev/null
+3
View File
@@ -22,6 +22,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://publicApi/api/;
proxy_buffering off;
}
location QL_BASE_URL/api/ {
@@ -29,6 +30,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://baseApi/api/;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
@@ -39,6 +41,7 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://baseApi/open/;
proxy_buffering off;
}
gzip on;
+31
View File
@@ -0,0 +1,31 @@
module.exports = {
apps: [
{
name: 'schedule',
max_restarts: 10,
kill_timeout: 15000,
wait_ready: true,
source_map_support: true,
time: true,
script: 'static/build/schedule/index.js',
},
{
name: 'public',
max_restarts: 10,
kill_timeout: 15000,
wait_ready: true,
source_map_support: true,
time: true,
script: 'static/build/public.js',
},
{
name: 'panel',
max_restarts: 10,
kill_timeout: 15000,
wait_ready: true,
source_map_support: true,
time: true,
script: 'static/build/app.js',
},
],
};
+2 -1
View File
@@ -72,6 +72,7 @@
"form-data": "^4.0.0",
"got": "^11.8.2",
"hpagent": "^0.1.2",
"http-proxy-middleware": "^2.0.6",
"iconv-lite": "^0.6.3",
"js-yaml": "^4.1.0",
"jsonwebtoken": "^8.5.1",
@@ -86,7 +87,7 @@
"sequelize": "^6.25.5",
"serve-handler": "^6.1.3",
"sockjs": "^0.3.24",
"sqlite3": "git+https://github.com/whyour/node-sqlite3.git#v1.0.2",
"sqlite3": "git+https://github.com/whyour/node-sqlite3.git#v1.0.3",
"toad-scheduler": "^1.6.0",
"typedi": "^0.10.0",
"uuid": "^8.3.2",
+3013 -2720
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -2,7 +2,7 @@
create_token() {
local token_command="tsx ${dir_root}/back/token.ts"
local token_file="${dir_root}static/build/token.js"
local token_file="${dir_root}/static/build/token.js"
if [[ -f $token_file ]]; then
token_command="node ${token_file}"
fi
+12 -8
View File
@@ -74,19 +74,23 @@ check_pm2() {
fi
}
start_public() {
echo -e "=====> 启动公开服务\n"
pm2 delete public --source-map-support --time &>/dev/null
pm2 start $dir_static/build/public.js -n public --source-map-support --time &>/dev/null
}
main() {
echo -e "=====> 开始检测"
npm i -g pnpm
npm i -g pnpm@8.3.1
patch_version
apk add procps netcat-openbsd
if [[ $PipMirror ]]; then
pip3 config set global.index-url $PipMirror
fi
if [[ $NpmMirror ]]; then
cd && pnpm config set registry $NpmMirror
pnpm install -g
fi
pnpm add -g pm2 tsx
reset_env
start_public
copy_dep
check_ql
check_nginx
+29 -54
View File
@@ -18,6 +18,7 @@ dir_update_log=$dir_log/update
ql_static_repo=$dir_repo/static
## 文件
file_ecosystem_js=$dir_root/ecosystem.config.js
file_config_sample=$dir_sample/config.sample.sh
file_env=$dir_config/env.sh
file_sharecode=$dir_config/sharecode.sh
@@ -98,6 +99,9 @@ set_proxy() {
unset_proxy() {
unset http_proxy
unset https_proxy
unset ftp_proxy
unset all_proxy
unset no_proxy
}
make_dir() {
@@ -262,17 +266,6 @@ npm_install_sub() {
fi
}
npm_install_1() {
local dir_current=$(pwd)
local dir_work=$1
cd $dir_work
echo -e "运行 pnpm install...\n"
npm_install_sub
[[ $? -ne 0 ]] && echo -e "\nnpm install 运行不成功,请进入 $dir_work 目录后手动运行 pnpm install...\n"
cd $dir_current
}
npm_install_2() {
local dir_current=$(pwd)
local dir_work=$1
@@ -280,10 +273,6 @@ npm_install_2() {
cd $dir_work
echo -e "安装 $dir_work 依赖包...\n"
npm_install_sub
if [[ $? -ne 0 ]]; then
echo -e "\n安装 $dir_work 的依赖包运行不成功,再次尝试一遍...\n"
npm_install_1 $dir_work
fi
cd $dir_current
}
@@ -315,11 +304,13 @@ git_clone_scripts() {
echo -e "开始克隆仓库 $url$dir\n"
set_proxy "$proxy"
git clone --depth=1 $part_cmd $url $dir
exit_status=$?
unset_proxy
reset_branch "$branch"
reset_branch "$branch" "$dir"
unset_proxy
}
git_pull_scripts() {
@@ -329,19 +320,25 @@ git_pull_scripts() {
local proxy="$3"
cd $dir_work
echo -e "开始更新仓库:$dir_work"
set_proxy "$proxy"
if [[ ! $branch ]]; then
branch=$(cd $dir_work && git remote show origin | grep 'HEAD branch' | cut -d' ' -f5)
fi
local pre_commit_id=$(git rev-parse --short HEAD)
set_proxy "$proxy"
git fetch --depth=1 --all
git pull --depth=1 &>/dev/null
exit_status=$?
unset_proxy
reset_branch "$branch" "$dir_work"
reset_branch "$branch"
git fetch --depth 1 origin $branch
exit_status=$?
reset_branch "$branch" "$dir_work"
local cur_commit_id=$(git rev-parse --short HEAD)
if [[ $cur_commit_id != $pre_commit_id ]]; then
exit_status=0
fi
unset_proxy
cd $dir_current
}
@@ -359,19 +356,16 @@ reset_romote_url() {
git init
git remote add origin $url &>/dev/null
fi
cd $dir_current
}
reset_branch() {
local branch="$1"
local part_cmd="HEAD"
if [[ $branch ]]; then
part_cmd="origin/${branch}"
git checkout -B "$branch" &>/dev/null
git branch --set-upstream-to=$part_cmd $branch &>/dev/null
fi
local part_cmd="origin/${branch}"
git remote set-branches origin $branch
git reset --hard $part_cmd &>/dev/null
git checkout -b $branch $part_cmd &>/dev/null
}
random_range() {
@@ -381,16 +375,11 @@ random_range() {
}
reload_pm2() {
pm2 l &>/dev/null
cd $dir_root
# 代理会影响 grpc 服务
unset_proxy
pm2 flush &>/dev/null
echo -e "启动面板服务\n"
pm2 delete panel --source-map-support --time &>/dev/null
pm2 start $dir_static/build/app.js -n panel --source-map-support --time &>/dev/null
echo -e "启动定时服务\n"
pm2 delete schedule --source-map-support --time &>/dev/null
pm2 start $dir_static/build/schedule/index.js -n schedule --source-map-support --time &>/dev/null
pm2 startOrGracefulReload $file_ecosystem_js
}
diff_time() {
@@ -440,19 +429,6 @@ format_timestamp() {
}
patch_version() {
# 兼容pnpm@7
pnpm setup &>/dev/null
source ~/.bashrc
apk add procps
if [[ $PipMirror ]]; then
pip3 config set global.index-url $PipMirror
fi
if [[ $NpmMirror ]]; then
cd && pnpm config set registry $NpmMirror
pnpm install -g --force
fi
git config --global pull.rebase false
cp -f $dir_root/.env.example $dir_root/.env
@@ -493,7 +469,7 @@ init_nginx() {
cp -fv $nginx_conf /etc/nginx/nginx.conf
cp -fv $nginx_app_conf /etc/nginx/conf.d/front.conf
sed -i "s,QL_BASE_URL,${qlBaseUrl},g" /etc/nginx/conf.d/front.conf
ipv6=$(ip a | grep inet6)
ipv6Str=""
if [[ $ipv6 ]]; then
@@ -536,6 +512,5 @@ init_env
detect_termux
detect_macos
define_cmd
fix_config
import_config $1 2>$task_error_log_path
+4
View File
@@ -257,6 +257,9 @@ update_qinglong() {
cp -f $file_config_sample $dir_config/config.sample.sh
update_depend
[[ -f $dir_root/package.json ]] && ql_depend_new=$(cat $dir_root/package.json)
[[ "$ql_depend_old" != "$ql_depend_new" ]] && npm_install_2 $dir_root
update_qinglong_static "$1" "$primary_branch"
else
echo -e "\n更新青龙源文件失败,请检查网络...\n"
@@ -467,6 +470,7 @@ main() {
case $p1 in
update)
fix_config
eval update_qinglong "$2" $cmd
;;
extra)
+19 -6
View File
@@ -98,8 +98,7 @@ export default function () {
})
.catch((error) => {
console.log(error);
})
.finally(() => setInitLoading(false));
});
};
const getUser = (needLoading = true) => {
@@ -120,6 +119,22 @@ export default function () {
});
};
const getHealthStatus = () => {
request
.get(`${config.apiPrefix}public/health`)
.then((res) => {
if (res?.data?.status === 1) {
getSystemInfo();
} else {
history.push('/error');
}
})
.catch((error) => {
history.push('/error');
})
.finally(() => setInitLoading(false));
};
const reloadUser = (needLoading = false) => {
getUser(needLoading);
};
@@ -131,10 +146,8 @@ export default function () {
}, [location.pathname]);
useEffect(() => {
if (!systemInfo) {
getSystemInfo();
}
}, [systemInfo]);
getHealthStatus();
}, []);
useEffect(() => {
if (theme === 'vs-dark') {
+1 -1
View File
@@ -246,7 +246,7 @@ const Dependence = () => {
})
.then(({ code, data }) => {
if (code === 200 && force) {
const i = value.findIndex((x) => x.id === data.data[0].id);
const i = value.findIndex((x) => x.id === data[0].id);
if (i !== -1) {
const result = [...value];
result.splice(i, 1);
+1 -1
View File
@@ -394,7 +394,7 @@ const Env = () => {
if (code === 200) {
const newData = [...value];
newData.splice(dragIndex, 1);
newData.splice(hoverIndex, 0, { ...dragRow, ...data.data });
newData.splice(hoverIndex, 0, { ...dragRow, ...data });
setValue([...newData]);
}
});
+4 -2
View File
@@ -13,7 +13,8 @@
.code-box {
position: relative;
display: inline-block;
width: 80%;
width: 80vw;
height: 90vh;
margin: 16px;
background-color: #ffffff;
border: 1px solid rgba(5, 5, 5, 0.06);
@@ -44,9 +45,10 @@
}
.log {
height: calc(100vh - 150px);
height: calc(90vh - 150px);
overflow-y: auto;
padding: 12px;
white-space: pre-line;
}
}
}
+25 -4
View File
@@ -17,7 +17,7 @@ const Error = () => {
needLoading && setLoading(true);
request
.get(`${config.apiPrefix}public/health`)
.then(({ status, error }) => {
.then(({ error, status }) => {
if (status === 1) {
return reloadUser();
}
@@ -27,7 +27,6 @@ const Error = () => {
}
retryTimes.current += 1;
setTimeout(() => {
reloadUser();
getLog(false);
}, 3000);
})
@@ -53,10 +52,32 @@ const Error = () => {
<div className="browser-markup"></div>
<Alert
type="error"
message="服务启动超时,请检查如下日志或者进入容器执行 ql -l check 后刷新再试"
message={
<Typography.Title level={5} type="danger">
</Typography.Title>
}
description={
<Typography.Text type="danger">
<div>
<Typography.Link href="https://github.com/whyour/qinglong/issues/new?assignees=&labels=&template=bug_report.yml">
issue
</Typography.Link>
</div>
<div>
1. 宿 docker run --rm -v
/var/run/docker.sock:/var/run/docker.sock
containrrr/watchtower -cR &lt;&gt;
</div>
<div>2. ql -l checkql -l update</div>
</Typography.Text>
}
banner
/>
<Typography.Paragraph className="log">{data}</Typography.Paragraph>
<Typography.Paragraph code className="log">
{data}
</Typography.Paragraph>
</div>
) : (
<PageLoading tip="启动中,请稍后..." />
+1 -1
View File
@@ -219,7 +219,7 @@ const Initialization = () => {
<Button
type="primary"
onClick={() => {
history.push('/login');
window.location.reload();
}}
>
+1 -1
View File
@@ -91,7 +91,7 @@ export default {
{ value: 'aibotk', label: '智能微秘书' },
{ value: 'iGot', label: 'IGot' },
{ value: 'pushPlus', label: 'PushPlus' },
{ value: 'chat', label: '群chat' },
{ value: 'chat', label: '群chat' },
{ value: 'email', label: '邮箱' },
{ value: 'lark', label: '飞书机器人' },
{ value: 'webhook', label: '自定义通知' },
+4 -10
View File
@@ -1,11 +1,5 @@
version: 2.15.13
changeLogLink: https://t.me/jiao_long/373
version: 2.15.14
changeLogLink: https://t.me/jiao_long/374
changeLog: |
1. 增加运行、停止指定命令接口 system/command-runsystem/command-stop
2. 增加容器健康检查
3. 移除执行任务默认超时时间
4. 修改 task 命令生成日志逻辑和关联任务查询
5. 修复更新任务、环境变量、依赖、订阅状态丢失
6. 修改系统通知错误提示
7. 修复系统通知 gotify 配置
8. 其他 bug 修复
1. 接口 system/command-run 返回响应头 QL-Task-Pidsystem/command-stop 支持 pid 参数
2. 其他 bug 修复