endia 0.0.0-stage → 0.0.2
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 +202 -0
- package/README.md +34 -2
- package/dist/archives/archive-file.d.ts +36 -0
- package/dist/archives/archive-file.js +71 -0
- package/dist/archives/build-context.d.ts +63 -0
- package/dist/archives/build-context.js +132 -0
- package/dist/archives/docker-ignore.d.ts +57 -0
- package/dist/archives/docker-ignore.js +250 -0
- package/dist/archives/fleet-archive.d.ts +33 -0
- package/dist/archives/fleet-archive.js +134 -0
- package/dist/compose-model.d.ts +32 -0
- package/dist/compose-model.js +39 -0
- package/dist/contract/archives.d.ts +14 -0
- package/dist/contract/archives.js +1 -0
- package/dist/contract/bases.d.ts +48 -0
- package/dist/contract/bases.js +1 -0
- package/dist/contract/clients.d.ts +29 -0
- package/dist/contract/clients.js +1 -0
- package/dist/contract/common.d.ts +30 -0
- package/dist/contract/common.js +1 -0
- package/dist/contract/compose.d.ts +27 -0
- package/dist/contract/compose.js +1 -0
- package/dist/contract/desktop.d.ts +269 -0
- package/dist/contract/desktop.js +1 -0
- package/dist/contract/execs.d.ts +61 -0
- package/dist/contract/execs.js +1 -0
- package/dist/contract/fleets.d.ts +136 -0
- package/dist/contract/fleets.js +1 -0
- package/dist/contract/images.d.ts +130 -0
- package/dist/contract/images.js +1 -0
- package/dist/contract/machines.d.ts +199 -0
- package/dist/contract/machines.js +1 -0
- package/dist/contract/operations.d.ts +28 -0
- package/dist/contract/operations.js +1 -0
- package/dist/contract/processes.d.ts +75 -0
- package/dist/contract/processes.js +1 -0
- package/dist/contract/purposes.d.ts +62 -0
- package/dist/contract/purposes.js +1 -0
- package/dist/contract/space.d.ts +114 -0
- package/dist/contract/space.js +1 -0
- package/dist/contract/stats.d.ts +58 -0
- package/dist/contract/stats.js +1 -0
- package/dist/contract/status.d.ts +151 -0
- package/dist/contract/status.js +1 -0
- package/dist/contract/volumes.d.ts +22 -0
- package/dist/contract/volumes.js +1 -0
- package/dist/eastindia-client.d.ts +118 -0
- package/dist/eastindia-client.js +142 -0
- package/dist/environment.d.ts +52 -0
- package/dist/environment.js +133 -0
- package/dist/errors.d.ts +81 -0
- package/dist/errors.js +108 -0
- package/dist/exec/exec-frame.d.ts +38 -0
- package/dist/exec/exec-frame.js +50 -0
- package/dist/exec/exec-session.d.ts +64 -0
- package/dist/exec/exec-session.js +117 -0
- package/dist/groups/archives.d.ts +78 -0
- package/dist/groups/archives.js +117 -0
- package/dist/groups/bases.d.ts +28 -0
- package/dist/groups/bases.js +39 -0
- package/dist/groups/certificates.d.ts +32 -0
- package/dist/groups/certificates.js +43 -0
- package/dist/groups/desktop.d.ts +143 -0
- package/dist/groups/desktop.js +182 -0
- package/dist/groups/execs.d.ts +110 -0
- package/dist/groups/execs.js +119 -0
- package/dist/groups/fleets.d.ts +206 -0
- package/dist/groups/fleets.js +255 -0
- package/dist/groups/images.d.ts +130 -0
- package/dist/groups/images.js +109 -0
- package/dist/groups/machines.d.ts +124 -0
- package/dist/groups/machines.js +127 -0
- package/dist/groups/operations.d.ts +127 -0
- package/dist/groups/operations.js +174 -0
- package/dist/groups/processes.d.ts +77 -0
- package/dist/groups/processes.js +75 -0
- package/dist/groups/stats.d.ts +29 -0
- package/dist/groups/stats.js +33 -0
- package/dist/groups/system.d.ts +33 -0
- package/dist/groups/system.js +40 -0
- package/dist/groups/volumes.d.ts +36 -0
- package/dist/groups/volumes.js +40 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +20 -0
- package/dist/purposes.d.ts +17 -0
- package/dist/purposes.js +21 -0
- package/dist/routes.d.ts +71 -0
- package/dist/routes.js +73 -0
- package/dist/transport/api-connection.d.ts +185 -0
- package/dist/transport/api-connection.js +396 -0
- package/dist/transport/connection-failures.d.ts +14 -0
- package/dist/transport/connection-failures.js +57 -0
- package/dist/transport/json-lines.d.ts +10 -0
- package/dist/transport/json-lines.js +23 -0
- package/dist/transport/query-text.d.ts +49 -0
- package/dist/transport/query-text.js +62 -0
- package/dist/transport/service-address.d.ts +30 -0
- package/dist/transport/service-address.js +37 -0
- package/dist/transport/tls-files.d.ts +9 -0
- package/dist/transport/tls-files.js +1 -0
- package/package.json +44 -5
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type { Readable } from "node:stream";
|
|
2
|
+
import type { Filters } from "../contract/common.js";
|
|
3
|
+
import type { BuildResult, ImageDetail, ImageSummary, RemovalEntry, TagResult } from "../contract/images.js";
|
|
4
|
+
import type { BuilderPruneResult } from "../contract/space.js";
|
|
5
|
+
import type { OperationHandle } from "./operations.js";
|
|
6
|
+
/** What a build makes and how: the tags, the build arguments and labels, the stage to build, and the builder's resources. */
|
|
7
|
+
export interface BuildOptions {
|
|
8
|
+
/** The tags the new image carries, such as `lab/dotnet:10`. */
|
|
9
|
+
readonly tags?: readonly string[];
|
|
10
|
+
/** The build arguments, by name. */
|
|
11
|
+
readonly buildArgs?: Readonly<Record<string, string>>;
|
|
12
|
+
/** The labels added to the image, by key. */
|
|
13
|
+
readonly labels?: Readonly<Record<string, string>>;
|
|
14
|
+
/**
|
|
15
|
+
* The recipe's stage to build, named by its `FROM ... AS`, as `endia build --target` names it; the tags name that stage's result.
|
|
16
|
+
* The stages it is built on are built too, or found in the cache. When undefined, the build makes the recipe's last stage.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* For the recipe
|
|
20
|
+
* ```
|
|
21
|
+
* FROM eastindia/development:latest AS tools
|
|
22
|
+
* RUN choco install -y git
|
|
23
|
+
*
|
|
24
|
+
* FROM tools AS app
|
|
25
|
+
* COPY publish/ C:/app/
|
|
26
|
+
* ```
|
|
27
|
+
* `client.images.build({ folder: "./lab-image" }, { target: "tools", tags: ["lab/tools:1"] })` builds and tags the first stage
|
|
28
|
+
* alone. A later build without `target` finds that stage in the cache and builds only `app`.
|
|
29
|
+
*/
|
|
30
|
+
readonly target?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Whether to build every stage even when an image with the same build key exists. The build key is a SHA-256 hash of everything that decides
|
|
33
|
+
* a build's result, such as the parent image, every step and the content of every copied file; a build that finds an image with
|
|
34
|
+
* its key reuses that image.
|
|
35
|
+
*/
|
|
36
|
+
readonly noCache?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* The memory of the builder, the temporary machine that runs the recipe, in bytes; at least 2 GiB. When undefined, the service
|
|
39
|
+
* uses its configuration key `builderMemoryMiB`.
|
|
40
|
+
*/
|
|
41
|
+
readonly memory?: number;
|
|
42
|
+
/** The builder's processors, from 0.01 to 64. When undefined, the service uses its configuration key `builderProcessorCount`. */
|
|
43
|
+
readonly cpus?: number;
|
|
44
|
+
readonly signal?: AbortSignal;
|
|
45
|
+
}
|
|
46
|
+
/** A build context folder, packed as the `endia` CLI packs it. */
|
|
47
|
+
export interface FolderContext {
|
|
48
|
+
/** The context folder. */
|
|
49
|
+
readonly folder: string;
|
|
50
|
+
/** The recipe, inside the folder or outside it; when undefined, `Endiafile` in the folder when it exists, and `Dockerfile` otherwise. */
|
|
51
|
+
readonly recipe?: string;
|
|
52
|
+
}
|
|
53
|
+
/** A build context the caller has already packed as a tar archive. */
|
|
54
|
+
export interface ArchiveContext {
|
|
55
|
+
/** The archive: its bytes, or a function that opens it afresh, so that a retried request sends the same bytes. */
|
|
56
|
+
readonly archive: Uint8Array | (() => Readable);
|
|
57
|
+
/** The recipe's path inside the archive; when undefined, the service reads `Endiafile` at its root when it holds one, and `Dockerfile` otherwise. */
|
|
58
|
+
readonly recipe?: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The image routes: build, list, inspect, tag and remove, and the prune of the build cache that builds leave. A build and a prune
|
|
62
|
+
* each return an `OperationHandle`, because the service does that work in the background.
|
|
63
|
+
*/
|
|
64
|
+
export declare class ImagesClient {
|
|
65
|
+
private readonly connection;
|
|
66
|
+
private readonly operations;
|
|
67
|
+
/**
|
|
68
|
+
* Builds an image from a recipe and its context: `endia build`. A context folder is packed into a temporary archive as the CLI
|
|
69
|
+
* packs it, honouring its ignore file, and the archive is deleted once the service has accepted the build.
|
|
70
|
+
*
|
|
71
|
+
* @param context - A context folder with its recipe, or an archive the caller packed.
|
|
72
|
+
* @param options - The tags, build arguments, labels and resources.
|
|
73
|
+
* @returns The build's operation; its result is a `BuildResult`. Cancelling the request does not stop a build that has started.
|
|
74
|
+
*/
|
|
75
|
+
build(context: FolderContext | ArchiveContext, options?: BuildOptions): Promise<OperationHandle<BuildResult>>;
|
|
76
|
+
/**
|
|
77
|
+
* Lists images: `endia images`.
|
|
78
|
+
*
|
|
79
|
+
* @param options - `filters` such as `{ dangling: ["true"] }`, and a `reference` pattern such as `lab/*`.
|
|
80
|
+
* @returns The images.
|
|
81
|
+
*/
|
|
82
|
+
list(options?: {
|
|
83
|
+
readonly filters?: Filters;
|
|
84
|
+
readonly reference?: string;
|
|
85
|
+
readonly signal?: AbortSignal;
|
|
86
|
+
}): Promise<ImageSummary[]>;
|
|
87
|
+
/**
|
|
88
|
+
* Reads one image: `endia image inspect`.
|
|
89
|
+
*
|
|
90
|
+
* @param reference - A reference such as `lab/dotnet:10`, a digest, or a unique prefix of an image ID.
|
|
91
|
+
* @param signal - Cancels the request.
|
|
92
|
+
* @returns The image.
|
|
93
|
+
*/
|
|
94
|
+
inspect(reference: string, signal?: AbortSignal): Promise<ImageDetail>;
|
|
95
|
+
/**
|
|
96
|
+
* Points a tag at an image: `endia tag`.
|
|
97
|
+
*
|
|
98
|
+
* @param source - The image's reference, digest or ID prefix.
|
|
99
|
+
* @param target - The new reference, such as `lab/dotnet:approved`.
|
|
100
|
+
* @param signal - Cancels the request.
|
|
101
|
+
* @returns The tag, the image it now names, and the image it named before.
|
|
102
|
+
*/
|
|
103
|
+
tag(source: string, target: string, signal?: AbortSignal): Promise<TagResult>;
|
|
104
|
+
/**
|
|
105
|
+
* Removes a tag, and the image once no tag names it: `endia rmi`.
|
|
106
|
+
*
|
|
107
|
+
* @param reference - The reference, digest or ID prefix.
|
|
108
|
+
* @param options - `force` removes an image that several tags name.
|
|
109
|
+
* @returns Each tag removed and each image deleted.
|
|
110
|
+
*/
|
|
111
|
+
remove(reference: string, options?: {
|
|
112
|
+
readonly force?: boolean;
|
|
113
|
+
readonly signal?: AbortSignal;
|
|
114
|
+
}): Promise<RemovalEntry[]>;
|
|
115
|
+
/**
|
|
116
|
+
* Deletes the unused build cache: `endia builder prune`. A build-cache entry is the committed result of a recipe's stage that a
|
|
117
|
+
* build made below its target. An entry is unused when no image, machine or other entry is built on it and no running build has
|
|
118
|
+
* made or found it. The prune deletes every unused entry, repeating until none remains, and leaves the entries that running
|
|
119
|
+
* builds use.
|
|
120
|
+
*
|
|
121
|
+
* @param options - `all` is Docker's `--all`. It deletes the same entries, because once a build has finished the build cache holds
|
|
122
|
+
* nothing that a build still uses.
|
|
123
|
+
* @returns The prune's operation; its result names the entries deleted and the space freed.
|
|
124
|
+
*/
|
|
125
|
+
pruneBuildCache(options?: {
|
|
126
|
+
readonly all?: boolean;
|
|
127
|
+
readonly signal?: AbortSignal;
|
|
128
|
+
}): Promise<OperationHandle<BuilderPruneResult>>;
|
|
129
|
+
private sendBuild;
|
|
130
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { packBuildContext } from "../archives/build-context.js";
|
|
2
|
+
import { Routes } from "../routes.js";
|
|
3
|
+
import { jsonBody, tarBody } from "../transport/api-connection.js";
|
|
4
|
+
import { QueryText } from "../transport/query-text.js";
|
|
5
|
+
/**
|
|
6
|
+
* The image routes: build, list, inspect, tag and remove, and the prune of the build cache that builds leave. A build and a prune
|
|
7
|
+
* each return an `OperationHandle`, because the service does that work in the background.
|
|
8
|
+
*/
|
|
9
|
+
export class ImagesClient {
|
|
10
|
+
connection;
|
|
11
|
+
operations;
|
|
12
|
+
/** @internal */
|
|
13
|
+
constructor(connection, operations) {
|
|
14
|
+
this.connection = connection;
|
|
15
|
+
this.operations = operations;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Builds an image from a recipe and its context: `endia build`. A context folder is packed into a temporary archive as the CLI
|
|
19
|
+
* packs it, honouring its ignore file, and the archive is deleted once the service has accepted the build.
|
|
20
|
+
*
|
|
21
|
+
* @param context - A context folder with its recipe, or an archive the caller packed.
|
|
22
|
+
* @param options - The tags, build arguments, labels and resources.
|
|
23
|
+
* @returns The build's operation; its result is a `BuildResult`. Cancelling the request does not stop a build that has started.
|
|
24
|
+
*/
|
|
25
|
+
async build(context, options = {}) {
|
|
26
|
+
if ("archive" in context) {
|
|
27
|
+
const archive = context.archive;
|
|
28
|
+
const body = tarBody(archive);
|
|
29
|
+
return this.sendBuild(body, context.recipe, options);
|
|
30
|
+
}
|
|
31
|
+
const packed = await packBuildContext(context.folder, context.recipe);
|
|
32
|
+
try {
|
|
33
|
+
return await this.sendBuild(packed.archive.body, packed.recipe, options);
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
await packed.archive.delete();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Lists images: `endia images`.
|
|
41
|
+
*
|
|
42
|
+
* @param options - `filters` such as `{ dangling: ["true"] }`, and a `reference` pattern such as `lab/*`.
|
|
43
|
+
* @returns The images.
|
|
44
|
+
*/
|
|
45
|
+
list(options = {}) {
|
|
46
|
+
const query = new QueryText().addJson("filters", options.filters).add("reference", options.reference);
|
|
47
|
+
return this.connection.read(Routes.images + query.toString(), options.signal);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Reads one image: `endia image inspect`.
|
|
51
|
+
*
|
|
52
|
+
* @param reference - A reference such as `lab/dotnet:10`, a digest, or a unique prefix of an image ID.
|
|
53
|
+
* @param signal - Cancels the request.
|
|
54
|
+
* @returns The image.
|
|
55
|
+
*/
|
|
56
|
+
inspect(reference, signal) {
|
|
57
|
+
return this.connection.read(Routes.image(reference), signal);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Points a tag at an image: `endia tag`.
|
|
61
|
+
*
|
|
62
|
+
* @param source - The image's reference, digest or ID prefix.
|
|
63
|
+
* @param target - The new reference, such as `lab/dotnet:approved`.
|
|
64
|
+
* @param signal - Cancels the request.
|
|
65
|
+
* @returns The tag, the image it now names, and the image it named before.
|
|
66
|
+
*/
|
|
67
|
+
tag(source, target, signal) {
|
|
68
|
+
return this.connection.change({ method: "PUT", path: Routes.tag(target), body: jsonBody({ source }), signal });
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Removes a tag, and the image once no tag names it: `endia rmi`.
|
|
72
|
+
*
|
|
73
|
+
* @param reference - The reference, digest or ID prefix.
|
|
74
|
+
* @param options - `force` removes an image that several tags name.
|
|
75
|
+
* @returns Each tag removed and each image deleted.
|
|
76
|
+
*/
|
|
77
|
+
remove(reference, options = {}) {
|
|
78
|
+
const query = new QueryText().addFlag("force", options.force);
|
|
79
|
+
return this.connection.change({ method: "DELETE", path: Routes.image(reference) + query.toString(), signal: options.signal });
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Deletes the unused build cache: `endia builder prune`. A build-cache entry is the committed result of a recipe's stage that a
|
|
83
|
+
* build made below its target. An entry is unused when no image, machine or other entry is built on it and no running build has
|
|
84
|
+
* made or found it. The prune deletes every unused entry, repeating until none remains, and leaves the entries that running
|
|
85
|
+
* builds use.
|
|
86
|
+
*
|
|
87
|
+
* @param options - `all` is Docker's `--all`. It deletes the same entries, because once a build has finished the build cache holds
|
|
88
|
+
* nothing that a build still uses.
|
|
89
|
+
* @returns The prune's operation; its result names the entries deleted and the space freed.
|
|
90
|
+
*/
|
|
91
|
+
async pruneBuildCache(options = {}) {
|
|
92
|
+
const query = new QueryText().addFlag("all", options.all);
|
|
93
|
+
const accepted = await this.connection.change({ method: "POST", path: Routes.builderPrune + query.toString(), signal: options.signal });
|
|
94
|
+
return this.operations.handle(accepted);
|
|
95
|
+
}
|
|
96
|
+
async sendBuild(body, recipe, options) {
|
|
97
|
+
const query = new QueryText()
|
|
98
|
+
.addEach("t", options.tags)
|
|
99
|
+
.add("dockerfile", recipe)
|
|
100
|
+
.addJson("buildargs", options.buildArgs)
|
|
101
|
+
.addJson("labels", options.labels)
|
|
102
|
+
.add("target", options.target)
|
|
103
|
+
.add("memory", options.memory)
|
|
104
|
+
.add("cpus", options.cpus)
|
|
105
|
+
.addFlag("nocache", options.noCache);
|
|
106
|
+
const accepted = await this.connection.change({ method: "POST", path: Routes.build + query.toString(), body, signal: options.signal }, false);
|
|
107
|
+
return this.operations.handle(accepted);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { Filters } from "../contract/common.js";
|
|
2
|
+
import type { MachineDetail, MachineLogLine, MachineRestartResult, MachineSummary, MachinesResult } from "../contract/machines.js";
|
|
3
|
+
import type { MachinePurpose, MachinePurposeResult } from "../contract/purposes.js";
|
|
4
|
+
import { QueryText } from "../transport/query-text.js";
|
|
5
|
+
import type { OperationHandle } from "./operations.js";
|
|
6
|
+
/** Which lines of a machine's main-process output to read, as `endia logs` chooses them. */
|
|
7
|
+
export interface LogOptions {
|
|
8
|
+
/** Whether to keep reading new lines as the machine writes them, until the caller stops iterating. */
|
|
9
|
+
readonly follow?: boolean;
|
|
10
|
+
/** The number of lines from the end to start with, or `all`; every line when undefined. */
|
|
11
|
+
readonly tail?: number | "all";
|
|
12
|
+
/** The earliest line, as Docker writes the time: RFC 3339, Unix seconds, or a duration before now such as `10m`. */
|
|
13
|
+
readonly since?: string;
|
|
14
|
+
/** The latest line, in the same forms as `since`. */
|
|
15
|
+
readonly until?: string;
|
|
16
|
+
/** Ends the request; the iteration then throws the signal's reason. */
|
|
17
|
+
readonly signal?: AbortSignal;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Adds the query parameters of a log request.
|
|
21
|
+
*
|
|
22
|
+
* @param query - The query to add to.
|
|
23
|
+
* @param options - The lines to read.
|
|
24
|
+
* @returns The query.
|
|
25
|
+
*/
|
|
26
|
+
export declare function addLogOptions(query: QueryText, options: LogOptions): QueryText;
|
|
27
|
+
/**
|
|
28
|
+
* The machine routes: list, inspect, start, stop, restart, read the log, and read, set and clear a machine's own purpose. A machine is made and removed with its fleet
|
|
29
|
+
* (`FleetsClient.up` and `FleetsClient.down`). Starting, stopping and restarting return an `OperationHandle`, because the service
|
|
30
|
+
* does that work in the background.
|
|
31
|
+
*/
|
|
32
|
+
export declare class MachinesClient {
|
|
33
|
+
private readonly connection;
|
|
34
|
+
private readonly operations;
|
|
35
|
+
/**
|
|
36
|
+
* Lists machines: `endia ps`.
|
|
37
|
+
*
|
|
38
|
+
* @param options - `all` includes machines that are not running; `filters` such as `{ label: ["team=qa"] }`.
|
|
39
|
+
* @returns The machines.
|
|
40
|
+
*/
|
|
41
|
+
list(options?: {
|
|
42
|
+
readonly all?: boolean;
|
|
43
|
+
readonly filters?: Filters;
|
|
44
|
+
readonly signal?: AbortSignal;
|
|
45
|
+
}): Promise<MachineSummary[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Reads one machine: `endia inspect`.
|
|
48
|
+
*
|
|
49
|
+
* @param name - The machine name or a unique prefix of its ID.
|
|
50
|
+
* @param signal - Cancels the request.
|
|
51
|
+
* @returns The machine.
|
|
52
|
+
*/
|
|
53
|
+
inspect(name: string, signal?: AbortSignal): Promise<MachineDetail>;
|
|
54
|
+
/**
|
|
55
|
+
* Reads a machine's own purpose with every change to it, and the purpose in effect for the machine, its own or else its fleet's:
|
|
56
|
+
* `endia purpose show`.
|
|
57
|
+
*
|
|
58
|
+
* @param name - The machine name or a unique prefix of its ID.
|
|
59
|
+
* @param signal - Cancels the request.
|
|
60
|
+
* @returns The machine's own purpose and history, and its effective purpose with where it comes from.
|
|
61
|
+
*/
|
|
62
|
+
purpose(name: string, signal?: AbortSignal): Promise<MachinePurpose>;
|
|
63
|
+
/**
|
|
64
|
+
* Replaces a machine's own purpose, which overrides its fleet's for this machine only: `endia purpose set`.
|
|
65
|
+
*
|
|
66
|
+
* @param name - The machine name or a unique prefix of its ID.
|
|
67
|
+
* @param title - What the machine is being used for, in one line of 1 to 200 characters.
|
|
68
|
+
* @param options - `detail` is Markdown notes of at most 65536 bytes in UTF-8; without it the detail stored before is cleared.
|
|
69
|
+
* @returns The purpose now stored, which is also the machine's effective purpose.
|
|
70
|
+
* @throws Error when the title has a line break or the detail is too long. Nothing is sent then.
|
|
71
|
+
*/
|
|
72
|
+
setPurpose(name: string, title: string, options?: {
|
|
73
|
+
readonly detail?: string;
|
|
74
|
+
readonly signal?: AbortSignal;
|
|
75
|
+
}): Promise<MachinePurposeResult>;
|
|
76
|
+
/**
|
|
77
|
+
* Removes a machine's own purpose, which returns the machine to its fleet's: `endia purpose clear`.
|
|
78
|
+
*
|
|
79
|
+
* @param name - The machine name or a unique prefix of its ID.
|
|
80
|
+
* @param signal - Cancels the request.
|
|
81
|
+
* @returns The machine's own purpose now stored, which is null, and its effective purpose, which is its fleet's or null.
|
|
82
|
+
*/
|
|
83
|
+
clearPurpose(name: string, signal?: AbortSignal): Promise<MachinePurposeResult>;
|
|
84
|
+
/**
|
|
85
|
+
* Starts a stopped machine: `endia start`.
|
|
86
|
+
*
|
|
87
|
+
* @param name - The machine name or a unique prefix of its ID.
|
|
88
|
+
* @param signal - Cancels the request.
|
|
89
|
+
* @returns The start's operation; its result names the machine.
|
|
90
|
+
*/
|
|
91
|
+
start(name: string, signal?: AbortSignal): Promise<OperationHandle<MachinesResult>>;
|
|
92
|
+
/**
|
|
93
|
+
* Shuts a machine's Windows down: `endia stop`.
|
|
94
|
+
*
|
|
95
|
+
* @param name - The machine name or a unique prefix of its ID.
|
|
96
|
+
* @param options - `timeout` is the time in seconds Windows has to shut down before the virtual machine is turned off.
|
|
97
|
+
* @returns The stop's operation; its result names the machine.
|
|
98
|
+
*/
|
|
99
|
+
stop(name: string, options?: {
|
|
100
|
+
readonly timeout?: number;
|
|
101
|
+
readonly signal?: AbortSignal;
|
|
102
|
+
}): Promise<OperationHandle<MachinesResult>>;
|
|
103
|
+
/**
|
|
104
|
+
* Restarts a machine's Windows: `endia restart`.
|
|
105
|
+
*
|
|
106
|
+
* @param name - The machine name or a unique prefix of its ID.
|
|
107
|
+
* @param options - `timeout` as for `stop`; `hard` turns the virtual machine off and on instead of restarting Windows.
|
|
108
|
+
* @returns The restart's operation; its result has the boot IDs before and after.
|
|
109
|
+
*/
|
|
110
|
+
restart(name: string, options?: {
|
|
111
|
+
readonly timeout?: number;
|
|
112
|
+
readonly hard?: boolean;
|
|
113
|
+
readonly signal?: AbortSignal;
|
|
114
|
+
}): Promise<OperationHandle<MachineRestartResult>>;
|
|
115
|
+
/**
|
|
116
|
+
* Reads a machine's main-process output, one line at a time: `endia logs`.
|
|
117
|
+
*
|
|
118
|
+
* @param name - The machine name or a unique prefix of its ID.
|
|
119
|
+
* @param options - Which lines, and whether to follow new ones.
|
|
120
|
+
* @returns The lines, as they arrive.
|
|
121
|
+
*/
|
|
122
|
+
logs(name: string, options?: LogOptions): AsyncGenerator<MachineLogLine, void, undefined>;
|
|
123
|
+
private sendAction;
|
|
124
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { purposeBody } from "../purposes.js";
|
|
2
|
+
import { Routes } from "../routes.js";
|
|
3
|
+
import { jsonBody } from "../transport/api-connection.js";
|
|
4
|
+
import { QueryText } from "../transport/query-text.js";
|
|
5
|
+
/**
|
|
6
|
+
* Adds the query parameters of a log request.
|
|
7
|
+
*
|
|
8
|
+
* @param query - The query to add to.
|
|
9
|
+
* @param options - The lines to read.
|
|
10
|
+
* @returns The query.
|
|
11
|
+
*/
|
|
12
|
+
export function addLogOptions(query, options) {
|
|
13
|
+
return query.addFlag("follow", options.follow).add("tail", options.tail).add("since", options.since).add("until", options.until);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The machine routes: list, inspect, start, stop, restart, read the log, and read, set and clear a machine's own purpose. A machine is made and removed with its fleet
|
|
17
|
+
* (`FleetsClient.up` and `FleetsClient.down`). Starting, stopping and restarting return an `OperationHandle`, because the service
|
|
18
|
+
* does that work in the background.
|
|
19
|
+
*/
|
|
20
|
+
export class MachinesClient {
|
|
21
|
+
connection;
|
|
22
|
+
operations;
|
|
23
|
+
/** @internal */
|
|
24
|
+
constructor(connection, operations) {
|
|
25
|
+
this.connection = connection;
|
|
26
|
+
this.operations = operations;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Lists machines: `endia ps`.
|
|
30
|
+
*
|
|
31
|
+
* @param options - `all` includes machines that are not running; `filters` such as `{ label: ["team=qa"] }`.
|
|
32
|
+
* @returns The machines.
|
|
33
|
+
*/
|
|
34
|
+
list(options = {}) {
|
|
35
|
+
const query = new QueryText().addFlag("all", options.all).addJson("filters", options.filters);
|
|
36
|
+
return this.connection.read(Routes.machines + query.toString(), options.signal);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Reads one machine: `endia inspect`.
|
|
40
|
+
*
|
|
41
|
+
* @param name - The machine name or a unique prefix of its ID.
|
|
42
|
+
* @param signal - Cancels the request.
|
|
43
|
+
* @returns The machine.
|
|
44
|
+
*/
|
|
45
|
+
inspect(name, signal) {
|
|
46
|
+
return this.connection.read(Routes.machine(name), signal);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Reads a machine's own purpose with every change to it, and the purpose in effect for the machine, its own or else its fleet's:
|
|
50
|
+
* `endia purpose show`.
|
|
51
|
+
*
|
|
52
|
+
* @param name - The machine name or a unique prefix of its ID.
|
|
53
|
+
* @param signal - Cancels the request.
|
|
54
|
+
* @returns The machine's own purpose and history, and its effective purpose with where it comes from.
|
|
55
|
+
*/
|
|
56
|
+
purpose(name, signal) {
|
|
57
|
+
return this.connection.read(Routes.machinePurpose(name), signal);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Replaces a machine's own purpose, which overrides its fleet's for this machine only: `endia purpose set`.
|
|
61
|
+
*
|
|
62
|
+
* @param name - The machine name or a unique prefix of its ID.
|
|
63
|
+
* @param title - What the machine is being used for, in one line of 1 to 200 characters.
|
|
64
|
+
* @param options - `detail` is Markdown notes of at most 65536 bytes in UTF-8; without it the detail stored before is cleared.
|
|
65
|
+
* @returns The purpose now stored, which is also the machine's effective purpose.
|
|
66
|
+
* @throws Error when the title has a line break or the detail is too long. Nothing is sent then.
|
|
67
|
+
*/
|
|
68
|
+
async setPurpose(name, title, options = {}) {
|
|
69
|
+
const body = purposeBody(title, options.detail);
|
|
70
|
+
return await this.connection.change({ method: "PUT", path: Routes.machinePurpose(name), body: jsonBody(body), signal: options.signal });
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Removes a machine's own purpose, which returns the machine to its fleet's: `endia purpose clear`.
|
|
74
|
+
*
|
|
75
|
+
* @param name - The machine name or a unique prefix of its ID.
|
|
76
|
+
* @param signal - Cancels the request.
|
|
77
|
+
* @returns The machine's own purpose now stored, which is null, and its effective purpose, which is its fleet's or null.
|
|
78
|
+
*/
|
|
79
|
+
clearPurpose(name, signal) {
|
|
80
|
+
return this.connection.change({ method: "DELETE", path: Routes.machinePurpose(name), signal });
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Starts a stopped machine: `endia start`.
|
|
84
|
+
*
|
|
85
|
+
* @param name - The machine name or a unique prefix of its ID.
|
|
86
|
+
* @param signal - Cancels the request.
|
|
87
|
+
* @returns The start's operation; its result names the machine.
|
|
88
|
+
*/
|
|
89
|
+
start(name, signal) {
|
|
90
|
+
return this.sendAction(Routes.machineStart(name), new QueryText(), signal);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Shuts a machine's Windows down: `endia stop`.
|
|
94
|
+
*
|
|
95
|
+
* @param name - The machine name or a unique prefix of its ID.
|
|
96
|
+
* @param options - `timeout` is the time in seconds Windows has to shut down before the virtual machine is turned off.
|
|
97
|
+
* @returns The stop's operation; its result names the machine.
|
|
98
|
+
*/
|
|
99
|
+
stop(name, options = {}) {
|
|
100
|
+
return this.sendAction(Routes.machineStop(name), new QueryText().add("t", options.timeout), options.signal);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Restarts a machine's Windows: `endia restart`.
|
|
104
|
+
*
|
|
105
|
+
* @param name - The machine name or a unique prefix of its ID.
|
|
106
|
+
* @param options - `timeout` as for `stop`; `hard` turns the virtual machine off and on instead of restarting Windows.
|
|
107
|
+
* @returns The restart's operation; its result has the boot IDs before and after.
|
|
108
|
+
*/
|
|
109
|
+
restart(name, options = {}) {
|
|
110
|
+
const query = new QueryText().add("t", options.timeout).addFlag("hard", options.hard);
|
|
111
|
+
return this.sendAction(Routes.machineRestart(name), query, options.signal);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Reads a machine's main-process output, one line at a time: `endia logs`.
|
|
115
|
+
*
|
|
116
|
+
* @param name - The machine name or a unique prefix of its ID.
|
|
117
|
+
* @param options - Which lines, and whether to follow new ones.
|
|
118
|
+
* @returns The lines, as they arrive.
|
|
119
|
+
*/
|
|
120
|
+
logs(name, options = {}) {
|
|
121
|
+
return this.connection.readLines(Routes.machineLogs(name) + addLogOptions(new QueryText(), options).toString(), options.signal);
|
|
122
|
+
}
|
|
123
|
+
async sendAction(path, query, signal) {
|
|
124
|
+
const accepted = await this.connection.change({ method: "POST", path: path + query.toString(), signal });
|
|
125
|
+
return this.operations.handle(accepted);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import type { Readable } from "node:stream";
|
|
2
|
+
import type { Filters } from "../contract/common.js";
|
|
3
|
+
import type { Operation } from "../contract/operations.js";
|
|
4
|
+
/**
|
|
5
|
+
* Says whether an operation has finished: succeeded, failed, been cancelled or been interrupted.
|
|
6
|
+
*
|
|
7
|
+
* @param operation - The operation as last read.
|
|
8
|
+
* @returns True when its state never changes again.
|
|
9
|
+
*/
|
|
10
|
+
export declare function isFinished(operation: Operation): boolean;
|
|
11
|
+
/** The options of reading an operation's log. */
|
|
12
|
+
export interface OperationLogOptions {
|
|
13
|
+
/** Whether the stream stays open until the operation finishes. */
|
|
14
|
+
readonly follow?: boolean;
|
|
15
|
+
/** The number of lines from the end of the log to start with; the whole log when undefined. */
|
|
16
|
+
readonly tail?: number;
|
|
17
|
+
readonly signal?: AbortSignal;
|
|
18
|
+
}
|
|
19
|
+
/** The options of waiting for an operation to finish. */
|
|
20
|
+
export interface OperationWaitOptions {
|
|
21
|
+
/** Receives the operation's log text as the service writes it, each piece once. */
|
|
22
|
+
readonly onLog?: (text: string) => void;
|
|
23
|
+
readonly signal?: AbortSignal;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The operation routes: list, inspect, read the log, cancel; and handles that follow one operation to its end. Every route that
|
|
27
|
+
* starts work returns an `OperationHandle` built here.
|
|
28
|
+
*/
|
|
29
|
+
export declare class OperationsClient {
|
|
30
|
+
private readonly connection;
|
|
31
|
+
/**
|
|
32
|
+
* Lists every kept operation, newest first: `endia operation ls`.
|
|
33
|
+
*
|
|
34
|
+
* @param options - `filters` such as `{ state: ["running"], kind: ["build"] }`.
|
|
35
|
+
* @returns The operations.
|
|
36
|
+
*/
|
|
37
|
+
list(options?: {
|
|
38
|
+
readonly filters?: Filters;
|
|
39
|
+
readonly signal?: AbortSignal;
|
|
40
|
+
}): Promise<Operation[]>;
|
|
41
|
+
/**
|
|
42
|
+
* Reads one operation: `endia operation inspect`.
|
|
43
|
+
*
|
|
44
|
+
* @param id - The operation ID or a unique prefix of it.
|
|
45
|
+
* @param signal - Cancels the request.
|
|
46
|
+
* @returns The operation.
|
|
47
|
+
*/
|
|
48
|
+
inspect<TResult = unknown>(id: string, signal?: AbortSignal): Promise<Operation<TResult>>;
|
|
49
|
+
/**
|
|
50
|
+
* Opens an operation's log, the lines the command prints as the CLI prints them: `endia operation logs`.
|
|
51
|
+
*
|
|
52
|
+
* @param id - The operation ID or a unique prefix of it.
|
|
53
|
+
* @param options - With `follow`, the stream stays open until the operation finishes.
|
|
54
|
+
* @returns The log as UTF-8 text.
|
|
55
|
+
*/
|
|
56
|
+
logs(id: string, options?: OperationLogOptions): Promise<Readable>;
|
|
57
|
+
/**
|
|
58
|
+
* Asks the service to cancel an operation: `endia operation cancel`. A build or import cleans up as on failure; a fleet or machine
|
|
59
|
+
* operation stops before its next machine step; a prune stops before its next deletion.
|
|
60
|
+
*
|
|
61
|
+
* @param id - The operation ID or a unique prefix of it.
|
|
62
|
+
* @param signal - Cancels the request.
|
|
63
|
+
* @returns The operation in `cancelling`, or unchanged when it had already finished.
|
|
64
|
+
*/
|
|
65
|
+
cancel(id: string, signal?: AbortSignal): Promise<Operation>;
|
|
66
|
+
/**
|
|
67
|
+
* Wraps an operation that was read elsewhere, such as one another program started, in a handle that follows it and waits for its
|
|
68
|
+
* end.
|
|
69
|
+
*
|
|
70
|
+
* @param operation - The operation as last read.
|
|
71
|
+
* @returns The handle.
|
|
72
|
+
*/
|
|
73
|
+
handle<TResult>(operation: Operation): OperationHandle<TResult>;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Work the service has accepted and carries out in the background: a build, an import, a fleet or machine change, or a prune. The
|
|
77
|
+
* handle follows that work: it reads the operation's state, follows its log, cancels it, and waits for it to finish.
|
|
78
|
+
*
|
|
79
|
+
* @typeParam TResult - The result the operation gives when it succeeds, such as `BuildResult`.
|
|
80
|
+
*/
|
|
81
|
+
export declare class OperationHandle<TResult> {
|
|
82
|
+
private readonly operations;
|
|
83
|
+
/** The operation as the service answered when it accepted the work. */
|
|
84
|
+
readonly accepted: Operation;
|
|
85
|
+
/** The operation ID: 32 lower-case hexadecimal digits. */
|
|
86
|
+
get id(): string;
|
|
87
|
+
/**
|
|
88
|
+
* Reads the operation as it stands now.
|
|
89
|
+
*
|
|
90
|
+
* @param signal - Cancels the request.
|
|
91
|
+
* @returns The operation.
|
|
92
|
+
*/
|
|
93
|
+
inspect(signal?: AbortSignal): Promise<Operation<TResult>>;
|
|
94
|
+
/**
|
|
95
|
+
* Opens the operation's log.
|
|
96
|
+
*
|
|
97
|
+
* @param options - With `follow`, the stream stays open until the operation finishes.
|
|
98
|
+
* @returns The log as UTF-8 text.
|
|
99
|
+
*/
|
|
100
|
+
logs(options?: OperationLogOptions): Promise<Readable>;
|
|
101
|
+
/**
|
|
102
|
+
* Asks the service to cancel the operation. The operation then ends `cancelled`, which `wait` reports.
|
|
103
|
+
*
|
|
104
|
+
* @param signal - Cancels the request.
|
|
105
|
+
* @returns The operation in `cancelling`, or unchanged when it had already finished.
|
|
106
|
+
*/
|
|
107
|
+
cancel(signal?: AbortSignal): Promise<Operation>;
|
|
108
|
+
/**
|
|
109
|
+
* Waits until the operation finishes, whatever its outcome, by following its log to the end as the CLI does.
|
|
110
|
+
*
|
|
111
|
+
* When the followed log ends before the operation has finished, as when the connection breaks, the log is opened again after a
|
|
112
|
+
* pause. The log only grows, so the text `onLog` has already received is skipped and each piece reaches it once.
|
|
113
|
+
*
|
|
114
|
+
* @param options - `onLog` receives the log as it is written.
|
|
115
|
+
* @returns The finished operation, in `succeeded`, `failed`, `cancelled` or `interrupted`.
|
|
116
|
+
*/
|
|
117
|
+
wait(options?: OperationWaitOptions): Promise<Operation<TResult>>;
|
|
118
|
+
/**
|
|
119
|
+
* Waits until the operation finishes and gives its result.
|
|
120
|
+
*
|
|
121
|
+
* @param options - `onLog` receives the log as it is written.
|
|
122
|
+
* @returns The result of the succeeded operation.
|
|
123
|
+
* @throws EastIndiaApiError when the operation failed, was cancelled or was interrupted; its `code` is the operation's error code,
|
|
124
|
+
* such as `BUILD_FAILED`, and its `operation` is the finished operation.
|
|
125
|
+
*/
|
|
126
|
+
result(options?: OperationWaitOptions): Promise<TResult>;
|
|
127
|
+
}
|