@lazycatcloud/lzc-cli 1.2.0 → 1.2.2

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/README.md CHANGED
@@ -1,79 +1,47 @@
1
- # 懒猫云应用命令行工具
2
- ```
3
- <command> [options]
4
-
5
- Commands:
6
- lzc-cli box 盒子管理 lzc-cli app 应用管理 lzc-cli project 项目管理 lzc-cli appstore 应用商店
7
- Options:
8
- -h, --help [boolean] [default: false]
9
- --version Show version number [boolean]
10
- --log log level 'trace', 'debug', 'info', 'warn', 'error'
11
- [string] [default: "info"]
12
- ```
1
+ # lzc-cli 指南
13
2
 
14
- ## 安装
15
- ```
16
- npm install -g @lazycatcloud/lzc-cli
17
- ```
3
+ #### 依赖
18
4
 
19
- ## 虚拟盒子
5
+ 1. `ssh`
6
+ 2. `ssh-copy-id`
7
+ 3. `rsync`
20
8
 
21
- ### 创建虚拟盒子
22
- ```
23
- lzc-cli box create
24
- ```
25
- 将从 https://dl.lazycat.cloud 中下载最新的盒子系统数据,跟创建对应的 qemu 虚拟盒子。
9
+ #### 快速上手
26
10
 
27
- ### 启动盒子
28
- ```
29
- lzc-cli box start <boxname>
30
- # lzc-cli box start mydemobox
11
+ ```bash
12
+ npm install -g @lazycatcloud/lzc-cli
13
+ # 将 lzc-cli 添加 bash/zsh 补全支持
14
+ lzc-cli completion >> ~/.zshrc
31
15
  ```
32
- 启动盒子成功后,就可以在 https://<mydemobox>.heiyu.space 中看到盒子的主页了。
33
16
 
34
- ### 切换默认的盒子
35
- ```
36
- lzc-cli box switch <otherBoxName>
37
- ```
17
+ 下面开始使用 `lzc-cli` 去创建一个项目吧!
38
18
 
39
- ### 查看本地的虚拟盒子信息
40
- ```
41
- lzc-cli box info
42
- ```
19
+ ```bash
20
+ lzc-cli project create you_project
43
21
 
44
- ## 应用管理
22
+ # 构建懒猫云平台lpk包
23
+ lzc-cli project build
45
24
 
46
- ### 安装应用到盒子中去
25
+ # 将lpk包安装到盒子中去
26
+ lzc-cli app install
47
27
 
48
- - https://repo.lazycat.cloud 中安装
49
- ```
50
- lzc-cli app install https://repo.lazycat.cloud/pkgs/cloud.lazycat.app.kityminder/cloud.lazycat.app.kityminder-v1.0.3.lpk
51
- ```
28
+ # 使用 devshell 可以让你在盒子中开发调试
29
+ lzc-cli project devshell
52
30
 
53
- - 从本地安装
54
- ```
55
- lzc-cli app install ./kityminder.lpk
31
+ # 经过测试后,将包发布到懒猫云商店中去
32
+ lzc-cli appstore publish
56
33
  ```
57
34
 
58
- ### 卸载应用
59
- ```
60
- lzc-cli app uninstall cloud.lazycat.app.kityminder
61
- ```
35
+ ### FAQ
62
36
 
63
- ## 项目管理
37
+ #### 1. 开发者工具 ssh 的帐号密码是多少?
64
38
 
65
- ### 初始化懒猫云应用
66
- ```
67
- lzc-cli project create yourappname
68
- ```
39
+ 现在帐号密码设置为 box:box,后面会使用 pam 模块对接盒子帐号体系。
69
40
 
70
- ### 构建 lpk 包
71
- ```
72
- lzc-cli project build -o yourappname.lpk
73
- ```
41
+ #### 2. 如何切换默认的开发的盒子?
74
42
 
75
- ### 盒子内开发
76
- ```
77
- lzc-cli project devshell -b
78
- ```
79
- `-b` 表示是否重新构建盒子中项目环境。
43
+ 目前不支持通过 lzc-cli 工具切换默认的盒子,所以你需要在 lzc-client-desktop 客户端上点击你要使用的盒子来切换。
44
+
45
+ #### 3. 如果在盒子中构建镜像? 不想在本地构建
46
+
47
+ 现在已经把在盒子中构建镜像的功能去掉了,只能在本地或者其他地方构建好,然后指定 image 字段来选择你需要的开发环境。
@@ -71,7 +71,10 @@ export class DebugBridge {
71
71
  }
