@dagger.io/dagger 0.3.0 → 0.3.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 +72 -1
- package/dist/api/client.gen.d.ts +305 -145
- package/dist/api/client.gen.d.ts.map +1 -1
- package/dist/api/client.gen.js +426 -154
- package/dist/api/utils.d.ts +1 -1
- package/dist/api/utils.d.ts.map +1 -1
- package/dist/api/utils.js +43 -41
- package/dist/common/errors/DaggerSDKError.d.ts +4 -3
- package/dist/common/errors/DaggerSDKError.d.ts.map +1 -1
- package/dist/common/errors/DockerImageRefValidationError.d.ts +2 -2
- package/dist/common/errors/DockerImageRefValidationError.d.ts.map +1 -1
- package/dist/common/errors/DockerImageRefValidationError.js +3 -2
- package/dist/common/errors/EngineSessionConnectParamsParseError.d.ts +21 -0
- package/dist/common/errors/EngineSessionConnectParamsParseError.d.ts.map +1 -0
- package/dist/common/errors/EngineSessionConnectParamsParseError.js +16 -0
- package/dist/common/errors/EngineSessionConnectionTimeoutError.d.ts +21 -0
- package/dist/common/errors/EngineSessionConnectionTimeoutError.d.ts.map +1 -0
- package/dist/common/errors/EngineSessionConnectionTimeoutError.js +16 -0
- package/dist/common/errors/EngineSessionEOFErrorOptions.d.ts +16 -0
- package/dist/common/errors/EngineSessionEOFErrorOptions.d.ts.map +1 -0
- package/dist/common/errors/EngineSessionEOFErrorOptions.js +16 -0
- package/dist/common/errors/GraphQLRequestError.d.ts +2 -2
- package/dist/common/errors/GraphQLRequestError.d.ts.map +1 -1
- package/dist/common/errors/GraphQLRequestError.js +3 -2
- package/dist/common/errors/InitEngineSessionBinaryError.d.ts +2 -2
- package/dist/common/errors/InitEngineSessionBinaryError.d.ts.map +1 -1
- package/dist/common/errors/InitEngineSessionBinaryError.js +3 -2
- package/dist/common/errors/TooManyNestedObjectsError.d.ts +2 -2
- package/dist/common/errors/TooManyNestedObjectsError.d.ts.map +1 -1
- package/dist/common/errors/TooManyNestedObjectsError.js +3 -2
- package/dist/common/errors/UnknownDaggerError.d.ts +2 -2
- package/dist/common/errors/UnknownDaggerError.d.ts.map +1 -1
- package/dist/common/errors/UnknownDaggerError.js +3 -2
- package/dist/common/errors/errors-codes.d.ts +43 -0
- package/dist/common/errors/errors-codes.d.ts.map +1 -0
- package/dist/common/errors/errors-codes.js +35 -0
- package/dist/common/errors/index.d.ts +4 -1
- package/dist/common/errors/index.d.ts.map +1 -1
- package/dist/common/errors/index.js +4 -1
- package/dist/common/utils.d.ts +3 -3
- package/dist/connect.d.ts +24 -1
- package/dist/connect.d.ts.map +1 -1
- package/dist/connect.js +29 -5
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/provisioning/{docker-provision/image.d.ts → bin.d.ts} +35 -29
- package/dist/provisioning/bin.d.ts.map +1 -0
- package/dist/provisioning/bin.js +336 -0
- package/dist/provisioning/default.d.ts +1 -1
- package/dist/provisioning/default.d.ts.map +1 -1
- package/dist/provisioning/default.js +1 -2
- package/dist/provisioning/engineconn.d.ts +1 -1
- package/dist/provisioning/engineconn.d.ts.map +1 -1
- package/dist/provisioning/index.d.ts +1 -2
- package/dist/provisioning/index.d.ts.map +1 -1
- package/dist/provisioning/index.js +1 -2
- package/package.json +17 -11
- package/dist/common/errors/EngineSessionPortParseError.d.ts +0 -25
- package/dist/common/errors/EngineSessionPortParseError.d.ts.map +0 -1
- package/dist/common/errors/EngineSessionPortParseError.js +0 -20
- package/dist/provisioning/bin/bin.d.ts +0 -21
- package/dist/provisioning/bin/bin.d.ts.map +0 -1
- package/dist/provisioning/bin/bin.js +0 -116
- package/dist/provisioning/bin/index.d.ts +0 -2
- package/dist/provisioning/bin/index.d.ts.map +0 -1
- package/dist/provisioning/bin/index.js +0 -1
- package/dist/provisioning/docker-provision/image.d.ts.map +0 -1
- package/dist/provisioning/docker-provision/image.js +0 -275
- package/dist/provisioning/docker-provision/index.d.ts +0 -2
- package/dist/provisioning/docker-provision/index.d.ts.map +0 -1
- package/dist/provisioning/docker-provision/index.js +0 -1
- package/dist/provisioning/http/http.d.ts +0 -14
- package/dist/provisioning/http/http.d.ts.map +0 -1
- package/dist/provisioning/http/http.js +0 -33
- package/dist/provisioning/http/index.d.ts +0 -2
- package/dist/provisioning/http/index.d.ts.map +0 -1
- package/dist/provisioning/http/index.js +0 -1
- package/dist/provisioning/provisioner.d.ts +0 -11
- package/dist/provisioning/provisioner.d.ts.map +0 -1
- package/dist/provisioning/provisioner.js +0 -26
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { DaggerSDKError, DaggerSDKErrorOptions } from "./DaggerSDKError.js";
|
|
2
|
-
interface EngineSessionPortParseErrorOptions extends DaggerSDKErrorOptions {
|
|
3
|
-
parsedLine: string;
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* This error is thrown if the EngineSession does not manage to parse the required port successfully.
|
|
7
|
-
* This can happen if
|
|
8
|
-
* - Reading the port times out after 30 seconds
|
|
9
|
-
* - The parsed port is not a number
|
|
10
|
-
* - the reader does not read a single line
|
|
11
|
-
*/
|
|
12
|
-
export declare class EngineSessionPortParseError extends DaggerSDKError {
|
|
13
|
-
name: string;
|
|
14
|
-
code: string;
|
|
15
|
-
/**
|
|
16
|
-
* the line, which caused the error during parsing, if the error was caused because of parsing.
|
|
17
|
-
*/
|
|
18
|
-
parsedLine?: string;
|
|
19
|
-
/**
|
|
20
|
-
* @hidden
|
|
21
|
-
*/
|
|
22
|
-
constructor(message: string, options?: EngineSessionPortParseErrorOptions);
|
|
23
|
-
}
|
|
24
|
-
export {};
|
|
25
|
-
//# sourceMappingURL=EngineSessionPortParseError.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EngineSessionPortParseError.d.ts","sourceRoot":"","sources":["../../../common/errors/EngineSessionPortParseError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAE3E,UAAU,kCAAmC,SAAQ,qBAAqB;IACxE,UAAU,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;GAMG;AACH,qBAAa,2BAA4B,SAAQ,cAAc;IAC7D,IAAI,SAA2B;IAC/B,IAAI,SAAS;IAEb;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;;OAEG;gBACS,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kCAAkC;CAI1E"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { DaggerSDKError } from "./DaggerSDKError.js";
|
|
2
|
-
/**
|
|
3
|
-
* This error is thrown if the EngineSession does not manage to parse the required port successfully.
|
|
4
|
-
* This can happen if
|
|
5
|
-
* - Reading the port times out after 30 seconds
|
|
6
|
-
* - The parsed port is not a number
|
|
7
|
-
* - the reader does not read a single line
|
|
8
|
-
*/
|
|
9
|
-
export class EngineSessionPortParseError extends DaggerSDKError {
|
|
10
|
-
/**
|
|
11
|
-
* @hidden
|
|
12
|
-
*/
|
|
13
|
-
constructor(message, options) {
|
|
14
|
-
super(message, options);
|
|
15
|
-
this.name = "EngineSessionPortError";
|
|
16
|
-
this.code = "D103";
|
|
17
|
-
if (options)
|
|
18
|
-
this.parsedLine = options.parsedLine;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { ConnectOpts, EngineConn } from "../engineconn.js";
|
|
2
|
-
import Client from "../../api/client.gen.js";
|
|
3
|
-
/**
|
|
4
|
-
* Bin runs an engine session from a specified binary
|
|
5
|
-
*/
|
|
6
|
-
export declare class Bin implements EngineConn {
|
|
7
|
-
private subProcess?;
|
|
8
|
-
private path;
|
|
9
|
-
constructor(u: URL);
|
|
10
|
-
Addr(): string;
|
|
11
|
-
Connect(opts: ConnectOpts): Promise<Client>;
|
|
12
|
-
/**
|
|
13
|
-
* runEngineSession execute the engine binary and set up a GraphQL client that
|
|
14
|
-
* target this engine.
|
|
15
|
-
* TODO:(sipsma) dedupe this with equivalent code in image.ts
|
|
16
|
-
*/
|
|
17
|
-
private runEngineSession;
|
|
18
|
-
private readPort;
|
|
19
|
-
Close(): Promise<void>;
|
|
20
|
-
}
|
|
21
|
-
//# sourceMappingURL=bin.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../../../provisioning/bin/bin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAG1D,OAAO,MAAM,MAAM,yBAAyB,CAAA;AAG5C;;GAEG;AACH,qBAAa,GAAI,YAAW,UAAU;IACpC,OAAO,CAAC,UAAU,CAAC,CAAmB;IAEtC,OAAO,CAAC,IAAI,CAAQ;gBAER,CAAC,EAAE,GAAG;IAQlB,IAAI,IAAI,MAAM;IAIR,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAIjD;;;;OAIG;YACW,gBAAgB;YAyChB,QAAQ;IAiBhB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAO7B"}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
11
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
12
|
-
var m = o[Symbol.asyncIterator], i;
|
|
13
|
-
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
14
|
-
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
15
|
-
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
16
|
-
};
|
|
17
|
-
import readline from "readline";
|
|
18
|
-
import { execaCommand } from "execa";
|
|
19
|
-
import Client from "../../api/client.gen.js";
|
|
20
|
-
import { EngineSessionPortParseError } from "../../common/errors/index.js";
|
|
21
|
-
/**
|
|
22
|
-
* Bin runs an engine session from a specified binary
|
|
23
|
-
*/
|
|
24
|
-
export class Bin {
|
|
25
|
-
constructor(u) {
|
|
26
|
-
this.path = u.host + u.pathname;
|
|
27
|
-
if (this.path == "") {
|
|
28
|
-
// this results in execa looking for it in the $PATH
|
|
29
|
-
this.path = "dagger-engine-session";
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
Addr() {
|
|
33
|
-
return "http://dagger";
|
|
34
|
-
}
|
|
35
|
-
Connect(opts) {
|
|
36
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
-
return this.runEngineSession(this.path, opts);
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* runEngineSession execute the engine binary and set up a GraphQL client that
|
|
42
|
-
* target this engine.
|
|
43
|
-
* TODO:(sipsma) dedupe this with equivalent code in image.ts
|
|
44
|
-
*/
|
|
45
|
-
runEngineSession(engineSessionBinPath, opts) {
|
|
46
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
47
|
-
const engineSessionArgs = [engineSessionBinPath];
|
|
48
|
-
if (opts.Workdir) {
|
|
49
|
-
engineSessionArgs.push("--workdir", opts.Workdir);
|
|
50
|
-
}
|
|
51
|
-
if (opts.Project) {
|
|
52
|
-
engineSessionArgs.push("--project", opts.Project);
|
|
53
|
-
}
|
|
54
|
-
this.subProcess = execaCommand(engineSessionArgs.join(" "), {
|
|
55
|
-
stderr: opts.LogOutput || "ignore",
|
|
56
|
-
// Kill the process if parent exit.
|
|
57
|
-
cleanup: true,
|
|
58
|
-
});
|
|
59
|
-
const stdoutReader = readline.createInterface({
|
|
60
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
61
|
-
input: this.subProcess.stdout,
|
|
62
|
-
});
|
|
63
|
-
const port = yield Promise.race([
|
|
64
|
-
this.readPort(stdoutReader),
|
|
65
|
-
new Promise((_, reject) => {
|
|
66
|
-
setTimeout(() => {
|
|
67
|
-
reject(new EngineSessionPortParseError("timeout reading port from engine session"));
|
|
68
|
-
}, 300000).unref(); // long timeout to account for extensions, though that should be optimized in future
|
|
69
|
-
}),
|
|
70
|
-
]);
|
|
71
|
-
return new Client({ host: `127.0.0.1:${port}` });
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
readPort(stdoutReader) {
|
|
75
|
-
var _a, stdoutReader_1, stdoutReader_1_1;
|
|
76
|
-
var _b, e_1, _c, _d;
|
|
77
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
-
try {
|
|
79
|
-
for (_a = true, stdoutReader_1 = __asyncValues(stdoutReader); stdoutReader_1_1 = yield stdoutReader_1.next(), _b = stdoutReader_1_1.done, !_b;) {
|
|
80
|
-
_d = stdoutReader_1_1.value;
|
|
81
|
-
_a = false;
|
|
82
|
-
try {
|
|
83
|
-
const line = _d;
|
|
84
|
-
// Read line as a port number
|
|
85
|
-
const port = parseInt(line);
|
|
86
|
-
if (isNaN(port)) {
|
|
87
|
-
throw new EngineSessionPortParseError(`failed to parse port from engine session while parsing: ${line}`, { parsedLine: line });
|
|
88
|
-
}
|
|
89
|
-
return port;
|
|
90
|
-
}
|
|
91
|
-
finally {
|
|
92
|
-
_a = true;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
97
|
-
finally {
|
|
98
|
-
try {
|
|
99
|
-
if (!_a && !_b && (_c = stdoutReader_1.return)) yield _c.call(stdoutReader_1);
|
|
100
|
-
}
|
|
101
|
-
finally { if (e_1) throw e_1.error; }
|
|
102
|
-
}
|
|
103
|
-
throw new EngineSessionPortParseError("No line was found to parse the engine port");
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
Close() {
|
|
107
|
-
var _a;
|
|
108
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
109
|
-
if ((_a = this.subProcess) === null || _a === void 0 ? void 0 : _a.pid) {
|
|
110
|
-
this.subProcess.kill("SIGTERM", {
|
|
111
|
-
forceKillAfterTimeout: 2000,
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../provisioning/bin/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./bin.js";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../../provisioning/docker-provision/image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAM1D,OAAO,MAAM,MAAM,yBAAyB,CAAA;AA4D5C;;;GAGG;AACH,qBAAa,WAAY,YAAW,UAAU;IAC5C,OAAO,CAAC,QAAQ,CAAU;IAE1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAGxB;IAED,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAA0B;IAEvE,OAAO,CAAC,UAAU,CAAC,CAAmB;gBAE1B,CAAC,EAAE,GAAG;IAIlB;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB,IAAI,IAAI,MAAM;IAIR,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAWjD;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;IAItB;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAWpB;;OAEG;IACH,OAAO,CAAC,cAAc;IAStB;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAiE5B;;;OAGG;YACW,gBAAgB;YAgDhB,QAAQ;IAiBhB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAO7B"}
|
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
11
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
12
|
-
var m = o[Symbol.asyncIterator], i;
|
|
13
|
-
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
14
|
-
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
15
|
-
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
16
|
-
};
|
|
17
|
-
import * as path from "path";
|
|
18
|
-
import * as fs from "fs";
|
|
19
|
-
import * as os from "os";
|
|
20
|
-
import readline from "readline";
|
|
21
|
-
import { execaCommandSync, execaCommand } from "execa";
|
|
22
|
-
import Client from "../../api/client.gen.js";
|
|
23
|
-
import { DockerImageRefValidationError, EngineSessionPortParseError, InitEngineSessionBinaryError, } from "../../common/errors/index.js";
|
|
24
|
-
/**
|
|
25
|
-
* ImageRef is a simple abstraction of docker image reference.
|
|
26
|
-
*/
|
|
27
|
-
class ImageRef {
|
|
28
|
-
constructor(ref) {
|
|
29
|
-
/**
|
|
30
|
-
* trim image digests to 16 characters to make output more readable.
|
|
31
|
-
*/
|
|
32
|
-
this.DIGEST_LEN = 16;
|
|
33
|
-
// Throw error if ref is not correctly formatted.
|
|
34
|
-
ImageRef.validate(ref);
|
|
35
|
-
this.ref = ref;
|
|
36
|
-
const id = ref.split("@sha256:", 2)[1];
|
|
37
|
-
this.id = id.slice(0, this.DIGEST_LEN);
|
|
38
|
-
}
|
|
39
|
-
get Ref() {
|
|
40
|
-
return this.ref;
|
|
41
|
-
}
|
|
42
|
-
get ID() {
|
|
43
|
-
return this.id;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* validateImage verify that the passed ref
|
|
47
|
-
* is compliant with DockerImage constructor.
|
|
48
|
-
*
|
|
49
|
-
* This function does not return anything but
|
|
50
|
-
* only throw on error.
|
|
51
|
-
*
|
|
52
|
-
* @throws no digest found in ref.
|
|
53
|
-
*/
|
|
54
|
-
static validate(ref) {
|
|
55
|
-
if (!ref.includes("@sha256:")) {
|
|
56
|
-
throw new DockerImageRefValidationError(`no digest found in ref ${ref}`, {
|
|
57
|
-
ref: ref,
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* DockerImage is an implementation of EngineConn to set up a Dagger
|
|
64
|
-
* Engine session from a pulled docker image.
|
|
65
|
-
*/
|
|
66
|
-
export class DockerImage {
|
|
67
|
-
constructor(u) {
|
|
68
|
-
this.cacheDir = path.join(process.env.XDG_CACHE_HOME || path.join(os.homedir(), ".cache"), "dagger");
|
|
69
|
-
this.ENGINE_SESSION_BINARY_PREFIX = "dagger-engine-session";
|
|
70
|
-
this.imageRef = new ImageRef(u.host + u.pathname);
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Generate a unix timestamp in nanosecond
|
|
74
|
-
*/
|
|
75
|
-
getRandomId() {
|
|
76
|
-
return process.hrtime.bigint().toString();
|
|
77
|
-
}
|
|
78
|
-
Addr() {
|
|
79
|
-
return "http://dagger";
|
|
80
|
-
}
|
|
81
|
-
Connect(opts) {
|
|
82
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
83
|
-
this.createCacheDir();
|
|
84
|
-
const engineSessionBinPath = this.buildBinPath();
|
|
85
|
-
if (!fs.existsSync(engineSessionBinPath)) {
|
|
86
|
-
this.pullEngineSessionBin(engineSessionBinPath);
|
|
87
|
-
}
|
|
88
|
-
return this.runEngineSession(engineSessionBinPath, opts);
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* createCacheDir will create a cache directory on user
|
|
93
|
-
* host to store dagger binary.
|
|
94
|
-
*
|
|
95
|
-
* If set, it will use XDG directory, if not, it will use `$HOME/.cache`
|
|
96
|
-
* as base path.
|
|
97
|
-
* Nothing happens if the directory already exists.
|
|
98
|
-
*/
|
|
99
|
-
createCacheDir() {
|
|
100
|
-
fs.mkdirSync(this.cacheDir, { mode: 0o700, recursive: true });
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* buildBinPath create a path to output engine session binary.
|
|
104
|
-
*
|
|
105
|
-
* It will store it in the cache directory with a name composed
|
|
106
|
-
* of the base engine session as constant and the engine identifier.
|
|
107
|
-
*/
|
|
108
|
-
buildBinPath() {
|
|
109
|
-
const binPath = `${this.cacheDir}/${this.ENGINE_SESSION_BINARY_PREFIX}-${this.imageRef.ID}`;
|
|
110
|
-
switch (this.normalizedOS()) {
|
|
111
|
-
case "windows":
|
|
112
|
-
return `${binPath}.exe`;
|
|
113
|
-
default:
|
|
114
|
-
return binPath;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* normalizedArch returns the architecture name used by the rest of our SDKs.
|
|
119
|
-
*/
|
|
120
|
-
normalizedArch() {
|
|
121
|
-
switch (os.arch()) {
|
|
122
|
-
case "x64":
|
|
123
|
-
return "amd64";
|
|
124
|
-
default:
|
|
125
|
-
return os.arch();
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* normalizedOS returns the os name used by the rest of our SDKs.
|
|
130
|
-
*/
|
|
131
|
-
normalizedOS() {
|
|
132
|
-
switch (os.platform()) {
|
|
133
|
-
case "win32":
|
|
134
|
-
return "windows";
|
|
135
|
-
default:
|
|
136
|
-
return os.platform();
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* pullEngineSessionBin will retrieve Dagger binary from its docker image
|
|
141
|
-
* and copy it to the local host.
|
|
142
|
-
* This function automatically resolves host's platform to copy the correct
|
|
143
|
-
* binary.
|
|
144
|
-
*/
|
|
145
|
-
pullEngineSessionBin(engineSessionBinPath) {
|
|
146
|
-
// Create a temporary bin file path
|
|
147
|
-
const tmpBinPath = path.join(this.cacheDir, `temp-${this.ENGINE_SESSION_BINARY_PREFIX}-${this.getRandomId()}`);
|
|
148
|
-
const dockerRunArgs = [
|
|
149
|
-
"docker",
|
|
150
|
-
"run",
|
|
151
|
-
"--rm",
|
|
152
|
-
"--entrypoint",
|
|
153
|
-
"/bin/cat",
|
|
154
|
-
this.imageRef.Ref,
|
|
155
|
-
`/usr/bin/${this.ENGINE_SESSION_BINARY_PREFIX}-${this.normalizedOS()}-${this.normalizedArch()}`,
|
|
156
|
-
];
|
|
157
|
-
try {
|
|
158
|
-
const fd = fs.openSync(tmpBinPath, "w", 0o700);
|
|
159
|
-
execaCommandSync(dockerRunArgs.join(" "), {
|
|
160
|
-
stdout: fd,
|
|
161
|
-
stderr: "pipe",
|
|
162
|
-
encoding: null,
|
|
163
|
-
// Kill the process if parent exit.
|
|
164
|
-
cleanup: true,
|
|
165
|
-
// Throw on error
|
|
166
|
-
reject: true,
|
|
167
|
-
timeout: 300000,
|
|
168
|
-
});
|
|
169
|
-
fs.closeSync(fd);
|
|
170
|
-
fs.renameSync(tmpBinPath, engineSessionBinPath);
|
|
171
|
-
}
|
|
172
|
-
catch (e) {
|
|
173
|
-
fs.rmSync(tmpBinPath);
|
|
174
|
-
throw new InitEngineSessionBinaryError(`failed to copy engine session binary: ${e}`, { cause: e });
|
|
175
|
-
}
|
|
176
|
-
// Remove all temporary binary files
|
|
177
|
-
// Ignore current engine session binary or other files that have not be
|
|
178
|
-
// created by this SDK.
|
|
179
|
-
try {
|
|
180
|
-
const files = fs.readdirSync(this.cacheDir);
|
|
181
|
-
files.forEach((file) => {
|
|
182
|
-
const filePath = `${this.cacheDir}/${file}`;
|
|
183
|
-
if (filePath === engineSessionBinPath ||
|
|
184
|
-
!file.startsWith(this.ENGINE_SESSION_BINARY_PREFIX)) {
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
fs.unlinkSync(filePath);
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
catch (e) {
|
|
191
|
-
// Log the error but do not interrupt program.
|
|
192
|
-
console.error("could not clean up temporary binary files");
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* runEngineSession execute the engine binary and set up a GraphQL client that
|
|
197
|
-
* target this engine.
|
|
198
|
-
*/
|
|
199
|
-
runEngineSession(engineSessionBinPath, opts) {
|
|
200
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
201
|
-
const env = process.env;
|
|
202
|
-
if (!env.DAGGER_RUNNER_HOST) {
|
|
203
|
-
env.DAGGER_RUNNER_HOST = `docker-image://${this.imageRef.Ref}`;
|
|
204
|
-
}
|
|
205
|
-
const engineSessionArgs = [engineSessionBinPath];
|
|
206
|
-
if (opts.Workdir) {
|
|
207
|
-
engineSessionArgs.push("--workdir", opts.Workdir);
|
|
208
|
-
}
|
|
209
|
-
if (opts.Project) {
|
|
210
|
-
engineSessionArgs.push("--project", opts.Project);
|
|
211
|
-
}
|
|
212
|
-
this.subProcess = execaCommand(engineSessionArgs.join(" "), {
|
|
213
|
-
stderr: opts.LogOutput || "ignore",
|
|
214
|
-
// Kill the process if parent exit.
|
|
215
|
-
cleanup: true,
|
|
216
|
-
env: env,
|
|
217
|
-
});
|
|
218
|
-
const stdoutReader = readline.createInterface({
|
|
219
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
220
|
-
input: this.subProcess.stdout,
|
|
221
|
-
});
|
|
222
|
-
const port = yield Promise.race([
|
|
223
|
-
this.readPort(stdoutReader),
|
|
224
|
-
new Promise((_, reject) => {
|
|
225
|
-
setTimeout(() => {
|
|
226
|
-
reject(new EngineSessionPortParseError("timeout reading port from engine session"));
|
|
227
|
-
}, 300000).unref(); // long timeout to account for extensions, though that should be optimized in future
|
|
228
|
-
}),
|
|
229
|
-
]);
|
|
230
|
-
return new Client({ host: `127.0.0.1:${port}` });
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
readPort(stdoutReader) {
|
|
234
|
-
var _a, stdoutReader_1, stdoutReader_1_1;
|
|
235
|
-
var _b, e_1, _c, _d;
|
|
236
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
237
|
-
try {
|
|
238
|
-
for (_a = true, stdoutReader_1 = __asyncValues(stdoutReader); stdoutReader_1_1 = yield stdoutReader_1.next(), _b = stdoutReader_1_1.done, !_b;) {
|
|
239
|
-
_d = stdoutReader_1_1.value;
|
|
240
|
-
_a = false;
|
|
241
|
-
try {
|
|
242
|
-
const line = _d;
|
|
243
|
-
// Read line as a port number
|
|
244
|
-
const port = parseInt(line);
|
|
245
|
-
if (isNaN(port)) {
|
|
246
|
-
throw new EngineSessionPortParseError(`failed to parse port from engine session while parsing: ${line}`, { parsedLine: line });
|
|
247
|
-
}
|
|
248
|
-
return port;
|
|
249
|
-
}
|
|
250
|
-
finally {
|
|
251
|
-
_a = true;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
256
|
-
finally {
|
|
257
|
-
try {
|
|
258
|
-
if (!_a && !_b && (_c = stdoutReader_1.return)) yield _c.call(stdoutReader_1);
|
|
259
|
-
}
|
|
260
|
-
finally { if (e_1) throw e_1.error; }
|
|
261
|
-
}
|
|
262
|
-
throw new EngineSessionPortParseError("No line was found to parse the engine port");
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
Close() {
|
|
266
|
-
var _a;
|
|
267
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
268
|
-
if ((_a = this.subProcess) === null || _a === void 0 ? void 0 : _a.pid) {
|
|
269
|
-
this.subProcess.kill("SIGTERM", {
|
|
270
|
-
forceKillAfterTimeout: 2000,
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../provisioning/docker-provision/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./image.js";
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { ConnectOpts, EngineConn } from "../engineconn.js";
|
|
2
|
-
import Client from "../../api/client.gen.js";
|
|
3
|
-
/**
|
|
4
|
-
* HTTP is an implementation of EngineConn to connect to an existing
|
|
5
|
-
* engine session over http.
|
|
6
|
-
*/
|
|
7
|
-
export declare class HTTP implements EngineConn {
|
|
8
|
-
private url;
|
|
9
|
-
constructor(u: URL);
|
|
10
|
-
Addr(): string;
|
|
11
|
-
Connect(opts: ConnectOpts): Promise<Client>;
|
|
12
|
-
Close(): Promise<void>;
|
|
13
|
-
}
|
|
14
|
-
//# sourceMappingURL=http.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../provisioning/http/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC1D,OAAO,MAAM,MAAM,yBAAyB,CAAA;AAE5C;;;GAGG;AACH,qBAAa,IAAK,YAAW,UAAU;IACrC,OAAO,CAAC,GAAG,CAAK;gBAEJ,CAAC,EAAE,GAAG;IAIlB,IAAI,IAAI,MAAM;IAKR,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAI3C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
import Client from "../../api/client.gen.js";
|
|
11
|
-
/**
|
|
12
|
-
* HTTP is an implementation of EngineConn to connect to an existing
|
|
13
|
-
* engine session over http.
|
|
14
|
-
*/
|
|
15
|
-
export class HTTP {
|
|
16
|
-
constructor(u) {
|
|
17
|
-
this.url = u;
|
|
18
|
-
}
|
|
19
|
-
Addr() {
|
|
20
|
-
return this.url.toString();
|
|
21
|
-
}
|
|
22
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
23
|
-
Connect(opts) {
|
|
24
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
25
|
-
return new Client({ host: this.url.host });
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
Close() {
|
|
29
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
30
|
-
return;
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../provisioning/http/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./http.js";
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { EngineConn } from "./engineconn.js";
|
|
2
|
-
/**
|
|
3
|
-
* getProvisioner returns a ready to use Engine connector.
|
|
4
|
-
* This method parse the given host to find out which kind
|
|
5
|
-
* of provisioner shall be returned.
|
|
6
|
-
*
|
|
7
|
-
* It supports the following provisioners:
|
|
8
|
-
* - docker-image
|
|
9
|
-
*/
|
|
10
|
-
export declare function getProvisioner(host: string): EngineConn;
|
|
11
|
-
//# sourceMappingURL=provisioner.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"provisioner.d.ts","sourceRoot":"","sources":["../../provisioning/provisioner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAa5C;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAWvD"}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { DockerImage } from "./docker-provision/image.js";
|
|
2
|
-
import { HTTP } from "./http/http.js";
|
|
3
|
-
import { Bin } from "./bin/bin.js";
|
|
4
|
-
const provisioners = {
|
|
5
|
-
"docker-image": (u) => new DockerImage(u),
|
|
6
|
-
http: (u) => new HTTP(u),
|
|
7
|
-
bin: (u) => new Bin(u),
|
|
8
|
-
};
|
|
9
|
-
/**
|
|
10
|
-
* getProvisioner returns a ready to use Engine connector.
|
|
11
|
-
* This method parse the given host to find out which kind
|
|
12
|
-
* of provisioner shall be returned.
|
|
13
|
-
*
|
|
14
|
-
* It supports the following provisioners:
|
|
15
|
-
* - docker-image
|
|
16
|
-
*/
|
|
17
|
-
export function getProvisioner(host) {
|
|
18
|
-
const url = new URL(host);
|
|
19
|
-
// Use slice(0, -1) to remove the extra : from the protocol
|
|
20
|
-
// For instance http: -> http
|
|
21
|
-
const provisioner = provisioners[url.protocol.slice(0, -1)];
|
|
22
|
-
if (!provisioner) {
|
|
23
|
-
throw new Error(`invalid dagger host: ${host}.`);
|
|
24
|
-
}
|
|
25
|
-
return provisioner(url);
|
|
26
|
-
}
|