@lazycatcloud/lzc-cli 1.1.5 → 1.1.6
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/cmds/app.js +1 -5
- package/cmds/dev.js +11 -5
- package/lib/api.js +21 -7
- package/lib/app/index.js +92 -0
- package/lib/app/lpk_build.js +229 -0
- package/lib/app/lpk_create.js +201 -0
- package/lib/app/lpk_devshell.js +621 -0
- package/lib/app/lpk_installer.js +67 -0
- package/lib/archiver.js +0 -42
- package/lib/autologin.js +84 -0
- package/lib/box/check_qemu.js +39 -16
- package/lib/box/hportal.js +7 -1
- package/lib/box/index.js +7 -6
- package/lib/box/qemu_vm_mgr.js +12 -11
- package/lib/dev.js +0 -4
- package/lib/env.js +9 -5
- package/lib/generator.js +2 -2
- package/lib/sdk.js +5 -6
- package/lib/utils.js +69 -46
- package/package.json +7 -1
- package/scripts/cli.js +91 -12
- package/template/_lazycat/debug/shell/Dockerfile +5 -3
- package/template/_lazycat/debug/shell/docker-compose.override.yml.in +2 -12
- package/template/_lazycat/debug/shell/entrypoint.sh +3 -1
- package/template/_lpk/Dockerfile.in +8 -0
- package/template/_lpk/devshell/Dockerfile +18 -0
- package/template/_lpk/devshell/build.sh +5 -0
- package/template/_lpk/devshell/entrypoint.sh +8 -0
- package/template/_lpk/devshell/sshd_config +117 -0
- package/template/_lpk/manifest.yml.in +17 -0
- package/template/_lpk/sync/Dockerfile +16 -0
- package/template/_lpk/sync/build.sh +5 -0
- package/template/_lpk/sync/entrypoint.sh +8 -0
- package/template/_lpk/sync/sshd_config +117 -0
- package/template/_lpk/sync.manifest.yml.in +3 -0
- package/template/golang/build.sh +6 -0
- package/template/golang/lzc-build.yml +52 -0
- package/template/ionic_vue3/lzc-build.yml +53 -0
- package/template/ionic_vue3/vite.config.ts +1 -1
- package/template/release/golang/build.sh +1 -1
- package/template/release/ionic_vue3/Dockerfile +1 -1
- package/template/release/ionic_vue3/build.sh +1 -3
- package/template/release/ionic_vue3/docker-compose.yml.in +0 -5
- package/template/release/vue/Dockerfile +1 -1
- package/template/release/vue/build.sh +2 -3
- package/template/release/vue/docker-compose.yml.in +0 -5
- package/template/vue/lzc-build.yml +53 -0
- package/template/vue/src/main.js +3 -14
- package/template/vue/vue.config.js +2 -1
- package/template/_lazycat/debug/shell/nginx.conf.template +0 -64
- package/template/vue/src/lzc.js +0 -110
package/lib/archiver.js
CHANGED
|
@@ -94,54 +94,12 @@ class Archiver {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
async finalize(zip = true) {
|
|
97
|
-
// await this._changeContent();
|
|
98
97
|
if (zip) {
|
|
99
98
|
return await archiveFolder(this.tmpDir);
|
|
100
99
|
} else {
|
|
101
100
|
return this.tmpDir;
|
|
102
101
|
}
|
|
103
102
|
}
|
|
104
|
-
//
|
|
105
|
-
// permissions:
|
|
106
|
-
// - lzcapis
|
|
107
|
-
// need REMOVE deprecated
|
|
108
|
-
async _changeContent() {
|
|
109
|
-
let base = new DockerCompose(path.join(this.tmpDir, "docker-compose.yml"));
|
|
110
|
-
base
|
|
111
|
-
.pipe((template) => {
|
|
112
|
-
const meta = template[META_MARK];
|
|
113
|
-
if (
|
|
114
|
-
meta &&
|
|
115
|
-
Array.isArray(meta["permissions"]) &&
|
|
116
|
-
meta["permissions"].includes("lzcapis")
|
|
117
|
-
) {
|
|
118
|
-
template[META_MARK]["ingress"].push({
|
|
119
|
-
service: "lazycat-apis-sidecar",
|
|
120
|
-
port: 8888,
|
|
121
|
-
subdomain: env.get("APP_ID"),
|
|
122
|
-
path: "/lzcapis/",
|
|
123
|
-
auth: "oidc",
|
|
124
|
-
authcallback: "/lzcapis/oidc-callback",
|
|
125
|
-
});
|
|
126
|
-
template["services"]["lazycat-apis-sidecar"] = {
|
|
127
|
-
image: "registry.lazycat.cloud/lazycat-apis-sidecar",
|
|
128
|
-
pull_policy: "always",
|
|
129
|
-
// volumes_from: ["${APP_NAME}:rw"],
|
|
130
|
-
volumes: ["lzcapis-lzcapp:/lzcapp"],
|
|
131
|
-
command: [
|
|
132
|
-
"--client-id=${LAZYCAT_AUTH_OIDC_CLIENT_ID}",
|
|
133
|
-
"--client-secret=${LAZYCAT_AUTH_OIDC_CLIENT_SECRET}",
|
|
134
|
-
"--client-url=https://${LAZYCAT_APP_ORIGIN}/lzcapis/",
|
|
135
|
-
"--issuer=${LAZYCAT_AUTH_OIDC_ISSUER_URL}",
|
|
136
|
-
"--prefix=lzcapis",
|
|
137
|
-
"--fs-root=/lzcapp/documents",
|
|
138
|
-
],
|
|
139
|
-
};
|
|
140
|
-
template["volumes"]["lzcapis-lzcapp"] = null;
|
|
141
|
-
}
|
|
142
|
-
})
|
|
143
|
-
.save();
|
|
144
|
-
}
|
|
145
103
|
}
|
|
146
104
|
|
|
147
105
|
export default Archiver;
|
package/lib/autologin.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import fetch from "node-fetch";
|
|
2
|
+
|
|
3
|
+
// autologin.js 提供一个封装好的 fetch request 请求方法,通过这个中间件,可以不用考虑
|
|
4
|
+
// auth:auto 所做的授权验证。
|
|
5
|
+
let AutoLoginToken = "";
|
|
6
|
+
let AutoLoginFailed = false;
|
|
7
|
+
|
|
8
|
+
function fetchTokenAction(url) {
|
|
9
|
+
return fetch(url).then(async (res) => {
|
|
10
|
+
const body = await res.text();
|
|
11
|
+
const token = body.match(/name=\"token\" value=\"(.*?)\"/i)[1];
|
|
12
|
+
const action = body.match(/action=\"(.*?)\"/i)[1];
|
|
13
|
+
|
|
14
|
+
return { token, action };
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function fetchTokenActionAndRedirect(dataToken, dataAction) {
|
|
19
|
+
return fetch(dataAction, {
|
|
20
|
+
method: "POST",
|
|
21
|
+
body: `token=${dataToken}`,
|
|
22
|
+
redirect: "follow",
|
|
23
|
+
headers: {
|
|
24
|
+
accept:
|
|
25
|
+
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
|
|
26
|
+
"accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
|
|
27
|
+
"content-type": "application/x-www-form-urlencoded",
|
|
28
|
+
},
|
|
29
|
+
}).then(async (res) => {
|
|
30
|
+
let body = await res.text();
|
|
31
|
+
const token = body.match(/name=\"token\" value=\"(.*?)\"/i)[1];
|
|
32
|
+
const action = body.match(/action=\"(.*?)\"/i)[1];
|
|
33
|
+
const redirect = body.match(/name=\"redirect\" value=\"(.*?)\"/i)[1];
|
|
34
|
+
|
|
35
|
+
return { token, action, redirect };
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export async function request(url, options = {}) {
|
|
40
|
+
if (AutoLoginFailed) {
|
|
41
|
+
return fetch(url, options);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
await tryAuthLogin(url);
|
|
45
|
+
|
|
46
|
+
if (!AutoLoginToken) {
|
|
47
|
+
return fetch(url, options);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let headers = { cookie: `HC-Auth-Token=${AutoLoginToken}` };
|
|
51
|
+
if (options.headers) {
|
|
52
|
+
headers = Object.assign({}, options.headers, headers);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
options = Object.assign({}, options, { headers });
|
|
56
|
+
return fetch(url, options);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export async function tryAuthLogin(url) {
|
|
60
|
+
if (!url.startsWith("http")) {
|
|
61
|
+
url = "https://" + url;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
if (!AutoLoginToken) {
|
|
66
|
+
let _url = new URL(url);
|
|
67
|
+
let u = _url.host.split(".").reverse().slice(0, 3).reverse().join(".");
|
|
68
|
+
|
|
69
|
+
console.log(`${u} 尝试自动登录...`);
|
|
70
|
+
|
|
71
|
+
let data = await fetchTokenAction(`${_url.protocol}//${u}`);
|
|
72
|
+
let data2 = await fetchTokenActionAndRedirect(data.token, data.action);
|
|
73
|
+
|
|
74
|
+
AutoLoginToken = data2.token;
|
|
75
|
+
console.log(`自动登录成功!`);
|
|
76
|
+
return AutoLoginToken;
|
|
77
|
+
}
|
|
78
|
+
} catch (e) {
|
|
79
|
+
console.error(e);
|
|
80
|
+
console.log(`尝试自动登录失败,正在使用默认的登录方式...`);
|
|
81
|
+
AutoLoginFailed = true;
|
|
82
|
+
return "";
|
|
83
|
+
}
|
|
84
|
+
}
|
package/lib/box/check_qemu.js
CHANGED
|
@@ -1,27 +1,50 @@
|
|
|
1
1
|
// 检测当前系统是否安装 qemu 软件
|
|
2
2
|
import commandExist from "command-exists";
|
|
3
3
|
import chalk from "chalk";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
|
|
6
|
+
function linuxPlatform(pkg) {
|
|
7
|
+
let r = os.release();
|
|
8
|
+
if (r.search(/arch/gi) > -1) {
|
|
9
|
+
return `sudo pacman -S ${pkg}`;
|
|
10
|
+
} else if (r.search(/debian/gi) > -1) {
|
|
11
|
+
return `sudo apt install ${pkg}`;
|
|
12
|
+
} else {
|
|
13
|
+
return ``;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function platformPackage(pkg) {
|
|
18
|
+
let cmd = "";
|
|
19
|
+
switch (os.platform()) {
|
|
20
|
+
case "darwin":
|
|
21
|
+
cmd = `brew install ${pkg}`;
|
|
22
|
+
break;
|
|
23
|
+
case "linux":
|
|
24
|
+
cmd = linuxPlatform(pkg);
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
return `${pkg}包没有发现,请先通过系统包管理器安装。\n${cmd}`;
|
|
28
|
+
}
|
|
4
29
|
|
|
5
30
|
export class CheckQemu {
|
|
6
31
|
constructor() {
|
|
7
|
-
this.commands = ["qemu-img", "qemu-system-x86_64"
|
|
32
|
+
this.commands = ["qemu-img", "qemu-system-x86_64"];
|
|
8
33
|
}
|
|
9
34
|
|
|
10
35
|
async init() {
|
|
11
|
-
let
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
});
|
|
25
|
-
return Promise.all(ps);
|
|
36
|
+
for (let cmd of this.commands) {
|
|
37
|
+
if (!commandExist.sync(cmd)) {
|
|
38
|
+
let cmdErr = chalk.red(`${cmd} 命令没有发现`);
|
|
39
|
+
let pkgTips = chalk.blue(platformPackage("qemu"));
|
|
40
|
+
let tips = `${cmdErr}
|
|
41
|
+
|
|
42
|
+
${pkgTips}
|
|
43
|
+
|
|
44
|
+
查看更多信息 https://www.qemu.org/download/
|
|
45
|
+
`;
|
|
46
|
+
throw tips;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
26
49
|
}
|
|
27
50
|
}
|
package/lib/box/hportal.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import fetch from "node-fetch";
|
|
2
|
+
import logger from "loglevel";
|
|
2
3
|
|
|
3
4
|
export class HportalManager {
|
|
4
5
|
constructor(apiHost) {
|
|
@@ -58,11 +59,16 @@ export class HportalManager {
|
|
|
58
59
|
async boxs(boxName, defaultBoxName = "") {
|
|
59
60
|
let url = this.apiHost + "/admin/boxes";
|
|
60
61
|
|
|
61
|
-
let origin;
|
|
62
|
+
let origin = [];
|
|
62
63
|
try {
|
|
63
64
|
const resp = await fetch(url);
|
|
64
65
|
if (resp.status == 200) {
|
|
65
66
|
origin = await resp.json();
|
|
67
|
+
} else {
|
|
68
|
+
logger.debug(
|
|
69
|
+
`status: ${resp.status}, url: ${resp.url}, text: ${resp.statusText}`
|
|
70
|
+
);
|
|
71
|
+
return [];
|
|
66
72
|
}
|
|
67
73
|
} catch {
|
|
68
74
|
return [];
|
package/lib/box/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import { contextDirname } from "../utils.js";
|
|
|
7
7
|
import env, { sdkEnv } from "../env.js";
|
|
8
8
|
import { HportalManager, showBoxInfo } from "./hportal.js";
|
|
9
9
|
import { CheckQemu } from "./check_qemu.js";
|
|
10
|
+
import logger from "loglevel";
|
|
10
11
|
|
|
11
12
|
async function initQemuVM(ensureResources = false) {
|
|
12
13
|
let defaultSchemeFile = path.join(
|
|
@@ -60,7 +61,7 @@ export function boxCommand(box) {
|
|
|
60
61
|
// 创建盒子阶段,如果出错,将直接删除所有的资源。
|
|
61
62
|
boxId = await m.createVM(answer);
|
|
62
63
|
} catch (error) {
|
|
63
|
-
|
|
64
|
+
logger.error(error);
|
|
64
65
|
await m.cleanVM(answer.boxName);
|
|
65
66
|
return;
|
|
66
67
|
}
|
|
@@ -74,11 +75,11 @@ export function boxCommand(box) {
|
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
let h = await initHportal();
|
|
77
|
-
|
|
78
|
+
logger.debug("添加盒子到 Hportal ......");
|
|
78
79
|
await h.addBox(answer.boxName);
|
|
79
|
-
|
|
80
|
+
logger.debug("正在使用管理员帐号密码登录中......");
|
|
80
81
|
await h.loginBox(boxId, answer.adminName, answer.adminPass);
|
|
81
|
-
|
|
82
|
+
logger.debug("登录成功!");
|
|
82
83
|
},
|
|
83
84
|
},
|
|
84
85
|
{
|
|
@@ -88,7 +89,7 @@ export function boxCommand(box) {
|
|
|
88
89
|
let m = await initQemuVM();
|
|
89
90
|
let boxid = await m.runVM(boxName);
|
|
90
91
|
if (boxid) {
|
|
91
|
-
|
|
92
|
+
logger.info("盒子ID: ", boxid);
|
|
92
93
|
}
|
|
93
94
|
},
|
|
94
95
|
},
|
|
@@ -127,7 +128,7 @@ export function boxCommand(box) {
|
|
|
127
128
|
|
|
128
129
|
// 过滤条件不满足
|
|
129
130
|
if (vmInfos.length == 0 && rmInfos == 0 && boxName) {
|
|
130
|
-
|
|
131
|
+
logger.info(`${boxName} 盒子不存在`);
|
|
131
132
|
let allVmInfos = await m.infoVM("", defaultBoxName);
|
|
132
133
|
let allRmInfos = await rm.boxs("", defaultBoxName);
|
|
133
134
|
showBoxInfo(allVmInfos, allRmInfos);
|
package/lib/box/qemu_vm_mgr.js
CHANGED
|
@@ -10,6 +10,7 @@ import net from "node:net";
|
|
|
10
10
|
import fetch from "node-fetch";
|
|
11
11
|
import zlib from "node:zlib";
|
|
12
12
|
import os from "node:os";
|
|
13
|
+
import logger from "loglevel";
|
|
13
14
|
|
|
14
15
|
async function getFreePort() {
|
|
15
16
|
return new Promise((resolve, reject) => {
|
|
@@ -215,7 +216,7 @@ export class QemuVM {
|
|
|
215
216
|
p.on("error", (e) => {
|
|
216
217
|
throw e;
|
|
217
218
|
});
|
|
218
|
-
|
|
219
|
+
logger.debug("启动中...");
|
|
219
220
|
|
|
220
221
|
// 需要等待 boxid 的出现
|
|
221
222
|
return new Promise((resolve, reject) => {
|
|
@@ -239,7 +240,7 @@ export class QemuVM {
|
|
|
239
240
|
clearInterval(id);
|
|
240
241
|
p.unref();
|
|
241
242
|
resolve(boxId);
|
|
242
|
-
|
|
243
|
+
logger.debug("启动成功!");
|
|
243
244
|
}
|
|
244
245
|
}, 1000);
|
|
245
246
|
|
|
@@ -260,17 +261,17 @@ export class QemuVM {
|
|
|
260
261
|
async runVM(name) {
|
|
261
262
|
let boxid = this.readBoxid(name);
|
|
262
263
|
if (!boxid) {
|
|
263
|
-
|
|
264
|
+
logger.info(`${name} 盒子不存在,请通过 lzc-cli box create 创建`);
|
|
264
265
|
return;
|
|
265
266
|
}
|
|
266
267
|
let vmDir = path.join(this.scheme.path, `vm-${name}`);
|
|
267
268
|
let pid = parseVmPID(vmDir);
|
|
268
269
|
if (pid) {
|
|
269
|
-
|
|
270
|
+
logger.info(`${name} 盒子已经启动`);
|
|
270
271
|
return boxid;
|
|
271
272
|
}
|
|
272
273
|
await this.startVM(name, vmDir);
|
|
273
|
-
|
|
274
|
+
logger.info(`${name} 盒子启动成功!`);
|
|
274
275
|
}
|
|
275
276
|
|
|
276
277
|
/**
|
|
@@ -281,7 +282,7 @@ export class QemuVM {
|
|
|
281
282
|
this.ensureVolumeDir(vmDir);
|
|
282
283
|
await this.buildDisks(vmDir);
|
|
283
284
|
let boxId = await this.startVM(boxName, vmDir);
|
|
284
|
-
|
|
285
|
+
logger.info("盒子ID: ", boxId);
|
|
285
286
|
|
|
286
287
|
await this.registerVM(boxId, {
|
|
287
288
|
boxName,
|
|
@@ -372,7 +373,7 @@ export class QemuVM {
|
|
|
372
373
|
}
|
|
373
374
|
|
|
374
375
|
async buildSystemDisk(name, diskPath, diskInfo) {
|
|
375
|
-
|
|
376
|
+
logger.debug(`构建系统盘快照:${diskPath}`);
|
|
376
377
|
let baseImage = path.join(this.scheme.path, name);
|
|
377
378
|
return spawnSync(
|
|
378
379
|
"qemu-img",
|
|
@@ -382,7 +383,7 @@ export class QemuVM {
|
|
|
382
383
|
}
|
|
383
384
|
|
|
384
385
|
async buildDataDisk(name, diskPath, diskInfo) {
|
|
385
|
-
|
|
386
|
+
logger.debug(`构建数据盘:${diskPath}`);
|
|
386
387
|
return spawnSync(
|
|
387
388
|
"qemu-img",
|
|
388
389
|
["create", "-f", "qcow2", diskPath, diskInfo.size],
|
|
@@ -459,7 +460,7 @@ export class QemuVM {
|
|
|
459
460
|
if (pid) {
|
|
460
461
|
process.kill(pid);
|
|
461
462
|
}
|
|
462
|
-
|
|
463
|
+
logger.info(`${name} 盒子已停止`);
|
|
463
464
|
}
|
|
464
465
|
|
|
465
466
|
/**
|
|
@@ -487,7 +488,7 @@ export class QemuVM {
|
|
|
487
488
|
fs.accessSync(vmDir);
|
|
488
489
|
} catch {
|
|
489
490
|
if (!silence) {
|
|
490
|
-
|
|
491
|
+
logger.warn(`${name} 盒子不存在或者该盒子为一个真实盒子`);
|
|
491
492
|
}
|
|
492
493
|
return;
|
|
493
494
|
}
|
|
@@ -508,7 +509,7 @@ export class QemuVM {
|
|
|
508
509
|
return;
|
|
509
510
|
}
|
|
510
511
|
process.kill(pid);
|
|
511
|
-
|
|
512
|
+
logger.info(`${name} 盒子已停止`);
|
|
512
513
|
});
|
|
513
514
|
}
|
|
514
515
|
|
package/lib/dev.js
CHANGED
|
@@ -13,7 +13,6 @@ import path from "path";
|
|
|
13
13
|
import env, { sdkEnv } from "./env.js";
|
|
14
14
|
import _get from "lodash.get";
|
|
15
15
|
import { execPreBuild } from "./builder.js";
|
|
16
|
-
import Key from "./key.js";
|
|
17
16
|
import chokidar from "chokidar";
|
|
18
17
|
import commandExists from "command-exists";
|
|
19
18
|
|
|
@@ -262,9 +261,6 @@ class DevModule {
|
|
|
262
261
|
let appAddr;
|
|
263
262
|
|
|
264
263
|
try {
|
|
265
|
-
// 确保 sdk 能通过公钥正常访问
|
|
266
|
-
await new Key().ensure(sdkEnv.sdkUrl);
|
|
267
|
-
|
|
268
264
|
keyFile = path.join(this.tempDir, "debug/ssh/id_ed25519");
|
|
269
265
|
appAddr = this.getAddress();
|
|
270
266
|
|
package/lib/env.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
import { debuglog } from "util";
|
|
13
13
|
import inquirer from "inquirer";
|
|
14
14
|
import chalk from "chalk";
|
|
15
|
-
import
|
|
15
|
+
import { request } from "./autologin.js";
|
|
16
16
|
const debug = debuglog("lib/env");
|
|
17
17
|
|
|
18
18
|
const GLOBAL_CONFIG_NAME = "box-config.json";
|
|
@@ -83,7 +83,7 @@ async function checkURL(url, suffix = "") {
|
|
|
83
83
|
}, 5000);
|
|
84
84
|
|
|
85
85
|
try {
|
|
86
|
-
const resp = await
|
|
86
|
+
const resp = await request(url + suffix, { signal: controller.signal });
|
|
87
87
|
if (resp.status != 200) {
|
|
88
88
|
// 设备可以访问 (client 有正常连接), 但是sdk 这个服务无法访问
|
|
89
89
|
throw new Error(
|
|
@@ -99,9 +99,6 @@ async function checkURL(url, suffix = "") {
|
|
|
99
99
|
case "FetchError":
|
|
100
100
|
console.log(chalk.red("盒子入口地址有误,请核对后再试"));
|
|
101
101
|
process.exit();
|
|
102
|
-
case "AbortError":
|
|
103
|
-
console.log(chalk.red(`请求 ${url} 超时, 请确保懒猫云客户端已连接`));
|
|
104
|
-
process.exit();
|
|
105
102
|
default:
|
|
106
103
|
throw error;
|
|
107
104
|
}
|
|
@@ -246,6 +243,13 @@ class SDKEnv {
|
|
|
246
243
|
return "";
|
|
247
244
|
}
|
|
248
245
|
|
|
246
|
+
get sdkHostName() {
|
|
247
|
+
if (env.has("DEFAULT_BOXNAME")) {
|
|
248
|
+
return `sdk.${env.get("DEFAULT_BOXNAME")}.heiyu.space`;
|
|
249
|
+
}
|
|
250
|
+
return "";
|
|
251
|
+
}
|
|
252
|
+
|
|
249
253
|
async ensure() {
|
|
250
254
|
if (this.sdkUrl) {
|
|
251
255
|
try {
|
package/lib/generator.js
CHANGED
|
@@ -12,7 +12,7 @@ export const TemplateConfig = {
|
|
|
12
12
|
ionic_vue3: {
|
|
13
13
|
template: "ionic_vue3",
|
|
14
14
|
defaultEnvs: {
|
|
15
|
-
HTTP_SERVICE_PORT: "
|
|
15
|
+
HTTP_SERVICE_PORT: "80",
|
|
16
16
|
BUILD_CONTEXT: ".lazycat/release",
|
|
17
17
|
},
|
|
18
18
|
after: async function (name) {
|
|
@@ -43,7 +43,7 @@ export const TemplateConfig = {
|
|
|
43
43
|
vue: {
|
|
44
44
|
template: "vue",
|
|
45
45
|
defaultEnvs: {
|
|
46
|
-
HTTP_SERVICE_PORT: "
|
|
46
|
+
HTTP_SERVICE_PORT: "80",
|
|
47
47
|
BUILD_CONTEXT: ".lazycat/release",
|
|
48
48
|
},
|
|
49
49
|
after: async function (name) {
|
package/lib/sdk.js
CHANGED
|
@@ -4,8 +4,8 @@ import Docker from "dockerode";
|
|
|
4
4
|
import process from "process";
|
|
5
5
|
import fs from "fs";
|
|
6
6
|
import { Client } from "ssh2";
|
|
7
|
-
import chalk from "chalk";
|
|
8
7
|
import Key from "./key.js";
|
|
8
|
+
import logger from "loglevel";
|
|
9
9
|
|
|
10
10
|
export async function connectOptions(host) {
|
|
11
11
|
const pairs = await new Key().getKeyPair();
|
|
@@ -38,7 +38,7 @@ export class DockerClient {
|
|
|
38
38
|
async init() {
|
|
39
39
|
this.docker = !!this.host
|
|
40
40
|
? new Docker({
|
|
41
|
-
protocal: "
|
|
41
|
+
protocal: "ssh",
|
|
42
42
|
agent: ssh(await connectOptions(this.host)),
|
|
43
43
|
})
|
|
44
44
|
: new Docker();
|
|
@@ -47,9 +47,7 @@ export class DockerClient {
|
|
|
47
47
|
|
|
48
48
|
async function onUncaughtException(e) {
|
|
49
49
|
if (e.code == "ECONNREFUSED") {
|
|
50
|
-
|
|
51
|
-
chalk.red(`无法连接 sdk 服务, 请确保 ${chalk.yellow(host)} 可以访问`)
|
|
52
|
-
);
|
|
50
|
+
logger.error(`无法连接 sdk 服务, 请确保 ${host} 可以访问`);
|
|
53
51
|
process.exit(1);
|
|
54
52
|
} else {
|
|
55
53
|
throw e;
|
|
@@ -78,6 +76,7 @@ export class SSHClient {
|
|
|
78
76
|
this.con
|
|
79
77
|
.on("ready", () => resolve(this.con))
|
|
80
78
|
.on("error", (err) => {
|
|
79
|
+
logger.error("ssh client ", err);
|
|
81
80
|
reject(err);
|
|
82
81
|
})
|
|
83
82
|
.on("close", () => resolve(null))
|
|
@@ -126,7 +125,7 @@ export class SSHClient {
|
|
|
126
125
|
}
|
|
127
126
|
|
|
128
127
|
export async function dockerPullLzcAppsImage(host) {
|
|
129
|
-
|
|
128
|
+
logger.warn("* 更新lzcapp镜像, 未来可能会移除此操作");
|
|
130
129
|
const opts = await connectOptions(host);
|
|
131
130
|
const client = new SSHClient(opts);
|
|
132
131
|
await client.connect();
|