retool QemuVM to use the process launcher interface
Relatively easy since we basically comform to a subset of execa anyways.
This commit is contained in:
parent
d19f649a55
commit
adcefd76ef
3 changed files with 60 additions and 34 deletions
|
@ -1,11 +1,10 @@
|
|||
// Default process implementation.
|
||||
// This uses execa like the current code, but conforms to our abstration :)
|
||||
|
||||
import EventEmitter from "events";
|
||||
import { IProcess, IProcessLauncher, ProcessLaunchOptions } from "./ProcessInterface";
|
||||
import { execaCommand } from "execa";
|
||||
import { Readable, Writable } from "stream";
|
||||
// This uses execa like the previous code, but conforms to our abstration :)
|
||||
|
||||
import EventEmitter from 'events';
|
||||
import { IProcess, IProcessLauncher, ProcessLaunchOptions } from './ProcessInterface';
|
||||
import { execaCommand } from 'execa';
|
||||
import { Readable, Writable } from 'stream';
|
||||
|
||||
class DefaultProcess extends EventEmitter implements IProcess {
|
||||
private process;
|
||||
|
@ -35,6 +34,15 @@ class DefaultProcess extends EventEmitter implements IProcess {
|
|||
kill(signal?: number | NodeJS.Signals): boolean {
|
||||
return this.process.kill(signal);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.stdin = null;
|
||||
this.stdout = null;
|
||||
this.stderr = null;
|
||||
|
||||
this.process.removeAllListeners();
|
||||
this.removeAllListeners();
|
||||
}
|
||||
}
|
||||
|
||||
export class DefaultProcessLauncher implements IProcessLauncher {
|
||||
|
|
|
@ -28,6 +28,7 @@ export interface IProcess extends EventEmitter {
|
|||
|
||||
kill(signal?: number | NodeJS.Signals): boolean;
|
||||
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
// Launches a processs.
|
||||
|
|
|
@ -5,6 +5,8 @@ import { unlink } from 'node:fs/promises';
|
|||
|
||||
import pino from 'pino';
|
||||
import { Readable, Writable } from 'stream';
|
||||
import { IProcess, IProcessLauncher } from './ProcessInterface.js';
|
||||
import { DefaultProcessLauncher } from './DefaultProcess.js';
|
||||
|
||||
export enum VMState {
|
||||
Stopped,
|
||||
|
@ -68,7 +70,8 @@ export class QemuVM extends EventEmitter {
|
|||
// QMP stuff.
|
||||
private qmpInstance: QmpClient = new QmpClient();
|
||||
|
||||
private qemuProcess: ExecaChildProcess | null = null;
|
||||
private qemuProcess: IProcess | null = null;
|
||||
private qemuLauncher: IProcessLauncher;
|
||||
|
||||
private displayInfo: QemuVMDisplayInfo | null = null;
|
||||
private definition: QemuVmDefinition;
|
||||
|
@ -76,13 +79,23 @@ export class QemuVM extends EventEmitter {
|
|||
|
||||
private logger: pino.Logger;
|
||||
|
||||
constructor(def: QemuVmDefinition) {
|
||||
constructor(def: QemuVmDefinition, processLauncher?: IProcessLauncher) {
|
||||
super();
|
||||
this.definition = def;
|
||||
this.logger = pino({
|
||||
name: `SuperQEMU.QemuVM/${this.definition.id}`
|
||||
});
|
||||
|
||||
// Fall back to the default process launcher. This is
|
||||
// done so we can have our cake (compatibility) and eat it too
|
||||
// (do this fun process abstraction stuff for whatever really)
|
||||
if(!processLauncher) {
|
||||
this.logger.warn('Using default process launcher. If this is not desired review your code to make sure the launcher is passed properly!');
|
||||
this.qemuLauncher = new DefaultProcessLauncher();
|
||||
} else {
|
||||
this.qemuLauncher = processLauncher;
|
||||
}
|
||||
|
||||
let self = this;
|
||||
|
||||
// Handle the STOP event sent when using -no-shutdown
|
||||
|
@ -233,7 +246,7 @@ export class QemuVM extends EventEmitter {
|
|||
this.logger.info(`Starting QEMU with command \"${split}\"`);
|
||||
|
||||
// Start QEMU
|
||||
this.qemuProcess = execaCommand(split, {
|
||||
this.qemuProcess = this.qemuLauncher.launch(split, {
|
||||
stdin: 'pipe',
|
||||
stdout: 'pipe',
|
||||
stderr: 'pipe'
|
||||
|
@ -251,6 +264,10 @@ export class QemuVM extends EventEmitter {
|
|||
this.qemuProcess.on('exit', async (code) => {
|
||||
self.logger.info('QEMU process exited');
|
||||
|
||||
// Dispose events. StartQemu() will assign them again to the new process.
|
||||
// A bit mucky but /shrug.
|
||||
self.qemuProcess?.dispose();
|
||||
|
||||
self.qmpInstance.reset();
|
||||
self.qmpInstance.setWriter(null);
|
||||
|
||||
|
|
Loading…
Reference in a new issue