@lazycatcloud/lzc-cli 1.1.11 → 1.1.13
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/lib/api.js +3 -3
- package/lib/app/index.js +23 -2
- package/lib/app/lpk_build.js +5 -0
- package/lib/app/lpk_create.js +9 -3
- package/lib/app/lpk_devshell.js +6 -17
- package/lib/app/lpk_installer.js +4 -14
- package/lib/appstore/login.js +1 -1
- package/lib/box/qemu_vm_mgr.js +1 -1
- package/lib/core.proto +118 -0
- package/lib/env.js +2 -2
- package/lib/fetch.js +50 -0
- package/lib/lzc_sdk.js +61 -17
- package/lib/utils.js +5 -0
- package/package.json +5 -2
- package/scripts/cli.js +6 -6
package/lib/api.js
CHANGED
|
@@ -2,7 +2,7 @@ import ora from "ora";
|
|
|
2
2
|
import chalk from "chalk";
|
|
3
3
|
import fs from "fs";
|
|
4
4
|
import logger from "loglevel";
|
|
5
|
-
import fetch from "
|
|
5
|
+
import fetch from "./fetch.js";
|
|
6
6
|
|
|
7
7
|
//
|
|
8
8
|
// sdk 提供的API
|
|
@@ -12,12 +12,12 @@ export default class API {
|
|
|
12
12
|
this.host = host;
|
|
13
13
|
this.uid = uid;
|
|
14
14
|
}
|
|
15
|
-
async install(zipPath) {
|
|
15
|
+
async install(zipPath, isDevshell = false) {
|
|
16
16
|
if (!fs.existsSync(zipPath)) {
|
|
17
17
|
throw `${zipPath} 不存在`;
|
|
18
18
|
}
|
|
19
19
|
const resp = await fetch(
|
|
20
|
-
`${this.host}/api/v1/app/install?id=${this.appId}`,
|
|
20
|
+
`${this.host}/api/v1/app/install?id=${this.appId}&devshell=${isDevshell}`,
|
|
21
21
|
{
|
|
22
22
|
method: "POST",
|
|
23
23
|
body: fs.createReadStream(zipPath),
|
package/lib/app/index.js
CHANGED
|
@@ -6,6 +6,9 @@ import { LpkInstaller } from "./lpk_installer.js";
|
|
|
6
6
|
import { LpkUninstaller } from "./lpk_uninstall.js";
|
|
7
7
|
import { LpkStatuser } from "./lpk_status.js";
|
|
8
8
|
import { LpkLogger } from "./lpk_log.js";
|
|
9
|
+
import logger from "loglevel";
|
|
10
|
+
import fetch from "../fetch.js";
|
|
11
|
+
import { sdkEnv } from "../env.js";
|
|
9
12
|
|
|
10
13
|
export function lpkProjectCommand(program) {
|
|
11
14
|
let subCommands = [
|
|
@@ -72,9 +75,27 @@ export function lpkProjectCommand(program) {
|
|
|
72
75
|
type: "string",
|
|
73
76
|
default: "lzc-build.yml",
|
|
74
77
|
});
|
|
78
|
+
args.option("contentdir", {
|
|
79
|
+
describe: "同时打包 lzc-build.yml 中指定的 contentdir 目录",
|
|
80
|
+
type: "boolean",
|
|
81
|
+
});
|
|
75
82
|
},
|
|
76
|
-
handler: async ({ context, shell, force, config }) => {
|
|
77
|
-
const
|
|
83
|
+
handler: async ({ context, shell, force, config, contentdir }) => {
|
|
84
|
+
const cwd = context ? path.resolve(context) : process.cwd();
|
|
85
|
+
const lpkBuild = await new LpkBuild(cwd, config).init();
|
|
86
|
+
lpkBuild.onBeforeBuildPackage(async (options) => {
|
|
87
|
+
// devshell 正常情况下,不需要执行 buildscript 和 contentdir 字段
|
|
88
|
+
logger.debug("devshell delete 'buildscript' field");
|
|
89
|
+
delete options["buildscript"];
|
|
90
|
+
|
|
91
|
+
if (!contentdir) {
|
|
92
|
+
logger.debug("devshell delete 'contentdir' field");
|
|
93
|
+
delete options["contentdir"];
|
|
94
|
+
}
|
|
95
|
+
return options;
|
|
96
|
+
});
|
|
97
|
+
await fetch(`${sdkEnv.sdkUrl}/api/v1/ping`);
|
|
98
|
+
const app = new AppDevShell(cwd, lpkBuild, force);
|
|
78
99
|
await app.init();
|
|
79
100
|
await app.build();
|
|
80
101
|
await app.rsyncShell(shell);
|
package/lib/app/lpk_build.js
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
isFileExist,
|
|
9
9
|
dumpToYaml,
|
|
10
10
|
envTemplateFile,
|
|
11
|
+
isValidPackageName,
|
|
11
12
|
} from "../utils.js";
|
|
12
13
|
import { spawnSync } from "child_process";
|
|
13
14
|
import { LpkManifest } from "./lpk_create.js";
|
|
@@ -191,6 +192,10 @@ export class LpkBuild {
|
|
|
191
192
|
let lpkM = new LpkManifest();
|
|
192
193
|
await lpkM.init(this.manifestFilePath);
|
|
193
194
|
this.manifest = lpkM.manifest;
|
|
195
|
+
|
|
196
|
+
if (!isValidPackageName(this.manifest["package"])) {
|
|
197
|
+
throw `${this.manifest["package"]} 含有非法字符,请使用正确的包名格式(java的包名格式),如:cloud.lazycat.apps.video`;
|
|
198
|
+
}
|
|
194
199
|
return this.manifest;
|
|
195
200
|
}
|
|
196
201
|
|
package/lib/app/lpk_create.js
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
ensureDir,
|
|
8
8
|
dumpToYaml,
|
|
9
9
|
isFileExist,
|
|
10
|
+
isValidPackageName,
|
|
10
11
|
} from "../utils.js";
|
|
11
12
|
import path from "node:path";
|
|
12
13
|
import { TemplateConfig } from "./lpk_create_generator.js";
|
|
@@ -74,9 +75,14 @@ export class LpkManifest {
|
|
|
74
75
|
{
|
|
75
76
|
type: "input",
|
|
76
77
|
name: "package",
|
|
77
|
-
message: "请输入应用ID",
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
message: "请输入应用ID, 如 cloud.lazycat.app.video",
|
|
79
|
+
validate: (input) => {
|
|
80
|
+
if (isValidPackageName(input)) {
|
|
81
|
+
return true;
|
|
82
|
+
} else {
|
|
83
|
+
return "应用ID错误,请输入正确的格式, 如 cloud.lazycat.app.video";
|
|
84
|
+
}
|
|
85
|
+
},
|
|
80
86
|
},
|
|
81
87
|
{
|
|
82
88
|
type: "input",
|
package/lib/app/lpk_devshell.js
CHANGED
|
@@ -129,19 +129,14 @@ class AppDevShellMonitor {
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
export class AppDevShell {
|
|
132
|
-
constructor(cwd,
|
|
133
|
-
this.cwd = cwd
|
|
134
|
-
this.lpkBuild =
|
|
132
|
+
constructor(cwd, lpkBuild, forceBuild = false) {
|
|
133
|
+
this.cwd = cwd;
|
|
134
|
+
this.lpkBuild = lpkBuild;
|
|
135
135
|
this.monitor = undefined;
|
|
136
136
|
this.forceBuild = forceBuild;
|
|
137
|
-
this.lpkBuildConfig = config;
|
|
138
137
|
}
|
|
139
138
|
|
|
140
139
|
async init() {
|
|
141
|
-
if (!this.lpkBuild) {
|
|
142
|
-
this.lpkBuild = new LpkBuild(this.cwd, this.lpkBuildConfig);
|
|
143
|
-
await this.lpkBuild.init();
|
|
144
|
-
}
|
|
145
140
|
const manifest = await this.lpkBuild.getManifest();
|
|
146
141
|
const uid = await getUidByManifest(manifest);
|
|
147
142
|
this.monitor = await new AppDevShellMonitor(
|
|
@@ -165,13 +160,7 @@ export class AppDevShell {
|
|
|
165
160
|
await k.ensure(sdkEnv.sdkUrl);
|
|
166
161
|
const pairs = await k.getKeyPair();
|
|
167
162
|
|
|
168
|
-
// devshell 不需要执行 buildscript 和 contentdir 也不需要
|
|
169
163
|
this.lpkBuild.onBeforeBuildPackage(async (options) => {
|
|
170
|
-
logger.debug("devshell delete 'buildscript' field");
|
|
171
|
-
logger.debug("devshell delete 'contentdir' field");
|
|
172
|
-
delete options["buildscript"];
|
|
173
|
-
delete options["contentdir"];
|
|
174
|
-
|
|
175
164
|
const devshell = options["devshell"];
|
|
176
165
|
if (!devshell) {
|
|
177
166
|
throw "devshell 模式下,devshell 字段必须要指定";
|
|
@@ -371,7 +360,7 @@ export class AppDevShell {
|
|
|
371
360
|
// 在构建生成 lpk 包后,调用 deploy 进行部署
|
|
372
361
|
let installer = new LpkInstaller();
|
|
373
362
|
await installer.init();
|
|
374
|
-
await installer.deploy(this.lpkBuild);
|
|
363
|
+
await installer.deploy(this.lpkBuild, true);
|
|
375
364
|
|
|
376
365
|
await sleep(2000);
|
|
377
366
|
}
|
|
@@ -444,11 +433,11 @@ class DevShell {
|
|
|
444
433
|
|
|
445
434
|
let rsyncDebug = process.env.RSYNCDEBUG ? "-P" : "";
|
|
446
435
|
const userId = this.uid ? `/${this.uid}` : "";
|
|
447
|
-
let storePath = `/run/
|
|
436
|
+
let storePath = `/lzcsys/run/data/app/cache/${appId}${userId}/devshell`;
|
|
448
437
|
// FIXME: 下方执行命令不确定是否有兼容性问题
|
|
449
438
|
try {
|
|
450
439
|
execSync(
|
|
451
|
-
`rsync ${rsyncDebug} --rsh='${rsh}' --recursive --relative --perms --update . ${host}:${storePath} --filter=':- .gitignore' --
|
|
440
|
+
`rsync ${rsyncDebug} --rsh='${rsh}' --recursive --relative --perms --update . ${host}:${storePath} --filter=':- .gitignore' --ignore-errors --usermap=:nobody --groupmap=*:nobody`,
|
|
452
441
|
{ stdio: ["ignore", "inherit", "inherit"] }
|
|
453
442
|
);
|
|
454
443
|
} catch (err) {
|
package/lib/app/lpk_installer.js
CHANGED
|
@@ -4,10 +4,9 @@ import logger from "loglevel";
|
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import Key from "../key.js";
|
|
7
|
-
import { loadFromYaml, Downloader
|
|
7
|
+
import { loadFromYaml, Downloader } from "../utils.js";
|
|
8
8
|
import { spawnSync } from "node:child_process";
|
|
9
9
|
import { getUidByManifest } from "../lzc_sdk.js";
|
|
10
|
-
import fetch from "node-fetch";
|
|
11
10
|
|
|
12
11
|
export class LpkInstaller {
|
|
13
12
|
constructor() {}
|
|
@@ -21,7 +20,8 @@ export class LpkInstaller {
|
|
|
21
20
|
await k.ensure(sdkEnv.sdkUrl);
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
// TODO: 将 devshell 的判断逻辑放在 builder 中判断
|
|
24
|
+
async deploy(builder, isDevshell = false) {
|
|
25
25
|
if (!builder) {
|
|
26
26
|
throw "deploy 必须传递一个 builder";
|
|
27
27
|
}
|
|
@@ -32,24 +32,14 @@ export class LpkInstaller {
|
|
|
32
32
|
|
|
33
33
|
let pkgPath = await builder.exec("");
|
|
34
34
|
logger.info("开始部署应用");
|
|
35
|
-
await api.install(pkgPath);
|
|
35
|
+
await api.install(pkgPath, isDevshell);
|
|
36
36
|
|
|
37
37
|
const appUrl = sdkEnv.sdkUrl.replace(
|
|
38
38
|
/sdk/,
|
|
39
39
|
manifest["application"]["subdomain"]
|
|
40
40
|
);
|
|
41
|
-
// 如果是多实例的应用,需要先访问下,才会创建对应的容器
|
|
42
|
-
if (manifest["application"]["user_app"]) {
|
|
43
|
-
const res = await fetch(appUrl);
|
|
44
|
-
if (res.status >= 400) {
|
|
45
|
-
throw `访问 ${appUrl} 失败`;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
41
|
// 新安装的应用默认为休眠的状态,需要先等容器创建成功,等成为 paused 后 resume 下
|
|
50
42
|
await api.checkStatus(true);
|
|
51
|
-
|
|
52
|
-
await sleep(2000);
|
|
53
43
|
logger.info(`👉 请在浏览器中访问 ${appUrl}`);
|
|
54
44
|
}
|
|
55
45
|
|
package/lib/appstore/login.js
CHANGED
package/lib/box/qemu_vm_mgr.js
CHANGED
|
@@ -5,7 +5,7 @@ import path from "node:path";
|
|
|
5
5
|
import inquirer from "inquirer";
|
|
6
6
|
import process from "node:process";
|
|
7
7
|
import net from "node:net";
|
|
8
|
-
import fetch from "
|
|
8
|
+
import fetch from "../fetch.js";
|
|
9
9
|
import os from "node:os";
|
|
10
10
|
import logger from "loglevel";
|
|
11
11
|
import glob from "fast-glob";
|
package/lib/core.proto
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package space.heiyu.hportal.shell;
|
|
4
|
+
|
|
5
|
+
import "google/protobuf/empty.proto";
|
|
6
|
+
|
|
7
|
+
// 此接口为hclient&hserver曝露给管理界面、命令行客户端等使用的API
|
|
8
|
+
service ShellCore {
|
|
9
|
+
// 查询当前盒子列表的状态
|
|
10
|
+
rpc QueryBoxList(google.protobuf.Empty) returns(BoxList) {}
|
|
11
|
+
// 添加、修改盒子的登陆信息、开启、关闭盒子等
|
|
12
|
+
rpc ModifyBox(BoxSetting) returns (google.protobuf.Empty);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// 盒子只会处于以下四种状态之一
|
|
16
|
+
enum BoxStatus {
|
|
17
|
+
// 此盒子当前未激活
|
|
18
|
+
DISABLED = 0;
|
|
19
|
+
|
|
20
|
+
// 正在连接中,此过程持续时间无法评估,
|
|
21
|
+
// 可能瞬间结束也可能持续一两分钟(在确实可以连接上的前提下)
|
|
22
|
+
CONNECTING = 1;
|
|
23
|
+
|
|
24
|
+
// 成功连接上了
|
|
25
|
+
CONNECTED = 2;
|
|
26
|
+
|
|
27
|
+
// 确定无法连接,此时不会继续重试,需要客户端
|
|
28
|
+
// 修正环境后,重新调用ModifyBox后继续尝试。
|
|
29
|
+
FAILED = 3;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
enum ConnectingStatus {
|
|
33
|
+
AWAIT_NEW_DEVICE_AUTH = 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
enum FailedStatus {
|
|
37
|
+
// 未知原因失败
|
|
38
|
+
FAILED_UNKNOWN = 0;
|
|
39
|
+
|
|
40
|
+
// 当前盒子无管理员帐号,需要调用CreateUser创建管理员帐号
|
|
41
|
+
FAILED_NO_ADMINUSER = 1;
|
|
42
|
+
|
|
43
|
+
// 当前盒子未注册盒子名称,需要调用SetupNewBox向horigin申请盒子名称以及配套资源
|
|
44
|
+
FAILED_NO_BOXNAME = 2;
|
|
45
|
+
|
|
46
|
+
// 当前登陆信息不正确,需要调用ModifyBox设置新的auth信息
|
|
47
|
+
FAILED_INVALID_PASSWORD = 3;
|
|
48
|
+
|
|
49
|
+
// 当前客户端与服务器版本不匹配,无法连接,需要升级盒子系统或客户端软件
|
|
50
|
+
FAILED_MISMATCH_BOX_VERSION = 4;
|
|
51
|
+
|
|
52
|
+
// 当前设备被拒绝登录
|
|
53
|
+
FAILED_DEVICE_AUTH_REJECT = 5;
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
//------ 100+的失败状态一般为本机特有错误状态
|
|
57
|
+
|
|
58
|
+
//调用LoginBox的过程中,此盒子的状态被其他API请求转换为disabled了
|
|
59
|
+
FAILED_LOCAL_DISABLED_BOX = 100;
|
|
60
|
+
|
|
61
|
+
//调用LoginBox时使用了一个不存在的盒子名称。(若只是本地不盒子列表不存在此盒子,会自动添加到盒子列表)
|
|
62
|
+
FAILED_LOCAL_NO_SUCH_BOX_IN_THE_WORLD = 101;
|
|
63
|
+
|
|
64
|
+
//使用LoginBox时,登陆超时
|
|
65
|
+
FAILED_LOCAL_CONNECTING_TIMEOUT = 102;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
enum ExceptionStatus {
|
|
69
|
+
OK = 0;
|
|
70
|
+
Error = 1;
|
|
71
|
+
Booting = 2;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
message BoxInfo {
|
|
75
|
+
string box_id = 1;
|
|
76
|
+
string box_name = 2;
|
|
77
|
+
string box_home_url = 3 [deprecated = true];
|
|
78
|
+
string box_domain = 14;
|
|
79
|
+
string box_virtual_ip = 10;
|
|
80
|
+
|
|
81
|
+
BoxStatus status = 4;
|
|
82
|
+
string status_reason = 5;
|
|
83
|
+
optional FailedStatus failed_status = 6;
|
|
84
|
+
optional ConnectingStatus connecting_status = 12; // deprecated
|
|
85
|
+
ExceptionStatus exception_status = 11;
|
|
86
|
+
|
|
87
|
+
bool is_relay_connection = 13;
|
|
88
|
+
|
|
89
|
+
string login_user = 7;
|
|
90
|
+
bool is_admin_login = 8;
|
|
91
|
+
string auth_token = 9;
|
|
92
|
+
|
|
93
|
+
bool is_default_box = 15;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
message BoxList {
|
|
97
|
+
repeated BoxInfo boxes = 1;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
message BoxSetting {
|
|
101
|
+
string id = 1;
|
|
102
|
+
|
|
103
|
+
optional string name = 2;
|
|
104
|
+
|
|
105
|
+
// 若不设置则使用当前值
|
|
106
|
+
optional bool enabled = 3;
|
|
107
|
+
|
|
108
|
+
message AuthInfo {
|
|
109
|
+
string user = 3;
|
|
110
|
+
string password = 4;
|
|
111
|
+
optional string verification_code = 5;
|
|
112
|
+
}
|
|
113
|
+
optional AuthInfo auth = 4;
|
|
114
|
+
|
|
115
|
+
//设置此盒子为默认盒子,会覆盖其他(如果有)默认盒子的配置
|
|
116
|
+
//第一个添加的盒子会自动成为默认盒子
|
|
117
|
+
optional bool set_as_default_box = 5;
|
|
118
|
+
}
|
package/lib/env.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
import inquirer from "inquirer";
|
|
10
10
|
import chalk from "chalk";
|
|
11
11
|
import logger from "loglevel";
|
|
12
|
-
import fetch from "
|
|
12
|
+
import fetch from "./fetch.js";
|
|
13
13
|
|
|
14
14
|
const GLOBAL_CONFIG_NAME = "box-config.json";
|
|
15
15
|
const allPermitEnv = [
|
|
@@ -188,7 +188,7 @@ class SDKEnv {
|
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
buildSdkUrl(boxname) {
|
|
191
|
-
return `
|
|
191
|
+
return `https://sdk.${boxname}.heiyu.space`;
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
/**
|
package/lib/fetch.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import nodeFetch from "node-fetch";
|
|
2
|
+
import makeFetchCookie from "fetch-cookie";
|
|
3
|
+
import { FileCookieStore } from "tough-cookie-file-store";
|
|
4
|
+
import inquirer from "inquirer";
|
|
5
|
+
import env from "./env.js";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { GLOBAL_CONFIG_DIR } from "./utils.js";
|
|
8
|
+
|
|
9
|
+
const cookieFetch = makeFetchCookie(
|
|
10
|
+
nodeFetch,
|
|
11
|
+
new makeFetchCookie.toughCookie.CookieJar(
|
|
12
|
+
new FileCookieStore(path.resolve(GLOBAL_CONFIG_DIR, "cookie.json"))
|
|
13
|
+
)
|
|
14
|
+
);
|
|
15
|
+
const fetch = async (url, options) => {
|
|
16
|
+
const resp = await cookieFetch(url, options);
|
|
17
|
+
if (resp.status == 401) {
|
|
18
|
+
await login();
|
|
19
|
+
}
|
|
20
|
+
return resp;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export async function login() {
|
|
24
|
+
const boxname = env.get("DEFAULT_BOXNAME");
|
|
25
|
+
const boxUrl = `https://${boxname}.heiyu.space`;
|
|
26
|
+
|
|
27
|
+
const questions = [
|
|
28
|
+
{
|
|
29
|
+
name: "username",
|
|
30
|
+
type: "input",
|
|
31
|
+
message: "请输入帐号名",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
type: "password",
|
|
35
|
+
mask: "*",
|
|
36
|
+
name: "password",
|
|
37
|
+
message: "请输入登录密码",
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
const answers = await inquirer.prompt(questions);
|
|
41
|
+
await fetch(`${boxUrl}/sys/login?type=plain`, {
|
|
42
|
+
headers: {
|
|
43
|
+
"content-type": "application/x-www-form-urlencoded",
|
|
44
|
+
},
|
|
45
|
+
body: `username=${answers.username}&password=${answers.password}`,
|
|
46
|
+
method: "POST",
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export default fetch;
|
package/lib/lzc_sdk.js
CHANGED
|
@@ -1,25 +1,69 @@
|
|
|
1
|
-
import
|
|
1
|
+
import grpc from "@grpc/grpc-js";
|
|
2
|
+
import protoLoader from "@grpc/proto-loader";
|
|
3
|
+
import { contextDirname } from "./utils.js";
|
|
2
4
|
import path from "node:path";
|
|
3
|
-
import
|
|
5
|
+
import env from "./env.js";
|
|
4
6
|
import logger from "loglevel";
|
|
7
|
+
import os from "node:os";
|
|
8
|
+
import fs from "node:fs";
|
|
5
9
|
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
".
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
const SHELLAPI_CONFIG_DIR = path.join(os.homedir(), "/.config/hportal-client");
|
|
11
|
+
const coreDefinition = protoLoader.loadSync(
|
|
12
|
+
path.join(contextDirname(), "./core.proto"),
|
|
13
|
+
{
|
|
14
|
+
keepCase: true,
|
|
15
|
+
longs: String,
|
|
16
|
+
enums: String,
|
|
17
|
+
defaults: true,
|
|
18
|
+
oneofs: true,
|
|
19
|
+
}
|
|
11
20
|
);
|
|
21
|
+
const core =
|
|
22
|
+
grpc.loadPackageDefinition(coreDefinition).space.heiyu.hportal.shell;
|
|
23
|
+
|
|
24
|
+
let client;
|
|
25
|
+
|
|
26
|
+
function readShellApiInfo() {
|
|
27
|
+
const addr = fs.readFileSync(
|
|
28
|
+
path.resolve(SHELLAPI_CONFIG_DIR, "shellapi_addr"),
|
|
29
|
+
{ encoding: "utf-8" }
|
|
30
|
+
);
|
|
31
|
+
const cred = fs.readFileSync(
|
|
32
|
+
path.resolve(SHELLAPI_CONFIG_DIR, "shellapi_cred"),
|
|
33
|
+
{ encoding: "utf-8" }
|
|
34
|
+
);
|
|
35
|
+
return { addr, cred };
|
|
36
|
+
}
|
|
12
37
|
|
|
13
|
-
let lzcConfig = undefined;
|
|
14
38
|
export async function getUidByManifest(manifest) {
|
|
15
|
-
if (manifest["application"]["user_app"]) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
39
|
+
if (!manifest["application"]["user_app"]) {
|
|
40
|
+
return "";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const { addr, cred } = readShellApiInfo();
|
|
44
|
+
|
|
45
|
+
if (!client) {
|
|
46
|
+
client = new core.ShellCore(addr, grpc.credentials.createInsecure());
|
|
23
47
|
}
|
|
24
|
-
|
|
48
|
+
|
|
49
|
+
const metadata = new grpc.Metadata();
|
|
50
|
+
metadata.add("lzc-shellapi-cred", cred);
|
|
51
|
+
|
|
52
|
+
const boxName = env.get("DEFAULT_BOXNAME");
|
|
53
|
+
return new Promise((resolve, reject) => {
|
|
54
|
+
client.queryBoxList({}, metadata, function (err, response) {
|
|
55
|
+
if (err) {
|
|
56
|
+
reject(err);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
for (let box of response.boxes) {
|
|
60
|
+
if (box.box_name == boxName) {
|
|
61
|
+
logger.debug("当前登录用户: ", box.login_user);
|
|
62
|
+
resolve(box.login_user);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
reject("没有默认盒子信息");
|
|
67
|
+
});
|
|
68
|
+
});
|
|
25
69
|
}
|
package/lib/utils.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lazycatcloud/lzc-cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.13",
|
|
4
4
|
"description": "lazycat cloud developer kit",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "tap",
|
|
@@ -29,9 +29,10 @@
|
|
|
29
29
|
"license": "ISC",
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@balena/dockerignore": "^1.0.2",
|
|
32
|
+
"@grpc/grpc-js": "^1.8.12",
|
|
33
|
+
"@grpc/proto-loader": "^0.7.6",
|
|
32
34
|
"@improbable-eng/grpc-web": "^0.15.0",
|
|
33
35
|
"@improbable-eng/grpc-web-node-http-transport": "^0.15.0",
|
|
34
|
-
"@lazycatcloud/sdk": "^0.1.120",
|
|
35
36
|
"archiver": "^5.3.0",
|
|
36
37
|
"browser-headers": "^0.4.1",
|
|
37
38
|
"chalk": "^4.1.2",
|
|
@@ -43,6 +44,7 @@
|
|
|
43
44
|
"envsub": "^4.0.7",
|
|
44
45
|
"execa": "^5.1.1",
|
|
45
46
|
"fast-glob": "^3.2.7",
|
|
47
|
+
"fetch-cookie": "^2.1.0",
|
|
46
48
|
"form-data": "^4.0.0",
|
|
47
49
|
"ignore": "^5.2.0",
|
|
48
50
|
"inquirer": "^8.2.0",
|
|
@@ -64,6 +66,7 @@
|
|
|
64
66
|
"ssh2": "^1.5.0",
|
|
65
67
|
"ssh2-promise": "^1.0.2",
|
|
66
68
|
"tar": "^6.1.11",
|
|
69
|
+
"tough-cookie-file-store": "^2.0.3",
|
|
67
70
|
"urllib": "^3.1.0",
|
|
68
71
|
"yargs": "^17.5.1"
|
|
69
72
|
},
|
package/scripts/cli.js
CHANGED
|
@@ -96,14 +96,14 @@ lpkAppCommand(program);
|
|
|
96
96
|
lpkProjectCommand(program);
|
|
97
97
|
appstoreCommand(program);
|
|
98
98
|
|
|
99
|
-
const parser = program
|
|
100
|
-
.strict()
|
|
101
|
-
.showHelpOnFail(false, "使用 lzc-cli help 查看更多帮助")
|
|
102
|
-
.middleware([setLoggerLevel])
|
|
103
|
-
.parse();
|
|
104
|
-
|
|
105
99
|
// 当没有参数的时候,默认显示帮助。
|
|
106
100
|
(async () => {
|
|
101
|
+
const parser = program
|
|
102
|
+
.strict()
|
|
103
|
+
.showHelpOnFail(false, "使用 lzc-cli help 查看更多帮助")
|
|
104
|
+
.middleware([setLoggerLevel])
|
|
105
|
+
.parse();
|
|
106
|
+
|
|
107
107
|
const argv = await parser;
|
|
108
108
|
if (argv._.length == 1) {
|
|
109
109
|
switch (argv._[0]) {
|