Skip to content

Commit 8abeff1

Browse files
committed
feat: v0.2.1
1 parent 9a994ab commit 8abeff1

File tree

10 files changed

+113
-150
lines changed

10 files changed

+113
-150
lines changed

README.md

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ Node wrapper for nerdctl
99
```shell
1010
# Install Homebrew
1111
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
12-
13-
# Install Lima
14-
brew install lima
1512
```
1613

1714
## Windows
@@ -73,15 +70,23 @@ yarn add nerdctl
7370
```ts
7471
import { factory } from "nerdctl";
7572

76-
const engine = factory();
73+
const callback: ProcessCallback = (data) => {
74+
console.log(data);
75+
};
7776

78-
await engine.initVM();
79-
await engine.startVM();
77+
const vm = factory();
78+
if (!(await vm.checkVM())) {
79+
await vm.initVM(callback);
80+
}
81+
if (!(await vm.checkInstance())) {
82+
await vm.initInstance(callback);
83+
}
8084

8185
const IMAGE = "hello-world";
8286

83-
await engine.pullImage(IMAGE);
84-
await engine.run(IMAGE);
87+
await vm.pullImage(IMAGE, callback);
88+
await vm.run(IMAGE, { rm: true }, callback);
89+
await vm.removeImage(IMAGE);
8590
```
8691

8792
## License

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "nerdctl",
3-
"version": "0.2.0",
3+
"version": "0.2.1",
44
"main": "dist/index.js",
55
"types": "dist/index.d.ts",
66
"description": "Node wrapper for nerdctl",

src/constants/app.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1 @@
11
export const APP_NAME = "node-nerdctl";
2-
export const IMAGE_VERSION = "0.2.9";
3-
export const ALPINE_EDITION = "rd";
4-
export const ALPINE_VERSION = "3.14.3";

src/index.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1+
import { isWindows, platform } from "./utils";
2+
13
import BaseBackend from "@/vms/base";
24
import LimaBackend from "@/vms/lima";
35
import WslBackend from "@/vms/wsl";
46
import os from "os";
5-
import { platform } from "./utils";
67