72
72
 
73
73
  async isDevshell(appId) {
74
- const stdout = await this.common(this.sshCmd, [`isDevshell`, appId]);
74
+ const stdout = await this.common(this.sshCmd, [
75
+ `isDevshell --uid ${this.uid}`,
76
+ appId,
77
+ ]);
75
78
  return stdout == "true";
76
79
  }
77
80
 
@@ -83,10 +86,17 @@ export class DebugBridge {
83
86
  return this.common(this.sshCmd, [`uninstall --uid ${this.uid}`, appId]);
84
87
  }
85
88
 
86
- async devshell(appId) {
89
+ async devshell(appId, isUserApp) {
87
90
  const stream = spawn(
88
91
  this.sshCmd,
89
- ["-t", "devshell", appId, "/lzcapp/pkg/content/devshell/exec.sh"],
92
+ [
93
+ "-t",
94
+ "devshell",
95
+ `--uid ${this.uid}`,
96
+ isUserApp ? "--userapp" : "",
97
+ appId,
98
+ "/lzcapp/pkg/content/devshell/exec.sh",
99
+ ],
90
100
  {
91
101
  shell: true,
92
102
  stdio: "inherit",
@@ -15,12 +15,12 @@ import {
15
15
  md5File,
16
16
  loadFromYaml,
17
17
  FileLocker,
18
+ isUserApp,
18
19
  } from "../utils.js";
19
20
  import os from "node:os";
20
21
  import commandExists from "command-exists";
21
22
  import chokidar from "chokidar";
22
23
  import _ from "lodash";
23
- import { getUidByManifest } from "../lzc_sdk.js";
24
24
  import { DebugBridge } from "./lpk_debug_bridge.js";
25
25
  import shellApi from "../shellapi.js";
26
26
 
@@ -107,16 +107,16 @@ export class AppDevShell {
107
107
  this.lpkBuild = lpkBuild;
108
108
  this.monitor = undefined;
109
109
  this.forceBuild = forceBuild;
110
+ this.isUserApp = false;
110
111
  }
111
112
 
112
113
  async init() {
113
114
  const manifest = await this.lpkBuild.getManifest();
114
- const uid = await getUidByManifest(manifest);
115
115
  this.monitor = await new AppDevShellMonitor(
116
116
  this.cwd,
117
- manifest["package"],
118
- uid
117
+ manifest["package"]
119
118
  ).init();
119
+ this.isUserApp = isUserApp(manifest);
120
120
  }
121
121
 
122
122
  async build() {
@@ -337,8 +337,7 @@ export class AppDevShell {
337
337
  logger.debug(err);
338
338
  }
339
339
 
340
- const uid = await getUidByManifest(manifest);
341
- const devshell = new DevShell(pkgId, uid);
340
+ const devshell = new DevShell(pkgId, this.isUserApp);
342
341
  if (isSync) {
343
342
  await devshell.shell();
344
343
  } else {
@@ -352,9 +351,9 @@ export class AppDevShell {
352
351
  }
353
352
 
354
353
  class DevShell {
355
- constructor(appId, uid = "") {
354
+ constructor(appId, isUserApp) {
356
355
  this.appId = appId;
357
- this.uid = uid;
356
+ this.isUserApp = isUserApp;
358
357
  }
359
358
 
360
359
  async syncProject(appId) {
@@ -377,7 +376,10 @@ class DevShell {
377
376
  }
378
377
 
379
378
  const rsyncDebug = process.env.RSYNCDEBUG ? "-P" : "";
380
- const dest = `root@app.${appId}.lzcapp:/lzcapp/cache/devshell`;
379
+ const host = this.isUserApp
380
+ ? `${shellApi.uid}.app.${appId}.lzcapp`
381
+ : `app.${appId}.lzcapp`;
382
+ const dest = `root@${host}:/lzcapp/cache/devshell`;
381
383
  try {
382
384
  execSync(
383
385
  `rsync ${rsyncDebug} --rsh='${rsh}' --recursive --relative --perms --update --filter=':- .gitignore' --ignore-errors --usermap=:nobody --groupmap=*:nobody . ${dest}`,
@@ -466,6 +468,6 @@ class DevShell {
466
468
 
467
469
  async connectShell() {
468
470
  const bridge = new DebugBridge();
469
- await bridge.devshell(this.appId);
471
+ await bridge.devshell(this.appId, this.isUserApp);
470
472
  }
471
473
  }
package/lib/utils.js CHANGED
@@ -294,3 +294,7 @@ export function isValidPackageName(packageName) {
294
294
  const regex = new RegExp("^(?:[a-z][a-z0-9_]*\\.)+[a-z][a-z0-9_]*$");
295
295
  return regex.test(packageName);
296
296
  }
297
+
298
+ export function isUserApp(manifest) {
299
+ return !!manifest["application"]["user_app"];
300
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazycatcloud/lzc-cli",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "lazycat cloud developer kit",
5
5
  "scripts": {
6
6
  "test": "tap",
@@ -15,8 +15,7 @@
15
15
  "files": [
16
16
  "template",
17
17
  "scripts",
18
- "lib",
19
- "cmds"
18
+ "lib"
20
19
  ],
21
20
  "bin": {
22
21
  "lzc-cli": "./scripts/cli.js"
@@ -9,5 +9,6 @@ fi
9
9
  set -e
10
10
 
11
11
  # 切换目录
12
+ mkdir -p /lzcapp/cache/devshell
12
13
  cd /lzcapp/cache/devshell
13
14
  exec /bin/sh
package/lib/lzc_sdk.js DELETED
@@ -1,83 +0,0 @@
1
- import grpc from "@grpc/grpc-js";
2
- import protoLoader from "@grpc/proto-loader";
3
- import { contextDirname } from "./utils.js";
4
- import path from "node:path";
5
- import env from "./env.js";
6
- import logger from "loglevel";
7
- import os from "node:os";
8
- import fs from "node:fs";
9
-
10
- /**
11
- * @link {https://www.npmjs.com/package/appdirs}
12
- */
13
- function getShellAPIConfigDir() {
14
- const home = os.homedir();
15
- const isMacos = process.platform == "darwin";
16
- let sufix = "/.config/hportal-client";
17
- if (isMacos) {
18
- sufix = "/Library/Application Support/hportal-client";
19
- } // TODO: need reimpl fetch windows
20
- const SHELLAPI_CONFIG_DIR = path.join(home, sufix);
21
- return SHELLAPI_CONFIG_DIR;
22
- }
23
-
24
- const coreDefinition = protoLoader.loadSync(
25
- path.join(contextDirname(), "./shellapi.proto"),
26
- {
27
- keepCase: true,
28
- longs: String,
29
- enums: String,
30
- defaults: true,
31
- oneofs: true,
32
- }
33
- );
34
- const core =
35
- grpc.loadPackageDefinition(coreDefinition).space.heiyu.hportal.shell;
36
-
37
- let client;
38
-
39
- function readShellApiInfo() {
40
- const SHELLAPI_CONFIG_DIR = getShellAPIConfigDir();
41
- const addr = fs.readFileSync(
42
- path.resolve(SHELLAPI_CONFIG_DIR, "shellapi_addr"),
43
- { encoding: "utf-8" }
44
- );
45
- const cred = fs.readFileSync(
46
- path.resolve(SHELLAPI_CONFIG_DIR, "shellapi_cred"),
47
- { encoding: "utf-8" }
48
- );
49
- return { addr, cred };
50
- }
51
-
52
- export async function getUidByManifest(manifest) {
53
- if (!manifest["application"]["user_app"]) {
54
- return "";
55
- }
56
-
57
- const { addr, cred } = readShellApiInfo();
58
-
59
- if (!client) {
60
- client = new core.ShellCore(addr, grpc.credentials.createInsecure());
61
- }
62
-
63
- const metadata = new grpc.Metadata();
64
- metadata.add("lzc-shellapi-cred", cred);
65
-
66
- const boxName = env.get("DEFAULT_BOXNAME");
67
- return new Promise((resolve, reject) => {
68
- client.queryBoxList({}, metadata, function (err, response) {
69
- if (err) {
70
- reject(err);
71
- return;
72
- }
73
- for (let box of response.boxes) {
74
- if (box.box_name == boxName) {
75
- logger.debug("当前登录用户: ", box.login_user);
76
- resolve(box.login_user);
77
- return;
78
- }
79
- }
80
- reject("没有默认盒子信息");
81
- });
82
- });
83
- }