@lazycatcloud/lzc-cli 1.1.7 → 1.1.9

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.
Files changed (105) hide show
  1. package/README.md +69 -11
  2. package/lib/api.js +71 -36
  3. package/lib/app/index.js +79 -23
  4. package/lib/app/lpk_build.js +96 -52
  5. package/lib/app/lpk_create.js +63 -41
  6. package/lib/app/lpk_create_generator.js +202 -0
  7. package/lib/app/lpk_devshell.js +393 -328
  8. package/lib/app/lpk_devshell_docker.js +211 -0
  9. package/lib/app/lpk_installer.js +63 -26
  10. package/lib/app/lpk_log.js +68 -0
  11. package/lib/app/lpk_status.js +18 -0
  12. package/lib/app/lpk_uninstall.js +19 -0
  13. package/lib/appstore/index.js +37 -0
  14. package/lib/appstore/login.js +137 -0
  15. package/lib/appstore/publish.js +62 -0
  16. package/lib/autologin.js +0 -80
  17. package/lib/box/api/clientapi.js +1322 -0
  18. package/lib/box/api/empty.js +35 -0
  19. package/lib/box/check_qemu.js +1 -0
  20. package/lib/box/index.js +41 -94
  21. package/lib/box/qemu_vm_mgr.js +208 -239
  22. package/lib/box/schemes/vm_box_system_debian.json +1 -1
  23. package/lib/docker-compose.js +1 -2
  24. package/lib/env.js +23 -142
  25. package/lib/key.js +1 -0
  26. package/lib/sdk.js +10 -25
  27. package/lib/utils.js +156 -233
  28. package/package.json +19 -11
  29. package/scripts/cli.js +14 -135
  30. package/template/_lpk/README.md +31 -0
  31. package/template/_lpk/exec.sh +19 -0
  32. package/template/_lpk/golang.manifest.yml.in +16 -0
  33. package/template/_lpk/lazycat.png +0 -0
  34. package/template/_lpk/lite.manifest.yml.in +19 -0
  35. package/template/_lpk/local_devshell/Dockerfile +16 -0
  36. package/template/_lpk/local_devshell/build.sh +5 -0
  37. package/template/_lpk/local_devshell/entrypoint.sh +87 -0
  38. package/template/{_lazycat/debug/shell → _lpk/local_devshell}/sshd_config +8 -8
  39. package/template/_lpk/manifest.yml.in +0 -1
  40. package/template/{vue/lzc-build.yml → _lpk/vue.lzc-build.yml.in} +9 -1
  41. package/template/golang/README.md +0 -2
  42. package/template/golang/_gitignore +2 -0
  43. package/template/golang/build.sh +6 -0
  44. package/template/golang/lazycat.png +0 -0
  45. package/template/golang/lzc-build.yml +9 -1
  46. package/template/golang/rego.go +15 -16
  47. package/template/golang/rego_test.go +13 -0
  48. package/template/ionic_vue3/lazycat.png +0 -0
  49. package/template/ionic_vue3/lzc-build.yml +9 -1
  50. package/template/lite/error_pages/502.html.tpl +13 -0
  51. package/template/lite/lazycat.png +0 -0
  52. package/template/lite/lzc-build.yml +60 -0
  53. package/cmds/app.js +0 -133
  54. package/cmds/config.js +0 -55
  55. package/cmds/create.js +0 -55
  56. package/cmds/dev.js +0 -130
  57. package/cmds/init.js +0 -125
  58. package/cmds/log.js +0 -103
  59. package/cmds/publish.js +0 -116
  60. package/lib/archiver.js +0 -105
  61. package/lib/box/hportal.js +0 -120
  62. package/lib/builder.js +0 -313
  63. package/lib/dev.js +0 -314
  64. package/lib/generator.js +0 -146
  65. package/template/_lazycat/_gitignore +0 -1
  66. package/template/_lazycat/app-config +0 -1
  67. package/template/_lazycat/debug/devforward/50x.html +0 -30
  68. package/template/_lazycat/debug/devforward/Dockerfile +0 -16
  69. package/template/_lazycat/debug/devforward/docker-compose.override.yml.in +0 -11
  70. package/template/_lazycat/debug/devforward/entrypoint.sh +0 -10
  71. package/template/_lazycat/debug/devforward/nginx.conf.template +0 -56
  72. package/template/_lazycat/debug/devforward/sshd_config +0 -116
  73. package/template/_lazycat/debug/shell/50x.html +0 -32
  74. package/template/_lazycat/debug/shell/Dockerfile +0 -18
  75. package/template/_lazycat/debug/shell/build.sh +0 -15
  76. package/template/_lazycat/debug/shell/docker-compose.override.yml.in +0 -13
  77. package/template/_lazycat/debug/shell/entrypoint.sh +0 -12
  78. package/template/_lazycat/docker-compose.yml.in +0 -15
  79. package/template/_lazycat/icon.svg +0 -1
  80. package/template/_lazycat/screenshot.png +0 -0
  81. package/template/_lpk/sync/Dockerfile +0 -16
  82. package/template/_lpk/sync/build.sh +0 -5
  83. package/template/_lpk/sync/entrypoint.sh +0 -8
  84. package/template/_lpk/sync/sshd_config +0 -117
  85. package/template/_lpk/sync.manifest.yml.in +0 -3
  86. package/template/release/golang/Dockerfile +0 -18
  87. package/template/release/golang/build.sh +0 -13
  88. package/template/release/ionic_vue3/Dockerfile +0 -10
  89. package/template/release/ionic_vue3/build.sh +0 -7
  90. package/template/release/ionic_vue3/docker-compose.yml.in +0 -3
  91. package/template/release/vue/Dockerfile +0 -10
  92. package/template/release/vue/build.sh +0 -10
  93. package/template/release/vue/docker-compose.yml.in +0 -3
  94. package/template/vue/README.md +0 -29
  95. package/template/vue/_dockerignore +0 -1
  96. package/template/vue/babel.config.js +0 -3
  97. package/template/vue/package.json +0 -43
  98. package/template/vue/public/favicon.ico +0 -0
  99. package/template/vue/public/index.html +0 -33
  100. package/template/vue/src/App.vue +0 -39
  101. package/template/vue/src/main.js +0 -8
  102. package/template/vue/src/todo.vue +0 -640
  103. package/template/vue/src/top-bar.vue +0 -100
  104. package/template/vue/src/webdav.vue +0 -183
  105. package/template/vue/vue.config.js +0 -21