7-
export function factory(
8-
vm?: string,
9-
instance: string = "default"
10-
): BaseBackend {
8+
export function factory(vm?: string, instance?: string): BaseBackend {
119
const arch = os.arch() === "arm64" ? "aarch64" : "x86_64";
10+
instance = instance ?? isWindows ? "Ubuntu-20.04" : "default";
1211
switch (platform) {
1312
case "linux":
1413
return new LimaBackend(arch, vm, instance);

src/tests/container.test.ts

Lines changed: 0 additions & 22 deletions
This file was deleted.

src/tests/images.test.ts

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/types/index.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
import { ChildProcess } from "child_process";
2-
import { ShellString } from "shelljs";
3-
41
export type Architecture = "x86_64" | "aarch64";
52

6-
export type ExecResult = ChildProcess | ShellString | null;
7-
3+
export type ProcessCallback = (data: string) => void;
84
export interface ChildResultType {
95
stdout: string;
106
stderr: string;

src/vms/base.ts

Lines changed: 84 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Architecture, ExecResult } from "@/types";
2-
import { ExecOptions, ShellString, exec } from "shelljs";
1+
import { Architecture, ProcessCallback } from "@/types";
2+
import { ExecOptions, ShellString, exec, which } from "shelljs";
33
import { ImageResult, RemoveImageCommandFlags } from "@/types/images";
44
import {
55
LogsCommandFlags,
@@ -39,10 +39,44 @@ export default abstract class BaseBackend {
3939
return `${this.vm} shell ${this.instance} ${this.runtime}`;
4040
}
4141

42+
//#region commons
43+
protected async fork(
44+
command: string,
45+
callback?: ProcessCallback
46+
): Promise<boolean> {
47+
const child = (await this.exec(command)) as ChildProcess;
48+
49+
return await new Promise((resolve) => {
50+
child?.stdout?.on("data", (data) => {
51+
callback && callback(data);
52+
});
53+
child?.stdout?.on("close", () => {
54+
resolve(true);
55+
});
56+
child?.stderr?.on("data", (data) => {
57+
callback && callback(data);
58+
});
59+
child?.stderr?.on("close", () => {
60+
resolve(false);
61+
});
62+
});
63+
}
64+
65+
protected async execSync(
66+
command: string,
67+
options?: Omit<ExecOptions, "async">
68+
): Promise<ShellString> {
69+
return exec(command, {
70+
silent: true,
71+
async: false,
72+
...options,
73+
}) as ShellString;
74+
}
75+
4276
protected async exec(
4377
command: string,
44-
options?: ExecOptions
45-
): Promise<ExecResult> {
78+
options?: Omit<ExecOptions, "async">
79+
): Promise<ChildProcess> {
4680
return exec(command, { silent: true, async: true, ...options });
4781
}
4882

@@ -73,11 +107,22 @@ export default abstract class BaseBackend {
73107

74108
return params;
75109
}
110+
//#endregion
76111

77-
abstract initVM(): Promise<boolean>;
78-
abstract startVM(): Promise<ChildProcess | null>;
79-
abstract stopVM(): Promise<void>;
80-
abstract deleteVM(): Promise<void>;
112+
//#region VMs
113+
async checkVM(): Promise<boolean> {
114+
return !!which(this.vm);
115+
}
116+
async checkInstance(): Promise<boolean> {
117+
return true;
118+
}
119+
async initVM(callback?: ProcessCallback): Promise<boolean> {
120+
return true;
121+
}
122+
async initInstance(callback?: ProcessCallback): Promise<boolean> {
123+
return true;
124+
}
125+
//#endregion
81126

82127
//#region registry
83128
async login(
@@ -88,20 +133,25 @@ export default abstract class BaseBackend {
88133
flags
89134
)} ${server}`;
90135

91-
return (await this.exec(command, { async: false })) as ShellString;
136+
return await this.execSync(command);
92137
}
93138

94139
async logout(server?: string): Promise<ShellString> {
95140
const command = `${this.container} logout ${server}`;
96141

97-
return (await this.exec(command, { async: false })) as ShellString;
142+
return await this.execSync(command);
98143
}
99144
//#endregion
100145

101146
//#region containers
102-
async run(image: string, flags?: RunCommandFlags): Promise<ChildProcess> {
147+
async run(
148+
image: string,
149+
flags?: RunCommandFlags,
150+
callback?: ProcessCallback
151+
): Promise<boolean> {
103152
const command = `${this.container} run ${this.mergeFlags(flags)} ${image}`;
104-
return (await this.exec(command)) as ChildProcess;
153+
154+
return await this.fork(command, callback);
105155
}
106156

107157
async stop(
@@ -111,10 +161,11 @@ export default abstract class BaseBackend {
111161
const containers = Array.isArray(container)
112162
? container.join(" ")
113163
: container;
114-
return (await this.exec(
115-
`${this.container} stop ${this.mergeFlags(flags)} ${containers}`,
116-
{ async: false }
117-
)) as ShellString;
164+
const command = `${this.container} stop ${this.mergeFlags(
165+
flags
166+
)} ${containers}`;
167+
168+
return await this.execSync(command);
118169
}
119170

120171
async remove(
@@ -124,25 +175,27 @@ export default abstract class BaseBackend {
124175
const containers = Array.isArray(container)
125176
? container.join(" ")
126177
: container;
127-
return (await this.exec(
128-
`${this.container} rm ${this.mergeFlags(flags)} ${containers}`,
129-
{ async: false }
130-
)) as ShellString;
178+
const command = `${this.container} rm ${this.mergeFlags(
179+
flags
180+
)} ${containers}`;
181+
182+
return await this.execSync(command);
131183
}
132184

133-
async logs(
134-
container: string,
135-
flags?: LogsCommandFlags
136-
): Promise<ChildProcess> {
137-
return (await this.exec(
138-
`${this.container} logs ${this.mergeFlags(flags)} ${container}`
139-
)) as ChildProcess;
185+
async logs(container: string, flags?: LogsCommandFlags): Promise<boolean> {
186+
const command = `${this.container} logs ${this.mergeFlags(
187+
flags
188+
)} ${container}`;
189+
190+
return await this.fork(command);
140191
}
141192
//#endregion
142193

143194
//#region images
144-
async pullImage(image: string): Promise<ChildProcess> {
145-
return (await this.exec(`${this.container} pull ${image}`)) as ChildProcess;
195+
async pullImage(image: string, callback?: ProcessCallback): Promise<boolean> {
196+
const command = `${this.container} pull ${image}`;
197+
198+
return await this.fork(command, callback);
146199
}
147200

148201
async getImages(): Promise<ImageResult[]> {
@@ -171,11 +224,9 @@ export default abstract class BaseBackend {
171224
flags?: RemoveImageCommandFlags
172225
): Promise<ShellString> {
173226
const images = Array.isArray(image) ? image.join(" ") : image;
227+
const command = `${this.container} rmi ${this.mergeFlags(flags)} ${images}`;
174228

175-
return (await this.exec(
176-
`${this.container} rmi ${this.mergeFlags(flags)} ${images}`,
177-
{ async: false }
178-
)) as ShellString;
229+
return await this.execSync(command);
179230
}
180231
//#endregion
181232
}

src/vms/lima.ts

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,11 @@
11
import BaseBackend from "./base";
22
import { ChildProcess } from "child_process";
33
import { LimaListResult } from "@/types/lima";
4+
import { ProcessCallback } from "@/types";
45
import { isM1 } from "@/utils";
5-
import { which } from "shelljs";
66

77
export default class LimaBackend extends BaseBackend {
8-
async initVM(): Promise<boolean> {
9-
if (!which("brew")) return false;
10-
if (!which(this.vm)) {
11-
const command = `${isM1 ? `arch -arm64 ` : ""}brew install lima`;
12-
const child = (await this.exec(command)) as ChildProcess;
13-
await new Promise((resolve, reject) => {
14-
child?.stdout?.on("data", (data) => {
15-
console.log(data);
16-
});
17-
child?.stdout?.on("close", () => {
18-
resolve(true);
19-
});
20-
child?.stderr?.on("data", (data) => {
21-
console.log(data);
22-
});
23-
child?.stderr?.on("close", () => {
24-
reject(false);
25-
});
26-
});
27-
}
28-
8+
async checkInstance(): Promise<boolean> {
299
const listChild = (await this.exec(
3010
`${this.vm} list --json`
3111
)) as ChildProcess;
@@ -53,17 +33,15 @@ export default class LimaBackend extends BaseBackend {
5333
return true;
5434
}
5535

56-
async startVM(): Promise<ChildProcess> {
57-
return (await this.exec(
58-
`${this.vm} start ${this.instance}`
59-
)) as ChildProcess;
60-
}
36+
async initVM(callback?: ProcessCallback): Promise<boolean> {
37+
const command = `${isM1 ? `arch -arm64 ` : ""}brew install lima`;
6138

62-
async stopVM(): Promise<void> {
63-
await this.exec(`${this.vm} stop ${this.instance}`);
39+
return await this.fork(command, callback);
6440
}
6541

66-
async deleteVM(): Promise<void> {
67-
await this.exec(`${this.vm} delete ${this.instance}`);
42+
async initInstance(callback?: ProcessCallback): Promise<boolean> {
43+
const command = `${this.vm} start ${this.instance}`;
44+
45+
return await this.fork(command, callback);
6846
}
6947
}

0 commit comments

Comments
 (0)