From 2e5d524443dc6860a5ec1fa95093b969a4bde3ef Mon Sep 17 00:00:00 2001 From: zuoxiaobai Date: Mon, 3 Oct 2022 00:36:06 +0800 Subject: [PATCH 01/12] =?UTF-8?q?feat(v1.0.0):=20linux=20=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E9=9D=A2=E6=9D=BF=E6=94=B9=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/args.json | 1 + demo/deploy.sh | 2 + demo/temp.sh | 1 + demo/test.sh | 1 + frontend/admin.html | 270 +++++++++++++++++++++++++++++++++++++++++ index.js | 5 +- package.json | 2 +- server/index.js | 142 +++++++++++++++++++++- server/utils/runCmd.js | 17 ++- servertemp.sh | 2 + v1.0.0.md | 15 +++ 11 files changed, 451 insertions(+), 7 deletions(-) create mode 100644 demo/args.json create mode 100644 demo/deploy.sh create mode 100644 demo/temp.sh create mode 100644 demo/test.sh create mode 100644 frontend/admin.html create mode 100644 servertemp.sh create mode 100644 v1.0.0.md diff --git a/demo/args.json b/demo/args.json new file mode 100644 index 0000000..8b9bcb5 --- /dev/null +++ b/demo/args.json @@ -0,0 +1 @@ +{"port":7777,"password":"888888"} \ No newline at end of file diff --git a/demo/deploy.sh b/demo/deploy.sh new file mode 100644 index 0000000..91437ff --- /dev/null +++ b/demo/deploy.sh @@ -0,0 +1,2 @@ +git pull +npm run build diff --git a/demo/temp.sh b/demo/temp.sh new file mode 100644 index 0000000..3fbb950 --- /dev/null +++ b/demo/temp.sh @@ -0,0 +1 @@ +ls \ No newline at end of file diff --git a/demo/test.sh b/demo/test.sh new file mode 100644 index 0000000..f748bdd --- /dev/null +++ b/demo/test.sh @@ -0,0 +1 @@ +pwd diff --git a/frontend/admin.html b/frontend/admin.html new file mode 100644 index 0000000..c8ffeb3 --- /dev/null +++ b/frontend/admin.html @@ -0,0 +1,270 @@ + + + + + + + + zuo-deploy + + + + + + + + + + + + + +
+ + +
+ + + + +
+ +
+
+ + 运行 +
+
+
+

日志:

+ 清除日志 +
+
+
+            
{{text}}
+
+
+
+
+
+ + +
+
+ 运行当前脚本 {{shellList[curShellTabIndex].name}} + 新增脚本 +
+
+ + + +
+
+
{{shellList[curShellTabIndex].content}}
+
+
+ 新增 +
+
+
+

日志:

