endia 0.0.1 → 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/README.md +14 -0
- package/dist/contract/images.d.ts +16 -3
- package/dist/contract/space.d.ts +29 -1
- package/dist/groups/images.d.ts +36 -4
- package/dist/groups/images.js +18 -2
- package/dist/groups/system.d.ts +9 -4
- package/dist/groups/system.js +9 -4
- package/dist/routes.d.ts +1 -0
- package/dist/routes.js +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,6 +6,16 @@ The package needs Node 20 or later and ships ES modules with TypeScript declarat
|
|
|
6
6
|
|
|
7
7
|
## Example
|
|
8
8
|
|
|
9
|
+
`ledger/Endiafile` holds a recipe of two stages; each stage begins with a `FROM`, and `AS` names it:
|
|
10
|
+
|
|
11
|
+
```dockerfile
|
|
12
|
+
FROM eastindia/development:latest AS tools
|
|
13
|
+
RUN choco install -y git
|
|
14
|
+
|
|
15
|
+
FROM tools AS app
|
|
16
|
+
COPY publish/ C:/app/
|
|
17
|
+
```
|
|
18
|
+
|
|
9
19
|
```js
|
|
10
20
|
import { EastIndiaClient } from "endia";
|
|
11
21
|
|
|
@@ -17,5 +27,9 @@ const build = await client.images.build({ folder: "./ledger" }, { tags: ["lab/le
|
|
|
17
27
|
const built = await build.result({ onLog: (text) => process.stdout.write(text) });
|
|
18
28
|
console.log(built.digest);
|
|
19
29
|
|
|
30
|
+
// A recipe of several stages: target names the stage to build, here the first.
|
|
31
|
+
const tools = await (await client.images.build({ folder: "./ledger" }, { target: "tools", tags: ["lab/tools:1"] })).result();
|
|
32
|
+
console.log(tools.stages?.map((stage) => [stage.name, stage.cacheHit]));
|
|
33
|
+
|
|
20
34
|
client.close();
|
|
21
35
|
```
|
|
@@ -102,16 +102,29 @@ export interface RemovalEntry {
|
|
|
102
102
|
/** The digest of the image that was deleted, or null when the event is a removed tag. */
|
|
103
103
|
readonly deleted?: string | null;
|
|
104
104
|
}
|
|
105
|
-
/** The result of a finished build: the image it made or reused, the tags that now name that image, and
|
|
105
|
+
/** The result of a finished build: the image it made or reused for its target stage, the tags that now name that image, whether anything was built, and what each stage on the way to the target gave. */
|
|
106
106
|
export interface BuildResult {
|
|
107
107
|
/** The digest of the image, in the form `sha256:` followed by 64 hexadecimal digits. */
|
|
108
108
|
readonly digest: string;
|
|
109
109
|
/** The tags that were requested, each of which now names the image; empty when the build asked for none. */
|
|
110
110
|
readonly tags: readonly string[];
|
|
111
|
-
/** The build key: a SHA-256 hash of everything that decides
|
|
111
|
+
/** The target stage's build key: a SHA-256 hash of everything that decides its result. A later build with the same key reuses this image. */
|
|
112
112
|
readonly buildKey: string;
|
|
113
|
-
/** Whether
|
|
113
|
+
/** Whether every stage was found in the cache, so that nothing was built. */
|
|
114
114
|
readonly cacheHit: boolean;
|
|
115
115
|
/** How long the build took, in seconds, from the start of the operation's work to the last tag moved. */
|
|
116
116
|
readonly seconds: number;
|
|
117
|
+
/** Each stage the build made or found, from the lowest, built on an image, to the target. A recipe of one stage gives one. A service older than multi-stage builds leaves it out. */
|
|
118
|
+
readonly stages?: readonly BuildStageResult[];
|
|
119
|
+
}
|
|
120
|
+
/** What one stage of a build gave: the image, for the target stage, or a build-cache entry, for a stage below it. A stage is the part of a recipe from one `FROM` to the next; a build-cache entry is a stage's committed result that is not an image, which a later build whose stage has the same build key reuses. */
|
|
121
|
+
export interface BuildStageResult {
|
|
122
|
+
/** The name that the stage's `FROM ... AS` gives it, in lower case, or null for a stage without one. */
|
|
123
|
+
readonly name: string | null;
|
|
124
|
+
/** The digest of the stage's result, in the form `sha256:` followed by 64 hexadecimal digits. */
|
|
125
|
+
readonly digest: string;
|
|
126
|
+
/** The stage's build key: a SHA-256 hash of everything that decides the stage's result. */
|
|
127
|
+
readonly buildKey: string;
|
|
128
|
+
/** Whether an image or build-cache entry with the stage's build key already existed, so that the stage was not built. */
|
|
129
|
+
readonly cacheHit: boolean;
|
|
117
130
|
}
|
package/dist/contract/space.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Timestamp } from "./common.js";
|
|
2
|
-
/** The answer to `endia system df`, as `docker system df` answers: what the images, machines
|
|
2
|
+
/** The answer to `endia system df`, as `docker system df` answers: what the images, machines, named volumes and build cache hold on disk, which of it is in use and which `system prune` would delete, and how much room the image folder's volume has left. */
|
|
3
3
|
export interface DiskUsage {
|
|
4
4
|
/** Every image. */
|
|
5
5
|
readonly images: readonly ImageUsage[];
|
|
@@ -7,6 +7,8 @@ export interface DiskUsage {
|
|
|
7
7
|
readonly machines: readonly MachineUsage[];
|
|
8
8
|
/** Every named volume. */
|
|
9
9
|
readonly volumes: readonly VolumeUsage[];
|
|
10
|
+
/** Every build-cache entry. A service older than multi-stage builds leaves it out. */
|
|
11
|
+
readonly buildCache?: readonly BuildCacheUsage[];
|
|
10
12
|
/** The image folder's volume: its free space, its capacity and the space EastIndia keeps free on it. */
|
|
11
13
|
readonly imageFolder: ImageFolderSpace;
|
|
12
14
|
/** The storage root: what its records take and the free space on its volume. */
|
|
@@ -49,6 +51,23 @@ export interface VolumeUsage {
|
|
|
49
51
|
/** The machine the volume is attached to, or null. */
|
|
50
52
|
readonly attachedTo: string | null;
|
|
51
53
|
}
|
|
54
|
+
/** One build-cache entry as `system df` counts it: the committed result of a recipe's stage that a build made below its target. It is not an image; a later build whose stage has the same build key reuses it. */
|
|
55
|
+
export interface BuildCacheUsage {
|
|
56
|
+
/** The entry's digest. */
|
|
57
|
+
readonly id: string;
|
|
58
|
+
/** The digest of the image or build-cache entry the entry is built on. */
|
|
59
|
+
readonly parentId: string | null;
|
|
60
|
+
/** When a build made the entry. */
|
|
61
|
+
readonly created: Timestamp;
|
|
62
|
+
/** When a build last made or found the entry. */
|
|
63
|
+
readonly lastUsed: Timestamp;
|
|
64
|
+
/** The size on disk of the entry's own disk file. */
|
|
65
|
+
readonly sizeBytes: number;
|
|
66
|
+
/** Whether an image, machine or other entry is built on the entry, or a running build has made or found it. `system df` counts such entries as active. */
|
|
67
|
+
readonly inUse: boolean;
|
|
68
|
+
/** Whether `builder prune` would delete the entry. */
|
|
69
|
+
readonly reclaimable: boolean;
|
|
70
|
+
}
|
|
52
71
|
/** The room left on the image folder's volume, where every disk lives. */
|
|
53
72
|
export interface ImageFolderSpace {
|
|
54
73
|
/** The image folder's full path. */
|
|
@@ -75,6 +94,8 @@ export interface PruneResult {
|
|
|
75
94
|
readonly deletedMachines: readonly string[];
|
|
76
95
|
/** The images deleted, by digest. */
|
|
77
96
|
readonly deletedImages: readonly string[];
|
|
97
|
+
/** The build-cache entries deleted, by digest: the results of recipe stages below a build's target that nothing used. A service older than multi-stage builds leaves it out. */
|
|
98
|
+
readonly deletedBuildCache?: readonly string[];
|
|
78
99
|
/** The named volumes deleted, by name. */
|
|
79
100
|
readonly deletedVolumes: readonly string[];
|
|
80
101
|
/** The number of finished operations deleted, those older than `operationRetentionDays`. */
|
|
@@ -84,3 +105,10 @@ export interface PruneResult {
|
|
|
84
105
|
/** The size of the files deleted. */
|
|
85
106
|
readonly reclaimedBytes: number;
|
|
86
107
|
}
|
|
108
|
+
/** The result of a `builder prune` operation: the build-cache entries it deleted and the space that freed. */
|
|
109
|
+
export interface BuilderPruneResult {
|
|
110
|
+
/** The build-cache entries deleted, by digest, in the order deleted. */
|
|
111
|
+
readonly deletedBuildCache: readonly string[];
|
|
112
|
+
/** The size of the disk files deleted. */
|
|
113
|
+
readonly reclaimedBytes: number;
|
|
114
|
+
}
|
package/dist/groups/images.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { Readable } from "node:stream";
|
|
2
2
|
import type { Filters } from "../contract/common.js";
|
|
3
3
|
import type { BuildResult, ImageDetail, ImageSummary, RemovalEntry, TagResult } from "../contract/images.js";
|
|
4
|
+
import type { BuilderPruneResult } from "../contract/space.js";
|
|
4
5
|
import type { OperationHandle } from "./operations.js";
|
|
5
|
-
/** What a build makes and how: the tags, the build arguments and labels, and the builder's resources. */
|
|
6
|
+
/** What a build makes and how: the tags, the build arguments and labels, the stage to build, and the builder's resources. */
|
|
6
7
|
export interface BuildOptions {
|
|
7
8
|
/** The tags the new image carries, such as `lab/dotnet:10`. */
|
|
8
9
|
readonly tags?: readonly string[];
|
|
@@ -11,7 +12,24 @@ export interface BuildOptions {
|
|
|
11
12
|
/** The labels added to the image, by key. */
|
|
12
13
|
readonly labels?: Readonly<Record<string, string>>;
|
|
13
14
|
/**
|
|
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
|
|
15
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
|
|
16
34
|
* its key reuses that image.
|
|
17
35
|
*/
|
|
@@ -40,8 +58,8 @@ export interface ArchiveContext {
|
|
|
40
58
|
readonly recipe?: string;
|
|
41
59
|
}
|
|
42
60
|
/**
|
|
43
|
-
* The image routes: build, list, inspect, tag and remove
|
|
44
|
-
* background.
|
|
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.
|
|
45
63
|
*/
|
|
46
64
|
export declare class ImagesClient {
|
|
47
65
|
private readonly connection;
|
|
@@ -94,5 +112,19 @@ export declare class ImagesClient {
|
|
|
94
112
|
readonly force?: boolean;
|
|
95
113
|
readonly signal?: AbortSignal;
|
|
96
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>>;
|
|
97
129
|
private sendBuild;
|
|
98
130
|
}
|
package/dist/groups/images.js
CHANGED
|
@@ -3,8 +3,8 @@ import { Routes } from "../routes.js";
|
|
|
3
3
|
import { jsonBody, tarBody } from "../transport/api-connection.js";
|
|
4
4
|
import { QueryText } from "../transport/query-text.js";
|
|
5
5
|
/**
|
|
6
|
-
* The image routes: build, list, inspect, tag and remove
|
|
7
|
-
* background.
|
|
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
8
|
*/
|
|
9
9
|
export class ImagesClient {
|
|
10
10
|
connection;
|
|
@@ -78,12 +78,28 @@ export class ImagesClient {
|
|
|
78
78
|
const query = new QueryText().addFlag("force", options.force);
|
|
79
79
|
return this.connection.change({ method: "DELETE", path: Routes.image(reference) + query.toString(), signal: options.signal });
|
|
80
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
|
+
}
|
|
81
96
|
async sendBuild(body, recipe, options) {
|
|
82
97
|
const query = new QueryText()
|
|
83
98
|
.addEach("t", options.tags)
|
|
84
99
|
.add("dockerfile", recipe)
|
|
85
100
|
.addJson("buildargs", options.buildArgs)
|
|
86
101
|
.addJson("labels", options.labels)
|
|
102
|
+
.add("target", options.target)
|
|
87
103
|
.add("memory", options.memory)
|
|
88
104
|
.add("cpus", options.cpus)
|
|
89
105
|
.addFlag("nocache", options.noCache);
|
package/dist/groups/system.d.ts
CHANGED
|
@@ -5,16 +5,21 @@ export declare class SystemClient {
|
|
|
5
5
|
private readonly connection;
|
|
6
6
|
private readonly operations;
|
|
7
7
|
/**
|
|
8
|
-
* Reads what images, machines and
|
|
8
|
+
* Reads what images, machines, volumes and the build cache take on disk, and the free space: `endia system df`.
|
|
9
9
|
*
|
|
10
10
|
* @param signal - Cancels the request.
|
|
11
11
|
* @returns The disk use.
|
|
12
12
|
*/
|
|
13
13
|
diskUsage(signal?: AbortSignal): Promise<DiskUsage>;
|
|
14
14
|
/**
|
|
15
|
-
* Deletes what nothing uses: `endia system prune`.
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* Deletes what nothing uses: `endia system prune`. It deletes, in this order:
|
|
16
|
+
* 1. every machine in state `exited` or `created`;
|
|
17
|
+
* 2. every image with no tag, no children and no machine;
|
|
18
|
+
* 3. the unused build cache, the entries that `images.pruneBuildCache` deletes;
|
|
19
|
+
* 4. the finished operations older than the service's retention;
|
|
20
|
+
* 5. the host objects whose owner no longer exists.
|
|
21
|
+
*
|
|
22
|
+
* It deletes what every caller of the service made, not only this caller's.
|
|
18
23
|
*
|
|
19
24
|
* @param options - `all` deletes every image that no machine uses and no image is built on, tagged or not. `volumes` is Docker's
|
|
20
25
|
* option for anonymous volumes; EastIndia has none, so it deletes nothing more.
|
package/dist/groups/system.js
CHANGED
|
@@ -10,7 +10,7 @@ export class SystemClient {
|
|
|
10
10
|
this.operations = operations;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
* Reads what images, machines and
|
|
13
|
+
* Reads what images, machines, volumes and the build cache take on disk, and the free space: `endia system df`.
|
|
14
14
|
*
|
|
15
15
|
* @param signal - Cancels the request.
|
|
16
16
|
* @returns The disk use.
|
|
@@ -19,9 +19,14 @@ export class SystemClient {
|
|
|
19
19
|
return this.connection.read(Routes.systemDf, signal);
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
|
-
* Deletes what nothing uses: `endia system prune`.
|
|
23
|
-
*
|
|
24
|
-
*
|
|
22
|
+
* Deletes what nothing uses: `endia system prune`. It deletes, in this order:
|
|
23
|
+
* 1. every machine in state `exited` or `created`;
|
|
24
|
+
* 2. every image with no tag, no children and no machine;
|
|
25
|
+
* 3. the unused build cache, the entries that `images.pruneBuildCache` deletes;
|
|
26
|
+
* 4. the finished operations older than the service's retention;
|
|
27
|
+
* 5. the host objects whose owner no longer exists.
|
|
28
|
+
*
|
|
29
|
+
* It deletes what every caller of the service made, not only this caller's.
|
|
25
30
|
*
|
|
26
31
|
* @param options - `all` deletes every image that no machine uses and no image is built on, tagged or not. `volumes` is Docker's
|
|
27
32
|
* option for anonymous volumes; EastIndia has none, so it deletes nothing more.
|
package/dist/routes.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare const Routes: {
|
|
|
8
8
|
readonly hostStats: "/v1/host/stats";
|
|
9
9
|
readonly systemDf: "/v1/system/df";
|
|
10
10
|
readonly systemPrune: "/v1/system/prune";
|
|
11
|
+
readonly builderPrune: "/v1/builder/prune";
|
|
11
12
|
readonly images: "/v1/images";
|
|
12
13
|
readonly build: "/v1/images/build";
|
|
13
14
|
readonly baseImport: "/v1/bases/import";
|
package/dist/routes.js
CHANGED
package/package.json
CHANGED