@@ -0,0 +1,60 @@
1
+ # 整个文件中,可以通过 ${var} 的方式,使用 manifest.yml 文件中定义的值
2
+
3
+ # buildscript
4
+ # - 可以为构建脚本的路径地址
5
+ # - 如果构建命令简单,也可以直接写 sh 的命令
6
+ # buildscript: ./build.sh
7
+
8
+ # manifest: 指定 lpk 包的 manifest.yml 文件路径
9
+ # manifest: ./lzc-manifest.yml
10
+
11
+ # contentdir: 指定打包的内容,将会打包到 lpk 中
12
+ contentdir: ./error_pages
13
+
14
+ # pkgout: lpk 包的输出路径
15
+ pkgout: ./
16
+
17
+ # icon 指定 lpk 包 icon 的路径路径,如果不指定将会警告
18
+ # icon 仅仅允许 png 后缀的文件
19
+ icon: ./lazycat.png
20
+
21
+ # devshell 自定义应用的开发容器环境
22
+ # - routers 指定应用容器的访问路由
23
+
24
+ # devshell 没有指定 image 的情况,将会默认使用 registry.lazycat.cloud/lzc-cli/devshell:latest
25
+ # devshell:
26
+ # routers:
27
+ # - /=http://127.0.0.1:8080
28
+
29
+ # devshell 指定 image 的情况
30
+ # devshell:
31
+ # routes:
32
+ # - /=http://127.0.0.1:3000
33
+ # image: registry.lazycat.cloud/lzc-cli/devshell:0.0.4
34
+
35
+ # devshell 指定构建Dockerfile
36
+ # image 字段如果没有定义,将默认使用 ${package}-devshell:${version}
37
+ # devshell:
38
+ # routes:
39
+ # - /=http://127.0.0.1:3000
40
+ # image: ${package}-devshell:${version}
41
+ # pull_policy: build
42
+ # build: .
43
+
44
+ # dvshell 指定开发依赖的情况
45
+ # 这种情况下,选用 apline:3.16 作为基础镜像,在 dependencies 中添加所需要的开发依赖即可
46
+ # 如果 dependencies 和 build 同时存在,将会优先使用 dependencies
47
+ # devshell:
48
+ # routes:
49
+ # - /=http://127.0.0.1:3000
50
+ # dependencies:
51
+ # - go
52
+ # - vim
53
+ # # setupscript 每次进入到app container后都会执行的配置脚本
54
+ # # - 可以为脚本的路径地址
55
+ # # - 如果构建命令简单,也可以直接写 sh 的命令
56
+ # # setupscript: export GOPROXY=https://goproxy.cn
57
+ # # setupscript: ./setupscript.sh
58
+ # setupscript: |
59
+ # export GOPROXY=https://goproxy.cn
60
+ # export npm_config_registry=https://registry.npmmirror.com
package/cmds/app.js DELETED
@@ -1,133 +0,0 @@
1
- import process from "process";
2
- import path from "path";
3
- import {
4
- archiveFolder,
5
- isValidApp,
6
- getMetaInfo,
7
- ensureDir,
8
- } from "../lib/utils.js";
9
- import fs from "fs";
10
- import chalk from "chalk";
11
- import Builder, { execPreBuild } from "../lib/builder.js";
12
- import env, { sdkEnv } from "../lib/env.js";
13
- import BoxAPI from "../lib/api.js";
14
- import Archiver from "../lib/archiver.js";
15
- import Key from "../lib/key.js";
16
-
17
- // this set of api target box
18
- class App {
19
- constructor(context) {
20
- this.context = context;
21
-
22
- const { appDir, isTemplate } = isValidApp(process.cwd());
23
- if (!appDir) {
24
- console.log(chalk.red("未识别懒猫云应用"));
25
- process.exit(1);
26
- }
27
- this.appPath = appDir;
28
- this.isTemplate = isTemplate;
29
- env.load(process.cwd());
30
- }
31
-
32
- async deploy() {
33
- try {
34
- if (this.isTemplate) {
35
- const outDir = await this.prepare();
36
-
37
- await this.archiveAndInstall(outDir);
38
- } else {
39
- await sdkEnv.ensure();
40
-
41
- await this.archiveAndInstall(this.appPath);
42
- }
43
- } catch (e) {
44
- throw e;
45
- }
46
- }
47
-
48
- async uninstall() {
49
- let api;
50
- const sdkUrl = sdkEnv.sdkUrl;
51
- if (this.isTemplate) {
52
- api = new BoxAPI(env.get("APP_ID"), sdkUrl);
53
- } else {
54
- const metaInfo = getMetaInfo(
55
- path.join(this.appPath, "docker-compose.yml")
56
- );
57
- api = new BoxAPI(metaInfo.id, sdkUrl);
58
- }
59
-
60
- try {
61
- await api.uninstall();
62
- } catch (e) {
63
- throw e;
64
- }
65
- }
66
-
67
- async prepare() {
68
- await this.prepareBuildEnv();
69
-
70
- const outputDir = path.join(this.appPath, "output/release/");
71
- const buildDir = path.join(process.cwd(), env.get("BUILD_CONTEXT"));
72
-
73
- ensureDir(outputDir);
74
-
75
- await new Key().ensure(sdkEnv.sdkUrl);
76
-
77
- const envAll = {
78
- ...env.all,
79
- APP_IMAGE_NAME: env.get("APP_ID"),
80
- };
81
-
82
- // exec pre build
83
- await execPreBuild(buildDir, process.cwd(), envAll);
84
-
85
- // do image build
86
- await new Builder(envAll).buildImage(process.cwd(), buildDir);
87
-
88
- // do archive
89
- const archiver = new Archiver(outputDir);
90
- console.log("appPath", this.appPath);
91
- await archiver.load(this.appPath);
92
- await archiver.add(buildDir);
93
-
94
- await archiver.finalize();
95
-
96
- return outputDir;
97
- }
98
-
99
- async prepareBuildEnv() {
100
- await sdkEnv.ensure();
101
- await env.ensure([{ name: "HTTP_SERVICE_PORT" }]);
102
- }
103
-
104
- // archive current dir and install
105
- async archiveAndInstall(dir) {
106
- const metaInfo = getMetaInfo(path.join(dir, "docker-compose.yml"));
107
- const api = new BoxAPI(metaInfo.id, sdkEnv.sdkUrl);
108
- let out;
109
- try {
110
- const out = await archiveFolder(dir);
111
- console.log(chalk.green("开始部署应用"));
112
- await api.applyZip(out.path);
113
- await api.checkStatus();
114
-
115
- console.log(
116
- `请在浏览器中访问 ${chalk.green(
117
- sdkEnv.sdkUrl.replace(/sdk/, metaInfo.id)
118
- )}`
119
- );
120
- } catch (e) {
121
- throw e;
122
- } finally {
123
- if (out) fs.rmSync(out.path, { recursive: true });
124
- }
125
- }
126
- }
127
-
128
- const app = new App();
129
-
130
- export default {
131
- deploy: () => app.deploy(),
132
- uninstall: () => app.uninstall(),
133
- };
package/cmds/config.js DELETED
@@ -1,55 +0,0 @@
1
- import process from "process";
2
- import { isValidApp } from "../lib/utils.js";
3
- import env, { sdkEnv } from "../lib/env.js";
4
- import { debuglog } from "util";
5
-
6
- const debug = debuglog("cmd/config");
7
-
8
- class Config {
9
- constructor(context) {
10
- this.context = context;
11
- }
12
- async exec() {
13
- const [key, value, options] = this.context;
14
-
15
- isValidApp(process.cwd());
16
- env.load(process.cwd());
17
-
18
- // // lzc-cli config
19
- if (!key && !value) {
20
- console.log(env.stringify());
21
- return;
22
- }
23
-
24
- // lzc-cli config SDK_URL
25
- if (key && !value) {
26
- if (env.get(key)) {
27
- console.log(env.get(key));
28
- }
29
- return;
30
- }
31
-
32
- if (key && value) {
33
- const pair = Object.fromEntries([[key, value]]);
34
- // if (pair["SDK_URL"]) {
35
- // pair["SDK_URL"] = pair["SDK_URL"].replace(/\/$/, "");
36
- //
37
- // try {
38
- // // 这里只需要测试sdk的合法性即可, 不需要处理安装的逻辑
39
- // await sdkEnv.checkConnection(pair["SDK_URL"]);
40
- // } catch (e) {
41
- // console.log(e.message);
42
- // debug("got error when check connection %s", e);
43
- // process.exit();
44
- // }
45
- // }
46
- env.set(pair, options.global);
47
- }
48
- }
49
- }
50
-
51
- export default {
52
- config: async (context) => {
53
- return await new Config(context).exec();
54
- },
55
- };
package/cmds/create.js DELETED
@@ -1,55 +0,0 @@
1
- import chalk from "chalk";
2
- import { Init, chooseTemplate } from "./init.js";
3
- import path from "path";
4
- import Generator, { TemplateConfig } from "../lib/generator.js";
5
- import fs from "fs";
6
- import inquirer from "inquirer";
7
- import { parse2CorrectName } from "../lib/utils.js";
8
- const fsPromises = fs.promises;
9
- class Create {
10
- constructor({ name }) {
11
- this.name = name;
12
- }
13
-
14
- async exec() {
15
- const type = await chooseTemplate();
16
- this.init = new Init({
17
- cwd: path.join(process.cwd(), this.name),
18
- type: type,
19
- });
20
- if (TemplateConfig[type]) {
21
- const config = TemplateConfig[type];
22
- const init = this.init;
23
- const answers = await init.askQuestions();
24
- console.log(chalk.green(`初始化项目 ${this.name}`));
25
- await Generator().generate(type, this.name);
26
- console.log(chalk.green("设置懒猫云应用"));
27
- await init.createTemplates(answers);
28
- await init.createReleaseFolder();
29
- await config.after(this.name);
30
- }
31
- }
32
- }
33
-
34
- export default async (context) => {
35
- context.name = parse2CorrectName(context.name);
36
- await fsPromises.access(process.cwd() + "/" + context.name).then(
37
- async () => {
38
- const questions = [
39
- {
40
- name: "override",
41
- type: "input",
42
- default: "n",
43
- message: "项目已存在,是否覆盖(y/n): ",
44
- },
45
- ];
46
- const answers = await inquirer.prompt(questions);
47
- if (answers.override.toLowerCase() === "y") {
48
- return new Create(context).exec();
49
- }
50
- },
51
- () => {
52
- return new Create(context).exec();
53
- }
54
- );
55
- };
package/cmds/dev.js DELETED
@@ -1,130 +0,0 @@
1
- import process from "process";
2
- import { isValidApp } from "../lib/utils.js";
3
- import chalk from "chalk";
4
- import Dev from "../lib/dev.js";
5
- import env, { sdkEnv } from "../lib/env.js";
6
- import BoxAPI from "../lib/api.js";
7
- import { dockerPullLzcAppsImage } from "../lib/sdk.js";
8
- import Key from "../lib/key.js";
9
- import logger from "loglevel";
10
-
11
- // this set of api target box
12
- class Develop {
13
- constructor(context) {
14
- this.context = context;
15
-
16
- const { appDir, isTemplate } = isValidApp(process.cwd());
17
- if (!appDir) {
18
- console.log(chalk.red("未识别懒猫云应用"));
19
- process.exit(1);
20
- }
21
-
22
- this.appPath = appDir;
23
- this.isTemplate = isTemplate;
24
- env.load(process.cwd());
25
- }
26
-
27
- async devShell({ build }) {
28
- let appdev = new Dev(env.get("APP_ID"), this.appPath);
29
-
30
- await sdkEnv.ensure();
31
-
32
- // 确保 sdk 能通过公钥正常访问
33
- await new Key().ensure(sdkEnv.sdkUrl);
34
-
35
- if (build) {
36
- appdev.reset();
37
- await dockerPullLzcAppsImage(sdkEnv.sdkHostName);
38
- }
39
-
40
- // 当如果已经连接。直接连接ssh
41
- if (appdev.hasShellStatus()) {
42
- try {
43
- await appdev.directShell();
44
- return;
45
- } catch (e) {
46
- return Promise.reject(e);
47
- }
48
- }
49
-
50
- // 重新部署dev app container
51
- try {
52
- const { APP_ID: appId } = await env.ensure([{ name: "APP_ID" }]);
53
-
54
- logger.debug(sdkEnv.sdkUrl);
55
- const api = new BoxAPI(appId, sdkEnv.sdkUrl);
56
-
57
- let out = await appdev.fakeApp("shell");
58
-
59
- logger.debug("设置端口转发");
60
- await api.applyZip(out.path, { build: true });
61
- await api.checkStatus();
62
-
63
- await appdev.shell();
64
- return;
65
- } catch (e) {
66
- return Promise.reject(e);
67
- }
68
- }
69
-
70
- async devPortForward(localaddr) {
71
- console.log("逻辑需要重新梳理");
72
- process.exit();
73
- // try {
74
- // await this.ensureEnv([
75
- // {
76
- // name: "DEV_PORT",
77
- // type: "input",
78
- // message: "开发暴露端口",
79
- // default: "8080",
80
- // },
81
- // {
82
- // name: "DEV_CMD",
83
- // type: "input",
84
- // default: "npm run serve",
85
- // message: "开发运行命令",
86
- // },
87
- // ]);
88
- //
89
- // await this.ensureSDK();
90
- //
91
- // console.debug(env.get("SDK_URL"));
92
- // const api = new BoxAPI(env.get("APP_ID"), env.get("SDK_URL"));
93
- //
94
- // let appdev = new Dev(env.get("APP_ID"), this.appPath);
95
- //
96
- // let out = await appdev.fakeApp("devforward");
97
- //
98
- // console.debug("设置端口转发");
99
- // await api.install(out.path, { build: true });
100
- // await api.checkStatus();
101
- //
102
- // console.log(
103
- // `请在浏览器中访问 ${chalk.green(
104
- // env.get("SDK_URL").replace(/sdk/, env.get("APP_ID"))
105
- // )}`
106
- // );
107
- //
108
- // await appdev.portForward(localaddr);
109
- // } catch (e) {
110
- // throw e;
111
- // }
112
- }
113
- }
114
-
115
- const dev = new Develop();
116
-
117
- export default {
118
- dev: (addr) => dev.devPortForward(addr),
119
- devShell: async (options) => {
120
- try {
121
- await dev.devShell(options);
122
- } catch (e) {
123
- console.log(chalk.red(e));
124
- process.exit(1);
125
- }
126
-
127
- // 需要显示的退出,因为当shell退出后,rsync和watch的进程还在执行
128
- // process.exit();
129
- },
130
- };
package/cmds/init.js DELETED
@@ -1,125 +0,0 @@
1
- import path from "path";
2
- import inquirer from "inquirer";
3
- import generator, { TemplateConfig } from "../lib/generator.js";
4
- import { APP_FOLDER } from "../lib/utils.js";
5
- import env from "../lib/env.js";
6
- import fs from "fs";
7
- let fsPromises = fs.promises;
8
- import { debuglog } from "util";
9
-
10
- const debug = debuglog("cmd/init");
11
-
12
- export class Init {
13
- constructor(context) {
14
- this.context = context;
15
- this.type = context.type;
16
- }
17
-
18
- async askQuestions() {
19
- const questions = [
20
- {
21
- name: "APP_ID",
22
- type: "input",
23
- default: () => {
24
- const name = path.basename(this.context.cwd);
25
- return name;
26
- },
27
- message: "应用名称",
28
- validate: (input) => {
29
- if (!/^([a-z]|[0-9]|[\-])+$/.test(input)) {
30
- return "应用名称只能包含(减号,小写字母,数字),请重新输入";
31
- }
32
- return true;
33
- },
34
- },
35
- {
36
- name: "APP_DESCRIPTION",
37
- type: "input",
38
- default: (answers) => {
39
- return answers["APP_ID"];
40
- },
41
- message: "应用描述",
42
- },
43
- ];
44
- return inquirer.prompt(questions);
45
- }
46
-
47
- async createTemplates(answers) {
48
- answers["APP_VERSION"] = "0.0.1";
49
- env.load(path.join(this.context.cwd));
50
- await generator(answers).generate(
51
- APP_FOLDER.replace(".", "_"),
52
- this.context.cwd,
53
- {
54
- prefix: APP_FOLDER,
55
- }
56
- );
57
- debug(answers);
58
- env.set(answers);
59
- this.setDefaultEnvs(env);
60
- }
61
-
62
- async createReleaseFolder() {
63
- await generator({}).generate(
64
- "release/" + this.type,
65
- path.join(this.context.cwd, APP_FOLDER),
66
- {
67
- prefix: "release",
68
- }
69
- );
70
- }
71
-
72
- async setDefaultEnvs(env) {
73
- debug(TemplateConfig[this.type].defaultEnvs);
74
- env.set(TemplateConfig[this.type].defaultEnvs);
75
- }
76
-
77
- async create() {
78
- if (!this.type) {
79
- this.type = await chooseTemplate();
80
- }
81
- const createConfig = async () => {
82
- const answers = await this.askQuestions();
83
- await this.createTemplates(answers);
84
- await this.createReleaseFolder();
85
- };
86
- // .lazycat文件已存在时提示用户是否需要覆盖
87
- await fsPromises
88
- .access(
89
- this.context.cwd + "/.lazycat/",
90
- fs.constants.F_OK | fs.constants.W_OK
91
- )
92
- .then(
93
- async () => {
94
- const questions = [
95
- {
96
- name: "override",
97
- type: "input",
98
- default: "n",
99
- message: "懒猫云已配置,是否覆盖(y/n): ",
100
- },
101
- ];
102
- const answers = await inquirer.prompt(questions);
103
- if (answers.override.toLowerCase() === "y") {
104
- createConfig();
105
- }
106
- },
107
- async () => {
108
- createConfig();
109
- }
110
- );
111
- }
112
- }
113
-
114
- export async function chooseTemplate() {
115
- return (
116
- await inquirer.prompt([
117
- {
118
- name: "type",
119
- message: "选择项目构建模板",
120
- type: "list",
121
- choices: ["vue", "golang", "ionic_vue3"],
122
- },
123
- ])
124
- )["type"];
125
- }
package/cmds/log.js DELETED
@@ -1,103 +0,0 @@
1
- import { readFileSync } from "fs";
2
- import { Client } from "ssh2";
3
- import os from "os";
4
- import path from "path";
5
- import process from "process";
6
- import { isValidApp, META_MARK } from "../lib/utils.js";
7
- import yaml from "js-yaml";
8
- import env, { sdkEnv } from "../lib/env.js";
9
- import chalk from "chalk";
10
- import { SSHClient, connectOptions } from "../lib/sdk.js";
11
-
12
- function StreamPromise(stream) {
13
- let data = "";
14
- return new Promise((resolve, reject) => {
15
- stream
16
- .on("data", (d) => {
17
- data = d;
18
- })
19
- .on("close", (code, signal) => {
20
- resolve(String(data));
21
- })
22
- .stderr.on("data", (data) => {
23
- reject(String(data));
24
- });
25
- });
26
- }
27
-
28
- export async function monitor(projectName, options = {}) {
29
- env.load(process.cwd());
30
-
31
- await sdkEnv.ensure();
32
-
33
- const sdk_url = sdkEnv.sdkUrl;
34
-
35
- if (!sdk_url) {
36
- console.log(chalk.red("无法连接SDK, 请确保已设置 DEFAULT_BOXNAME"));
37
- process.exit(1);
38
- }
39
-
40
- const host = new URL(sdk_url).hostname;
41
- if (projectName) {
42
- await new Log(host, projectName).start();
43
- } else {
44
- const name = tryGuessProject(options.user);
45
- // console.log(chalk.green("guess project name " + name));
46
- await new Log(host, name).start();
47
- }
48
- }
49
-
50
- function tryGuessProject(user) {
51
- const { appDir, isTemplate } = isValidApp(process.cwd());
52
- if (!appDir) {
53
- console.log(chalk.red("无法识别为懒猫云应用"));
54
- process.exit(1);
55
- }
56
-
57
- let info;
58
- let appId;
59
- if (isTemplate) {
60
- info = yaml.load(readFileSync(path.join(appDir, "docker-compose.yml.in")));
61
- appId = env.get("APP_ID");
62
- } else {
63
- info = yaml.load(readFileSync(path.join(appDir, "docker-compose.yml")));
64
- appId = info[META_MARK]["id"];
65
- }
66
- return `lzc-${user || ""}-${appId}`;
67
- }
68
-
69
- class Log {
70
- constructor(host, project) {
71
- this.project = project;
72
- this.host = host;
73
- }
74
-
75
- async start() {
76
- const opts = await connectOptions(this.host);
77
- const client = new SSHClient(opts);
78
- try {
79
- await client.connect();
80
- let stream = await client.exec(
81
- `docker-compose ls | grep -wE '^${this.project}'`
82
- );
83
-
84
- const result = await StreamPromise(stream);
85
- if (result != "") {
86
- stream = await client.exec(
87
- `docker-compose -p ${this.project} logs -f`,
88
- { pty: true }
89
- );
90
- stream.stdout.pipe(process.stdout);
91
- stream.stderr.pipe(process.stdout);
92
- } else {
93
- client.close();
94
- }
95
- } catch (e) {
96
- client.close();
97
- }
98
- }
99
- }
100
-
101
- export default {
102
- monitor,
103
- };