@usine/cloudflare 0.0.0-stage → 0.1.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/LICENSE +661 -0
- package/README.md +95 -2
- package/dist/access.d.ts +12 -0
- package/dist/access.d.ts.map +1 -0
- package/dist/access.js +32 -0
- package/dist/access.js.map +1 -0
- package/dist/api/api.d.ts +215 -0
- package/dist/api/api.d.ts.map +1 -0
- package/dist/api/api.js +180 -0
- package/dist/api/api.js.map +1 -0
- package/dist/api/harness.d.ts +49 -0
- package/dist/api/harness.d.ts.map +1 -0
- package/dist/api/harness.js +57 -0
- package/dist/api/harness.js.map +1 -0
- package/dist/api/names.d.ts +28 -0
- package/dist/api/names.d.ts.map +1 -0
- package/dist/api/names.js +31 -0
- package/dist/api/names.js.map +1 -0
- package/dist/api/stream.d.ts +65 -0
- package/dist/api/stream.d.ts.map +1 -0
- package/dist/api/stream.js +70 -0
- package/dist/api/stream.js.map +1 -0
- package/dist/registry.d.ts +28 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +45 -0
- package/dist/registry.js.map +1 -0
- package/dist/sandbox/outbound.d.ts +53 -0
- package/dist/sandbox/outbound.d.ts.map +1 -0
- package/dist/sandbox/outbound.js +109 -0
- package/dist/sandbox/outbound.js.map +1 -0
- package/dist/sandbox/ports.d.ts +99 -0
- package/dist/sandbox/ports.d.ts.map +1 -0
- package/dist/sandbox/ports.js +66 -0
- package/dist/sandbox/ports.js.map +1 -0
- package/dist/sandbox/process.d.ts +55 -0
- package/dist/sandbox/process.d.ts.map +1 -0
- package/dist/sandbox/process.js +172 -0
- package/dist/sandbox/process.js.map +1 -0
- package/dist/sandbox/sandbox.d.ts +36 -0
- package/dist/sandbox/sandbox.d.ts.map +1 -0
- package/dist/sandbox/sandbox.js +387 -0
- package/dist/sandbox/sandbox.js.map +1 -0
- package/dist/sandbox/stream.d.ts +26 -0
- package/dist/sandbox/stream.d.ts.map +1 -0
- package/dist/sandbox/stream.js +167 -0
- package/dist/sandbox/stream.js.map +1 -0
- package/dist/worker.d.ts +77 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +362 -0
- package/dist/worker.js.map +1 -0
- package/image/Dockerfile +43 -0
- package/image/codex-config.toml +10 -0
- package/image/init.sh +17 -0
- package/package.json +59 -3
- package/wrangler.jsonc +32 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { CloudflareInstanceType } from "@usine/core/worker";
|
|
2
|
+
import { Context, type DateTime, type Duration, Effect, type Option, Schema } from "effect";
|
|
3
|
+
import { SandboxCredentials, SandboxName, SandboxSummary } from "../api/api.ts";
|
|
4
|
+
import type { Interception } from "./outbound.ts";
|
|
5
|
+
/** A command started in the container, with the streams the start requested. */
|
|
6
|
+
export interface ContainerProcess {
|
|
7
|
+
readonly stdin: WritableStream<Uint8Array> | null;
|
|
8
|
+
readonly stdout: ReadableStream<Uint8Array> | null;
|
|
9
|
+
readonly stderr: ReadableStream<Uint8Array> | null;
|
|
10
|
+
readonly exitCode: Promise<number>;
|
|
11
|
+
}
|
|
12
|
+
export declare const ContainerOperation: Schema.Literals<readonly ["start", "exec", "read", "destroy", "keep-alive", "intercept"]>;
|
|
13
|
+
export type ContainerOperation = typeof ContainerOperation.Type;
|
|
14
|
+
declare const ContainerFailure_base: Schema.Class<ContainerFailure, Schema.TaggedStruct<"ContainerFailure", {
|
|
15
|
+
readonly operation: Schema.Literals<readonly ["start", "exec", "read", "destroy", "keep-alive", "intercept"]>;
|
|
16
|
+
readonly message: Schema.String;
|
|
17
|
+
}>, import("effect/Cause").YieldableError>;
|
|
18
|
+
/** A Container API call failed. `message` comes from the runtime and contains no credential. */
|
|
19
|
+
export declare class ContainerFailure extends ContainerFailure_base {
|
|
20
|
+
}
|
|
21
|
+
declare const SandboxContainer_base: Context.ServiceClass<SandboxContainer, "@usine/cloudflare/SandboxContainer", {
|
|
22
|
+
readonly running: Effect.Effect<boolean>;
|
|
23
|
+
/** The Worker's `containers[].images`, by name. */
|
|
24
|
+
readonly images: Effect.Effect<Readonly<Record<string, string>>>;
|
|
25
|
+
/** Starts the container from `image`, an entry of `images`, without internet access. */
|
|
26
|
+
readonly start: (image: string, instanceType: CloudflareInstanceType) => Effect.Effect<void, ContainerFailure>;
|
|
27
|
+
/** Runs `command` as the image's user in its home directory, with `HOME` set and piped output. */
|
|
28
|
+
readonly exec: (command: ReadonlyArray<string>, stdin: "pipe" | "closed") => Effect.Effect<ContainerProcess, ContainerFailure>;
|
|
29
|
+
/** Returns the content of `path`, or `None` if it doesn't exist. */
|
|
30
|
+
readonly read: (path: string) => Effect.Effect<Option.Option<Uint8Array>, ContainerFailure>;
|
|
31
|
+
/** Returns the content of `path` after its first `offset` bytes, or `None` if it doesn't exist. */
|
|
32
|
+
readonly readFrom: (path: string, offset: number) => Effect.Effect<Option.Option<Uint8Array>, ContainerFailure>;
|
|
33
|
+
/** Returns the size of `path` in bytes, or `None` if it doesn't exist. */
|
|
34
|
+
readonly size: (path: string) => Effect.Effect<Option.Option<number>, ContainerFailure>;
|
|
35
|
+
readonly destroy: Effect.Effect<void, ContainerFailure>;
|
|
36
|
+
/** Sets the time without a request after which the platform stops the container. */
|
|
37
|
+
readonly keepAlive: (inactivity: Duration.Duration) => Effect.Effect<void, ContainerFailure>;
|
|
38
|
+
/** Sends the container's requests for the interception's host to its outbound handler. */
|
|
39
|
+
readonly intercept: (interception: Interception) => Effect.Effect<void, ContainerFailure>;
|
|
40
|
+
}>;
|
|
41
|
+
/** The Durable Object Container API calls a sandbox makes (`ctx.container` in the Worker). */
|
|
42
|
+
export declare class SandboxContainer extends SandboxContainer_base {
|
|
43
|
+
}
|
|
44
|
+
declare const StoredSandbox_base: Schema.Class<StoredSandbox, Schema.Struct<{
|
|
45
|
+
readonly name: Schema.brand<Schema.String, "SandboxName">;
|
|
46
|
+
readonly owner: Schema.brand<Schema.String, "SandboxOwner">;
|
|
47
|
+
readonly attempt: Schema.brand<Schema.NonEmptyString, "AttemptId">;
|
|
48
|
+
readonly image: Schema.brand<Schema.String, "CloudflareImageName">;
|
|
49
|
+
readonly instanceType: Schema.Literals<readonly ["lite", "basic", "standard-1", "standard-2", "standard-3", "standard-4"]>;
|
|
50
|
+
readonly createdAt: Schema.DateTimeUtc;
|
|
51
|
+
/**
|
|
52
|
+
* The keepalive alarm keeps the container running until this time. Each create, credential
|
|
53
|
+
* renewal, and command extends it.
|
|
54
|
+
*/
|
|
55
|
+
readonly leaseUntil: Schema.DateTimeUtc;
|
|
56
|
+
/**
|
|
57
|
+
* Whether usine holds the sandbox for a checkout that it keeps. The keepalive alarm then keeps
|
|
58
|
+
* the container running past `leaseUntil`, until usine destroys the sandbox.
|
|
59
|
+
*/
|
|
60
|
+
readonly held: Schema.withDecodingDefaultKey<Schema.Boolean, never>;
|
|
61
|
+
/** Kept so the outbound handlers can be registered again after the Durable Object restarts. */
|
|
62
|
+
readonly credentials: typeof SandboxCredentials;
|
|
63
|
+
}>, {}>;
|
|
64
|
+
/** A sandbox as its Durable Object stores it. */
|
|
65
|
+
export declare class StoredSandbox extends StoredSandbox_base {
|
|
66
|
+
summary(running: boolean, draining: boolean): SandboxSummary;
|
|
67
|
+
}
|
|
68
|
+
declare const SandboxStorage_base: Context.ServiceClass<SandboxStorage, "@usine/cloudflare/SandboxStorage", {
|
|
69
|
+
readonly load: Effect.Effect<Option.Option<StoredSandbox>>;
|
|
70
|
+
/**
|
|
71
|
+
* Passes the stored sandbox, or `None`, to `change`, saves the sandbox that `change` returns
|
|
72
|
+
* with its result, and returns the result. Saves nothing when that sandbox is `None`. No other
|
|
73
|
+
* request runs between the read and the write.
|
|
74
|
+
*/
|
|
75
|
+
readonly modify: <A>(change: (stored: Option.Option<StoredSandbox>) => readonly [A, Option.Option<StoredSandbox>]) => Effect.Effect<A>;
|
|
76
|
+
/** Deletes the stored sandbox and its alarm. */
|
|
77
|
+
readonly clear: Effect.Effect<void>;
|
|
78
|
+
/** Replaces the sandbox's alarm. */
|
|
79
|
+
readonly alarmAt: (at: DateTime.Utc) => Effect.Effect<void>;
|
|
80
|
+
}>;
|
|
81
|
+
/** The Durable Object storage of one sandbox. */
|
|
82
|
+
export declare class SandboxStorage extends SandboxStorage_base {
|
|
83
|
+
}
|
|
84
|
+
declare const SandboxDirectory_base: Context.ServiceClass<SandboxDirectory, "@usine/cloudflare/SandboxDirectory", {
|
|
85
|
+
readonly record: (sandbox: SandboxSummary) => Effect.Effect<void>;
|
|
86
|
+
readonly forget: (name: SandboxName) => Effect.Effect<void>;
|
|
87
|
+
}>;
|
|
88
|
+
/** The registry that lists the sandboxes of each usine Worker. */
|
|
89
|
+
export declare class SandboxDirectory extends SandboxDirectory_base {
|
|
90
|
+
}
|
|
91
|
+
declare const SandboxSettings_base: Context.ServiceClass<SandboxSettings, "@usine/cloudflare/SandboxSettings", {
|
|
92
|
+
/** The hosts the sandboxes reach over HTTPS without a credential, from `ALLOWED_HOSTS`. */
|
|
93
|
+
readonly allowedHosts: ReadonlyArray<string>;
|
|
94
|
+
}>;
|
|
95
|
+
/** The Worker's settings that every sandbox reads. */
|
|
96
|
+
export declare class SandboxSettings extends SandboxSettings_base {
|
|
97
|
+
}
|
|
98
|
+
export {};
|
|
99
|
+
//# sourceMappingURL=ports.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ports.d.ts","sourceRoot":"","sources":["../../src/sandbox/ports.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { AttemptId } from "@usine/core/attempt";
|
|
2
|
+
import { CloudflareImageName, CloudflareInstanceType } from "@usine/core/worker";
|
|
3
|
+
import { Context, Effect, Schema } from "effect";
|
|
4
|
+
import { SandboxCredentials, SandboxName, SandboxOwner, SandboxSummary } from "../api/api.js";
|
|
5
|
+
export const ContainerOperation = Schema.Literals([
|
|
6
|
+
"start",
|
|
7
|
+
"exec",
|
|
8
|
+
"read",
|
|
9
|
+
"destroy",
|
|
10
|
+
"keep-alive",
|
|
11
|
+
"intercept",
|
|
12
|
+
]);
|
|
13
|
+
/** A Container API call failed. `message` comes from the runtime and contains no credential. */
|
|
14
|
+
export class ContainerFailure extends Schema.TaggedError()("ContainerFailure", {
|
|
15
|
+
operation: ContainerOperation,
|
|
16
|
+
message: Schema.String,
|
|
17
|
+
}) {
|
|
18
|
+
}
|
|
19
|
+
/** The Durable Object Container API calls a sandbox makes (`ctx.container` in the Worker). */
|
|
20
|
+
export class SandboxContainer extends Context.Service()("@usine/cloudflare/SandboxContainer") {
|
|
21
|
+
}
|
|
22
|
+
/** A sandbox as its Durable Object stores it. */
|
|
23
|
+
export class StoredSandbox extends Schema.Class("@usine/cloudflare/StoredSandbox")({
|
|
24
|
+
name: SandboxName,
|
|
25
|
+
owner: SandboxOwner,
|
|
26
|
+
attempt: AttemptId,
|
|
27
|
+
image: CloudflareImageName,
|
|
28
|
+
instanceType: CloudflareInstanceType,
|
|
29
|
+
createdAt: Schema.DateTimeUtc,
|
|
30
|
+
/**
|
|
31
|
+
* The keepalive alarm keeps the container running until this time. Each create, credential
|
|
32
|
+
* renewal, and command extends it.
|
|
33
|
+
*/
|
|
34
|
+
leaseUntil: Schema.DateTimeUtc,
|
|
35
|
+
/**
|
|
36
|
+
* Whether usine holds the sandbox for a checkout that it keeps. The keepalive alarm then keeps
|
|
37
|
+
* the container running past `leaseUntil`, until usine destroys the sandbox.
|
|
38
|
+
*/
|
|
39
|
+
held: Schema.Boolean.pipe(Schema.withDecodingDefaultKey(Effect.succeed(false))),
|
|
40
|
+
/** Kept so the outbound handlers can be registered again after the Durable Object restarts. */
|
|
41
|
+
credentials: SandboxCredentials,
|
|
42
|
+
}) {
|
|
43
|
+
summary(running, draining) {
|
|
44
|
+
return new SandboxSummary({
|
|
45
|
+
name: this.name,
|
|
46
|
+
owner: this.owner,
|
|
47
|
+
attempt: this.attempt,
|
|
48
|
+
image: this.image,
|
|
49
|
+
instanceType: this.instanceType,
|
|
50
|
+
createdAt: this.createdAt,
|
|
51
|
+
running,
|
|
52
|
+
held: this.held,
|
|
53
|
+
draining,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/** The Durable Object storage of one sandbox. */
|
|
58
|
+
export class SandboxStorage extends Context.Service()("@usine/cloudflare/SandboxStorage") {
|
|
59
|
+
}
|
|
60
|
+
/** The registry that lists the sandboxes of each usine Worker. */
|
|
61
|
+
export class SandboxDirectory extends Context.Service()("@usine/cloudflare/SandboxDirectory") {
|
|
62
|
+
}
|
|
63
|
+
/** The Worker's settings that every sandbox reads. */
|
|
64
|
+
export class SandboxSettings extends Context.Service()("@usine/cloudflare/SandboxSettings") {
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=ports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ports.js","sourceRoot":"","sources":["../../src/sandbox/ports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAE,OAAO,EAAgC,MAAM,EAAe,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC5F,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAW9F,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,QAAQ,CAAC;IAChD,OAAO;IACP,MAAM;IACN,MAAM;IACN,SAAS;IACT,YAAY;IACZ,WAAW;CACZ,CAAC,CAAC;AAGH,gGAAgG;AAChG,MAAM,OAAO,gBAAiB,SAAQ,MAAM,CAAC,WAAW,EAAoB,CAAC,kBAAkB,EAAE;IAC/F,SAAS,EAAE,kBAAkB;IAC7B,OAAO,EAAE,MAAM,CAAC,MAAM;CACvB,CAAC;CAAG;AAEL,8FAA8F;AAC9F,MAAM,OAAO,gBAAiB,SAAQ,OAAO,CAAC,OAAO,EA+BlD,CAAC,oCAAoC,CAAC;CAAG;AAE5C,iDAAiD;AACjD,MAAM,OAAO,aAAc,SAAQ,MAAM,CAAC,KAAK,CAAgB,iCAAiC,CAAC,CAAC;IAChG,IAAI,EAAE,WAAW;IACjB,KAAK,EAAE,YAAY;IACnB,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,mBAAmB;IAC1B,YAAY,EAAE,sBAAsB;IACpC,SAAS,EAAE,MAAM,CAAC,WAAW;IAC7B;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC,WAAW;IAC9B;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/E,+FAA+F;IAC/F,WAAW,EAAE,kBAAkB;CAChC,CAAC;IACA,OAAO,CAAC,OAAgB,EAAE,QAAiB;QACzC,OAAO,IAAI,cAAc,CAAC;YACxB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,QAAQ;SACT,CAAC,CAAC;IACL,CAAC;CACF;AAED,iDAAiD;AACjD,MAAM,OAAO,cAAe,SAAQ,OAAO,CAAC,OAAO,EAiBhD,CAAC,kCAAkC,CAAC;CAAG;AAE1C,kEAAkE;AAClE,MAAM,OAAO,gBAAiB,SAAQ,OAAO,CAAC,OAAO,EAMlD,CAAC,oCAAoC,CAAC;CAAG;AAE5C,sDAAsD;AACtD,MAAM,OAAO,eAAgB,SAAQ,OAAO,CAAC,OAAO,EAMjD,CAAC,mCAAmC,CAAC;CAAG"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Option } from "effect";
|
|
2
|
+
import { ProcessId } from "../api/api.ts";
|
|
3
|
+
/**
|
|
4
|
+
* Returns the Container API options of a command the Worker runs. The platform passes a command
|
|
5
|
+
* only the image's `PATH`, not its `ENV HOME`, so the options set `HOME` and start the command in
|
|
6
|
+
* the sandbox home.
|
|
7
|
+
*/
|
|
8
|
+
export declare const commandOptions: (stdin: "pipe" | "closed") => ContainerExecOptions;
|
|
9
|
+
/** The files a command leaves in its process directory. */
|
|
10
|
+
export declare const processFiles: (process: ProcessId) => {
|
|
11
|
+
/** The command's process ID, which is also its process group and session. */
|
|
12
|
+
readonly pid: `${string}/pid`;
|
|
13
|
+
/** The exit code, written once the command exits. */
|
|
14
|
+
readonly exit: `${string}/exit`;
|
|
15
|
+
readonly stdout: `${string}/stdout`;
|
|
16
|
+
readonly stderr: `${string}/stderr`;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* A POSIX shell script that runs the command line `$2` with process files in the directory `$1`,
|
|
20
|
+
* and passes its stdin, stdout, stderr, and exit code through. Run it with `sh -c`.
|
|
21
|
+
*
|
|
22
|
+
* The command runs in its own session and writes its process ID to `pid`. The command and every
|
|
23
|
+
* process that it starts get `USINE_PROCESS`, the directory, in their environment, so that
|
|
24
|
+
* `STOP_SCRIPT` finds them even after the command exits or they leave its session. `tee -p` copies
|
|
25
|
+
* its output to `stdout` and `stderr` and keeps copying if the stream that started it closes, so a
|
|
26
|
+
* later request can attach. The exit code goes to `exit` when the command ends.
|
|
27
|
+
*/
|
|
28
|
+
export declare const PROCESS_SCRIPT: string;
|
|
29
|
+
/** Returns the container command that runs `command` through `PROCESS_SCRIPT`. */
|
|
30
|
+
export declare const processCommand: (process: ProcessId, command: string) => ReadonlyArray<string>;
|
|
31
|
+
/**
|
|
32
|
+
* A bash script that stops what the commands in the processes directory `$1` started: every
|
|
33
|
+
* process in the session of each command, and in the session of each process whose
|
|
34
|
+
* `USINE_PROCESS` is in `$1`, so it includes what a command left running after it exited. It sends
|
|
35
|
+
* TERM to each process group in those sessions, waits up to five seconds, then sends KILL until no
|
|
36
|
+
* process is left. It prints the number of sessions it signaled, and fails if a process still runs
|
|
37
|
+
* five seconds after the first KILL.
|
|
38
|
+
*
|
|
39
|
+
* A command that exited has released its process ID. If another process has that ID now, the
|
|
40
|
+
* command's session has ended, and the script skips the session that has the ID now.
|
|
41
|
+
*/
|
|
42
|
+
export declare const STOP_SCRIPT: string;
|
|
43
|
+
/** Returns the container command that runs `STOP_SCRIPT`. */
|
|
44
|
+
export declare const stopCommand: ReadonlyArray<string>;
|
|
45
|
+
/** Returns the container command that prints the bytes of `file` from `offset`. */
|
|
46
|
+
export declare const readFromCommand: (file: string, offset: number) => ReadonlyArray<string>;
|
|
47
|
+
/** Returns the number that `STOP_SCRIPT` printed, or `None` for any other output. */
|
|
48
|
+
export declare const stoppedCount: (output: string) => Option.Option<number>;
|
|
49
|
+
/** Returns the process ID in a `pid` file, or `None` if it's empty or malformed. */
|
|
50
|
+
export declare const pidOf: (content: string) => Option.Option<number>;
|
|
51
|
+
/** Returns the exit code in an `exit` file, or `None` if it's malformed. */
|
|
52
|
+
export declare const exitCodeOf: (content: string) => Option.Option<number>;
|
|
53
|
+
/** Returns a new random process ID. */
|
|
54
|
+
export declare const newProcessId: () => ProcessId;
|
|
55
|
+
//# sourceMappingURL=process.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/sandbox/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAG1C;;;;GAIG;AACH,eAAO,MAAM,cAAc,UAAW,MAAM,GAAG,QAAQ,KAAG,oBAQzD,CAAC;AAKF,2DAA2D;AAC3D,eAAO,MAAM,YAAY,YAAa,SAAS;IAG3C,6EAA6E;aAC7E,GAAG;IACH,qDAAqD;aACrD,IAAI;aACJ,MAAM;aACN,MAAM;CAET,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,QAenB,CAAC;AAET,kFAAkF;AAClF,eAAO,MAAM,cAAc,YAAa,SAAS,WAAW,MAAM,KAAG,aAAa,CAAC,MAAM,CAOxF,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,QA8DhB,CAAC;AAET,6DAA6D;AAC7D,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,MAAM,CAM7C,CAAC;AAEF,mFAAmF;AACnF,eAAO,MAAM,eAAe,SAAU,MAAM,UAAU,MAAM,KAAG,aAAa,CAAC,MAAM,CAMlF,CAAC;AAMF,qFAAqF;AACrF,eAAO,MAAM,YAAY,WAAY,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAA+B,CAAC;AAMlG,oFAAoF;AACpF,eAAO,MAAM,KAAK,YAAa,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAA8B,CAAC;AAM3F,4EAA4E;AAC5E,eAAO,MAAM,UAAU,YAAa,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CACjC,CAAC;AAIjC,uCAAuC;AACvC,eAAO,MAAM,YAAY,QAAO,SAG/B,CAAC"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { Option, Schema } from "effect";
|
|
2
|
+
import { ProcessId } from "../api/api.js";
|
|
3
|
+
import { PROCESSES_DIRECTORY, SANDBOX_HOME } from "../api/harness.js";
|
|
4
|
+
/**
|
|
5
|
+
* Returns the Container API options of a command the Worker runs. The platform passes a command
|
|
6
|
+
* only the image's `PATH`, not its `ENV HOME`, so the options set `HOME` and start the command in
|
|
7
|
+
* the sandbox home.
|
|
8
|
+
*/
|
|
9
|
+
export const commandOptions = (stdin) => {
|
|
10
|
+
const options = {
|
|
11
|
+
cwd: SANDBOX_HOME,
|
|
12
|
+
env: { HOME: SANDBOX_HOME },
|
|
13
|
+
stdout: "pipe",
|
|
14
|
+
stderr: "pipe",
|
|
15
|
+
};
|
|
16
|
+
return stdin === "pipe" ? { ...options, stdin: "pipe" } : options;
|
|
17
|
+
};
|
|
18
|
+
/** Returns the directory with the process files of `process`. */
|
|
19
|
+
const processDirectory = (process) => `${PROCESSES_DIRECTORY}/${process}`;
|
|
20
|
+
/** The files a command leaves in its process directory. */
|
|
21
|
+
export const processFiles = (process) => {
|
|
22
|
+
const directory = processDirectory(process);
|
|
23
|
+
return {
|
|
24
|
+
/** The command's process ID, which is also its process group and session. */
|
|
25
|
+
pid: `${directory}/pid`,
|
|
26
|
+
/** The exit code, written once the command exits. */
|
|
27
|
+
exit: `${directory}/exit`,
|
|
28
|
+
stdout: `${directory}/stdout`,
|
|
29
|
+
stderr: `${directory}/stderr`,
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* A POSIX shell script that runs the command line `$2` with process files in the directory `$1`,
|
|
34
|
+
* and passes its stdin, stdout, stderr, and exit code through. Run it with `sh -c`.
|
|
35
|
+
*
|
|
36
|
+
* The command runs in its own session and writes its process ID to `pid`. The command and every
|
|
37
|
+
* process that it starts get `USINE_PROCESS`, the directory, in their environment, so that
|
|
38
|
+
* `STOP_SCRIPT` finds them even after the command exits or they leave its session. `tee -p` copies
|
|
39
|
+
* its output to `stdout` and `stderr` and keeps copying if the stream that started it closes, so a
|
|
40
|
+
* later request can attach. The exit code goes to `exit` when the command ends.
|
|
41
|
+
*/
|
|
42
|
+
export const PROCESS_SCRIPT = String.raw `
|
|
43
|
+
d=$1
|
|
44
|
+
mkdir -p "$d" && mkfifo "$d/stdout.pipe" "$d/stderr.pipe" || exit 125
|
|
45
|
+
exec 3<&0
|
|
46
|
+
tee -p -a "$d/stdout" < "$d/stdout.pipe" &
|
|
47
|
+
tee -p -a "$d/stderr" < "$d/stderr.pipe" >&2 &
|
|
48
|
+
USINE_PROCESS=$d setsid -w sh -c 'printf %s "$$" > "$0" && exec sh -c "$1"' "$d/pid" "$2" <&3 > "$d/stdout.pipe" 2> "$d/stderr.pipe" &
|
|
49
|
+
command=$!
|
|
50
|
+
exec 3<&-
|
|
51
|
+
wait "$command"
|
|
52
|
+
code=$?
|
|
53
|
+
wait
|
|
54
|
+
printf %s "$code" > "$d/exit.next" && mv "$d/exit.next" "$d/exit"
|
|
55
|
+
rm -f "$d/stdout.pipe" "$d/stderr.pipe"
|
|
56
|
+
exit "$code"
|
|
57
|
+
`.trim();
|
|
58
|
+
/** Returns the container command that runs `command` through `PROCESS_SCRIPT`. */
|
|
59
|
+
export const processCommand = (process, command) => [
|
|
60
|
+
"sh",
|
|
61
|
+
"-c",
|
|
62
|
+
PROCESS_SCRIPT,
|
|
63
|
+
"usine-process",
|
|
64
|
+
processDirectory(process),
|
|
65
|
+
command,
|
|
66
|
+
];
|
|
67
|
+
/**
|
|
68
|
+
* A bash script that stops what the commands in the processes directory `$1` started: every
|
|
69
|
+
* process in the session of each command, and in the session of each process whose
|
|
70
|
+
* `USINE_PROCESS` is in `$1`, so it includes what a command left running after it exited. It sends
|
|
71
|
+
* TERM to each process group in those sessions, waits up to five seconds, then sends KILL until no
|
|
72
|
+
* process is left. It prints the number of sessions it signaled, and fails if a process still runs
|
|
73
|
+
* five seconds after the first KILL.
|
|
74
|
+
*
|
|
75
|
+
* A command that exited has released its process ID. If another process has that ID now, the
|
|
76
|
+
* command's session has ended, and the script skips the session that has the ID now.
|
|
77
|
+
*/
|
|
78
|
+
export const STOP_SCRIPT = `
|
|
79
|
+
root=$1
|
|
80
|
+
declare -A groups=() sessions=()
|
|
81
|
+
read -r line < "/proc/$$/stat"
|
|
82
|
+
fields=(\${line##*") "})
|
|
83
|
+
own=\${fields[3]}
|
|
84
|
+
scan() {
|
|
85
|
+
local process line fields entry
|
|
86
|
+
groups=()
|
|
87
|
+
for process in /proc/[0-9]*; do
|
|
88
|
+
read -r line 2>/dev/null < "$process/stat" || continue
|
|
89
|
+
fields=(\${line##*") "})
|
|
90
|
+
case \${fields[0]} in Z|X) continue ;; esac
|
|
91
|
+
groups[\${fields[3]}]+=" \${fields[2]}"
|
|
92
|
+
[ "\${fields[3]}" = "$own" ] && continue
|
|
93
|
+
while IFS= read -r -d '' entry; do
|
|
94
|
+
case $entry in "USINE_PROCESS=$root"/*) sessions[\${fields[3]}]=1; break ;; esac
|
|
95
|
+
done 2>/dev/null < "$process/environ"
|
|
96
|
+
done
|
|
97
|
+
}
|
|
98
|
+
signal() {
|
|
99
|
+
local session group
|
|
100
|
+
local -A sent=()
|
|
101
|
+
for session in "\${!sessions[@]}"; do
|
|
102
|
+
for group in \${groups[$session]-}; do
|
|
103
|
+
[ -n "\${sent[$group]-}" ] || kill "-$1" -- "-$group" 2>/dev/null
|
|
104
|
+
sent[$group]=1
|
|
105
|
+
done
|
|
106
|
+
done
|
|
107
|
+
}
|
|
108
|
+
running() {
|
|
109
|
+
local session
|
|
110
|
+
for session in "\${!sessions[@]}"; do
|
|
111
|
+
[ -n "\${groups[$session]-}" ] && echo "$session"
|
|
112
|
+
done
|
|
113
|
+
}
|
|
114
|
+
scan
|
|
115
|
+
for pidfile in "$root"/*/pid; do
|
|
116
|
+
[ -f "$pidfile" ] || continue
|
|
117
|
+
read -r pid < "$pidfile"
|
|
118
|
+
case "$pid" in ''|*[!0-9]*) continue ;; esac
|
|
119
|
+
[ -f "\${pidfile%/pid}/exit" ] && [ -e "/proc/$pid" ] && continue
|
|
120
|
+
[ "$pid" != "$own" ] && [ -n "\${groups[$pid]-}" ] && sessions[$pid]=1
|
|
121
|
+
done
|
|
122
|
+
signal TERM
|
|
123
|
+
for _ in {1..20}; do
|
|
124
|
+
[ -z "$(running)" ] && break
|
|
125
|
+
sleep 0.25
|
|
126
|
+
scan
|
|
127
|
+
done
|
|
128
|
+
for _ in {1..20}; do
|
|
129
|
+
[ -z "$(running)" ] && break
|
|
130
|
+
signal KILL
|
|
131
|
+
sleep 0.25
|
|
132
|
+
scan
|
|
133
|
+
done
|
|
134
|
+
left=$(running)
|
|
135
|
+
if [ -n "$left" ]; then
|
|
136
|
+
echo "Processes still run after KILL in sessions" $left >&2
|
|
137
|
+
exit 1
|
|
138
|
+
fi
|
|
139
|
+
echo "\${#sessions[@]}"
|
|
140
|
+
`.trim();
|
|
141
|
+
/** Returns the container command that runs `STOP_SCRIPT`. */
|
|
142
|
+
export const stopCommand = [
|
|
143
|
+
"bash",
|
|
144
|
+
"-c",
|
|
145
|
+
STOP_SCRIPT,
|
|
146
|
+
"usine-stop",
|
|
147
|
+
PROCESSES_DIRECTORY,
|
|
148
|
+
];
|
|
149
|
+
/** Returns the container command that prints the bytes of `file` from `offset`. */
|
|
150
|
+
export const readFromCommand = (file, offset) => [
|
|
151
|
+
"tail",
|
|
152
|
+
"-c",
|
|
153
|
+
`+${String(offset + 1)}`,
|
|
154
|
+
"--",
|
|
155
|
+
file,
|
|
156
|
+
];
|
|
157
|
+
const decodeCount = Schema.decodeUnknownOption(Schema.NumberFromString.check(Schema.isInt(), Schema.isGreaterThanOrEqualTo(0)));
|
|
158
|
+
/** Returns the number that `STOP_SCRIPT` printed, or `None` for any other output. */
|
|
159
|
+
export const stoppedCount = (output) => decodeCount(output.trim());
|
|
160
|
+
const decodePid = Schema.decodeUnknownOption(Schema.NumberFromString.check(Schema.isInt(), Schema.isGreaterThanOrEqualTo(1)));
|
|
161
|
+
/** Returns the process ID in a `pid` file, or `None` if it's empty or malformed. */
|
|
162
|
+
export const pidOf = (content) => decodePid(content.trim());
|
|
163
|
+
const decodeExitCode = Schema.decodeUnknownOption(Schema.NumberFromString.check(Schema.isInt(), Schema.isBetween({ minimum: 0, maximum: 255 })));
|
|
164
|
+
/** Returns the exit code in an `exit` file, or `None` if it's malformed. */
|
|
165
|
+
export const exitCodeOf = (content) => decodeExitCode(content.trim());
|
|
166
|
+
const ProcessIdBytes = 16;
|
|
167
|
+
/** Returns a new random process ID. */
|
|
168
|
+
export const newProcessId = () => {
|
|
169
|
+
const bytes = crypto.getRandomValues(new Uint8Array(ProcessIdBytes));
|
|
170
|
+
return ProcessId.make([...bytes].map((byte) => byte.toString(16).padStart(2, "0")).join(""));
|
|
171
|
+
};
|
|
172
|
+
//# sourceMappingURL=process.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/sandbox/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtE;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAwB,EAAwB,EAAE;IAC/E,MAAM,OAAO,GAAyB;QACpC,GAAG,EAAE,YAAY;QACjB,GAAG,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE;QAC3B,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,MAAM;KACf,CAAC;IACF,OAAO,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;AACpE,CAAC,CAAC;AAEF,iEAAiE;AACjE,MAAM,gBAAgB,GAAG,CAAC,OAAkB,EAAU,EAAE,CAAC,GAAG,mBAAmB,IAAI,OAAO,EAAE,CAAC;AAE7F,2DAA2D;AAC3D,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAkB,EAAE,EAAE;IACjD,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC5C,OAAO;QACL,6EAA6E;QAC7E,GAAG,EAAE,GAAG,SAAS,MAAM;QACvB,qDAAqD;QACrD,IAAI,EAAE,GAAG,SAAS,OAAO;QACzB,MAAM,EAAE,GAAG,SAAS,SAAS;QAC7B,MAAM,EAAE,GAAG,SAAS,SAAS;KACrB,CAAC;AACb,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;CAevC,CAAC,IAAI,EAAE,CAAC;AAET,kFAAkF;AAClF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,OAAkB,EAAE,OAAe,EAAyB,EAAE,CAAC;IAC5F,IAAI;IACJ,IAAI;IACJ,cAAc;IACd,eAAe;IACf,gBAAgB,CAAC,OAAO,CAAC;IACzB,OAAO;CACR,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8D1B,CAAC,IAAI,EAAE,CAAC;AAET,6DAA6D;AAC7D,MAAM,CAAC,MAAM,WAAW,GAA0B;IAChD,MAAM;IACN,IAAI;IACJ,WAAW;IACX,YAAY;IACZ,mBAAmB;CACpB,CAAC;AAEF,mFAAmF;AACnF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAY,EAAE,MAAc,EAAyB,EAAE,CAAC;IACtF,MAAM;IACN,IAAI;IACJ,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE;IACxB,IAAI;IACJ,IAAI;CACL,CAAC;AAEF,MAAM,WAAW,GAAG,MAAM,CAAC,mBAAmB,CAC5C,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAChF,CAAC;AAEF,qFAAqF;AACrF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAc,EAAyB,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;AAElG,MAAM,SAAS,GAAG,MAAM,CAAC,mBAAmB,CAC1C,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAChF,CAAC;AAEF,oFAAoF;AACpF,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,OAAe,EAAyB,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAE3F,MAAM,cAAc,GAAG,MAAM,CAAC,mBAAmB,CAC/C,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,CAC9F,CAAC;AAEF,4EAA4E;AAC5E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAe,EAAyB,EAAE,CACnE,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAEjC,MAAM,cAAc,GAAG,EAAE,CAAC;AAE1B,uCAAuC;AACvC,MAAM,CAAC,MAAM,YAAY,GAAG,GAAc,EAAE;IAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC;IACrE,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/F,CAAC,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Duration, Effect, Layer } from "effect";
|
|
2
|
+
import { ContainerUnavailable, SandboxNotFound } from "../api/api.ts";
|
|
3
|
+
import { ContainerFailure, type ContainerProcess, SandboxContainer, SandboxDirectory, SandboxSettings, SandboxStorage, StoredSandbox } from "./ports.ts";
|
|
4
|
+
/** How long the keepalive alarm keeps a container running after the last create, renewal, or command. */
|
|
5
|
+
export declare const LEASE: Duration.Duration;
|
|
6
|
+
/** Waits for `process` to exit and returns its output bytes, unchanged, and exit code. */
|
|
7
|
+
export declare const collectBytes: (process: ContainerProcess) => Effect.Effect<{
|
|
8
|
+
stdout: Uint8Array<ArrayBufferLike>;
|
|
9
|
+
stderr: Uint8Array<ArrayBufferLike>;
|
|
10
|
+
exitCode: number;
|
|
11
|
+
}, ContainerFailure, never>;
|
|
12
|
+
/** Returns the stored sandbox if its container runs, or fails with `ContainerUnavailable`. */
|
|
13
|
+
export declare const runningSandboxFor: (name: string & import("effect/Brand").Brand<"SandboxName">) => Effect.Effect<StoredSandbox, ContainerUnavailable | SandboxNotFound, SandboxContainer | SandboxStorage>;
|
|
14
|
+
/**
|
|
15
|
+
* Extends the sandbox's lease from now and returns the stored sandbox, or fails with
|
|
16
|
+
* `SandboxNotFound` if it was destroyed.
|
|
17
|
+
*/
|
|
18
|
+
export declare const extendLease: (name: string & import("effect/Brand").Brand<"SandboxName">) => Effect.Effect<StoredSandbox, SandboxNotFound, SandboxStorage>;
|
|
19
|
+
/**
|
|
20
|
+
* Keeps the container running while the sandbox's lease lasts or usine holds it, then lets the
|
|
21
|
+
* platform stop it after `INACTIVITY_TIMEOUT`. Runs from the Durable Object's alarm, and sets the
|
|
22
|
+
* next one.
|
|
23
|
+
*/
|
|
24
|
+
export declare const keepAlive: () => Effect.Effect<void, never, SandboxContainer | SandboxStorage>;
|
|
25
|
+
/**
|
|
26
|
+
* Registers the outbound handlers and sets the inactivity timeout again after the Durable Object
|
|
27
|
+
* restarts while its container runs, since the platform resets both for each instance. Does
|
|
28
|
+
* nothing for a sandbox without a running container.
|
|
29
|
+
*/
|
|
30
|
+
export declare const restore: () => Effect.Effect<void, never, SandboxContainer | SandboxSettings | SandboxStorage>;
|
|
31
|
+
/**
|
|
32
|
+
* The health and sandbox routes of `SandboxApi`, served by each sandbox's Durable Object. Requires
|
|
33
|
+
* `SandboxContainer`, `SandboxStorage`, `SandboxDirectory`, and `SandboxSettings`.
|
|
34
|
+
*/
|
|
35
|
+
export declare const sandboxRoutes: Layer.Layer<never, never, import("effect/http/HttpRouter").HttpRouter | import("effect/http/HttpRouter").Request<"Requires", SandboxDirectory> | import("effect/http/HttpRouter").Request<"Requires", SandboxSettings> | (import("effect/http/HttpRouter").Request<"Requires", SandboxContainer> | import("effect/http/HttpRouter").Request<"Requires", SandboxStorage>)>;
|
|
36
|
+
//# sourceMappingURL=sandbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/sandbox/sandbox.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,QAAQ,EAAE,MAAM,EAAE,KAAK,EAA6B,MAAM,QAAQ,CAAC;AAGtF,OAAO,EACL,oBAAoB,EAgBpB,eAAe,EAGhB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,aAAa,EACd,MAAM,YAAY,CAAC;AAGpB,yGAAyG;AACzG,eAAO,MAAM,KAAK,mBAAoB,CAAC;AAevC,0FAA0F;AAC1F,eAAO,MAAM,YAAY,YAAa,gBAAgB;;;;2BAQ+B,CAAC;AA+CtF,8FAA8F;AAC9F,eAAO,MAAM,iBAAiB,yKAS5B,CAAC;AAsDH;;;GAGG;AACH,eAAO,MAAM,WAAW,+HAMtB,CAAC;AAmOH;;;;GAIG;AACH,eAAO,MAAM,SAAS,qEAiCpB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,OAAO,uFA2BlB,CAAC;AAyBH;;;GAGG;AACH,eAAO,MAAM,aAAa,2WAGzB,CAAC"}
|