@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.
- package/README.md +69 -11
- package/lib/api.js +71 -36
- package/lib/app/index.js +79 -23
- package/lib/app/lpk_build.js +96 -52
- package/lib/app/lpk_create.js +63 -41
- package/lib/app/lpk_create_generator.js +202 -0
- package/lib/app/lpk_devshell.js +393 -328
- package/lib/app/lpk_devshell_docker.js +211 -0
- package/lib/app/lpk_installer.js +63 -26
- package/lib/app/lpk_log.js +68 -0
- package/lib/app/lpk_status.js +18 -0
- package/lib/app/lpk_uninstall.js +19 -0
- package/lib/appstore/index.js +37 -0
- package/lib/appstore/login.js +137 -0
- package/lib/appstore/publish.js +62 -0
- package/lib/autologin.js +0 -80
- package/lib/box/api/clientapi.js +1322 -0
- package/lib/box/api/empty.js +35 -0
- package/lib/box/check_qemu.js +1 -0
- package/lib/box/index.js +41 -94
- package/lib/box/qemu_vm_mgr.js +208 -239
- package/lib/box/schemes/vm_box_system_debian.json +1 -1
- package/lib/docker-compose.js +1 -2
- package/lib/env.js +23 -142
- package/lib/key.js +1 -0
- package/lib/sdk.js +10 -25
- package/lib/utils.js +156 -233
- package/package.json +19 -11
- package/scripts/cli.js +14 -135
- package/template/_lpk/README.md +31 -0
- package/template/_lpk/exec.sh +19 -0
- package/template/_lpk/golang.manifest.yml.in +16 -0
- package/template/_lpk/lazycat.png +0 -0
- package/template/_lpk/lite.manifest.yml.in +19 -0
- package/template/_lpk/local_devshell/Dockerfile +16 -0
- package/template/_lpk/local_devshell/build.sh +5 -0
- package/template/_lpk/local_devshell/entrypoint.sh +87 -0
- package/template/{_lazycat/debug/shell → _lpk/local_devshell}/sshd_config +8 -8
- package/template/_lpk/manifest.yml.in +0 -1
- package/template/{vue/lzc-build.yml → _lpk/vue.lzc-build.yml.in} +9 -1
- package/template/golang/README.md +0 -2
- package/template/golang/_gitignore +2 -0
- package/template/golang/build.sh +6 -0
- package/template/golang/lazycat.png +0 -0
- package/template/golang/lzc-build.yml +9 -1
- package/template/golang/rego.go +15 -16
- package/template/golang/rego_test.go +13 -0
- package/template/ionic_vue3/lazycat.png +0 -0
- package/template/ionic_vue3/lzc-build.yml +9 -1
- package/template/lite/error_pages/502.html.tpl +13 -0
- package/template/lite/lazycat.png +0 -0
- package/template/lite/lzc-build.yml +60 -0
- package/cmds/app.js +0 -133
- package/cmds/config.js +0 -55
- package/cmds/create.js +0 -55
- package/cmds/dev.js +0 -130
- package/cmds/init.js +0 -125
- package/cmds/log.js +0 -103
- package/cmds/publish.js +0 -116
- package/lib/archiver.js +0 -105
- package/lib/box/hportal.js +0 -120
- package/lib/builder.js +0 -313
- package/lib/dev.js +0 -314
- package/lib/generator.js +0 -146
- package/template/_lazycat/_gitignore +0 -1
- package/template/_lazycat/app-config +0 -1
- package/template/_lazycat/debug/devforward/50x.html +0 -30
- package/template/_lazycat/debug/devforward/Dockerfile +0 -16
- package/template/_lazycat/debug/devforward/docker-compose.override.yml.in +0 -11
- package/template/_lazycat/debug/devforward/entrypoint.sh +0 -10
- package/template/_lazycat/debug/devforward/nginx.conf.template +0 -56
- package/template/_lazycat/debug/devforward/sshd_config +0 -116
- package/template/_lazycat/debug/shell/50x.html +0 -32
- package/template/_lazycat/debug/shell/Dockerfile +0 -18
- package/template/_lazycat/debug/shell/build.sh +0 -15
- package/template/_lazycat/debug/shell/docker-compose.override.yml.in +0 -13
- package/template/_lazycat/debug/shell/entrypoint.sh +0 -12
- package/template/_lazycat/docker-compose.yml.in +0 -15
- package/template/_lazycat/icon.svg +0 -1
- package/template/_lazycat/screenshot.png +0 -0
- package/template/_lpk/sync/Dockerfile +0 -16
- package/template/_lpk/sync/build.sh +0 -5
- package/template/_lpk/sync/entrypoint.sh +0 -8
- package/template/_lpk/sync/sshd_config +0 -117
- package/template/_lpk/sync.manifest.yml.in +0 -3
- package/template/release/golang/Dockerfile +0 -18
- package/template/release/golang/build.sh +0 -13
- package/template/release/ionic_vue3/Dockerfile +0 -10
- package/template/release/ionic_vue3/build.sh +0 -7
- package/template/release/ionic_vue3/docker-compose.yml.in +0 -3
- package/template/release/vue/Dockerfile +0 -10
- package/template/release/vue/build.sh +0 -10
- package/template/release/vue/docker-compose.yml.in +0 -3
- package/template/vue/README.md +0 -29
- package/template/vue/_dockerignore +0 -1
- package/template/vue/babel.config.js +0 -3
- package/template/vue/package.json +0 -43
- package/template/vue/public/favicon.ico +0 -0
- package/template/vue/public/index.html +0 -33
- package/template/vue/src/App.vue +0 -39
- package/template/vue/src/main.js +0 -8
- package/template/vue/src/todo.vue +0 -640
- package/template/vue/src/top-bar.vue +0 -100
- package/template/vue/src/webdav.vue +0 -183
- package/template/vue/vue.config.js +0 -21
package/lib/dev.js
DELETED
|
@@ -1,314 +0,0 @@
|
|
|
1
|
-
import execa from "execa";
|
|
2
|
-
import { execSync } from "child_process";
|
|
3
|
-
import fs from "fs";
|
|
4
|
-
import chalk from "chalk";
|
|
5
|
-
import {
|
|
6
|
-
GitIgnore,
|
|
7
|
-
isDirSync,
|
|
8
|
-
isFileExist,
|
|
9
|
-
urlHostname,
|
|
10
|
-
APP_SDK_HOSTNAME,
|
|
11
|
-
} from "./utils.js";
|
|
12
|
-
import path from "path";
|
|
13
|
-
import env, { sdkEnv } from "./env.js";
|
|
14
|
-
import _get from "lodash.get";
|
|
15
|
-
import { execPreBuild } from "./builder.js";
|
|
16
|
-
import chokidar from "chokidar";
|
|
17
|
-
import commandExists from "command-exists";
|
|
18
|
-
|
|
19
|
-
import Archiver from "../lib/archiver.js";
|
|
20
|
-
|
|
21
|
-
async function sdkSSHAddr(env) {
|
|
22
|
-
let url = sdkEnv.sdkUrl;
|
|
23
|
-
return `${APP_SDK_HOSTNAME}@${urlHostname(url)}:2222`;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function ParseAppAddress(appId) {
|
|
27
|
-
return `${appId}.${appId}.lzcapp`;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
class DevModule {
|
|
31
|
-
constructor(appId, cwd) {
|
|
32
|
-
this.appId = appId;
|
|
33
|
-
this.tempDir = path.join(cwd, "output/debug");
|
|
34
|
-
this.cwd = cwd;
|
|
35
|
-
// this.env = Env(cwd);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
reset() {
|
|
39
|
-
try {
|
|
40
|
-
fs.rmSync(this.tempDir, { recursive: true });
|
|
41
|
-
} catch (e) {}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// 生成一个包含ssh key的App
|
|
45
|
-
async fakeApp(command) {
|
|
46
|
-
const buildDir = path.join(this.cwd, `debug/${command}`);
|
|
47
|
-
try {
|
|
48
|
-
const allEnv = {
|
|
49
|
-
...env.all,
|
|
50
|
-
APP_IMAGE_NAME: env.get("APP_ID"),
|
|
51
|
-
};
|
|
52
|
-
await execPreBuild(buildDir, buildDir, allEnv);
|
|
53
|
-
let arch = new Archiver(this.tempDir);
|
|
54
|
-
await arch.load(this.cwd, allEnv);
|
|
55
|
-
await arch.add(buildDir);
|
|
56
|
-
return await arch.finalize();
|
|
57
|
-
} catch (e) {
|
|
58
|
-
throw e;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
getAddress() {
|
|
63
|
-
return ParseAppAddress(this.appId);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// 使用tempDir中的private key进行连接
|
|
67
|
-
async portForward(localaddr) {
|
|
68
|
-
let localServer;
|
|
69
|
-
|
|
70
|
-
try {
|
|
71
|
-
if (!localaddr) {
|
|
72
|
-
let port = env.get("DEV_PORT");
|
|
73
|
-
localaddr = `0.0.0.0:${port}`;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
localServer = execa.command(env.get("DEV_CMD"), {
|
|
77
|
-
stdio: "inherit",
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
const appAddr = this.getAddress();
|
|
81
|
-
|
|
82
|
-
let jump = await sdkSSHAddr(env);
|
|
83
|
-
const subproces = execa(
|
|
84
|
-
"ssh",
|
|
85
|
-
[
|
|
86
|
-
"-J",
|
|
87
|
-
jump,
|
|
88
|
-
"-o",
|
|
89
|
-
"StrictHostKeyChecking=no",
|
|
90
|
-
"-o",
|
|
91
|
-
"UserKnownHostsFile=/dev/null",
|
|
92
|
-
"-o",
|
|
93
|
-
"ConnectionAttempts=3",
|
|
94
|
-
"-o",
|
|
95
|
-
"ConnectTimeout=30",
|
|
96
|
-
"-o",
|
|
97
|
-
"LogLevel=ERROR",
|
|
98
|
-
"-R",
|
|
99
|
-
`/lazycat_cloud_debug.sock:${localaddr}`,
|
|
100
|
-
"root@" + appAddr,
|
|
101
|
-
"-i",
|
|
102
|
-
path.join(this.tempDir, "debug/ssh/id_ed25519"),
|
|
103
|
-
"-t",
|
|
104
|
-
],
|
|
105
|
-
{ stdio: ["pipe", "inherit", "inherit"] }
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
process.on("SIGINT", () => {
|
|
109
|
-
process.exit();
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
await subproces;
|
|
113
|
-
} catch (e) {
|
|
114
|
-
this.reset();
|
|
115
|
-
return Promise.reject(e);
|
|
116
|
-
} finally {
|
|
117
|
-
if (localServer) localServer.kill("SIGINT");
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
async syncProject(keyFile, appAddr) {
|
|
122
|
-
let jump = await sdkSSHAddr(env);
|
|
123
|
-
let rsh = [
|
|
124
|
-
"ssh",
|
|
125
|
-
"-J",
|
|
126
|
-
jump,
|
|
127
|
-
"-o",
|
|
128
|
-
`"StrictHostKeyChecking=no"`,
|
|
129
|
-
"-o",
|
|
130
|
-
`"UserKnownHostsFile=/dev/null"`,
|
|
131
|
-
"-o",
|
|
132
|
-
`"ConnectionAttempts=3"`,
|
|
133
|
-
"-o",
|
|
134
|
-
`"ConnectTimeout=30"`,
|
|
135
|
-
"-o",
|
|
136
|
-
`"LogLevel=ERROR"`,
|
|
137
|
-
"-i",
|
|
138
|
-
keyFile,
|
|
139
|
-
].join(" ");
|
|
140
|
-
// 检查rsync工具是否存在:提示用户
|
|
141
|
-
const rsyncExisted = commandExists.sync('rsync')
|
|
142
|
-
if (!rsyncExisted) {
|
|
143
|
-
console.log(chalk.red("请检查 rsync 是否安装,路径是否正确!"));
|
|
144
|
-
process.exit();
|
|
145
|
-
}
|
|
146
|
-
// FIXME: 下方执行命令不确定是否有兼容性问题
|
|
147
|
-
execSync(
|
|
148
|
-
`rsync --rsh='${rsh}' -czrPR . root@${appAddr}:/root/${this.appId} --filter=':- .gitignore' --exclude='node_modules' --exclude='.git' --delete`,
|
|
149
|
-
{ stdio: ["ignore", "ignore", "inherit"] }
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// fallback fs.watch on not darwin and windows platform
|
|
154
|
-
// FILEPATH directory or file path
|
|
155
|
-
// CALLBACK => function(eventType, filename)
|
|
156
|
-
// fs.watch 虽然不支持递归,但可以直接监听整个文件夹的变动
|
|
157
|
-
async fallbackWatch(filepath, gitignore, callback) {
|
|
158
|
-
if (gitignore.contain(filepath)) {
|
|
159
|
-
return Promise.resolve();
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (filepath.endsWith(".git") || filepath.endsWith(".lazycat")) {
|
|
163
|
-
return Promise.resolve();
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
fs.watch(filepath, callback(filepath));
|
|
167
|
-
|
|
168
|
-
// 如果为一个文件夹,则扫描当中是否含有子文件夹
|
|
169
|
-
if (isDirSync(filepath)) {
|
|
170
|
-
return gitignore.readdir(filepath, (err, files) => {
|
|
171
|
-
if (err) {
|
|
172
|
-
throw err;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (files.length <= 0) {
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
files.forEach((f) => {
|
|
180
|
-
if (f.isDirectory()) {
|
|
181
|
-
this.fallbackWatch(
|
|
182
|
-
path.join(filepath, f.name),
|
|
183
|
-
gitignore,
|
|
184
|
-
callback
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// 监听非.gitignore文件
|
|
193
|
-
// TODO: 目前仅仅监听process.cwd()以下的文件
|
|
194
|
-
async watchFile(keyFile, appAddr) {
|
|
195
|
-
const ignore = new GitIgnore(process.cwd());
|
|
196
|
-
await ignore.collect();
|
|
197
|
-
chokidar
|
|
198
|
-
.watch(".", {
|
|
199
|
-
ignored: (path) => {
|
|
200
|
-
if ([".git", ".lazycat"].some((p) => path.startsWith(p))) return true;
|
|
201
|
-
|
|
202
|
-
return ignore.contain(path);
|
|
203
|
-
},
|
|
204
|
-
ignoreInitial: true,
|
|
205
|
-
})
|
|
206
|
-
.on("all", (event, path) => {
|
|
207
|
-
// console.log(event, path);
|
|
208
|
-
this.syncProject(keyFile, appAddr);
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// 保存一个dev shell状态的文件,如果重复执行dev shell
|
|
213
|
-
// 会先判断这个临时文件是否存在,如果不存在重新部署,更新流程
|
|
214
|
-
// 否则直接ssh连接
|
|
215
|
-
async storeShellStatus(keyFile, appAddr, isWatch) {
|
|
216
|
-
fs.writeFileSync(
|
|
217
|
-
path.join(this.tempDir, ".shellStatus"),
|
|
218
|
-
JSON.stringify({
|
|
219
|
-
keyFile,
|
|
220
|
-
appAddr,
|
|
221
|
-
isWatch,
|
|
222
|
-
})
|
|
223
|
-
);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
hasShellStatus() {
|
|
227
|
-
return isFileExist(path.join(this.tempDir, ".shellStatus"));
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
async readShellStatus() {
|
|
231
|
-
return JSON.parse(
|
|
232
|
-
fs.readFileSync(path.join(this.tempDir, ".shellStatus"), "utf-8")
|
|
233
|
-
);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
async directShell() {
|
|
237
|
-
let keyFile, appAddr, isWatch;
|
|
238
|
-
try {
|
|
239
|
-
({ keyFile, appAddr, isWatch } = await this.readShellStatus());
|
|
240
|
-
|
|
241
|
-
if (!isWatch) {
|
|
242
|
-
await this.syncProject(keyFile, appAddr);
|
|
243
|
-
// 注册watch函数
|
|
244
|
-
await this.watchFile(keyFile, appAddr);
|
|
245
|
-
|
|
246
|
-
this.storeShellStatus(keyFile, appAddr, true);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
await this.connectShell(keyFile, appAddr);
|
|
250
|
-
} catch (e) {
|
|
251
|
-
return Promise.reject(e);
|
|
252
|
-
} finally {
|
|
253
|
-
if (!isWatch) {
|
|
254
|
-
this.storeShellStatus(keyFile, appAddr, false);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
async shell() {
|
|
260
|
-
let keyFile;
|
|
261
|
-
let appAddr;
|
|
262
|
-
|
|
263
|
-
try {
|
|
264
|
-
keyFile = path.join(this.tempDir, "debug/ssh/id_ed25519");
|
|
265
|
-
appAddr = this.getAddress();
|
|
266
|
-
|
|
267
|
-
// 当进入shell的时候,都同步一次
|
|
268
|
-
await this.syncProject(keyFile, appAddr);
|
|
269
|
-
// 注册watch函数
|
|
270
|
-
await this.watchFile(keyFile, appAddr);
|
|
271
|
-
|
|
272
|
-
this.storeShellStatus(keyFile, appAddr, true);
|
|
273
|
-
|
|
274
|
-
await this.connectShell(keyFile, appAddr);
|
|
275
|
-
} catch (e) {
|
|
276
|
-
console.log(e);
|
|
277
|
-
// this.reset();
|
|
278
|
-
return Promise.reject(e);
|
|
279
|
-
} finally {
|
|
280
|
-
// 当shell退出后,更新isWatch状态
|
|
281
|
-
this.storeShellStatus(keyFile, appAddr, false);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
async connectShell(keyFile, appAddr) {
|
|
286
|
-
let jump = await sdkSSHAddr(env);
|
|
287
|
-
const subproces = execa(
|
|
288
|
-
"ssh",
|
|
289
|
-
[
|
|
290
|
-
"-J",
|
|
291
|
-
jump,
|
|
292
|
-
"-o",
|
|
293
|
-
"StrictHostKeyChecking=no",
|
|
294
|
-
"-o",
|
|
295
|
-
"UserKnownHostsFile=/dev/null",
|
|
296
|
-
"-o",
|
|
297
|
-
"ConnectionAttempts=3",
|
|
298
|
-
"-o",
|
|
299
|
-
"ConnectTimeout=30",
|
|
300
|
-
"-o",
|
|
301
|
-
"LogLevel=ERROR",
|
|
302
|
-
"root@" + appAddr,
|
|
303
|
-
"-i",
|
|
304
|
-
keyFile,
|
|
305
|
-
"-t",
|
|
306
|
-
`"cd ~/${env.get("APP_ID")}; exec \\$SHELL -l"`,
|
|
307
|
-
],
|
|
308
|
-
{ stdio: "inherit", shell: true }
|
|
309
|
-
);
|
|
310
|
-
await subproces;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
export default DevModule;
|
package/lib/generator.js
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import glob from "fast-glob";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import fs from "fs";
|
|
4
|
-
import execa from "execa";
|
|
5
|
-
import { isBinaryFileSync } from "isbinaryfile";
|
|
6
|
-
import { contextDirname } from "./utils.js";
|
|
7
|
-
import chalk from "chalk";
|
|
8
|
-
|
|
9
|
-
const __dirname = contextDirname();
|
|
10
|
-
|
|
11
|
-
export const TemplateConfig = {
|
|
12
|
-
ionic_vue3: {
|
|
13
|
-
template: "ionic_vue3",
|
|
14
|
-
defaultEnvs: {
|
|
15
|
-
HTTP_SERVICE_PORT: "80",
|
|
16
|
-
BUILD_CONTEXT: ".lazycat/release",
|
|
17
|
-
},
|
|
18
|
-
after: async function (name) {
|
|
19
|
-
console.log(chalk.green("开始安装依赖"));
|
|
20
|
-
|
|
21
|
-
const subprocess = execa("npm", ["install"], {
|
|
22
|
-
cwd: path.join(process.cwd(), name),
|
|
23
|
-
stdio: "inherit",
|
|
24
|
-
});
|
|
25
|
-
await subprocess;
|
|
26
|
-
console.log(
|
|
27
|
-
chalk.green(
|
|
28
|
-
`
|
|
29
|
-
✨ 懒猫云应用 ${name} 已创建:
|
|
30
|
-
${chalk.yellow(`cd ${name}`)}
|
|
31
|
-
${chalk.yellow(`npm run dev`)}
|
|
32
|
-
将应用部署至设备中:
|
|
33
|
-
${chalk.yellow(`lzc-cli deploy`)}
|
|
34
|
-
生成android代码:
|
|
35
|
-
${chalk.yellow(`npm run build_android`)}
|
|
36
|
-
生成ios代码:
|
|
37
|
-
${chalk.yellow(`npm run build_ios`)}
|
|
38
|
-
`.trim()
|
|
39
|
-
)
|
|
40
|
-
);
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
vue: {
|
|
44
|
-
template: "vue",
|
|
45
|
-
defaultEnvs: {
|
|
46
|
-
HTTP_SERVICE_PORT: "80",
|
|
47
|
-
BUILD_CONTEXT: ".lazycat/release",
|
|
48
|
-
},
|
|
49
|
-
after: async function (name) {
|
|
50
|
-
console.log(chalk.green("开始安装依赖"));
|
|
51
|
-
|
|
52
|
-
const subprocess = execa("npm", ["install"], {
|
|
53
|
-
cwd: path.join(process.cwd(), name),
|
|
54
|
-
stdio: "inherit",
|
|
55
|
-
});
|
|
56
|
-
await subprocess;
|
|
57
|
-
console.log(
|
|
58
|
-
chalk.green(
|
|
59
|
-
`
|
|
60
|
-
✨ 懒猫云应用 ${name} 已创建:
|
|
61
|
-
${chalk.yellow(`cd ${name}`)}
|
|
62
|
-
${chalk.yellow(`npm run serve`)}
|
|
63
|
-
将应用部署至设备中:
|
|
64
|
-
${chalk.yellow(`lzc-cli deploy`)}
|
|
65
|
-
`.trim()
|
|
66
|
-
)
|
|
67
|
-
);
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
golang: {
|
|
71
|
-
template: "golang",
|
|
72
|
-
defaultEnvs: {
|
|
73
|
-
BUILD_CMD: "go build -o release .",
|
|
74
|
-
HTTP_SERVICE_PORT: "3000",
|
|
75
|
-
},
|
|
76
|
-
after: function (name) {
|
|
77
|
-
console.log(
|
|
78
|
-
chalk.green(
|
|
79
|
-
`
|
|
80
|
-
✨ 懒猫云应用 ${name} 已创建:
|
|
81
|
-
${chalk.yellow(`cd ${name}`)}
|
|
82
|
-
${chalk.yellow(`go run .`)}
|
|
83
|
-
将应用部署至设备中:
|
|
84
|
-
${chalk.yellow(`lzc-cli deploy`)}
|
|
85
|
-
`.trim()
|
|
86
|
-
)
|
|
87
|
-
);
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
class Generator {
|
|
93
|
-
constructor(context) {
|
|
94
|
-
this.context = context || {};
|
|
95
|
-
this.templateRoot = path.join(__dirname, "../template/");
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
async generate(from, to, opts = {}) {
|
|
99
|
-
const files = await this.loadFiles(from, opts.prefix);
|
|
100
|
-
this.writeFileTree(to, files);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
async loadFiles(dirPath, prefix = "") {
|
|
104
|
-
const templateDir = path.join(this.templateRoot, dirPath);
|
|
105
|
-
|
|
106
|
-
const _files = await glob(["**/*"], { cwd: templateDir });
|
|
107
|
-
let content;
|
|
108
|
-
let files = {};
|
|
109
|
-
for (let p of _files) {
|
|
110
|
-
const sourcePath = path.join(templateDir, p);
|
|
111
|
-
|
|
112
|
-
const statInfo = fs.statSync(sourcePath);
|
|
113
|
-
const mode = statInfo.mode;
|
|
114
|
-
if (isBinaryFileSync(sourcePath)) {
|
|
115
|
-
content = fs.readFileSync(sourcePath);
|
|
116
|
-
} else {
|
|
117
|
-
content = fs.readFileSync(sourcePath, "utf8");
|
|
118
|
-
}
|
|
119
|
-
// change _ prefix file into dot file
|
|
120
|
-
if (p.startsWith("_")) {
|
|
121
|
-
p = p.replace("_", ".");
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
files[path.join(prefix, p)] = {
|
|
125
|
-
content,
|
|
126
|
-
mode,
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
return new Promise((resolve) => resolve(files));
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
writeFileTree(target, files) {
|
|
133
|
-
Object.keys(files).forEach((p) => {
|
|
134
|
-
const filePath = path.join(target, p);
|
|
135
|
-
if (!fs.existsSync(path.dirname(filePath))) {
|
|
136
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
137
|
-
}
|
|
138
|
-
console.log(`创建文件 ${filePath}`);
|
|
139
|
-
fs.writeFileSync(filePath, files[p].content, { mode: files[p].mode });
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
export default (context) => {
|
|
145
|
-
return new Generator(context);
|
|
146
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/output
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE >
|
|
2
|
-
<html>
|
|
3
|
-
<meta charset="utf-8" />
|
|
4
|
-
<head>
|
|
5
|
-
<title>OMG!!</title>
|
|
6
|
-
</head>
|
|
7
|
-
<body>
|
|
8
|
-
<h1>错误,请检查相关的服务已经启动</h1>
|
|
9
|
-
<ul>
|
|
10
|
-
<li><code>lzc-cli dev forward</code> 会将本地的端口转发到app容器里面</li>
|
|
11
|
-
<li><code>lzc-cli dev shell</code> 进去app容器</li>
|
|
12
|
-
<li><code>lzc-cli deploy</code>部署app</li>
|
|
13
|
-
</ul>
|
|
14
|
-
</body>
|
|
15
|
-
|
|
16
|
-
<style>
|
|
17
|
-
li {
|
|
18
|
-
margin: 14px;
|
|
19
|
-
font-size: 1.5rem;
|
|
20
|
-
}
|
|
21
|
-
code {
|
|
22
|
-
color: rgb(115 193 153);
|
|
23
|
-
margin: 0px 14px;
|
|
24
|
-
}
|
|
25
|
-
.warning {
|
|
26
|
-
width: fit-content;
|
|
27
|
-
background-color: rgb(255 229 100 / 30%);
|
|
28
|
-
}
|
|
29
|
-
</style>
|
|
30
|
-
</html>
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
FROM nginx:1.21.4-alpine
|
|
2
|
-
|
|
3
|
-
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
|
|
4
|
-
|
|
5
|
-
RUN apk add --no-cache openssh nginx \
|
|
6
|
-
&& echo "root:root" | chpasswd
|
|
7
|
-
|
|
8
|
-
EXPOSE 22
|
|
9
|
-
|
|
10
|
-
COPY sshd_config /etc/ssh/sshd_config
|
|
11
|
-
|
|
12
|
-
COPY entrypoint.sh /entrypoint.sh
|
|
13
|
-
|
|
14
|
-
RUN chmod +x /entrypoint.sh
|
|
15
|
-
|
|
16
|
-
ENTRYPOINT ["/entrypoint.sh"]
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
services:
|
|
2
|
-
${APP_ID}:
|
|
3
|
-
pull_policy: build
|
|
4
|
-
build: .
|
|
5
|
-
environment:
|
|
6
|
-
- NGINX_ENVSUBST_OUTPUT_DIR=/etc/nginx
|
|
7
|
-
- APP_PORT=${DEV_PORT}
|
|
8
|
-
volumes:
|
|
9
|
-
- ./debug/ssh:/root/.ssh
|
|
10
|
-
- ./nginx.conf.template:/etc/nginx/templates/nginx.conf.template
|
|
11
|
-
- ./50x.html:/etc/nginx/50x.html
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
# need to use root permission to connect unix socket
|
|
2
|
-
user root;
|
|
3
|
-
worker_processes 1;
|
|
4
|
-
|
|
5
|
-
error_log /var/log/nginx/error.log info;
|
|
6
|
-
pid /var/run/nginx.pid;
|
|
7
|
-
|
|
8
|
-
events {
|
|
9
|
-
worker_connections 1024;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
http {
|
|
14
|
-
include /etc/nginx/mime.types;
|
|
15
|
-
default_type application/octet-stream;
|
|
16
|
-
|
|
17
|
-
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
|
18
|
-
'$status $body_bytes_sent "$http_referer" '
|
|
19
|
-
'"$http_user_agent" "$http_x_forwarded_for"';
|
|
20
|
-
|
|
21
|
-
access_log /var/log/nginx/access.log main;
|
|
22
|
-
|
|
23
|
-
sendfile on;
|
|
24
|
-
#tcp_nopush on;
|
|
25
|
-
|
|
26
|
-
keepalive_timeout 65;
|
|
27
|
-
|
|
28
|
-
map $http_upgrade $connection_upgrade {
|
|
29
|
-
default upgrade;
|
|
30
|
-
'' close;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
#gzip on;
|
|
34
|
-
|
|
35
|
-
server {
|
|
36
|
-
listen ${APP_PORT};
|
|
37
|
-
server_name localhost;
|
|
38
|
-
error_page 502 503 504 /50x.html;
|
|
39
|
-
|
|
40
|
-
location = /50x.html {
|
|
41
|
-
root /etc/nginx;
|
|
42
|
-
internal;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
location / {
|
|
46
|
-
# sock name need to same with ssh -R
|
|
47
|
-
proxy_pass http://unix:/lazycat_cloud_debug.sock:/;
|
|
48
|
-
proxy_set_header Host $http_host;
|
|
49
|
-
proxy_set_header X-Real-IP $remote_addr;
|
|
50
|
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
51
|
-
proxy_set_header Upgrade $http_upgrade;
|
|
52
|
-
proxy_set_header Connection $connection_upgrade;
|
|
53
|
-
proxy_next_upstream error timeout invalid_header http_502 http_503 http_504;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
# $OpenBSD: sshd_config,v 1.104 2021/07/02 05:11:21 dtucker Exp $
|
|
2
|
-
|
|
3
|
-
# This is the sshd server system-wide configuration file. See
|
|
4
|
-
# sshd_config(5) for more information.
|
|
5
|
-
|
|
6
|
-
# This sshd was compiled with PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
|
7
|
-
|
|
8
|
-
# The strategy used for options in the default sshd_config shipped with
|
|
9
|
-
# OpenSSH is to specify options with their default value where
|
|
10
|
-
# possible, but leave them commented. Uncommented options override the
|
|
11
|
-
# default value.
|
|
12
|
-
|
|
13
|
-
#Port 22
|
|
14
|
-
#AddressFamily any
|
|
15
|
-
#ListenAddress 0.0.0.0
|
|
16
|
-
#ListenAddress ::
|
|
17
|
-
|
|
18
|
-
#HostKey /etc/ssh/ssh_host_rsa_key
|
|
19
|
-
#HostKey /etc/ssh/ssh_host_ecdsa_key
|
|
20
|
-
#HostKey /etc/ssh/ssh_host_ed25519_key
|
|
21
|
-
|
|
22
|
-
# Ciphers and keying
|
|
23
|
-
#RekeyLimit default none
|
|
24
|
-
|
|
25
|
-
# Logging
|
|
26
|
-
#SyslogFacility AUTH
|
|
27
|
-
#LogLevel INFO
|
|
28
|
-
|
|
29
|
-
# Authentication:
|
|
30
|
-
|
|
31
|
-
#LoginGraceTime 2m
|
|
32
|
-
PermitRootLogin yes
|
|
33
|
-
#StrictModes yes
|
|
34
|
-
#MaxAuthTries 6
|
|
35
|
-
#MaxSessions 10
|
|
36
|
-
|
|
37
|
-
PubkeyAuthentication yes
|
|
38
|
-
|
|
39
|
-
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
|
|
40
|
-
# but this is overridden so installations will only check .ssh/authorized_keys
|
|
41
|
-
AuthorizedKeysFile .ssh/authorized_keys
|
|
42
|
-
|
|
43
|
-
#AuthorizedPrincipalsFile none
|
|
44
|
-
|
|
45
|
-
#AuthorizedKeysCommand none
|
|
46
|
-
#AuthorizedKeysCommandUser nobody
|
|
47
|
-
|
|
48
|
-
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
|
|
49
|
-
#HostbasedAuthentication no
|
|
50
|
-
# Change to yes if you don't trust ~/.ssh/known_hosts for
|
|
51
|
-
# HostbasedAuthentication
|
|
52
|
-
#IgnoreUserKnownHosts no
|
|
53
|
-
# Don't read the user's ~/.rhosts and ~/.shosts files
|
|
54
|
-
#IgnoreRhosts yes
|
|
55
|
-
|
|
56
|
-
# To disable tunneled clear text passwords, change to no here!
|
|
57
|
-
PasswordAuthentication no
|
|
58
|
-
PermitEmptyPasswords no
|
|
59
|
-
|
|
60
|
-
# Change to no to disable s/key passwords
|
|
61
|
-
#KbdInteractiveAuthentication yes
|
|
62
|
-
|
|
63
|
-
# Kerberos options
|
|
64
|
-
#KerberosAuthentication no
|
|
65
|
-
#KerberosOrLocalPasswd yes
|
|
66
|
-
#KerberosTicketCleanup yes
|
|
67
|
-
#KerberosGetAFSToken no
|
|
68
|
-
|
|
69
|
-
# GSSAPI options
|
|
70
|
-
#GSSAPIAuthentication no
|
|
71
|
-
#GSSAPICleanupCredentials yes
|
|
72
|
-
|
|
73
|
-
# Set this to 'yes' to enable PAM authentication, account processing,
|
|
74
|
-
# and session processing. If this is enabled, PAM authentication will
|
|
75
|
-
# be allowed through the KbdInteractiveAuthentication and
|
|
76
|
-
# PasswordAuthentication. Depending on your PAM configuration,
|
|
77
|
-
# PAM authentication via KbdInteractiveAuthentication may bypass
|
|
78
|
-
# the setting of "PermitRootLogin without-password".
|
|
79
|
-
# If you just want the PAM account and session checks to run without
|
|
80
|
-
# PAM authentication, then enable this but set PasswordAuthentication
|
|
81
|
-
# and KbdInteractiveAuthentication to 'no'.
|
|
82
|
-
#UsePAM no
|
|
83
|
-
|
|
84
|
-
#AllowAgentForwarding yes
|
|
85
|
-
# Feel free to re-enable these if your use case requires them.
|
|
86
|
-
AllowTcpForwarding yes
|
|
87
|
-
GatewayPorts yes
|
|
88
|
-
X11Forwarding no
|
|
89
|
-
#X11DisplayOffset 10
|
|
90
|
-
#X11UseLocalhost yes
|
|
91
|
-
#PermitTTY yes
|
|
92
|
-
#PrintMotd yes
|
|
93
|
-
#PrintLastLog yes
|
|
94
|
-
#TCPKeepAlive yes
|
|
95
|
-
#PermitUserEnvironment no
|
|
96
|
-
#Compression delayed
|
|
97
|
-
#ClientAliveInterval 0
|
|
98
|
-
#UseDNS no
|
|
99
|
-
#PidFile /run/sshd.pid
|
|
100
|
-
#MaxStartups 10:30:100
|
|
101
|
-
#PermitTunnel no
|
|
102
|
-
#ChrootDirectory none
|
|
103
|
-
#VersionAddendum none
|
|
104
|
-
|
|
105
|
-
# no default banner path
|
|
106
|
-
#Banner none
|
|
107
|
-
|
|
108
|
-
# override default of no subsystems
|
|
109
|
-
Subsystem sftp /usr/lib/ssh/sftp-server
|
|
110
|
-
|
|
111
|
-
# Example of overriding settings on a per-user basis
|
|
112
|
-
#Match User anoncvs
|
|
113
|
-
# X11Forwarding no
|
|
114
|
-
# AllowTcpForwarding no
|
|
115
|
-
# PermitTTY no
|
|
116
|
-
# ForceCommand cvs server
|