+ 清除日志 +
+
+
+            
{{text}}
+
+
+
+
+
+
+ + + + + + \ No newline at end of file diff --git a/index.js b/index.js index 4c1b9ff..9b4dde0 100644 --- a/index.js +++ b/index.js @@ -10,13 +10,16 @@ class ZuoDeploy { fs.writeFileSync("args.json", JSON.stringify(args)); // 删除原先的服务 runCmd("pm2", ["delete", "zuodeploy"], () => {}); - // 防止异步并行,sleep 1s + // // 防止异步并行,sleep 1s await new Promise((resolve) => setTimeout(resolve, 1000)); // 开启 pm2 服务 const argv = ["start", __dirname + "/server/index.js", "-n", "zuodeploy"]; runCmd("pm2", argv, (text) => { logger.log(text); }); + // runCmd("node", [__dirname + "/server/index.js"], (text) => { + // logger.log(text); + // }); } } diff --git a/package.json b/package.json index 62003d8..eb5854d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zuo-deploy", - "version": "0.3.2", + "version": "1.0.0", "description": "CI CD server", "main": "index.js", "scripts": { diff --git a/server/index.js b/server/index.js index 3126d4c..09c5dad 100644 --- a/server/index.js +++ b/server/index.js @@ -91,7 +91,147 @@ router.post("/deploy", async (ctx) => { function (text) { resolve(text); }, - socketIo + socketIo, + "deploy-log" + ); + } catch (e) { + logger.info(e); + reject(e); + } + }); + }; + + try { + let res = await execFunc(); + ctx.body = { + code: 0, + msg: res, + }; + } catch (e) { + ctx.body = { + code: -1, + msg: e.message, + }; + } +}); + +router.post("/runShell", async (ctx) => { + if (!ctx.session.isLogin) { + ctx.body = { + code: -2, + msg: "未登录", + }; + return; + } + + let { shellText, shellName = "temp.sh" } = ctx.request.body; + const shellFilePath = process.cwd() + "/" + shellName; + console.log("shellFilePath", shellFilePath); + try { + fs.writeFileSync(shellFilePath, shellText); + } catch (e) { + console.log(e); + } + + // // 执行部署脚本 + // // koa 注意异步 404 的问题 + let execFunc = () => { + return new Promise((resolve, reject) => { + try { + runCmd( + "sh", + [shellFilePath], + function (text) { + resolve(text); + }, + socketIo, + "runShell" + ); + } catch (e) { + logger.info(e); + reject(e); + } + }); + }; + + try { + let res = await execFunc(); + ctx.body = { + code: 0, + msg: res, + }; + } catch (e) { + ctx.body = { + code: -1, + msg: e.message, + }; + } +}); + +router.get("/shell/get", async (ctx) => { + if (!ctx.session.isLogin) { + ctx.body = { + code: -2, + msg: "未登录", + }; + return; + } + + const files = fs.readdirSync(`${process.cwd()}`); + let result = []; + // files [ 'args.json', 'temp.sh', 'test.sh' ] + files + .filter((item) => !["args.json", "temp.sh"].includes(item)) + .forEach((filePath) => { + let info = { name: filePath, content: "", desc: "" }; + const content = fs + .readFileSync(`${process.cwd()}/${filePath}`) + .toString(); + info.content = content; + result.push(info); + }); + + // [ + // { name: "1.sh", content: "ls\npwd\n", desc: "定时任务" }, + // { + // name: "2.sh", + // content: "git pull;\n npm i && npm run build\n", + // desc: "项目部署", + // }, + // ], + ctx.body = { + code: 0, + data: result, + msg: "成功", + }; +}); + +router.post("/runCurShell", async (ctx) => { + if (!ctx.session.isLogin) { + ctx.body = { + code: -2, + msg: "未登录", + }; + return; + } + + let { name } = ctx.request.body; + const shellFilePath = process.cwd() + "/" + name; + console.log("cur shellFilePath", shellFilePath); + + // // 执行部署脚本 + // // koa 注意异步 404 的问题 + let execFunc = () => { + return new Promise((resolve, reject) => { + try { + runCmd( + "sh", + [shellFilePath], + function (text) { + resolve(text); + }, + socketIo, + "shell-log-" + name ); } catch (e) { logger.info(e); diff --git a/server/utils/runCmd.js b/server/utils/runCmd.js index f68365c..036d1fb 100644 --- a/server/utils/runCmd.js +++ b/server/utils/runCmd.js @@ -1,18 +1,27 @@ +const fs = require("fs"); const logger = require("./logger"); // 使用子进程执行命令 -function runCmd(cmd, args, callback, socketIo) { +function runCmd(cmd, args, callback, socketIo, msgTag = "common-msg") { const spawn = require("child_process").spawn; const child = spawn(cmd, args); let resp = "当前执行路径:" + process.cwd() + "\n"; logger.info(resp); - socketIo && socketIo.emit("deploy-log", resp); + socketIo && socketIo.emit(msgTag, resp); + let shellCmd = cmd + " " + args + "\n"; + let shellText = args[0].includes(".sh") + ? fs.readFileSync(args[0] || "").toString() + : ""; + socketIo && socketIo.emit(msgTag, `开始执行脚本: ${shellCmd}`); + socketIo && socketIo.emit(msgTag, `@start 脚本内容-------`); + socketIo && socketIo.emit(msgTag, shellText); + socketIo && socketIo.emit(msgTag, `@end 脚本内容-------`); child.stdout.on("data", (buffer) => { let info = buffer.toString(); info = `${new Date().toLocaleString()}: ${info}`; resp += info; logger.info(info); - socketIo && socketIo.emit("deploy-log", info); + socketIo && socketIo.emit(msgTag, info); // log 较多时,怎么实时将消息通过接口返给前端,只能是 socket ? // 除了 socket 怎么将 log 数据一点点通过接口传给前端 }); @@ -27,7 +36,7 @@ function runCmd(cmd, args, callback, socketIo) { info = `${new Date().toLocaleString()}: ${info}`; resp += info; logger.info(info); - socketIo && socketIo.emit("deploy-log", info); + socketIo && socketIo.emit(msgTag, info); }); child.stderr.on("end", function () { callback(resp); diff --git a/servertemp.sh b/servertemp.sh new file mode 100644 index 0000000..e2f58e1 --- /dev/null +++ b/servertemp.sh @@ -0,0 +1,2 @@ +ls +pwd \ No newline at end of file diff --git a/v1.0.0.md b/v1.0.0.md new file mode 100644 index 0000000..c17c039 --- /dev/null +++ b/v1.0.0.md @@ -0,0 +1,15 @@ +# v1.0.0 TODO + +## v0.3.2 的缺点 + +- 在一个 linux 服务器只能运行在一个项目下,多项目会有问题,仅支持执行当前目录下 deploy-master.sh 脚本 +- 不支持修改服务器 nginx 配置 +- 不支持实时修改 shell 脚本。需要先在项目中修改在提交 git,服务器拉取再次执行才能生效 + +## TODO + +- 为了保证端口不被占用,先 pm2 delete 服务,但如果之前就没有,pm2 delete 会报错 +- 支持多项目部署,与多个项目保持独立,独立于一个文件夹 +- 支持动态修改 shell 脚本,指定执行的 shell 文件,增删查改 +- 支持 nginx 配置文件的增删查改 +- shell 取消执行 From 12846e0fd1ed280d843f142152ee5106458ddefa Mon Sep 17 00:00:00 2001 From: zuoxiaobai Date: Tue, 4 Oct 2022 01:23:52 +0800 Subject: [PATCH 02/12] =?UTF-8?q?feat(v1.0.1):=20shell=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=96=B0=E5=A2=9E,=E4=BF=AE=E6=94=B9,=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/b.sh | 2 + demo/c.sh | 1 + demo/temp.sh | 2 +- demo/test.sh | 1 - frontend/admin.html | 178 ++++++++++++++++++++++++++++++++++++++++---- package.json | 2 +- server/index.js | 94 +++++++++++++++++++++++ 7 files changed, 262 insertions(+), 18 deletions(-) create mode 100644 demo/b.sh create mode 100644 demo/c.sh delete mode 100644 demo/test.sh diff --git a/demo/b.sh b/demo/b.sh new file mode 100644 index 0000000..0979b00 --- /dev/null +++ b/demo/b.sh @@ -0,0 +1,2 @@ +git pull +npm run build \ No newline at end of file diff --git a/demo/c.sh b/demo/c.sh new file mode 100644 index 0000000..013c184 --- /dev/null +++ b/demo/c.sh @@ -0,0 +1 @@ +pwd \ No newline at end of file diff --git a/demo/temp.sh b/demo/temp.sh index 3fbb950..6c4e9b0 100644 --- a/demo/temp.sh +++ b/demo/temp.sh @@ -1 +1 @@ -ls \ No newline at end of file +echo 'ls' > projb.sh \ No newline at end of file diff --git a/demo/test.sh b/demo/test.sh deleted file mode 100644 index f748bdd..0000000 --- a/demo/test.sh +++ /dev/null @@ -1 +0,0 @@ -pwd diff --git a/frontend/admin.html b/frontend/admin.html index c8ffeb3..eb93723 100644 --- a/frontend/admin.html +++ b/frontend/admin.html @@ -83,24 +83,33 @@
- 运行当前脚本 {{shellList[curShellTabIndex].name}} - 新增脚本 + 新增脚本
- + +
+
+ 运行当前脚本 + {{shellList[curShellTabIndex].name}} + 修改 + {{shellList[curShellTabIndex].name}} + 删除 + {{shellList[curShellTabIndex].name}} +
{{shellList[curShellTabIndex].content}}
- 新增 + 新增

日志:

- 清除日志 + 清除日志 +
@@ -110,8 +119,54 @@
         
- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + @@ -107,10 +119,9 @@