Skip to content

Commit

Permalink
refactor(windows): support run and prepare cmd (#68)
Browse files Browse the repository at this point in the history
Signed-off-by: Kevin Cui <[email protected]>
  • Loading branch information
BlackHole1 authored Jul 12, 2024
1 parent dceccf2 commit 25c04db
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 22 deletions.
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export const createWindowsOVM = (options: OVMWindowsOptions): WindowsOVM => {
export {
OVMDarwinAppEventValue,
OVMDarwinVzState,
OVMWindowsSysEventValue,
OVMWindowsAppEventValue,
OVMWindowsRunEventValue,
OVMWindowsPrepareEventValue,
} from "./type";

export type {
Expand Down
14 changes: 9 additions & 5 deletions src/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,17 @@ abstract class Request {
public abstract info(): Promise<OVMDarwinInfo | OVMWindowsInfo>;

protected readonly socketPath: string;

protected constructor(socketPath: string) {
this.socketPath = socketPath;
}

protected async do(p: string, method: Method, timeout = DEFAULT_TIMEOUT, body?: Record<string, unknown>): Promise<string> {
protected async do(p: string, method: Method, timeout = DEFAULT_TIMEOUT, body?: Record<string, unknown>, socketPath?: string): Promise<string> {
return new Promise<string>((resolve, reject) => {
const r = http.request({
timeout,
method,
socketPath: this.socketPath,
socketPath: socketPath || this.socketPath,
path: `http://ovm/${p}`,
}, (response) => {
response.setEncoding("utf8");
Expand Down Expand Up @@ -93,23 +94,26 @@ export class RequestDarwin extends Request {
}

export class RequestWindows extends Request {
private readonly prepareSocketPath: string;

public constructor(name: string) {
super(`//./pipe/ovm-${name}`);
this.prepareSocketPath = `//./pipe/ovm-prepare-${name}`;
}

public async info(): Promise<OVMWindowsInfo> {
return JSON.parse(await this.do("info", Method.GET)) as OVMWindowsInfo;
}

public async enableFeature(): Promise<void> {
await this.do("enable-feature", Method.POST, NEVER_TIMEOUT);
await this.do("enable-feature", Method.POST, NEVER_TIMEOUT, undefined, this.prepareSocketPath);
}

public async reboot(): Promise<void> {
await this.do("reboot", Method.POST, NEVER_TIMEOUT);
await this.do("reboot", Method.POST, NEVER_TIMEOUT, undefined, this.prepareSocketPath);
}

public async updateWSL(): Promise<void> {
await this.do("update-wsl", Method.PUT, NEVER_TIMEOUT);
await this.do("update-wsl", Method.PUT, NEVER_TIMEOUT, undefined, this.prepareSocketPath);
}
}
10 changes: 5 additions & 5 deletions src/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export interface OVMWindowsOptions {
versions: OVMWindowsOptions["linuxPath"] & { data: string; };
}

export enum OVMWindowsSysEventValue {
export enum OVMWindowsPrepareEventValue {
SystemNotSupport = "SystemNotSupport",

NeedEnableFeature = "NeedEnableFeature",
Expand All @@ -93,7 +93,7 @@ export enum OVMWindowsSysEventValue {
UpdateWSLSuccess = "UpdateWSLSuccess",
}

export enum OVMWindowsAppEventValue {
export enum OVMWindowsRunEventValue {
UpdatingRootFS = "UpdatingRootFS",
UpdateRootFSFailed = "UpdateRootFSFailed",
UpdateRootFSSuccess = "UpdateRootFSSuccess",
Expand All @@ -104,12 +104,12 @@ export enum OVMWindowsAppEventValue {

Starting = "Starting",
Ready = "Ready",
Exit = "Exit",
}

export interface OVMWindowsEventData {
app: OVMWindowsAppEventValue,
sys: OVMWindowsSysEventValue,
run: OVMWindowsRunEventValue,
prepare: OVMWindowsPrepareEventValue,
error: string,
exit: void,
}

68 changes: 58 additions & 10 deletions src/windows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ import { RequestWindows } from "./request";
export class WindowsOVM extends RequestWindows {
public readonly events : EventReceiver<OVMWindowsEventData>;
readonly #events: Remitter<OVMWindowsEventData>;
private restful: Restful;
private readonly restfulNPipeName: string;
private restful: Record<"run" | "prepare", Restful>;
private readonly restfulNPipeRunName: string;
private readonly restfulNPipePrepareName: string;

private constructor(private options: OVMWindowsOptions) {
super(options.name);
this.restfulNPipeName = `ovm-${options.name}-restful`;
this.restfulNPipeRunName = `ovm-${options.name}-restful`;
this.restfulNPipePrepareName = `ovm-prepare-${options.name}-restful`;

this.events = this.#events = new Remitter();
}

Expand All @@ -24,18 +27,63 @@ export class WindowsOVM extends RequestWindows {
}

private initEventRestful(): void {
this.restful = new Restful();
this.restful = {
run: new Restful(),
prepare: new Restful(),
};

this.#events.remitAny((o) => {
return this.restful.run.events.onAny((data) => {
o.emit(data.event as keyof Omit<OVMWindowsEventData, "prepare">, data.data);
});
});

this.#events.remitAny((o) => {
return this.restful.events.onAny((data) => {
o.emit(data.event as keyof OVMWindowsEventData, data.data);
return this.restful.prepare.events.onAny((data) => {
o.emit(data.event as keyof Omit<OVMWindowsEventData, "run">, data.data);
});
});

this.restful.start(`//./pipe/${this.restfulNPipeName}`);
this.restful.run.start(`//./pipe/${this.restfulNPipeRunName}`);
this.restful.prepare.start(`//./pipe/${this.restfulNPipePrepareName}`);
}

public prepare(): void {
const prepareTimeout = new Promise<void>((resolve, reject) => {
const id = setTimeout(() => {
disposer();
// eslint-disable-next-line prefer-promise-reject-errors
reject();
}, 30 * 1000);

const disposer = this.#events.onceAny(() => {
clearTimeout(id);
resolve();
});
});

const ovm = cp.spawn(this.options.ovmPath, [
"-name", this.options.name,
"-log-path", this.options.logDir,
"-event-npipe-name", this.restfulNPipePrepareName,
"-bind-pid", String(process.pid),
], {
timeout: 0,
windowsHide: true,
detached: true,
stdio: "ignore",
cwd: this.options.imageDir,
});

ovm.unref();

prepareTimeout
.catch(() => {
this.#events.emit("error", "OVM prepare timeout");
});
}

public start(): void {
public run(): void {
const versions = Object.keys(this.options.versions).map((key) => {
return `${key}=${this.options.versions[key]}`;
}).join(",");
Expand All @@ -59,7 +107,7 @@ export class WindowsOVM extends RequestWindows {
"-image-dir", this.options.imageDir,
"-rootfs-path", this.options.linuxPath.rootfs,
"-versions", versions,
"-event-npipe-name", this.restfulNPipeName,
"-event-npipe-name", this.restfulNPipeRunName,
"-bind-pid", String(process.pid),
], {
timeout: 0,
Expand All @@ -73,7 +121,7 @@ export class WindowsOVM extends RequestWindows {

launchTimeout
.catch(() => {
this.#events.emit("error", "OVM start timeout");
this.#events.emit("error", "OVM run timeout");
});
}
}

0 comments on commit 25c04db

Please sign in to comment.