redkite 0.1.7 → 0.1.9
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 +343 -26
- package/dist/build.d.ts +2 -0
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +11 -1
- package/dist/build.js.map +1 -1
- package/dist/checks.d.ts.map +1 -1
- package/dist/checks.js +4 -0
- package/dist/checks.js.map +1 -1
- package/dist/cli/agent.d.ts +2 -0
- package/dist/cli/agent.d.ts.map +1 -1
- package/dist/cli/agent.js +23 -1
- package/dist/cli/agent.js.map +1 -1
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +15 -2
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +98 -30
- package/dist/cli/index.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +20 -1
- package/dist/config.js.map +1 -1
- package/dist/deploy.d.ts +4 -1
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +77 -23
- package/dist/deploy.js.map +1 -1
- package/dist/dockerfile.js +6 -7
- package/dist/dockerfile.js.map +1 -1
- package/dist/environment.d.ts +5 -0
- package/dist/environment.d.ts.map +1 -0
- package/dist/environment.js +20 -0
- package/dist/environment.js.map +1 -0
- package/dist/host.d.ts +2 -0
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +6 -0
- package/dist/host.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/localHost.d.ts.map +1 -1
- package/dist/localHost.js +2 -0
- package/dist/localHost.js.map +1 -1
- package/dist/plugin.d.ts +15 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +21 -0
- package/dist/plugin.js.map +1 -0
- package/dist/plugins/bitwarden.d.ts +11 -0
- package/dist/plugins/bitwarden.d.ts.map +1 -0
- package/dist/plugins/bitwarden.js +40 -0
- package/dist/plugins/bitwarden.js.map +1 -0
- package/dist/plugins/digitalOcean.d.ts +19 -0
- package/dist/plugins/digitalOcean.d.ts.map +1 -0
- package/dist/plugins/digitalOcean.js +71 -0
- package/dist/plugins/digitalOcean.js.map +1 -0
- package/dist/plugins/index.d.ts +5 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +5 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/rds.d.ts +14 -0
- package/dist/plugins/rds.d.ts.map +1 -0
- package/dist/plugins/rds.js +86 -0
- package/dist/plugins/rds.js.map +1 -0
- package/dist/plugins/snapshot.d.ts +7 -0
- package/dist/plugins/snapshot.d.ts.map +1 -0
- package/dist/plugins/snapshot.js +29 -0
- package/dist/plugins/snapshot.js.map +1 -0
- package/dist/presets/nodeApp.d.ts +1 -2
- package/dist/presets/nodeApp.d.ts.map +1 -1
- package/dist/presets/nodeApp.js +0 -1
- package/dist/presets/nodeApp.js.map +1 -1
- package/dist/recover.d.ts +19 -0
- package/dist/recover.d.ts.map +1 -0
- package/dist/recover.js +58 -0
- package/dist/recover.js.map +1 -0
- package/dist/secrets/store.d.ts +5 -2
- package/dist/secrets/store.d.ts.map +1 -1
- package/dist/secrets/store.js +25 -14
- package/dist/secrets/store.js.map +1 -1
- package/dist/source.d.ts +6 -1
- package/dist/source.d.ts.map +1 -1
- package/dist/source.js +12 -4
- package/dist/source.js.map +1 -1
- package/dist/sshHost.d.ts +2 -0
- package/dist/sshHost.d.ts.map +1 -1
- package/dist/sshHost.js +29 -11
- package/dist/sshHost.js.map +1 -1
- package/dist/steps.d.ts +0 -7
- package/dist/steps.d.ts.map +1 -1
- package/dist/steps.js +6 -3
- package/dist/steps.js.map +1 -1
- package/dist/types.d.ts +7 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/build.ts +12 -1
- package/src/checks.ts +4 -0
- package/src/cli/agent.ts +28 -1
- package/src/cli/config.ts +19 -2
- package/src/cli/index.ts +118 -29
- package/src/config.ts +27 -1
- package/src/deploy.ts +101 -29
- package/src/dockerfile.ts +7 -11
- package/src/environment.ts +24 -0
- package/src/host.ts +11 -0
- package/src/index.ts +4 -1
- package/src/localHost.ts +3 -0
- package/src/plugin.ts +50 -0
- package/src/plugins/bitwarden.ts +57 -0
- package/src/plugins/digitalOcean.ts +111 -0
- package/src/plugins/index.ts +4 -0
- package/src/plugins/rds.ts +126 -0
- package/src/plugins/snapshot.ts +44 -0
- package/src/presets/nodeApp.ts +1 -3
- package/src/recover.ts +90 -0
- package/src/secrets/store.ts +39 -20
- package/src/source.ts +20 -5
- package/src/sshHost.ts +35 -11
- package/src/steps.ts +7 -6
- package/src/types.ts +29 -12
- package/dist/secrets/bitwarden.d.ts +0 -3
- package/dist/secrets/bitwarden.d.ts.map +0 -1
- package/dist/secrets/bitwarden.js +0 -6
- package/dist/secrets/bitwarden.js.map +0 -1
- package/src/secrets/bitwarden.ts +0 -7
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
import { definePlugin } from "../plugin.js";
|
|
4
|
+
import { slug, snapshotName } from "./snapshot.js";
|
|
5
|
+
// A snapshot of a managed Postgres or MySQL, taken before anything migrates it.
|
|
6
|
+
// Through the AWS CLI rather than the REST API: signing a request by hand is a
|
|
7
|
+
// page of crypto that nothing here could check, and every runner already has
|
|
8
|
+
// the CLI with the credentials the job was given.
|
|
9
|
+
const run = promisify(execFile);
|
|
10
|
+
export function rdsSnapshot(options) {
|
|
11
|
+
assertOneTarget(options);
|
|
12
|
+
const target = slug(options.instance ?? options.cluster ?? "");
|
|
13
|
+
return definePlugin({
|
|
14
|
+
name: `rds-snapshot-${target}`,
|
|
15
|
+
steps: [snapshotStep(options)],
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
function snapshotStep(options) {
|
|
19
|
+
const target = options.instance ?? options.cluster ?? "";
|
|
20
|
+
const aws = options.aws ?? ((args) => run("aws", args));
|
|
21
|
+
return {
|
|
22
|
+
point: `swap:before:snapshot-${slug(target)}`,
|
|
23
|
+
run: async (input, context) => {
|
|
24
|
+
const identifier = snapshotName(options.name ?? target, context.environment, new Date());
|
|
25
|
+
context.task.detail(`snapshotting ${target} as ${identifier}`);
|
|
26
|
+
await aws(create(options, identifier));
|
|
27
|
+
// The data is captured when it begins, so this is not what makes the
|
|
28
|
+
// restore point good. It is what turns a snapshot that silently failed
|
|
29
|
+
// into a deploy that stops before the migration
|
|
30
|
+
if (options.wait) {
|
|
31
|
+
context.task.detail(`waiting for ${identifier}`);
|
|
32
|
+
await aws(ready(options, identifier));
|
|
33
|
+
}
|
|
34
|
+
return input;
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function create(options, identifier) {
|
|
39
|
+
const region = options.region ? ["--region", options.region] : [];
|
|
40
|
+
if (options.cluster) {
|
|
41
|
+
return [
|
|
42
|
+
"rds",
|
|
43
|
+
"create-db-cluster-snapshot",
|
|
44
|
+
"--db-cluster-identifier",
|
|
45
|
+
options.cluster,
|
|
46
|
+
"--db-cluster-snapshot-identifier",
|
|
47
|
+
identifier,
|
|
48
|
+
...region,
|
|
49
|
+
];
|
|
50
|
+
}
|
|
51
|
+
return [
|
|
52
|
+
"rds",
|
|
53
|
+
"create-db-snapshot",
|
|
54
|
+
"--db-instance-identifier",
|
|
55
|
+
options.instance ?? "",
|
|
56
|
+
"--db-snapshot-identifier",
|
|
57
|
+
identifier,
|
|
58
|
+
...region,
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
function ready(options, identifier) {
|
|
62
|
+
const region = options.region ? ["--region", options.region] : [];
|
|
63
|
+
if (options.cluster) {
|
|
64
|
+
return [
|
|
65
|
+
"rds",
|
|
66
|
+
"wait",
|
|
67
|
+
"db-cluster-snapshot-available",
|
|
68
|
+
"--db-cluster-snapshot-identifier",
|
|
69
|
+
identifier,
|
|
70
|
+
...region,
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
return ["rds", "wait", "db-snapshot-available", "--db-snapshot-identifier", identifier, ...region];
|
|
74
|
+
}
|
|
75
|
+
// An instance and a cluster are different API calls against different things,
|
|
76
|
+
// and guessing which was meant is worse than being told. Checked where the
|
|
77
|
+
// plugin is written rather than where it runs, so the config fails to load
|
|
78
|
+
function assertOneTarget(options) {
|
|
79
|
+
if (options.instance && options.cluster) {
|
|
80
|
+
throw new Error("rdsSnapshot names both an instance and a cluster, and they are different databases");
|
|
81
|
+
}
|
|
82
|
+
if (!options.instance && !options.cluster) {
|
|
83
|
+
throw new Error("rdsSnapshot names no instance or cluster to snapshot");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=rds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rds.js","sourceRoot":"","sources":["../../src/plugins/rds.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Plan } from "../pipeline.js";
|
|
2
|
+
export type SnapshotPoint = `swap:before:${string}`;
|
|
3
|
+
export declare function slug(value: string): string;
|
|
4
|
+
export declare function stamp(now: Date): string;
|
|
5
|
+
export declare function snapshotName(prefix: string, environment: string, now: Date): string;
|
|
6
|
+
export declare function tokenFrom(name: string, plan: Plan): string;
|
|
7
|
+
//# sourceMappingURL=snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/plugins/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAS3C,MAAM,MAAM,aAAa,GAAG,eAAe,MAAM,EAAE,CAAC;AAIpD,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,UAMjC;AAKD,wBAAgB,KAAK,CAAC,GAAG,EAAE,IAAI,UAE9B;AAID,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,UAE1E;AAID,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,UAOjD"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Letters, digits and single hyphens, which is the intersection of what RDS
|
|
2
|
+
// accepts as a snapshot identifier and what a point may be named
|
|
3
|
+
export function slug(value) {
|
|
4
|
+
return value
|
|
5
|
+
.toLowerCase()
|
|
6
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
7
|
+
.replace(/^-+|-+$/g, "")
|
|
8
|
+
.replace(/-{2,}/g, "-");
|
|
9
|
+
}
|
|
10
|
+
// Sortable, second-resolution, and legal in every identifier below. Two
|
|
11
|
+
// snapshots in one second would collide, and two deploys in one second is not
|
|
12
|
+
// a thing a swap can do
|
|
13
|
+
export function stamp(now) {
|
|
14
|
+
return now.toISOString().replace(/[-:T]/g, "").slice(0, 14);
|
|
15
|
+
}
|
|
16
|
+
// Names the deploy it was taken for. A snapshot nobody can place is one nobody
|
|
17
|
+
// will dare restore
|
|
18
|
+
export function snapshotName(prefix, environment, now) {
|
|
19
|
+
return slug(`${prefix}-${environment}-${stamp(now)}`);
|
|
20
|
+
}
|
|
21
|
+
// Read before the run starts, so a missing token is a config that fails while
|
|
22
|
+
// the host is untouched rather than a deploy that stops with the swap ahead
|
|
23
|
+
export function tokenFrom(name, plan) {
|
|
24
|
+
const value = process.env[name];
|
|
25
|
+
if (value)
|
|
26
|
+
return value;
|
|
27
|
+
throw new Error(`${name} is not set, and ${plan.config.project} snapshots its database before swapping`);
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=snapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/plugins/snapshot.ts"],"names":[],"mappings":"AAWA,4EAA4E;AAC5E,iEAAiE;AACjE,MAAM,UAAU,IAAI,CAAC,KAAa;IAChC,OAAO,KAAK;SACT,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED,wEAAwE;AACxE,8EAA8E;AAC9E,wBAAwB;AACxB,MAAM,UAAU,KAAK,CAAC,GAAS;IAC7B,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC9D,CAAC;AAED,+EAA+E;AAC/E,oBAAoB;AACpB,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,WAAmB,EAAE,GAAS;IACzE,OAAO,IAAI,CAAC,GAAG,MAAM,IAAI,WAAW,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACxD,CAAC;AAED,8EAA8E;AAC9E,4EAA4E;AAC5E,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,IAAU;IAChD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IAExB,MAAM,IAAI,KAAK,CACb,GAAG,IAAI,oBAAoB,IAAI,CAAC,MAAM,CAAC,OAAO,yCAAyC,CACxF,CAAC;AACJ,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BuildSpec, CarryPath
|
|
1
|
+
import type { BuildSpec, CarryPath } from "../types.js";
|
|
2
2
|
type NodeAppOptions = {
|
|
3
3
|
builder?: string;
|
|
4
4
|
runtime?: string;
|
|
@@ -12,7 +12,6 @@ type NodeAppOptions = {
|
|
|
12
12
|
carry?: CarryPath[];
|
|
13
13
|
submodules?: boolean;
|
|
14
14
|
caches?: string[];
|
|
15
|
-
sourcemaps?: SourcemapSpec;
|
|
16
15
|
};
|
|
17
16
|
export declare function nodeApp(options: NodeAppOptions): BuildSpec;
|
|
18
17
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodeApp.d.ts","sourceRoot":"","sources":["../../src/presets/nodeApp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"nodeApp.d.ts","sourceRoot":"","sources":["../../src/presets/nodeApp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExD,KAAK,cAAc,GAAG;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;IAGhB,YAAY,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,CAAC;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,SAAS,CA2B1D"}
|
package/dist/presets/nodeApp.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodeApp.js","sourceRoot":"","sources":["../../src/presets/nodeApp.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"nodeApp.js","sourceRoot":"","sources":["../../src/presets/nodeApp.ts"],"names":[],"mappings":"AAgBA,MAAM,UAAU,OAAO,CAAC,OAAuB;IAC7C,OAAO;QACL,MAAM,EAAE,SAAS;QACjB,YAAY,EAAE,QAAQ,OAAO,CAAC,OAAO,IAAI,WAAW,EAAE;QACtD,YAAY,EAAE,QAAQ,OAAO,CAAC,OAAO,IAAI,WAAW,EAAE;QACtD,YAAY,EACV,OAAO,CAAC,YAAY,KAAK,KAAK;YAC5B,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,IAAI;gBACvB,KAAK,EAAE,CAAC,cAAc,EAAE,WAAW,CAAC;gBACpC,IAAI,EAAE,gCAAgC;gBACtC,YAAY,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,aAAa,CAAC;aACvD,CAAC;QACR,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;QAC1B,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,4EAA4E;QAC5E,wEAAwE;QACxE,6DAA6D;QAC7D,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC;QACpD,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,KAAK;QACvC,2EAA2E;QAC3E,WAAW,EAAE,CAAC,KAAK,CAAC;QACpB,eAAe,EAAE,CAAC,MAAM,CAAC;QACzB,YAAY,EAAE,EAAE;KACjB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Host } from "./host.js";
|
|
2
|
+
import { type Log } from "./log.js";
|
|
3
|
+
import type { Deployment } from "./types.js";
|
|
4
|
+
export type RecoverOptions = {
|
|
5
|
+
config: Deployment;
|
|
6
|
+
environment: string;
|
|
7
|
+
host: Host;
|
|
8
|
+
log?: Log;
|
|
9
|
+
};
|
|
10
|
+
export type RolledBack = {
|
|
11
|
+
restored: string[];
|
|
12
|
+
untouched: string[];
|
|
13
|
+
};
|
|
14
|
+
export declare function rollback(options: RecoverOptions): Promise<RolledBack>;
|
|
15
|
+
export type TakenDown = {
|
|
16
|
+
stopped: string[];
|
|
17
|
+
};
|
|
18
|
+
export declare function down(options: RecoverOptions): Promise<TakenDown>;
|
|
19
|
+
//# sourceMappingURL=recover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recover.d.ts","sourceRoot":"","sources":["../src/recover.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAU,KAAK,GAAG,EAAE,MAAM,UAAU,CAAC;AAE5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAM7C,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,GAAG,CAAC,EAAE,GAAG,CAAC;CACX,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IAEvB,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB,CAAC;AAKF,wBAAsB,QAAQ,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAkB3E;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAKF,wBAAsB,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC,CAatE"}
|
package/dist/recover.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { revert } from "./deploy.js";
|
|
2
|
+
import { Docker } from "./docker.js";
|
|
3
|
+
import { finalHost } from "./host.js";
|
|
4
|
+
import { silent } from "./log.js";
|
|
5
|
+
import { topologyFor } from "./topology.js";
|
|
6
|
+
// A retired container is the whole signal. One exists between the swap and the
|
|
7
|
+
// cleanup that removes it, so finding one means a run moved an address and did
|
|
8
|
+
// not get to say whether that worked
|
|
9
|
+
export async function rollback(options) {
|
|
10
|
+
const { log, topology, docker } = opened(options);
|
|
11
|
+
const restored = [];
|
|
12
|
+
const untouched = [];
|
|
13
|
+
for (const app of topology.apps) {
|
|
14
|
+
if (!(await docker.container.exists(app.retired))) {
|
|
15
|
+
untouched.push(app.container);
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
log(`Putting ${app.container} back`);
|
|
19
|
+
await revert(docker, topology, app);
|
|
20
|
+
restored.push(app.container);
|
|
21
|
+
}
|
|
22
|
+
return { restored, untouched };
|
|
23
|
+
}
|
|
24
|
+
// Stopped rather than removed, so the next run adopts them where it left off.
|
|
25
|
+
// For an environment that exists to be built against rather than served from,
|
|
26
|
+
// which is the one a cancelled job should not leave running
|
|
27
|
+
export async function down(options) {
|
|
28
|
+
const { log, topology, docker } = opened(options);
|
|
29
|
+
const stopped = [];
|
|
30
|
+
for (const name of every(topology)) {
|
|
31
|
+
if (!(await docker.container.isRunning(name)))
|
|
32
|
+
continue;
|
|
33
|
+
log(`Stopping ${name}`);
|
|
34
|
+
await docker.container.stop(name);
|
|
35
|
+
stopped.push(name);
|
|
36
|
+
}
|
|
37
|
+
return { stopped };
|
|
38
|
+
}
|
|
39
|
+
// Everything this environment named, whether or not it was ever created. The
|
|
40
|
+
// proxy is derived rather than listed, so it would be missed by walking the
|
|
41
|
+
// config alone
|
|
42
|
+
function every(topology) {
|
|
43
|
+
return [
|
|
44
|
+
...topology.apps.flatMap((app) => [app.container, app.retired, app.failed]),
|
|
45
|
+
...topology.services.map((service) => service.container),
|
|
46
|
+
topology.router.container,
|
|
47
|
+
];
|
|
48
|
+
}
|
|
49
|
+
// Both of these exist because something was stopped, so neither may be refused
|
|
50
|
+
// by that same stop
|
|
51
|
+
function opened(options) {
|
|
52
|
+
return {
|
|
53
|
+
log: options.log ?? silent,
|
|
54
|
+
topology: topologyFor(options.config, options.environment),
|
|
55
|
+
docker: new Docker(finalHost(options.host)),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=recover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recover.js","sourceRoot":"","sources":["../src/recover.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,SAAS,EAAa,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,MAAM,EAAY,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAiB,MAAM,eAAe,CAAC;AAqB3D,+EAA+E;AAC/E,+EAA+E;AAC/E,qCAAqC;AACrC,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAAuB;IACpD,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAElD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;YAClD,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAC9B,SAAS;QACX,CAAC;QAED,GAAG,CAAC,WAAW,GAAG,CAAC,SAAS,OAAO,CAAC,CAAC;QACrC,MAAM,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;QACpC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACjC,CAAC;AAMD,8EAA8E;AAC9E,8EAA8E;AAC9E,4DAA4D;AAC5D,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAAuB;IAChD,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAAE,SAAS;QAExD,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;QACxB,MAAM,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC;AAED,6EAA6E;AAC7E,4EAA4E;AAC5E,eAAe;AACf,SAAS,KAAK,CAAC,QAAkB;IAC/B,OAAO;QACL,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAC3E,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC;QACxD,QAAQ,CAAC,MAAM,CAAC,SAAS;KAC1B,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,oBAAoB;AACpB,SAAS,MAAM,CAAC,OAAuB;IACrC,OAAO;QACL,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,MAAM;QAC1B,QAAQ,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC;QAC1D,MAAM,EAAE,IAAI,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;KAC5C,CAAC;AACJ,CAAC"}
|
package/dist/secrets/store.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import type { SecretStore } from "./refs.js";
|
|
2
2
|
export type BitwardenCredentials = {
|
|
3
|
+
detail?: (message: string) => void;
|
|
4
|
+
} & ({
|
|
5
|
+
session: string;
|
|
6
|
+
} | {
|
|
3
7
|
clientId: string;
|
|
4
8
|
clientSecret: string;
|
|
5
9
|
password: string;
|
|
6
|
-
|
|
7
|
-
};
|
|
10
|
+
});
|
|
8
11
|
export declare function bitwardenStore(credentials: BitwardenCredentials): Promise<SecretStore>;
|
|
9
12
|
//# sourceMappingURL=store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/secrets/store.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/secrets/store.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAa7C,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC,GAAG,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAUzF,wBAAsB,cAAc,CAClC,WAAW,EAAE,oBAAoB,GAChC,OAAO,CAAC,WAAW,CAAC,CA+CtB"}
|
package/dist/secrets/store.js
CHANGED
|
@@ -32,20 +32,7 @@ export async function bitwardenStore(credentials) {
|
|
|
32
32
|
},
|
|
33
33
|
maxBuffer: 32 * 1024 * 1024,
|
|
34
34
|
});
|
|
35
|
-
|
|
36
|
-
// Already logged in is not an error, the session is what matters
|
|
37
|
-
await bw(["login", "--apikey"], {
|
|
38
|
-
BW_CLIENTID: credentials.clientId,
|
|
39
|
-
BW_CLIENTSECRET: credentials.clientSecret,
|
|
40
|
-
}).catch(() => undefined);
|
|
41
|
-
const unlocked = await bw(["unlock", "--passwordenv", "BW_PASSWORD", "--raw"], {
|
|
42
|
-
BW_PASSWORD: credentials.password,
|
|
43
|
-
}).catch((error) => {
|
|
44
|
-
throw new Error(`Could not unlock the Bitwarden vault: ${messageOf(error)}`);
|
|
45
|
-
});
|
|
46
|
-
const session = unlocked.stdout.trim();
|
|
47
|
-
if (!session)
|
|
48
|
-
throw new Error("Bitwarden unlocked without a session");
|
|
35
|
+
const session = await unlock(bw, credentials, detail);
|
|
49
36
|
// An item added since the last deploy is not in the local vault otherwise,
|
|
50
37
|
// and bw get answers "not found" rather than fetching it
|
|
51
38
|
await bw(["sync"], { BW_SESSION: session }).catch(() => undefined);
|
|
@@ -68,6 +55,30 @@ export async function bitwardenStore(credentials) {
|
|
|
68
55
|
},
|
|
69
56
|
};
|
|
70
57
|
}
|
|
58
|
+
// A session handed in is one nobody had to obtain, which is the whole of what
|
|
59
|
+
// a key in the environment buys: no api credentials, no master password, and
|
|
60
|
+
// two fewer round trips before the first item is read
|
|
61
|
+
async function unlock(bw, credentials, detail) {
|
|
62
|
+
if ("session" in credentials) {
|
|
63
|
+
detail("using the session it was given");
|
|
64
|
+
return credentials.session;
|
|
65
|
+
}
|
|
66
|
+
detail("unlocking the vault");
|
|
67
|
+
// Already logged in is not an error, the session is what matters
|
|
68
|
+
await bw(["login", "--apikey"], {
|
|
69
|
+
BW_CLIENTID: credentials.clientId,
|
|
70
|
+
BW_CLIENTSECRET: credentials.clientSecret,
|
|
71
|
+
}).catch(() => undefined);
|
|
72
|
+
const unlocked = await bw(["unlock", "--passwordenv", "BW_PASSWORD", "--raw"], {
|
|
73
|
+
BW_PASSWORD: credentials.password,
|
|
74
|
+
}).catch((error) => {
|
|
75
|
+
throw new Error(`Could not unlock the Bitwarden vault: ${messageOf(error)}`);
|
|
76
|
+
});
|
|
77
|
+
const session = unlocked.stdout.trim();
|
|
78
|
+
if (session)
|
|
79
|
+
return session;
|
|
80
|
+
throw new Error("Bitwarden unlocked without a session");
|
|
81
|
+
}
|
|
71
82
|
// A machine with the CLI installed pays nothing. One without it installs the
|
|
72
83
|
// pinned version once, rather than resolving it again on every call below
|
|
73
84
|
async function resolveCli(detail) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/secrets/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAItC,8EAA8E;AAC9E,yBAAyB;AACzB,EAAE;AACF,8EAA8E;AAC9E,2EAA2E;AAC3E,oCAAoC;AAEpC,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/secrets/store.ts"],"names":[],"mappings":"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"}
|
package/dist/source.d.ts
CHANGED
|
@@ -3,12 +3,17 @@ export type Source = {
|
|
|
3
3
|
release: string;
|
|
4
4
|
tree: string;
|
|
5
5
|
};
|
|
6
|
+
export type RefKind = "branch" | "tag" | "commit";
|
|
7
|
+
export type Ref = {
|
|
8
|
+
kind: RefKind;
|
|
9
|
+
name: string;
|
|
10
|
+
};
|
|
6
11
|
export type SourceRequest = {
|
|
7
12
|
name: string;
|
|
8
13
|
repo?: string;
|
|
9
14
|
path?: string;
|
|
10
15
|
include?: string[];
|
|
11
|
-
|
|
16
|
+
ref: Ref;
|
|
12
17
|
submodules: boolean;
|
|
13
18
|
detail?: (message: string) => void;
|
|
14
19
|
};
|
package/dist/source.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAOtC,MAAM,MAAM,MAAM,GAAG;IAGnB,OAAO,EAAE,MAAM,CAAC;IAEhB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;
|
|
1
|
+
{"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAOtC,MAAM,MAAM,MAAM,GAAG;IAGnB,OAAO,EAAE,MAAM,CAAC;IAEhB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAIF,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,CAAC;AAElD,MAAM,MAAM,GAAG,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD,MAAM,MAAM,aAAa,GAAG;IAG1B,IAAI,EAAE,MAAM,CAAC;IAEb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IAGd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,EAAE,GAAG,CAAC;IACT,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC,CAAC;AAaF,wBAAsB,aAAa,CACjC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,CAKjB"}
|
package/dist/source.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
// Where each kind lives. A tag is peeled, so an annotated one answers with the
|
|
2
|
+
// commit it points at rather than with the tag object
|
|
3
|
+
const REVISION = {
|
|
4
|
+
branch: (name) => `refs/heads/${name}`,
|
|
5
|
+
tag: (name) => `refs/tags/${name}^{commit}`,
|
|
6
|
+
commit: (name) => `${name}^{commit}`,
|
|
7
|
+
};
|
|
1
8
|
// accept-new rather than no: a host key that changes is still worth refusing
|
|
2
9
|
const GIT_SSH = "ssh -o StrictHostKeyChecking=accept-new";
|
|
3
10
|
export async function prepareSource(host, request) {
|
|
@@ -56,7 +63,8 @@ async function clonedSource(host, repo, request) {
|
|
|
56
63
|
const detail = request.detail ?? (() => { });
|
|
57
64
|
const mirror = `${host.cache}/mirrors/${request.name}.git`;
|
|
58
65
|
const path = `${host.cache}/source/${request.name}`;
|
|
59
|
-
|
|
66
|
+
const { kind, name } = request.ref;
|
|
67
|
+
detail(`fetching ${name}`);
|
|
60
68
|
await run(host, `updating the mirror of ${repo}`, [
|
|
61
69
|
`if [ -d '${mirror}' ]; then`,
|
|
62
70
|
` git -C '${mirror}' remote set-url origin '${repo}'`,
|
|
@@ -66,12 +74,12 @@ async function clonedSource(host, repo, request) {
|
|
|
66
74
|
` git clone --mirror '${repo}' '${mirror}'`,
|
|
67
75
|
"fi",
|
|
68
76
|
]);
|
|
69
|
-
const resolved = await run(host, `resolving ${
|
|
70
|
-
`git -C '${mirror}' rev-parse '
|
|
77
|
+
const resolved = await run(host, `resolving ${name}`, [
|
|
78
|
+
`git -C '${mirror}' rev-parse '${REVISION[kind](name)}'`,
|
|
71
79
|
]);
|
|
72
80
|
const release = resolved.stdout.trim();
|
|
73
81
|
if (!/^[0-9a-f]{40}$/.test(release)) {
|
|
74
|
-
throw new Error(`${repo} has no
|
|
82
|
+
throw new Error(`${repo} has no ${kind} ${name}`);
|
|
75
83
|
}
|
|
76
84
|
detail(`checking out ${release.slice(0, 7)}`);
|
|
77
85
|
await run(host, `checking out ${release.slice(0, 7)}`, [
|
package/dist/source.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source.js","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"source.js","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"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"}
|
package/dist/sshHost.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Host, OnLine, Result } from "./host.js";
|
|
2
|
+
import type { HostKeys } from "./types.js";
|
|
2
3
|
export type Ssh = (args: string[], options?: {
|
|
3
4
|
stdin?: string;
|
|
4
5
|
onLine?: OnLine;
|
|
@@ -9,6 +10,7 @@ export type SshOptions = {
|
|
|
9
10
|
shell?: Shell;
|
|
10
11
|
directory?: string;
|
|
11
12
|
cache?: string;
|
|
13
|
+
hostKeys?: HostKeys;
|
|
12
14
|
signal?: AbortSignal;
|
|
13
15
|
};
|
|
14
16
|
export declare function sshHost(bastion: string, options?: SshOptions): Promise<Host>;
|
package/dist/sshHost.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sshHost.d.ts","sourceRoot":"","sources":["../src/sshHost.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"sshHost.d.ts","sourceRoot":"","sources":["../src/sshHost.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAO3C,MAAM,MAAM,GAAG,GAAG,CAChB,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,KAC1C,OAAO,CAAC,MAAM,CAAC,CAAC;AAIrB,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAEzD,MAAM,MAAM,UAAU,GAAG;IACvB,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAGpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AA8BF,wBAAsB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAwFtF"}
|
package/dist/sshHost.js
CHANGED
|
@@ -1,18 +1,32 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { dirname } from "node:path";
|
|
3
3
|
import { quote, spawnCollect } from "./shell.js";
|
|
4
|
+
// What ssh calls each of them. accept-new is the default rather than no: a
|
|
5
|
+
// deploy hands over a vault's contents, and the last thing it should do that
|
|
6
|
+
// to is a machine that answered to the address and nothing else
|
|
7
|
+
const CHECKING = {
|
|
8
|
+
"accept-new": "accept-new",
|
|
9
|
+
strict: "yes",
|
|
10
|
+
off: "no",
|
|
11
|
+
};
|
|
4
12
|
// One TCP connection and one authentication for the whole deploy. Without it
|
|
5
13
|
// every command pays a handshake, which is most of what a command costs
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
function multiplex(hostKeys = "accept-new") {
|
|
15
|
+
return [
|
|
16
|
+
"-o",
|
|
17
|
+
"ControlMaster=auto",
|
|
18
|
+
"-o",
|
|
19
|
+
"ControlPersist=60s",
|
|
20
|
+
"-o",
|
|
21
|
+
`StrictHostKeyChecking=${CHECKING[hostKeys]}`,
|
|
22
|
+
// Never a prompt. Unknown under strict is a refusal with a reason, and a
|
|
23
|
+
// question nobody is there to answer is a deploy that hangs
|
|
24
|
+
"-o",
|
|
25
|
+
"BatchMode=yes",
|
|
26
|
+
// The host clones from GitHub on our behalf rather than us shipping a tree
|
|
27
|
+
"-A",
|
|
28
|
+
];
|
|
29
|
+
}
|
|
16
30
|
export async function sshHost(bastion, options = {}) {
|
|
17
31
|
const control = `/tmp/redkite-${randomUUID().slice(0, 8)}.control`;
|
|
18
32
|
const directory = options.directory ?? `/tmp/redkite-${randomUUID().slice(0, 8)}`;
|
|
@@ -23,8 +37,9 @@ export async function sshHost(bastion, options = {}) {
|
|
|
23
37
|
const final = options.run ?? ((args, extra) => spawnCollect("ssh", args, extra));
|
|
24
38
|
const shell = options.shell ??
|
|
25
39
|
((command) => spawnCollect("sh", ["-c", command], { signal }));
|
|
40
|
+
const flags = multiplex(options.hostKeys);
|
|
26
41
|
const argv = (command) => [
|
|
27
|
-
...
|
|
42
|
+
...flags,
|
|
28
43
|
"-o",
|
|
29
44
|
`ControlPath=${control}`,
|
|
30
45
|
bastion,
|
|
@@ -61,6 +76,9 @@ export async function sshHost(bastion, options = {}) {
|
|
|
61
76
|
// Through the connection that is already open, so an image is streamed
|
|
62
77
|
// rather than written to a disk at each end and copied between them
|
|
63
78
|
pipe: async (local, remote) => await shell(`${local} | ssh ${argv(remote).map(quote).join(" ")}`),
|
|
79
|
+
// Runs on the connection that is already open, and without the signal that
|
|
80
|
+
// killed whatever made it necessary
|
|
81
|
+
final: async (command) => await final(argv(command)),
|
|
64
82
|
// Signalled where they are running, not here. Killing the client would
|
|
65
83
|
// leave the build going with nothing left able to reach it
|
|
66
84
|
stop: async (name) => {
|
package/dist/sshHost.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sshHost.js","sourceRoot":"","sources":["../src/sshHost.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"sshHost.js","sourceRoot":"","sources":["../src/sshHost.ts"],"names":[],"mappings":"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"}
|
package/dist/steps.d.ts
CHANGED
|
@@ -15,13 +15,6 @@ type MigrateOptions = {
|
|
|
15
15
|
};
|
|
16
16
|
export declare function migrate(options: MigrateOptions): Step<`swap:before:${string}`>;
|
|
17
17
|
export declare function builderOf(input: Built, name: string): string;
|
|
18
|
-
type SentryOptions = {
|
|
19
|
-
stripFromImage: string;
|
|
20
|
-
};
|
|
21
|
-
export declare function sentry(options: SentryOptions): {
|
|
22
|
-
provider: "sentry";
|
|
23
|
-
stripFromImage: string;
|
|
24
|
-
};
|
|
25
18
|
export declare function routeOf(app: AppSpec): string;
|
|
26
19
|
export {};
|
|
27
20
|
//# sourceMappingURL=steps.d.ts.map
|
package/dist/steps.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"steps.d.ts","sourceRoot":"","sources":["../src/steps.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"steps.d.ts","sourceRoot":"","sources":["../src/steps.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAQ,IAAI,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAKvD,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,EAAE,CAY7E;AAED,KAAK,cAAc,GAAG;IAGpB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAIhB,OAAO,CAAC,EAAE,WAAW,CAAC;IAItB,MAAM,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3E,CAAC;AAIF,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC,eAAe,MAAM,EAAE,CAAC,CA+B9E;AAqBD,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,UAKnD;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,UAEnC"}
|
package/dist/steps.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { environmentOf } from "./config.js";
|
|
2
|
+
import { envFlags } from "./environment.js";
|
|
2
3
|
// The flags that attach one. The deployment network carries the aliases too,
|
|
3
4
|
// because a service answers to its alias rather than its container name, and a
|
|
4
5
|
// step reaching postgres:5432 is the whole reason to be on that network
|
|
@@ -27,9 +28,14 @@ export function migrate(options) {
|
|
|
27
28
|
run: async (input, context) => {
|
|
28
29
|
const image = builderOf(input, options.app);
|
|
29
30
|
context.task.detail(`${options.app}: ${options.command}`);
|
|
31
|
+
// Nothing from the vault is in the image, so a migration reads its
|
|
32
|
+
// database url from the environment it is given rather than from a file
|
|
33
|
+
// the build left behind
|
|
34
|
+
const app = context.config.apps.find((item) => item.name === options.app);
|
|
30
35
|
await context.docker.runOrThrow([
|
|
31
36
|
"run --rm",
|
|
32
37
|
...attachment(options.network ?? "host", context.topology),
|
|
38
|
+
...(app ? await envFlags(app, context) : []),
|
|
33
39
|
"--workdir /app",
|
|
34
40
|
image,
|
|
35
41
|
...command,
|
|
@@ -60,9 +66,6 @@ export function builderOf(input, name) {
|
|
|
60
66
|
return app.builderTag;
|
|
61
67
|
throw new Error(`${name} has no builder image, so nothing can be run in it`);
|
|
62
68
|
}
|
|
63
|
-
export function sentry(options) {
|
|
64
|
-
return { provider: "sentry", stripFromImage: options.stripFromImage };
|
|
65
|
-
}
|
|
66
69
|
export function routeOf(app) {
|
|
67
70
|
return app.route;
|
|
68
71
|
}
|