@computesdk/archil 0.4.27 → 0.4.29
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 +122 -91
- package/dist/index.d.mts +14 -7
- package/dist/index.d.ts +14 -7
- package/dist/index.js +371 -139
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +372 -140
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -2,21 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
[Archil](https://archil.com) provider for [ComputeSDK](https://www.computesdk.com).
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
5
|
+
Archil sandboxes are persistent Linux VMs, and that is what this provider
|
|
6
|
+
creates by default:
|
|
7
|
+
|
|
8
|
+
- `create()` provisions a VM and waits until it is `running`. `getById`
|
|
9
|
+
fetches a VM (resuming it if paused or stopped), `list` returns the
|
|
10
|
+
account's VMs, and `destroy` stops and deletes one.
|
|
11
|
+
- `runCommand`, streaming (`onStdout`/`onStderr`) and `startProcess` run on
|
|
12
|
+
Archil's native process API over a short-lived WebSocket (a fresh connection
|
|
13
|
+
URL per process). Files move through Archil's native file transfer API.
|
|
14
|
+
- Snapshots are paused forks of a VM; `create({ snapshotId })` restores one
|
|
15
|
+
into a new VM. `sandbox.pause()`/`resume()` pause the VM natively (also on
|
|
16
|
+
`sandbox.getInstance()`).
|
|
17
|
+
|
|
18
|
+
The older disk exec surface (a fresh container per command with an existing
|
|
19
|
+
disk mounted at `/mnt/archil`) is still available as an explicit opt-in; see
|
|
20
|
+
[Exec mode](#exec-mode-opt-in).
|
|
20
21
|
|
|
21
22
|
## Installation
|
|
22
23
|
|
|
@@ -26,12 +27,12 @@ npm install @computesdk/archil
|
|
|
26
27
|
|
|
27
28
|
## Configuration
|
|
28
29
|
|
|
29
|
-
| Option | Env var | Required | Description
|
|
30
|
-
| ----------- | ------------------ | -------- |
|
|
31
|
-
| `apiKey` | `ARCHIL_API_KEY` | yes | Archil control-plane API key
|
|
32
|
-
| `region` | `ARCHIL_REGION` | yes | Archil region (e.g. `aws-us-east-1`)
|
|
33
|
-
| `baseUrl` | — | no | Override control-plane URL (for testing)
|
|
34
|
-
| `execution` |
|
|
30
|
+
| Option | Env var | Required | Description |
|
|
31
|
+
| ----------- | ------------------ | -------- | ---------------------------------------------------- |
|
|
32
|
+
| `apiKey` | `ARCHIL_API_KEY` | yes | Archil control-plane API key |
|
|
33
|
+
| `region` | `ARCHIL_REGION` | yes | Archil region (e.g. `aws-us-east-1`) |
|
|
34
|
+
| `baseUrl` | — | no | Override control-plane URL (for testing) |
|
|
35
|
+
| `execution` | `ARCHIL_EXECUTION` | no | `"persistent"` (default) or `"exec"` (disk exec) |
|
|
35
36
|
|
|
36
37
|
## Usage
|
|
37
38
|
|
|
@@ -40,94 +41,124 @@ import { archil } from '@computesdk/archil';
|
|
|
40
41
|
|
|
41
42
|
const provider = archil();
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
const sandbox = await provider.sandbox.create({
|
|
45
|
+
name: 'ci-job',
|
|
46
|
+
baseImage: 'node:24-bookworm', // OCI image; `image` / `templateId` work too
|
|
47
|
+
vcpus: 4, // or `cpu` / `cpus`, or `sizeClass: 'lg'`
|
|
48
|
+
memoryMiB: 8192, // or `memory`
|
|
49
|
+
env: { CI: '1' }, // or `envs`
|
|
50
|
+
maxTtlSeconds: 3600, // or `timeout` in ms; per powered-on session
|
|
51
|
+
sandbox: { /* extra Archil create fields */ },
|
|
46
52
|
});
|
|
47
53
|
|
|
48
|
-
|
|
49
|
-
|
|
54
|
+
// Filesystem state, installs and background processes persist between calls.
|
|
55
|
+
// `cwd` and `env` apply to every part of a compound command.
|
|
56
|
+
await sandbox.runCommand('npm ci && npm test', { cwd: '/repo', env: { CI: '1' } });
|
|
57
|
+
|
|
58
|
+
// Native streaming and processes.
|
|
59
|
+
await sandbox.runCommand('npm run build', { onStdout: (c) => process.stdout.write(c) });
|
|
60
|
+
const proc = await sandbox.startProcess('cat', { stdin: true });
|
|
61
|
+
await proc.write('hello\n');
|
|
62
|
+
await proc.closeStdin();
|
|
63
|
+
await proc.wait();
|
|
50
64
|
|
|
51
|
-
//
|
|
52
|
-
|
|
65
|
+
// Pause/resume the same VM (memory, processes and disk preserved).
|
|
66
|
+
await sandbox.pause!();
|
|
67
|
+
await sandbox.resume!();
|
|
53
68
|
|
|
54
|
-
await provider.sandbox.destroy(sandbox.
|
|
69
|
+
await provider.sandbox.destroy(sandbox.sandboxId);
|
|
55
70
|
```
|
|
56
71
|
|
|
57
|
-
`
|
|
72
|
+
The shared `ephemeral` create option overrides the configured mode per sandbox:
|
|
73
|
+
`ephemeral: true` resolves an exec-mode disk handle (requires `diskId`),
|
|
74
|
+
`ephemeral: false` provisions a VM.
|
|
58
75
|
|
|
59
|
-
###
|
|
76
|
+
### Snapshots
|
|
60
77
|
|
|
61
78
|
```ts
|
|
62
|
-
const
|
|
79
|
+
const snapshot = await provider.snapshot.create(sandbox.sandboxId, { name: 'golden' });
|
|
80
|
+
const restored = await provider.sandbox.create({ snapshotId: snapshot.id });
|
|
81
|
+
const snapshots = await provider.snapshot.list();
|
|
82
|
+
|
|
83
|
+
// Archil deletes forks before their parent (it returns 409 otherwise):
|
|
84
|
+
await provider.sandbox.destroy(restored.sandboxId);
|
|
85
|
+
await provider.snapshot.delete(snapshot.id);
|
|
86
|
+
await provider.sandbox.destroy(sandbox.sandboxId);
|
|
87
|
+
```
|
|
63
88
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
env: { CI: '1' },
|
|
70
|
-
maxTtlSeconds: 3600, // per powered-on session
|
|
71
|
-
sandbox: { /* extra Archil fields, e.g. network policy */ },
|
|
72
|
-
});
|
|
89
|
+
A snapshot is a fork of the source VM's memory and disk, paused so it holds
|
|
90
|
+
state without running, and named `csdk-snap-<name>-<suffix>`. `snapshot.list()`
|
|
91
|
+
returns VMs with that prefix and `sandbox.list()` leaves them out. Restoring
|
|
92
|
+
forks the snapshot again into an independent VM. Snapshot ids are ordinary
|
|
93
|
+
Archil sandbox ids, so any VM id can be passed as `snapshotId`.
|
|
73
94
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
95
|
+
Declared capabilities, observed live: `provider.sandbox.pause` is
|
|
96
|
+
`{ memory: true, createOptions: { ephemeral: false } }` and
|
|
97
|
+
`provider.snapshot.capabilities` is `{ scope: 'rootfs', memory: true,
|
|
98
|
+
destroysSource: false, createOptions: { ephemeral: false } }` — the whole disk
|
|
99
|
+
(`/tmp`, `/root`, `/opt`, …) and running processes survive both, and the source
|
|
100
|
+
keeps running after a snapshot. A process must outlive the command that started
|
|
101
|
+
it to survive: use `startProcess` or `setsid`, since Archil reaps a command's
|
|
102
|
+
process group (including `nohup … &` children) when the command exits.
|
|
77
103
|
|
|
78
|
-
|
|
79
|
-
const resumed = await provider.sandbox.getById(sandbox.instanceId);
|
|
104
|
+
## Exec mode (opt-in)
|
|
80
105
|
|
|
81
|
-
|
|
82
|
-
|
|
106
|
+
```ts
|
|
107
|
+
const provider = archil({ execution: 'exec' }); // or ARCHIL_EXECUTION=exec
|
|
83
108
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
109
|
+
const sandbox = await provider.sandbox.create({ diskId: 'dsk-0000000000000000' });
|
|
110
|
+
await sandbox.runCommand('echo hello > /mnt/archil/note && cat /mnt/archil/note');
|
|
111
|
+
```
|
|
87
112
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
### Choosing a mode
|
|
95
|
-
|
|
96
|
-
| | `exec` | `persistent` |
|
|
97
|
-
| --------------------- | ------------------------------- | ------------------------------------------- |
|
|
98
|
-
| Compute | Ephemeral container per command | Persistent VM |
|
|
99
|
-
| `cwd`/`env`/installs | Lost between commands | Persist while running |
|
|
100
|
-
| Filesystem writes | Only under `/mnt/archil` | Anywhere on the VM |
|
|
101
|
-
| Background processes | Die with the container | Keep running |
|
|
102
|
-
| `create` input | Existing `diskId` | Sandbox spec (image, vcpus, memory, …) |
|
|
103
|
-
| Billing | Per `executeMs` | Per running wall-clock time |
|
|
104
|
-
| `getUrl` | ❌ | ✅ (published endpoints) |
|
|
113
|
+
Each command runs in a fresh Archil-managed container with the disk mounted at
|
|
114
|
+
`/mnt/archil`. `create()` requires `diskId`; passing `diskId` without opting in
|
|
115
|
+
throws. `getById`/`list` operate on disks, `destroy` is a no-op (disk lifecycle
|
|
116
|
+
is managed by Archil), and ids starting with `dsk-` are always treated as disk
|
|
117
|
+
handles. `cwd`, `env` and installs do not persist between commands.
|
|
105
118
|
|
|
106
119
|
## Supported operations
|
|
107
120
|
|
|
108
|
-
| Method
|
|
109
|
-
|
|
|
110
|
-
| `create`
|
|
111
|
-
| `getById`
|
|
112
|
-
| `list`
|
|
113
|
-
| `destroy`
|
|
114
|
-
| `runCommand`
|
|
115
|
-
|
|
|
116
|
-
| `
|
|
117
|
-
| `filesystem`
|
|
121
|
+
| Method | Persistent VM (default) | Exec mode (opt-in) |
|
|
122
|
+
| ----------------- | ----------------------- | ------------------ |
|
|
123
|
+
| `create` | ✅ Provisions a VM, waits for `running`. | ✅ Resolves an existing disk from `diskId`. |
|
|
124
|
+
| `getById` | ✅ Fetches the VM; resumes if paused/stopped. | ✅ Fetches the disk. |
|
|
125
|
+
| `list` | ✅ All VMs on the account, minus snapshots. | ✅ All disks visible to the API key. |
|
|
126
|
+
| `destroy` | ✅ Stops and deletes the VM. | no-op |
|
|
127
|
+
| `runCommand` | ✅ Native process API. | ✅ HTTP `exec` endpoint. |
|
|
128
|
+
| Streaming | ✅ Native, live over the process WebSocket. | Output delivered when the command exits. |
|
|
129
|
+
| `startProcess` | ✅ Native (stdin, kill, wait). | ❌ |
|
|
130
|
+
| `filesystem` | ✅ Native file transfer for read/write; `mkdir`/`readdir`/`exists`/`remove` run shell commands. | ✅ Maps paths into `/mnt/archil`. |
|
|
131
|
+
| Snapshots | ✅ create / list / delete / restore. | ❌ |
|
|
132
|
+
| `pause`/`resume` | ✅ Native; memory and processes survive. | ❌ |
|
|
133
|
+
| `getUrl` | Only for ports already published as sandbox endpoints (not proven live). | ❌ |
|
|
118
134
|
|
|
119
135
|
## Limitations
|
|
120
136
|
|
|
121
|
-
-
|
|
122
|
-
|
|
123
|
-
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
137
|
+
- `list()` is one Archil API call: Archil's sandbox list endpoint returns every
|
|
138
|
+
sandbox in a single response (there is no cursor to page through).
|
|
139
|
+
- `kill(signal)` on a native process cancels it through Archil's process
|
|
140
|
+
control; Archil does not accept a signal name, so the result reports the
|
|
141
|
+
requested signal (`SIGKILL` by default) with exit code 137. Timed-out
|
|
142
|
+
commands report exit code 124.
|
|
143
|
+
- A VM with live forks (snapshots or VMs restored from it) cannot be deleted
|
|
144
|
+
until those forks are deleted.
|
|
145
|
+
- Exec mode: responses are truncated to ~5 MB by the Archil control plane, and
|
|
146
|
+
raw `runCommand` strings are not rewritten — commands that access the disk
|
|
147
|
+
must use `/mnt/archil` themselves.
|
|
148
|
+
|
|
149
|
+
## Standard sizes (persistent VMs only)
|
|
150
|
+
|
|
151
|
+
`archil().sizes.list()` / `resolve('sm')` declares exact `sm`, `md`, `lg`, and
|
|
152
|
+
`xl` requests. `create({ sizeClass: 'sm' })` maps to adapter `vcpus: 1`,
|
|
153
|
+
`memoryMiB: 2048`, then native `vcpuCount` / `memSizeMiB`. Exec mode
|
|
154
|
+
(`execution: 'exec'` or `ephemeral: true`) reports `unavailable` for VM sizing. Attach (`sandboxId`/`instanceId`)
|
|
155
|
+
and fork (`snapshotId`) standard requests reject as `unsupported` before API calls;
|
|
156
|
+
those paths cannot apply a new VM size. Conflicting native controls reject too.
|
|
157
|
+
`xs`/`2xl` remain `unknown` in this initial adapter catalog.
|
|
158
|
+
|
|
159
|
+
The persistent API documents 1–32 vCPUs and 256–65536 MiB, but adapter declarations
|
|
160
|
+
are not account/quota/region guarantees or measurements. Discovery is pure and
|
|
161
|
+
needs no credentials. Successful standardized creates expose frozen
|
|
162
|
+
`instance.sizing` request metadata, not observed CPU/RAM. Local mock coverage uses
|
|
163
|
+
the installed `disk` SDK; it does not certify separately locked consumer versions
|
|
164
|
+
or published artifacts. Legacy creates without `sizeClass` remain unchanged.
|
package/dist/index.d.mts
CHANGED
|
@@ -4,8 +4,8 @@ import { Archil, Sandbox } from 'disk';
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Archil execution mode:
|
|
7
|
-
* - "
|
|
8
|
-
* - "
|
|
7
|
+
* - "persistent" (default): a persistent sandbox VM run through the process API.
|
|
8
|
+
* - "exec": serverless per-command containers on an existing disk (opt-in).
|
|
9
9
|
*/
|
|
10
10
|
type ArchilExecutionMode = 'exec' | 'persistent';
|
|
11
11
|
interface ArchilConfig {
|
|
@@ -16,10 +16,11 @@ interface ArchilConfig {
|
|
|
16
16
|
/** Override the control-plane base URL (useful for testing). */
|
|
17
17
|
baseUrl?: string;
|
|
18
18
|
/**
|
|
19
|
-
* Which Archil compute surface to use.
|
|
20
|
-
* "persistent"
|
|
21
|
-
*
|
|
22
|
-
* create() options (true -> exec handle, false ->
|
|
19
|
+
* Which Archil compute surface to use. Falls back to ARCHIL_EXECUTION, then
|
|
20
|
+
* "persistent": create() provisions a persistent sandbox VM. "exec"
|
|
21
|
+
* resolves create({ diskId }) to a disk exec handle instead. Per-sandbox
|
|
22
|
+
* override: `ephemeral` on create() options (true -> exec handle, false ->
|
|
23
|
+
* persistent VM).
|
|
23
24
|
*/
|
|
24
25
|
execution?: ArchilExecutionMode;
|
|
25
26
|
}
|
|
@@ -45,7 +46,13 @@ interface ArchilSandbox {
|
|
|
45
46
|
vm?: Sandbox;
|
|
46
47
|
resolved: ResolvedConfig;
|
|
47
48
|
createdAt: Date;
|
|
49
|
+
/** persistent mode: pause the VM, preserving CPU and memory state. */
|
|
50
|
+
pause?: () => Promise<void>;
|
|
51
|
+
/** persistent mode: resume the paused VM under the same sandbox id. */
|
|
52
|
+
resume?: () => Promise<void>;
|
|
48
53
|
}
|
|
49
|
-
declare const archil: (config?: ArchilConfig) => _computesdk_provider.Provider<ArchilSandbox, any, any, computesdk.Volume
|
|
54
|
+
declare const archil: (config?: ArchilConfig) => _computesdk_provider.Provider<ArchilSandbox, any, any, computesdk.Volume> & {
|
|
55
|
+
readonly sizes: computesdk.InstanceSizeManager;
|
|
56
|
+
};
|
|
50
57
|
|
|
51
58
|
export { type ArchilConfig, type ArchilExecutionMode, type ArchilSandbox, archil };
|
package/dist/index.d.ts
CHANGED
|
@@ -4,8 +4,8 @@ import { Archil, Sandbox } from 'disk';
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Archil execution mode:
|
|
7
|
-
* - "
|
|
8
|
-
* - "
|
|
7
|
+
* - "persistent" (default): a persistent sandbox VM run through the process API.
|
|
8
|
+
* - "exec": serverless per-command containers on an existing disk (opt-in).
|
|
9
9
|
*/
|
|
10
10
|
type ArchilExecutionMode = 'exec' | 'persistent';
|
|
11
11
|
interface ArchilConfig {
|
|
@@ -16,10 +16,11 @@ interface ArchilConfig {
|
|
|
16
16
|
/** Override the control-plane base URL (useful for testing). */
|
|
17
17
|
baseUrl?: string;
|
|
18
18
|
/**
|
|
19
|
-
* Which Archil compute surface to use.
|
|
20
|
-
* "persistent"
|
|
21
|
-
*
|
|
22
|
-
* create() options (true -> exec handle, false ->
|
|
19
|
+
* Which Archil compute surface to use. Falls back to ARCHIL_EXECUTION, then
|
|
20
|
+
* "persistent": create() provisions a persistent sandbox VM. "exec"
|
|
21
|
+
* resolves create({ diskId }) to a disk exec handle instead. Per-sandbox
|
|
22
|
+
* override: `ephemeral` on create() options (true -> exec handle, false ->
|
|
23
|
+
* persistent VM).
|
|
23
24
|
*/
|
|
24
25
|
execution?: ArchilExecutionMode;
|
|
25
26
|
}
|
|
@@ -45,7 +46,13 @@ interface ArchilSandbox {
|
|
|
45
46
|
vm?: Sandbox;
|
|
46
47
|
resolved: ResolvedConfig;
|
|
47
48
|
createdAt: Date;
|
|
49
|
+
/** persistent mode: pause the VM, preserving CPU and memory state. */
|
|
50
|
+
pause?: () => Promise<void>;
|
|
51
|
+
/** persistent mode: resume the paused VM under the same sandbox id. */
|
|
52
|
+
resume?: () => Promise<void>;
|
|
48
53
|
}
|
|
49
|
-
declare const archil: (config?: ArchilConfig) => _computesdk_provider.Provider<ArchilSandbox, any, any, computesdk.Volume
|
|
54
|
+
declare const archil: (config?: ArchilConfig) => _computesdk_provider.Provider<ArchilSandbox, any, any, computesdk.Volume> & {
|
|
55
|
+
readonly sizes: computesdk.InstanceSizeManager;
|
|
56
|
+
};
|
|
50
57
|
|
|
51
58
|
export { type ArchilConfig, type ArchilExecutionMode, type ArchilSandbox, archil };
|