feat(runtime): stage VM runtime artifacts and writable drives in per-VM ephemeral storage by default
This commit is contained in:
@@ -678,6 +678,84 @@ tap.test('MicroVM - invalid lifecycle calls should throw SmartVMError', async ()
|
||||
expect((infoError as SmartVMError).code).toEqual('NO_CLIENT');
|
||||
});
|
||||
|
||||
tap.test('MicroVM - start() should stage writable drives ephemerally and clean them up on failure', async () => {
|
||||
const workDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'smartvm-ephemeral-drive-test-'));
|
||||
const runtimeDir = path.join(workDir, 'runtime');
|
||||
const sourceRootfs = path.join(workDir, 'rootfs.ext4');
|
||||
await fs.promises.writeFile(sourceRootfs, 'persistent-rootfs');
|
||||
|
||||
const config: IMicroVMConfig = {
|
||||
...sampleConfig,
|
||||
id: 'ephemeral-vm',
|
||||
drives: [
|
||||
{
|
||||
driveId: 'rootfs',
|
||||
pathOnHost: sourceRootfs,
|
||||
isRootDevice: true,
|
||||
isReadOnly: false,
|
||||
},
|
||||
],
|
||||
networkInterfaces: [],
|
||||
};
|
||||
const vm = new MicroVM(
|
||||
'ephemeral-vm',
|
||||
config,
|
||||
'/bin/false',
|
||||
path.join(runtimeDir, 'ephemeral-vm', 'firecracker.sock'),
|
||||
new NetworkManager(),
|
||||
{ runtimeDir },
|
||||
);
|
||||
|
||||
try {
|
||||
const error = await getRejectedError(vm.start());
|
||||
expect(error).toBeInstanceOf(SmartVMError);
|
||||
expect(fs.existsSync(path.join(runtimeDir, 'ephemeral-vm'))).toBeFalse();
|
||||
expect(await fs.promises.readFile(sourceRootfs, 'utf8')).toEqual('persistent-rootfs');
|
||||
expect(vm.getVMConfig().config.drives![0].pathOnHost).not.toEqual(sourceRootfs);
|
||||
} finally {
|
||||
await fs.promises.rm(workDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
tap.test('MicroVM - start() should honor per-drive ephemeral opt-out', async () => {
|
||||
const workDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'smartvm-persistent-drive-test-'));
|
||||
const runtimeDir = path.join(workDir, 'runtime');
|
||||
const sourceRootfs = path.join(workDir, 'rootfs.ext4');
|
||||
await fs.promises.writeFile(sourceRootfs, 'persistent-rootfs');
|
||||
|
||||
const config: IMicroVMConfig = {
|
||||
...sampleConfig,
|
||||
id: 'persistent-vm',
|
||||
drives: [
|
||||
{
|
||||
driveId: 'rootfs',
|
||||
pathOnHost: sourceRootfs,
|
||||
isRootDevice: true,
|
||||
isReadOnly: false,
|
||||
ephemeral: false,
|
||||
},
|
||||
],
|
||||
networkInterfaces: [],
|
||||
};
|
||||
const vm = new MicroVM(
|
||||
'persistent-vm',
|
||||
config,
|
||||
'/bin/false',
|
||||
path.join(runtimeDir, 'persistent-vm', 'firecracker.sock'),
|
||||
new NetworkManager(),
|
||||
{ runtimeDir },
|
||||
);
|
||||
|
||||
try {
|
||||
const error = await getRejectedError(vm.start());
|
||||
expect(error).toBeInstanceOf(SmartVMError);
|
||||
expect(vm.getVMConfig().config.drives![0].pathOnHost).toEqual(sourceRootfs);
|
||||
expect(fs.existsSync(path.join(runtimeDir, 'persistent-vm'))).toBeFalse();
|
||||
} finally {
|
||||
await fs.promises.rm(workDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
// ============================================================
|
||||
// SmartVM Tests
|
||||
// ============================================================
|
||||
@@ -688,6 +766,9 @@ tap.test('SmartVM - instantiation with defaults', async () => {
|
||||
expect(smartvm.imageManager).toBeTruthy();
|
||||
expect(smartvm.baseImageManager).toBeTruthy();
|
||||
expect(smartvm.networkManager).toBeTruthy();
|
||||
if (fs.existsSync('/dev/shm')) {
|
||||
expect(smartvm.getRuntimeDir()).toEqual('/dev/shm/.smartvm/runtime');
|
||||
}
|
||||
expect(smartvm.vmCount).toEqual(0);
|
||||
expect(smartvm.listVMs()).toHaveLength(0);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user