@braedonsaunders/appkit-desk 0.8.0 → 0.10.0
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 +119 -1
- package/backend.d.ts +13 -2
- package/backend.d.ts.map +1 -1
- package/backend.js +118 -9
- package/backend.js.map +1 -1
- package/host.d.ts +45 -4
- package/host.d.ts.map +1 -1
- package/host.js +192 -26
- package/host.js.map +1 -1
- package/machine.d.ts +12 -1
- package/machine.d.ts.map +1 -1
- package/machine.js +98 -2
- package/machine.js.map +1 -1
- package/package.json +1 -1
- package/plan.d.ts +78 -0
- package/plan.d.ts.map +1 -1
- package/plan.js +163 -7
- package/plan.js.map +1 -1
- package/virtualization.d.ts.map +1 -1
- package/virtualization.js +9 -1
- package/virtualization.js.map +1 -1
- package/vz/Sources/appkit-desk-vz/Helper.swift +45 -0
package/host.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Buffer } from 'node:buffer';
|
|
2
2
|
import type { Duplex } from 'node:stream';
|
|
3
|
-
import { type DeskLauncherIdentity, type DeskGuestNetworkOptions } from './plan.js';
|
|
3
|
+
import { type DeskLauncherIdentity, type DeskGuestNetworkOptions, type DeskShare, type DeskReadOnlyAttachment, type DeskVirtiofsdSandbox } from './plan.js';
|
|
4
4
|
import { type DeskBackend } from './backend.js';
|
|
5
5
|
import type { A11yNode, DeskFrameFormat, DeskHandoverScope, DeskPoint, DeskPointerButton, DeskPorts, DeskVideoChunkKind, WindowInfo } from './events.js';
|
|
6
6
|
export declare const DEFAULT_CAPACITY = 4;
|
|
@@ -35,6 +35,13 @@ export interface DeskHostOptions {
|
|
|
35
35
|
launcherIdentity?: DeskLauncherIdentity;
|
|
36
36
|
backend?: DeskBackend;
|
|
37
37
|
guestNetwork?: DeskGuestNetworkOptions;
|
|
38
|
+
/**
|
|
39
|
+
* Cloud Hypervisor only: the `virtiofsd` (1.13 or later) behind each share.
|
|
40
|
+
* Defaults to the first on `PATH`, then `/usr/libexec/virtiofsd`.
|
|
41
|
+
*/
|
|
42
|
+
virtiofsdPath?: string;
|
|
43
|
+
/** Cloud Hypervisor only: how `virtiofsd` confines itself; defaults to `namespace`. */
|
|
44
|
+
virtiofsdSandbox?: DeskVirtiofsdSandbox;
|
|
38
45
|
ports: DeskPorts;
|
|
39
46
|
/** Override TCP dialing for tests or a host-specific transport. */
|
|
40
47
|
connectGuest?: (address: string, port: number) => Promise<Duplex>;
|
|
@@ -47,6 +54,8 @@ export interface DeskHostOptions {
|
|
|
47
54
|
now?: () => number;
|
|
48
55
|
pathExists?: (path: string) => boolean;
|
|
49
56
|
deviceExists?: (path: string) => boolean;
|
|
57
|
+
/** Whether a share's path is an existing directory; injectable for tests. */
|
|
58
|
+
isDirectory?: (path: string) => boolean;
|
|
50
59
|
/**
|
|
51
60
|
* Delete a destroyed desk's overlay. Injectable so the destroy path is
|
|
52
61
|
* testable without a filesystem; defaults to `rm(path, { force: true })`.
|
|
@@ -68,17 +77,27 @@ export interface DeskHostOptions {
|
|
|
68
77
|
* occurrence is indistinguishable, from inside the guest, from a failing host.
|
|
69
78
|
*/
|
|
70
79
|
parkWithMemory?: boolean;
|
|
80
|
+
/** Opt in to Cloud Hypervisor copy-on-write snapshot restore. */
|
|
81
|
+
memoryRestoreMode?: 'copyonwrite';
|
|
82
|
+
/** Atomically retire a parked snapshot and sync its parent directory. */
|
|
83
|
+
retireSnapshot?: (from: string, to: string) => Promise<void>;
|
|
71
84
|
/** Identifies the host CPU for conservative snapshot portability checks. */
|
|
72
85
|
cpuSignature?: () => Promise<string>;
|
|
73
86
|
readSnapshotSignature?: (directory: string) => Promise<string | null>;
|
|
74
87
|
writeSnapshotSignature?: (directory: string, signature: string) => Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* The shares a parked desk was snapshotted with, which its restore uses in
|
|
90
|
+
* place of the start options' shares. Defaults to the record the backend
|
|
91
|
+
* writes beside the snapshot; a snapshot without one had no shares.
|
|
92
|
+
*/
|
|
93
|
+
readSnapshotShares?: (directory: string) => Promise<readonly DeskShare[]>;
|
|
75
94
|
/** Create a snapshot directory; defaults to `mkdir(path, { recursive: true })`. */
|
|
76
95
|
makeSnapshotDir?: (path: string) => Promise<void>;
|
|
77
96
|
/**
|
|
78
97
|
* Destroy a snapshot; defaults to `rm(path, { recursive: true, force: true })`.
|
|
79
98
|
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
99
|
+
* Eager restore removes the snapshot while paused. Copy-on-write restore
|
|
100
|
+
* removes its retired source only after the VMM exits.
|
|
82
101
|
*/
|
|
83
102
|
removeSnapshot?: (path: string) => Promise<void>;
|
|
84
103
|
/**
|
|
@@ -112,9 +131,14 @@ export interface DeskStartOptions {
|
|
|
112
131
|
deskId: string;
|
|
113
132
|
/** Absolute path of the golden base image this desk boots from. */
|
|
114
133
|
baseImage: string;
|
|
134
|
+
/** Optional kernel and initramfs for this desk; retain them with its disk. */
|
|
135
|
+
kernelPath?: string;
|
|
136
|
+
initramfsPath?: string;
|
|
115
137
|
/** Absolute path of this desk's copy-on-write overlay. */
|
|
116
138
|
overlayPath: string;
|
|
117
139
|
memoryMb?: number;
|
|
140
|
+
/** Enable Cloud Hypervisor free-page reporting on cold boot. */
|
|
141
|
+
freePageReporting?: boolean;
|
|
118
142
|
vcpus?: number;
|
|
119
143
|
leaseMs?: number;
|
|
120
144
|
network?: {
|
|
@@ -122,6 +146,16 @@ export interface DeskStartOptions {
|
|
|
122
146
|
macAddress?: string;
|
|
123
147
|
guestAddress?: string;
|
|
124
148
|
};
|
|
149
|
+
/**
|
|
150
|
+
* Host directories shared into the guest over virtio-fs. A desk parked with
|
|
151
|
+
* memory is restored with the shares it was parked with, because a snapshot
|
|
152
|
+
* holds its devices; these take effect on its next cold boot (see
|
|
153
|
+
* `shutdown`). A parked share whose directory is gone makes the restore fail,
|
|
154
|
+
* and the desk cold boots with these instead.
|
|
155
|
+
*/
|
|
156
|
+
shares?: readonly DeskShare[];
|
|
157
|
+
/** Immutable attachments; retain their path and contents while a snapshot exists. */
|
|
158
|
+
readOnlyAttachments?: readonly DeskReadOnlyAttachment[];
|
|
125
159
|
}
|
|
126
160
|
export interface DeskExecOptions {
|
|
127
161
|
command: string;
|
|
@@ -307,7 +341,9 @@ export interface DeskHandle {
|
|
|
307
341
|
readonly deskId: string;
|
|
308
342
|
renewLease(ms: number): void;
|
|
309
343
|
/** Open a host-to-guest TCP stream; the caller owns and closes it. */
|
|
310
|
-
connect(port: number
|
|
344
|
+
connect(port: number, options?: {
|
|
345
|
+
transport?: 'tcp' | 'vsock';
|
|
346
|
+
}): Promise<Duplex>;
|
|
311
347
|
exec(options: DeskExecOptions & {
|
|
312
348
|
keepAlive: true;
|
|
313
349
|
}): Promise<DeskJob>;
|
|
@@ -345,6 +381,11 @@ export interface DeskHostStats {
|
|
|
345
381
|
}
|
|
346
382
|
export interface DeskHost {
|
|
347
383
|
start(options: DeskStartOptions): Promise<DeskHandle>;
|
|
384
|
+
/** True when this resident desk supports in-memory pause. */
|
|
385
|
+
canPause(deskId: string): boolean;
|
|
386
|
+
/** Pause a resident desk; its lease and capacity remain in effect. */
|
|
387
|
+
pause(deskId: string): Promise<void>;
|
|
388
|
+
/** Resume a paused resident desk or restore a suspended desk. */
|
|
348
389
|
resume(deskId: string): Promise<DeskHandle>;
|
|
349
390
|
suspend(deskId: string): Promise<void>;
|
|
350
391
|
/**
|
package/host.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"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"}
|
package/host.js
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
* emission to the consumer's ports, and the handover masking contract. It
|
|
9
9
|
* never touches a database and knows nothing about tenants or approvals.
|
|
10
10
|
*/
|
|
11
|
-
import { existsSync } from 'node:fs';
|
|
11
|
+
import { createReadStream, existsSync } from 'node:fs';
|
|
12
12
|
import { execFile } from 'node:child_process';
|
|
13
|
-
import { mkdir, readFile, rm, statfs, writeFile } from 'node:fs/promises';
|
|
13
|
+
import { mkdir, open, readFile, rename, rm, statfs, writeFile } from 'node:fs/promises';
|
|
14
14
|
import { arch, cpus, release, tmpdir } from 'node:os';
|
|
15
15
|
import { dirname, join } from 'node:path';
|
|
16
16
|
import { createHash, randomUUID } from 'node:crypto';
|
|
@@ -18,6 +18,7 @@ import { Buffer } from 'node:buffer';
|
|
|
18
18
|
import { connect as tcpConnect, isIP } from 'node:net';
|
|
19
19
|
import { buildDeskLaunchPlan, cleanDeskId, DEFAULT_KVM_PATH, DEFAULT_VMM_PATH, DeskError, } from './plan.js';
|
|
20
20
|
import { cloudHypervisorBackend, } from './backend.js';
|
|
21
|
+
import { readShareManifest } from './machine.js';
|
|
21
22
|
import { parseCapabilities, parseClipboardText, parseExecResult, parseHandoverBegun, parseJobStarted, parseObservation, } from './protocol.js';
|
|
22
23
|
export const DEFAULT_CAPACITY = 4;
|
|
23
24
|
export const DEFAULT_IDLE_SUSPEND_MS = 5 * 60_000;
|
|
@@ -61,6 +62,19 @@ export function createDeskHost(options) {
|
|
|
61
62
|
const deviceExists = options.deviceExists ?? existsSync;
|
|
62
63
|
const removeOverlay = options.removeOverlay ?? ((path) => rm(path, { force: true }));
|
|
63
64
|
const parkWithMemory = options.parkWithMemory ?? false;
|
|
65
|
+
if (options.memoryRestoreMode && (!parkWithMemory || backend.hypervisor === 'virtualization')) {
|
|
66
|
+
throw new DeskError('Copy-on-write restore requires Cloud Hypervisor and parkWithMemory.');
|
|
67
|
+
}
|
|
68
|
+
const retireSnapshot = options.retireSnapshot ?? (async (from, to) => {
|
|
69
|
+
await rename(from, to);
|
|
70
|
+
const directory = await open(dirname(from), 'r');
|
|
71
|
+
try {
|
|
72
|
+
await directory.sync();
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
await directory.close();
|
|
76
|
+
}
|
|
77
|
+
});
|
|
64
78
|
const makeSnapshotDir = options.makeSnapshotDir ?? ((path) => mkdir(path, { recursive: true }).then(() => undefined));
|
|
65
79
|
const removeSnapshot = options.removeSnapshot ?? ((path) => rm(path, { recursive: true, force: true }));
|
|
66
80
|
const freeBytes = options.freeBytes ?? defaultFreeBytes;
|
|
@@ -124,7 +138,7 @@ export function createDeskHost(options) {
|
|
|
124
138
|
record.lastActivityAt = now();
|
|
125
139
|
}
|
|
126
140
|
function requireMachine(record, epoch) {
|
|
127
|
-
if (record.status !== 'resident' || record.epoch !== epoch || !record.machine) {
|
|
141
|
+
if (record.status !== 'resident' || record.paused || record.epoch !== epoch || !record.machine) {
|
|
128
142
|
throw new DeskError(`Desk ${record.deskId} is not resident; resume it first.`);
|
|
129
143
|
}
|
|
130
144
|
return record.machine;
|
|
@@ -280,8 +294,26 @@ export function createDeskHost(options) {
|
|
|
280
294
|
return join(dirname(overlayPath), `${deskId}.snapshot`);
|
|
281
295
|
}
|
|
282
296
|
async function teardown(record, keepMemory = true) {
|
|
297
|
+
if (record.status === 'suspending' && record.machine) {
|
|
298
|
+
// A previous stop failed. Keep the overlay fenced until a retry confirms
|
|
299
|
+
// the VMM has exited; never boot another VM or delete it underneath one.
|
|
300
|
+
await record.machine.shutdown();
|
|
301
|
+
await removeSnapshot(snapshotDirFor(record.startOptions.overlayPath, record.deskId));
|
|
302
|
+
record.machine = null;
|
|
303
|
+
record.status = 'suspended';
|
|
304
|
+
occupied -= 1;
|
|
305
|
+
lastSuspendedAt = iso(now());
|
|
306
|
+
drainQueue();
|
|
307
|
+
return true;
|
|
308
|
+
}
|
|
283
309
|
if (record.status !== 'resident')
|
|
284
310
|
return false;
|
|
311
|
+
// Resume before issuing trim, sync, or handover commands. On failure leave
|
|
312
|
+
// the resident record intact and fenced so the caller can retry.
|
|
313
|
+
if (record.paused) {
|
|
314
|
+
await record.machine.resume();
|
|
315
|
+
record.paused = false;
|
|
316
|
+
}
|
|
285
317
|
await endHandover(record, 'revoked');
|
|
286
318
|
for (const stop of [...record.streamStops])
|
|
287
319
|
stop();
|
|
@@ -333,6 +365,26 @@ export function createDeskHost(options) {
|
|
|
333
365
|
if (parking) {
|
|
334
366
|
const snapshotDir = snapshotDirFor(record.startOptions.overlayPath, record.deskId);
|
|
335
367
|
await makeSnapshotDir(snapshotDir);
|
|
368
|
+
// Persist attachment identity before the VMM can produce a complete
|
|
369
|
+
// snapshot. A crash must never leave attached VM state with no record.
|
|
370
|
+
if (record.startOptions.readOnlyAttachments?.length) {
|
|
371
|
+
const manifest = join(snapshotDir, 'attachments.json');
|
|
372
|
+
const file = await open(manifest, 'wx', 0o600);
|
|
373
|
+
try {
|
|
374
|
+
await file.writeFile(JSON.stringify(record.startOptions.readOnlyAttachments));
|
|
375
|
+
await file.sync();
|
|
376
|
+
}
|
|
377
|
+
finally {
|
|
378
|
+
await file.close();
|
|
379
|
+
}
|
|
380
|
+
const directory = await open(snapshotDir, 'r');
|
|
381
|
+
try {
|
|
382
|
+
await directory.sync();
|
|
383
|
+
}
|
|
384
|
+
finally {
|
|
385
|
+
await directory.close();
|
|
386
|
+
}
|
|
387
|
+
}
|
|
336
388
|
await machine.park(snapshotDir);
|
|
337
389
|
const signature = await (options.cpuSignature ?? hostCpuSignature)();
|
|
338
390
|
await (options.writeSnapshotSignature ?? writeSnapshotSignature)(snapshotDir, signature);
|
|
@@ -342,10 +394,16 @@ export function createDeskHost(options) {
|
|
|
342
394
|
}
|
|
343
395
|
}
|
|
344
396
|
catch (error) {
|
|
345
|
-
//
|
|
346
|
-
//
|
|
347
|
-
// that a later boot would try to restore from.
|
|
397
|
+
// Preparation can fail before park is called, so confirm the VMM is
|
|
398
|
+
// down even when park itself normally stops on failure.
|
|
348
399
|
lastError = errorMessage(error);
|
|
400
|
+
try {
|
|
401
|
+
await machine.shutdown();
|
|
402
|
+
}
|
|
403
|
+
catch (stopError) {
|
|
404
|
+
record.machine = machine;
|
|
405
|
+
throw new DeskError(`Desk ${record.deskId} could not stop after teardown failed: ${errorMessage(stopError)}`);
|
|
406
|
+
}
|
|
349
407
|
if (parking) {
|
|
350
408
|
await removeSnapshot(snapshotDirFor(record.startOptions.overlayPath, record.deskId)).catch(() => undefined);
|
|
351
409
|
}
|
|
@@ -419,32 +477,76 @@ export function createDeskHost(options) {
|
|
|
419
477
|
// names its vsock and tap, and a cold-boot retry that renumbered them would
|
|
420
478
|
// come up on a different tap than the one the egress rules were put on.
|
|
421
479
|
const cid = nextCid++;
|
|
422
|
-
const initramfsPath = resolveInitramfsPath();
|
|
423
|
-
|
|
480
|
+
const initramfsPath = startOptions.initramfsPath ?? resolveInitramfsPath();
|
|
481
|
+
let restoreDir = snapshotDir;
|
|
482
|
+
const planFor = (restore, shares = startOptions.shares) => buildDeskLaunchPlan({
|
|
424
483
|
deskId,
|
|
425
484
|
hypervisor: backend.hypervisor ?? 'cloud-hypervisor',
|
|
426
|
-
...(backend.hypervisor === 'virtualization'
|
|
485
|
+
...(backend.hypervisor === 'virtualization'
|
|
486
|
+
? { guestNetwork: options.guestNetwork }
|
|
487
|
+
: { virtiofsdPath: options.virtiofsdPath, virtiofsdSandbox: options.virtiofsdSandbox }),
|
|
427
488
|
vmmPath: options.vmmPath,
|
|
428
489
|
kvmPath: options.kvmPath,
|
|
429
|
-
kernelPath,
|
|
490
|
+
kernelPath: startOptions.kernelPath ?? kernelPath,
|
|
430
491
|
...(initramfsPath === undefined ? {} : { initramfsPath }),
|
|
431
492
|
baseImagePath: startOptions.baseImage,
|
|
432
493
|
overlayPath: startOptions.overlayPath,
|
|
433
494
|
memoryMb: startOptions.memoryMb,
|
|
495
|
+
freePageReporting: startOptions.freePageReporting,
|
|
434
496
|
vcpus: startOptions.vcpus,
|
|
435
497
|
vsockCid: cid,
|
|
436
498
|
runtimeDir: options.runtimeDir,
|
|
437
499
|
tapDevice: startOptions.network?.tapDevice,
|
|
438
500
|
macAddress: startOptions.network?.macAddress,
|
|
501
|
+
shares,
|
|
502
|
+
readOnlyAttachments: startOptions.readOnlyAttachments,
|
|
439
503
|
// Forward the host's cmdline only when set; otherwise the plan falls
|
|
440
504
|
// back to DEFAULT_KERNEL_CMDLINE.
|
|
441
505
|
...(kernelCmdline === undefined ? {} : { kernelCmdline }),
|
|
442
506
|
launcherIdentity: options.launcherIdentity,
|
|
443
|
-
snapshotDir,
|
|
444
|
-
...(restore ? { restore: true } : {}),
|
|
445
|
-
}, { pathExists, deviceExists });
|
|
507
|
+
snapshotDir: restore ? restoreDir : snapshotDir,
|
|
508
|
+
...(restore ? { restore: true, ...(options.memoryRestoreMode ? { memoryRestoreMode: options.memoryRestoreMode } : {}) } : {}),
|
|
509
|
+
}, { pathExists, deviceExists, ...(options.isDirectory ? { isDirectory: options.isDirectory } : {}) });
|
|
510
|
+
const restorePlan = async () => {
|
|
511
|
+
const parked = await (options.readSnapshotShares ?? readShareManifest)(restoreDir);
|
|
512
|
+
try {
|
|
513
|
+
return planFor(true, parked);
|
|
514
|
+
}
|
|
515
|
+
catch (error) {
|
|
516
|
+
throw new DeskError(`its restore, with the shares it was parked with, could not be planned: ${errorMessage(error)}`);
|
|
517
|
+
}
|
|
518
|
+
};
|
|
519
|
+
// Verify bytes, not just the caller's label, before the VMM can map them.
|
|
520
|
+
for (const image of startOptions.readOnlyAttachments ?? []) {
|
|
521
|
+
const hash = createHash('sha256');
|
|
522
|
+
for await (const chunk of createReadStream(image.path))
|
|
523
|
+
hash.update(chunk);
|
|
524
|
+
if (hash.digest('hex') !== image.sha256)
|
|
525
|
+
throw new DeskError(`Read-only attachment digest mismatch: ${image.path}`);
|
|
526
|
+
}
|
|
446
527
|
let resuming = parkWithMemory && pathExists(snapshotDir);
|
|
528
|
+
// Shared guest memory, required by virtio-fs, makes Cloud Hypervisor fall
|
|
529
|
+
// back to eager restore. Reject before retiring the snapshot or cold booting.
|
|
530
|
+
if (options.memoryRestoreMode === 'copyonwrite') {
|
|
531
|
+
if (startOptions.shares?.length)
|
|
532
|
+
throw new DeskError('Copy-on-write restore cannot be combined with virtio-fs shares.');
|
|
533
|
+
if (resuming && (await (options.readSnapshotShares ?? readShareManifest)(snapshotDir)).length) {
|
|
534
|
+
throw new DeskError('The parked snapshot has virtio-fs shares and cannot use copy-on-write restore.');
|
|
535
|
+
}
|
|
536
|
+
}
|
|
447
537
|
if (resuming) {
|
|
538
|
+
let savedAttachments;
|
|
539
|
+
try {
|
|
540
|
+
savedAttachments = JSON.parse(await readFile(join(snapshotDir, 'attachments.json'), 'utf8'));
|
|
541
|
+
}
|
|
542
|
+
catch (error) {
|
|
543
|
+
if (error.code !== 'ENOENT')
|
|
544
|
+
throw error;
|
|
545
|
+
savedAttachments = [];
|
|
546
|
+
}
|
|
547
|
+
if (JSON.stringify(savedAttachments) !== JSON.stringify(startOptions.readOnlyAttachments ?? [])) {
|
|
548
|
+
throw new DeskError('Snapshot read-only attachment identity does not match; restore requires the original images.');
|
|
549
|
+
}
|
|
448
550
|
const saved = await (options.readSnapshotSignature ?? readSnapshotSignature)(snapshotDir);
|
|
449
551
|
if (saved !== null && saved !== await (options.cpuSignature ?? hostCpuSignature)()) {
|
|
450
552
|
await removeSnapshot(snapshotDir);
|
|
@@ -452,15 +554,20 @@ export function createDeskHost(options) {
|
|
|
452
554
|
recordCpuFallback(deskId, 'signature_mismatch');
|
|
453
555
|
}
|
|
454
556
|
}
|
|
557
|
+
// Retire before starting the VMM: after a crash the old name can never be
|
|
558
|
+
// replayed against a disk the guest may have changed. The retired file is
|
|
559
|
+
// private backing memory, not a restorable snapshot.
|
|
560
|
+
if (resuming && options.memoryRestoreMode === 'copyonwrite') {
|
|
561
|
+
restoreDir = `${snapshotDir}.source-${randomUUID()}`;
|
|
562
|
+
await retireSnapshot(snapshotDir, restoreDir);
|
|
563
|
+
}
|
|
455
564
|
let machine;
|
|
456
565
|
try {
|
|
457
566
|
machine = resuming
|
|
458
|
-
? await backend.boot(
|
|
459
|
-
//
|
|
460
|
-
//
|
|
461
|
-
|
|
462
|
-
// than resumed, because resuming would leave both alive at once.
|
|
463
|
-
onRestored: () => removeSnapshot(snapshotDir),
|
|
567
|
+
? await backend.boot(await restorePlan(), {
|
|
568
|
+
// Eager restore removes the parked snapshot before resume. A CoW
|
|
569
|
+
// source was already retired durably before the VMM started.
|
|
570
|
+
onRestored: options.memoryRestoreMode === 'copyonwrite' ? async () => { } : () => removeSnapshot(snapshotDir),
|
|
464
571
|
})
|
|
465
572
|
: await backend.boot(planFor(false));
|
|
466
573
|
}
|
|
@@ -471,6 +578,7 @@ export function createDeskHost(options) {
|
|
|
471
578
|
// boot. Safe by construction — the guest never ran, so the disk is
|
|
472
579
|
// exactly as the pre-park sync left it.
|
|
473
580
|
const why = errorMessage(error);
|
|
581
|
+
resuming = false;
|
|
474
582
|
await removeSnapshot(snapshotDir);
|
|
475
583
|
if (isIncompatibleCpuSnapshotError(error))
|
|
476
584
|
recordCpuFallback(deskId, 'incompatible_cpuid');
|
|
@@ -486,12 +594,31 @@ export function createDeskHost(options) {
|
|
|
486
594
|
: new DeskError(`Desk ${deskId} failed to boot: ${errorMessage(error)}`);
|
|
487
595
|
}
|
|
488
596
|
}
|
|
597
|
+
if (resuming && options.memoryRestoreMode === 'copyonwrite') {
|
|
598
|
+
// The mapping remains file-backed until the VMM has exited. Never remove
|
|
599
|
+
// it after a failed stop; leaking it is safer than invalidating a live VM.
|
|
600
|
+
const restored = machine;
|
|
601
|
+
const stop = restored.shutdown.bind(restored);
|
|
602
|
+
const park = restored.park?.bind(restored);
|
|
603
|
+
const releaseSource = async () => {
|
|
604
|
+
try {
|
|
605
|
+
await removeSnapshot(restoreDir);
|
|
606
|
+
}
|
|
607
|
+
catch (error) {
|
|
608
|
+
lastError = `Snapshot source cleanup failed for ${deskId}: ${errorMessage(error)}`;
|
|
609
|
+
}
|
|
610
|
+
};
|
|
611
|
+
restored.shutdown = async () => { await stop(); await releaseSource(); };
|
|
612
|
+
if (park)
|
|
613
|
+
restored.park = async (dir) => { await park(dir); await releaseSource(); };
|
|
614
|
+
}
|
|
489
615
|
let record = records.get(deskId);
|
|
490
616
|
if (!record) {
|
|
491
617
|
record = {
|
|
492
618
|
deskId,
|
|
493
619
|
startOptions,
|
|
494
620
|
status: 'resident',
|
|
621
|
+
paused: false,
|
|
495
622
|
machine,
|
|
496
623
|
epoch: 1,
|
|
497
624
|
leaseDeadline: 0,
|
|
@@ -510,6 +637,7 @@ export function createDeskHost(options) {
|
|
|
510
637
|
else {
|
|
511
638
|
record.startOptions = startOptions;
|
|
512
639
|
record.status = 'resident';
|
|
640
|
+
record.paused = false;
|
|
513
641
|
record.machine = machine;
|
|
514
642
|
record.epoch += 1;
|
|
515
643
|
record.jobs = new Map();
|
|
@@ -756,22 +884,28 @@ export function createDeskHost(options) {
|
|
|
756
884
|
return {
|
|
757
885
|
deskId: record.deskId,
|
|
758
886
|
renewLease(ms) {
|
|
759
|
-
|
|
887
|
+
// Renewing a lease is host-side and remains valid during resident pause.
|
|
888
|
+
if (record.status !== 'resident' || record.epoch !== epoch || !record.machine) {
|
|
889
|
+
throw new DeskError(`Desk ${record.deskId} is not resident; resume it first.`);
|
|
890
|
+
}
|
|
760
891
|
record.leaseDeadline = now() + positiveInteger(ms, 'ms');
|
|
761
892
|
touch(record);
|
|
762
893
|
armTimer(record);
|
|
763
894
|
},
|
|
764
|
-
async connect(port) {
|
|
895
|
+
async connect(port, choice) {
|
|
765
896
|
requireMachine(record, epoch);
|
|
766
897
|
if (!Number.isInteger(port) || port < 1 || port > 65535)
|
|
767
898
|
throw new DeskError('Guest TCP port must be between 1 and 65535.');
|
|
768
899
|
const machine = requireMachine(record, epoch);
|
|
769
900
|
const address = record.startOptions.network?.guestAddress;
|
|
770
|
-
|
|
901
|
+
const useVsock = choice?.transport === 'vsock' || (choice?.transport !== 'tcp' && !!machine.connect);
|
|
902
|
+
if (useVsock && !machine.connect)
|
|
903
|
+
throw new DeskError('This backend has no service vsock connector.');
|
|
904
|
+
if (!useVsock && (!address || isIP(address) !== 4))
|
|
771
905
|
throw new DeskError('A guest IPv4 address is required to connect to a desk port.');
|
|
772
906
|
touch(record);
|
|
773
907
|
try {
|
|
774
|
-
const stream =
|
|
908
|
+
const stream = useVsock ? await machine.connect(port) : await (options.connectGuest ?? connectGuestTcp)(address, port);
|
|
775
909
|
try {
|
|
776
910
|
requireMachine(record, epoch);
|
|
777
911
|
}
|
|
@@ -1149,19 +1283,51 @@ export function createDeskHost(options) {
|
|
|
1149
1283
|
const deskId = cleanDeskId(startOptions.deskId);
|
|
1150
1284
|
return serializeLifecycle(deskId, async () => {
|
|
1151
1285
|
const existing = records.get(deskId);
|
|
1152
|
-
if (existing?.status === '
|
|
1286
|
+
if (existing?.status === 'suspending')
|
|
1287
|
+
throw new DeskError(`Desk ${deskId} has not stopped; retry suspend first.`);
|
|
1288
|
+
if (existing?.status === 'resident' && existing.handle) {
|
|
1289
|
+
if (existing.paused) {
|
|
1290
|
+
await existing.machine.resume();
|
|
1291
|
+
existing.paused = false;
|
|
1292
|
+
}
|
|
1153
1293
|
return existing.handle;
|
|
1294
|
+
}
|
|
1154
1295
|
return admit(() => boot(deskId, { ...startOptions, deskId }));
|
|
1155
1296
|
});
|
|
1156
1297
|
}
|
|
1298
|
+
function canPause(deskId) {
|
|
1299
|
+
const record = records.get(cleanDeskId(deskId));
|
|
1300
|
+
return record?.status === 'resident' && typeof record.machine?.pause === 'function' && typeof record.machine?.resume === 'function';
|
|
1301
|
+
}
|
|
1302
|
+
async function pause(deskId) {
|
|
1303
|
+
const id = cleanDeskId(deskId);
|
|
1304
|
+
await serializeLifecycle(id, async () => {
|
|
1305
|
+
const record = records.get(id);
|
|
1306
|
+
if (!record || record.status !== 'resident' || !canPause(id))
|
|
1307
|
+
throw new DeskError(`Desk ${id} cannot be paused.`);
|
|
1308
|
+
if (record.paused)
|
|
1309
|
+
return;
|
|
1310
|
+
if (record.screen?.handover)
|
|
1311
|
+
throw new DeskError(`Desk ${id} has an active handover.`);
|
|
1312
|
+
record.paused = true;
|
|
1313
|
+
await record.machine.pause();
|
|
1314
|
+
});
|
|
1315
|
+
}
|
|
1157
1316
|
async function resume(deskId) {
|
|
1158
1317
|
const id = cleanDeskId(deskId);
|
|
1159
1318
|
return serializeLifecycle(id, async () => {
|
|
1160
1319
|
const record = records.get(id);
|
|
1161
1320
|
if (!record)
|
|
1162
1321
|
throw new DeskError(`Unknown desk: ${deskId}`);
|
|
1163
|
-
if (record.status === '
|
|
1322
|
+
if (record.status === 'suspending')
|
|
1323
|
+
throw new DeskError(`Desk ${id} has not stopped; retry suspend first.`);
|
|
1324
|
+
if (record.status === 'resident' && record.handle) {
|
|
1325
|
+
if (record.paused) {
|
|
1326
|
+
await record.machine.resume();
|
|
1327
|
+
record.paused = false;
|
|
1328
|
+
}
|
|
1164
1329
|
return record.handle;
|
|
1330
|
+
}
|
|
1165
1331
|
return admit(() => boot(record.deskId, record.startOptions));
|
|
1166
1332
|
});
|
|
1167
1333
|
}
|
|
@@ -1283,7 +1449,7 @@ export function createDeskHost(options) {
|
|
|
1283
1449
|
lastSnapshotCpuFallback,
|
|
1284
1450
|
};
|
|
1285
1451
|
}
|
|
1286
|
-
return { start, resume, suspend, shutdown, destroy, stats, sweep };
|
|
1452
|
+
return { start, canPause, pause, resume, suspend, shutdown, destroy, stats, sweep };
|
|
1287
1453
|
}
|
|
1288
1454
|
/**
|
|
1289
1455
|
* Whether the overlay directory's filesystem can make reflink clones.
|