@capsulos/provider-lambda 0.1.1 → 0.2.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/dist/index.d.ts +16 -0
- package/dist/index.js +57 -4
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/create.test.ts +76 -0
- package/src/index.ts +59 -3
package/dist/index.d.ts
CHANGED
|
@@ -31,7 +31,23 @@ export declare class LambdaProvider implements Provider {
|
|
|
31
31
|
/** All microVMs of one template (the API lists per image). */
|
|
32
32
|
list(template?: string): Promise<CapsuleInfo[]>;
|
|
33
33
|
terminate(id: string): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* SuspendMicrovm: the snapshot is taken and the VM stops consuming CPU.
|
|
36
|
+
* The endpoint answers 502 for a few seconds right after; `Capsule.resume()`
|
|
37
|
+
* waits for the daemon, and a request with auto-resume also wakes it.
|
|
38
|
+
*/
|
|
39
|
+
pause(id: string): Promise<void>;
|
|
40
|
+
/** ResumeMicrovm, then wait until the service reports RUNNING. */
|
|
41
|
+
resume(id: string, timeoutMs?: number): Promise<void>;
|
|
34
42
|
connect(id: string): Promise<Connection>;
|
|
43
|
+
/**
|
|
44
|
+
* Did this call's RunMicrovm launch the VM, or did its clientToken hand
|
|
45
|
+
* back one launched earlier (idempotency/recovery)? The API does not say,
|
|
46
|
+
* so: no clientToken → ours; otherwise ours when the VM started after we
|
|
47
|
+
* asked (with a minute of slack for clock skew). Unknown → not ours, which
|
|
48
|
+
* errs on the side of leaving a VM alive.
|
|
49
|
+
*/
|
|
50
|
+
private launchedBy;
|
|
35
51
|
/** A Connection from an endpoint already in hand (get() returns it): no extra GetMicrovm. */
|
|
36
52
|
connectionFor(id: string, endpoint: string): Connection;
|
|
37
53
|
/** Headers to reach another port of the capsule through the same endpoint. */
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// - the idle policy suspends and the first request auto-resumes (~0.8 s)
|
|
11
11
|
// - clientToken is both idempotency and recovery (same token → same VM);
|
|
12
12
|
// a recovered VM may be SUSPENDED, which create() accepts as alive
|
|
13
|
-
import { LambdaMicrovmsClient, RunMicrovmCommand, GetMicrovmCommand, ListMicrovmsCommand, TerminateMicrovmCommand, CreateMicrovmAuthTokenCommand, } from '@aws-sdk/client-lambda-microvms';
|
|
13
|
+
import { LambdaMicrovmsClient, RunMicrovmCommand, GetMicrovmCommand, ListMicrovmsCommand, ResumeMicrovmCommand, SuspendMicrovmCommand, TerminateMicrovmCommand, CreateMicrovmAuthTokenCommand, } from '@aws-sdk/client-lambda-microvms';
|
|
14
14
|
import { CapsuleError, } from '@capsulos/sdk';
|
|
15
15
|
const CAPSULOD_PORT = 8080;
|
|
16
16
|
function toState(s) {
|
|
@@ -48,6 +48,7 @@ export class LambdaProvider {
|
|
|
48
48
|
return `arn:aws:lambda:${this.opts.region}:${this.opts.accountId}:microvm-image:${template}`;
|
|
49
49
|
}
|
|
50
50
|
async create(spec, opts = {}) {
|
|
51
|
+
const t0 = Date.now();
|
|
51
52
|
const ingress = this.opts.ingressConnectorArn ??
|
|
52
53
|
`arn:aws:lambda:${this.opts.region}:aws:network-connector:aws-network-connector:ALL_INGRESS`;
|
|
53
54
|
const res = await this.client.send(new RunMicrovmCommand({
|
|
@@ -78,10 +79,17 @@ export class LambdaProvider {
|
|
|
78
79
|
}
|
|
79
80
|
catch (err) {
|
|
80
81
|
// Never leave a VM running without an owner: the caller gets an error,
|
|
81
|
-
// not a capsule, so the VM goes too (the error still names it).
|
|
82
|
+
// not a capsule, so the VM goes too (the error still names it). Unless
|
|
83
|
+
// the clientToken recovered a VM someone else launched: that one has
|
|
84
|
+
// an owner, so it stays and the error says so.
|
|
82
85
|
if (err instanceof CapsuleError && err.capsuleId === id) {
|
|
83
|
-
await this.
|
|
84
|
-
|
|
86
|
+
if (await this.launchedBy(id, t0, spec.clientToken)) {
|
|
87
|
+
await this.terminate(id).catch(() => undefined);
|
|
88
|
+
throw new CapsuleError(`${err.message}; terminated it`, err.status, { capsuleId: id });
|
|
89
|
+
}
|
|
90
|
+
throw new CapsuleError(`${err.message}; left it running (recovered through clientToken, it has another owner)`, err.status, {
|
|
91
|
+
capsuleId: id,
|
|
92
|
+
});
|
|
85
93
|
}
|
|
86
94
|
throw err;
|
|
87
95
|
}
|
|
@@ -138,12 +146,57 @@ export class LambdaProvider {
|
|
|
138
146
|
this.tokens.delete(id);
|
|
139
147
|
}
|
|
140
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* SuspendMicrovm: the snapshot is taken and the VM stops consuming CPU.
|
|
151
|
+
* The endpoint answers 502 for a few seconds right after; `Capsule.resume()`
|
|
152
|
+
* waits for the daemon, and a request with auto-resume also wakes it.
|
|
153
|
+
*/
|
|
154
|
+
async pause(id) {
|
|
155
|
+
await this.client.send(new SuspendMicrovmCommand({ microvmIdentifier: id }));
|
|
156
|
+
}
|
|
157
|
+
/** ResumeMicrovm, then wait until the service reports RUNNING. */
|
|
158
|
+
async resume(id, timeoutMs = 60_000) {
|
|
159
|
+
await this.client.send(new ResumeMicrovmCommand({ microvmIdentifier: id }));
|
|
160
|
+
const t0 = Date.now();
|
|
161
|
+
for (;;) {
|
|
162
|
+
const vm = await this.client.send(new GetMicrovmCommand({ microvmIdentifier: id }));
|
|
163
|
+
if (vm.state === 'RUNNING')
|
|
164
|
+
return;
|
|
165
|
+
if (vm.state === 'TERMINATED' || vm.state === 'TERMINATING') {
|
|
166
|
+
throw new CapsuleError(`microVM ${id} died while resuming: ${vm.stateReason ?? vm.state}`, undefined, { capsuleId: id });
|
|
167
|
+
}
|
|
168
|
+
if (Date.now() - t0 > timeoutMs) {
|
|
169
|
+
throw new CapsuleError(`microVM ${id} did not resume within ${timeoutMs}ms (state ${vm.state})`, undefined, { capsuleId: id });
|
|
170
|
+
}
|
|
171
|
+
await new Promise((r) => setTimeout(r, 400));
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// No snapshot(): the service builds images from a code artifact only; a
|
|
175
|
+
// live microVM cannot be turned into one (docs/lambda-microvms-findings.md).
|
|
141
176
|
async connect(id) {
|
|
142
177
|
const vm = await this.client.send(new GetMicrovmCommand({ microvmIdentifier: id }));
|
|
143
178
|
if (!vm.endpoint)
|
|
144
179
|
throw new CapsuleError(`microVM ${id} has no endpoint yet (state ${vm.state})`, undefined, { capsuleId: id });
|
|
145
180
|
return this.connectionFor(id, vm.endpoint);
|
|
146
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* Did this call's RunMicrovm launch the VM, or did its clientToken hand
|
|
184
|
+
* back one launched earlier (idempotency/recovery)? The API does not say,
|
|
185
|
+
* so: no clientToken → ours; otherwise ours when the VM started after we
|
|
186
|
+
* asked (with a minute of slack for clock skew). Unknown → not ours, which
|
|
187
|
+
* errs on the side of leaving a VM alive.
|
|
188
|
+
*/
|
|
189
|
+
async launchedBy(id, t0, clientToken) {
|
|
190
|
+
if (!clientToken)
|
|
191
|
+
return true;
|
|
192
|
+
try {
|
|
193
|
+
const vm = await this.client.send(new GetMicrovmCommand({ microvmIdentifier: id }));
|
|
194
|
+
return vm.startedAt !== undefined && vm.startedAt.getTime() >= t0 - 60_000;
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
147
200
|
/** A Connection from an endpoint already in hand (get() returns it): no extra GetMicrovm. */
|
|
148
201
|
connectionFor(id, endpoint) {
|
|
149
202
|
return {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capsulos/provider-lambda",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "capsulos provider for AWS Lambda MicroVMs: capsules on your own AWS account.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"keywords": [
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@aws-sdk/client-lambda-microvms": "^3.1158.0",
|
|
47
|
-
"@capsulos/sdk": "0.
|
|
47
|
+
"@capsulos/sdk": "0.2.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@types/node": "^22.20.1",
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// create(): what happens to the VM when the wait for RUNNING fails. The AWS
|
|
2
|
+
// client is stubbed: these tests are about ownership, not about the service.
|
|
3
|
+
import { describe, expect, it } from 'vitest';
|
|
4
|
+
import { CapsuleError, type Provider } from '@capsulos/sdk';
|
|
5
|
+
import { LambdaProvider } from './index.js';
|
|
6
|
+
|
|
7
|
+
type Sent = { name: string; input: Record<string, unknown> };
|
|
8
|
+
|
|
9
|
+
function provider(vm: { state: string; startedAt?: Date }) {
|
|
10
|
+
const sent: Sent[] = [];
|
|
11
|
+
const p = new LambdaProvider({ region: 'us-east-1', accountId: '123' });
|
|
12
|
+
(p as unknown as { client: { send: (cmd: { constructor: { name: string }; input: Record<string, unknown> }) => Promise<unknown> } }).client = {
|
|
13
|
+
async send(cmd) {
|
|
14
|
+
sent.push({ name: cmd.constructor.name, input: cmd.input });
|
|
15
|
+
switch (cmd.constructor.name) {
|
|
16
|
+
case 'RunMicrovmCommand':
|
|
17
|
+
return { microvmId: 'mvm-1' };
|
|
18
|
+
case 'GetMicrovmCommand':
|
|
19
|
+
return { microvmId: 'mvm-1', state: vm.state, startedAt: vm.startedAt, endpoint: 'x.on.aws' };
|
|
20
|
+
case 'TerminateMicrovmCommand':
|
|
21
|
+
case 'SuspendMicrovmCommand':
|
|
22
|
+
case 'ResumeMicrovmCommand':
|
|
23
|
+
return {};
|
|
24
|
+
default:
|
|
25
|
+
throw new Error(`unexpected ${cmd.constructor.name}`);
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
return { p, sent, terminated: () => sent.filter((s) => s.name === 'TerminateMicrovmCommand').length };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
describe('LambdaProvider.create on timeout', () => {
|
|
33
|
+
it('terminates a VM it launched itself and names it in the error', async () => {
|
|
34
|
+
const { p, terminated } = provider({ state: 'PENDING', startedAt: new Date() });
|
|
35
|
+
const err = await p.create({ template: 't' }, { timeoutMs: 1 }).catch((e: unknown) => e);
|
|
36
|
+
expect(err).toBeInstanceOf(CapsuleError);
|
|
37
|
+
expect((err as CapsuleError).capsuleId).toBe('mvm-1');
|
|
38
|
+
expect((err as CapsuleError).message).toMatch(/terminated it/);
|
|
39
|
+
expect(terminated()).toBe(1);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('leaves alone a VM that the clientToken recovered from an earlier launch', async () => {
|
|
43
|
+
const { p, terminated } = provider({ state: 'PENDING', startedAt: new Date(Date.now() - 10 * 60_000) });
|
|
44
|
+
const err = await p.create({ template: 't', clientToken: 'row-1' }, { timeoutMs: 1 }).catch((e: unknown) => e);
|
|
45
|
+
expect((err as CapsuleError).message).toMatch(/left it running/);
|
|
46
|
+
expect((err as CapsuleError).capsuleId).toBe('mvm-1');
|
|
47
|
+
expect(terminated()).toBe(0);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('with a clientToken, a VM that started after the call is still ours', async () => {
|
|
51
|
+
const { p, terminated } = provider({ state: 'PENDING', startedAt: new Date(Date.now() + 1000) });
|
|
52
|
+
await p.create({ template: 't', clientToken: 'row-1' }, { timeoutMs: 1 }).catch(() => undefined);
|
|
53
|
+
expect(terminated()).toBe(1);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('accepts a SUSPENDED VM as alive', async () => {
|
|
57
|
+
const { p } = provider({ state: 'SUSPENDED', startedAt: new Date() });
|
|
58
|
+
const handle = await p.create({ template: 't', clientToken: 'row-1' });
|
|
59
|
+
expect(handle.state).toBe('suspended');
|
|
60
|
+
expect(handle.connection.baseUrl).toBe('https://x.on.aws');
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe('LambdaProvider pause/resume/snapshot', () => {
|
|
65
|
+
it('pause suspends; resume resumes and waits for RUNNING', async () => {
|
|
66
|
+
const { p, sent } = provider({ state: 'RUNNING', startedAt: new Date() });
|
|
67
|
+
await p.pause('mvm-1');
|
|
68
|
+
await p.resume('mvm-1');
|
|
69
|
+
expect(sent.map((s) => s.name)).toEqual(['SuspendMicrovmCommand', 'ResumeMicrovmCommand', 'GetMicrovmCommand']);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('has no snapshot: the service cannot image a live VM', () => {
|
|
73
|
+
const asProvider: Provider = new LambdaProvider({ region: 'us-east-1', accountId: '1' });
|
|
74
|
+
expect(asProvider.snapshot).toBeUndefined();
|
|
75
|
+
});
|
|
76
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -15,6 +15,8 @@ import {
|
|
|
15
15
|
RunMicrovmCommand,
|
|
16
16
|
GetMicrovmCommand,
|
|
17
17
|
ListMicrovmsCommand,
|
|
18
|
+
ResumeMicrovmCommand,
|
|
19
|
+
SuspendMicrovmCommand,
|
|
18
20
|
TerminateMicrovmCommand,
|
|
19
21
|
CreateMicrovmAuthTokenCommand,
|
|
20
22
|
type LambdaMicrovmsClientConfig,
|
|
@@ -88,6 +90,7 @@ export class LambdaProvider implements Provider {
|
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
async create(spec: CapsuleSpec, opts: CreateOptions = {}): Promise<CapsuleHandle> {
|
|
93
|
+
const t0 = Date.now();
|
|
91
94
|
const ingress =
|
|
92
95
|
this.opts.ingressConnectorArn ??
|
|
93
96
|
`arn:aws:lambda:${this.opts.region}:aws:network-connector:aws-network-connector:ALL_INGRESS`;
|
|
@@ -119,10 +122,17 @@ export class LambdaProvider implements Provider {
|
|
|
119
122
|
info = await this.waitForRunning(id, opts);
|
|
120
123
|
} catch (err) {
|
|
121
124
|
// Never leave a VM running without an owner: the caller gets an error,
|
|
122
|
-
// not a capsule, so the VM goes too (the error still names it).
|
|
125
|
+
// not a capsule, so the VM goes too (the error still names it). Unless
|
|
126
|
+
// the clientToken recovered a VM someone else launched: that one has
|
|
127
|
+
// an owner, so it stays and the error says so.
|
|
123
128
|
if (err instanceof CapsuleError && err.capsuleId === id) {
|
|
124
|
-
await this.
|
|
125
|
-
|
|
129
|
+
if (await this.launchedBy(id, t0, spec.clientToken)) {
|
|
130
|
+
await this.terminate(id).catch(() => undefined);
|
|
131
|
+
throw new CapsuleError(`${err.message}; terminated it`, err.status, { capsuleId: id });
|
|
132
|
+
}
|
|
133
|
+
throw new CapsuleError(`${err.message}; left it running (recovered through clientToken, it has another owner)`, err.status, {
|
|
134
|
+
capsuleId: id,
|
|
135
|
+
});
|
|
126
136
|
}
|
|
127
137
|
throw err;
|
|
128
138
|
}
|
|
@@ -177,12 +187,58 @@ export class LambdaProvider implements Provider {
|
|
|
177
187
|
}
|
|
178
188
|
}
|
|
179
189
|
|
|
190
|
+
/**
|
|
191
|
+
* SuspendMicrovm: the snapshot is taken and the VM stops consuming CPU.
|
|
192
|
+
* The endpoint answers 502 for a few seconds right after; `Capsule.resume()`
|
|
193
|
+
* waits for the daemon, and a request with auto-resume also wakes it.
|
|
194
|
+
*/
|
|
195
|
+
async pause(id: string): Promise<void> {
|
|
196
|
+
await this.client.send(new SuspendMicrovmCommand({ microvmIdentifier: id }));
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** ResumeMicrovm, then wait until the service reports RUNNING. */
|
|
200
|
+
async resume(id: string, timeoutMs = 60_000): Promise<void> {
|
|
201
|
+
await this.client.send(new ResumeMicrovmCommand({ microvmIdentifier: id }));
|
|
202
|
+
const t0 = Date.now();
|
|
203
|
+
for (;;) {
|
|
204
|
+
const vm = await this.client.send(new GetMicrovmCommand({ microvmIdentifier: id }));
|
|
205
|
+
if (vm.state === 'RUNNING') return;
|
|
206
|
+
if (vm.state === 'TERMINATED' || vm.state === 'TERMINATING') {
|
|
207
|
+
throw new CapsuleError(`microVM ${id} died while resuming: ${vm.stateReason ?? vm.state}`, undefined, { capsuleId: id });
|
|
208
|
+
}
|
|
209
|
+
if (Date.now() - t0 > timeoutMs) {
|
|
210
|
+
throw new CapsuleError(`microVM ${id} did not resume within ${timeoutMs}ms (state ${vm.state})`, undefined, { capsuleId: id });
|
|
211
|
+
}
|
|
212
|
+
await new Promise((r) => setTimeout(r, 400));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// No snapshot(): the service builds images from a code artifact only; a
|
|
217
|
+
// live microVM cannot be turned into one (docs/lambda-microvms-findings.md).
|
|
218
|
+
|
|
180
219
|
async connect(id: string): Promise<Connection> {
|
|
181
220
|
const vm = await this.client.send(new GetMicrovmCommand({ microvmIdentifier: id }));
|
|
182
221
|
if (!vm.endpoint) throw new CapsuleError(`microVM ${id} has no endpoint yet (state ${vm.state})`, undefined, { capsuleId: id });
|
|
183
222
|
return this.connectionFor(id, vm.endpoint);
|
|
184
223
|
}
|
|
185
224
|
|
|
225
|
+
/**
|
|
226
|
+
* Did this call's RunMicrovm launch the VM, or did its clientToken hand
|
|
227
|
+
* back one launched earlier (idempotency/recovery)? The API does not say,
|
|
228
|
+
* so: no clientToken → ours; otherwise ours when the VM started after we
|
|
229
|
+
* asked (with a minute of slack for clock skew). Unknown → not ours, which
|
|
230
|
+
* errs on the side of leaving a VM alive.
|
|
231
|
+
*/
|
|
232
|
+
private async launchedBy(id: string, t0: number, clientToken?: string): Promise<boolean> {
|
|
233
|
+
if (!clientToken) return true;
|
|
234
|
+
try {
|
|
235
|
+
const vm = await this.client.send(new GetMicrovmCommand({ microvmIdentifier: id }));
|
|
236
|
+
return vm.startedAt !== undefined && vm.startedAt.getTime() >= t0 - 60_000;
|
|
237
|
+
} catch {
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
186
242
|
/** A Connection from an endpoint already in hand (get() returns it): no extra GetMicrovm. */
|
|
187
243
|
connectionFor(id: string, endpoint: string): Connection {
|
|
188
244
|
return {
|