@geekmidas/cli 10.0.0-alpha.74 → 10.0.0-alpha.76
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/dist/{LegacyStateStore-D_78eaHM.cjs → LegacyStateStore-DwngfJxr.cjs} +2 -2
- package/dist/{LegacyStateStore-D_78eaHM.cjs.map → LegacyStateStore-DwngfJxr.cjs.map} +1 -1
- package/dist/{LegacyStateStore-DTo7z924.mjs → LegacyStateStore-dyq07_Ir.mjs} +2 -2
- package/dist/{LegacyStateStore-DTo7z924.mjs.map → LegacyStateStore-dyq07_Ir.mjs.map} +1 -1
- package/dist/{LocalStateStore-BhrlQIXD.cjs → LocalStateStore-B0NCde8Z.cjs} +2 -2
- package/dist/{LocalStateStore-BhrlQIXD.cjs.map → LocalStateStore-B0NCde8Z.cjs.map} +1 -1
- package/dist/{LocalStateStore-CNjgkRk4.mjs → LocalStateStore-DLxCCatI.mjs} +2 -2
- package/dist/{LocalStateStore-CNjgkRk4.mjs.map → LocalStateStore-DLxCCatI.mjs.map} +1 -1
- package/dist/{S3StateStore-oCxRs6HM.cjs → S3StateStore-BOenb-3o.cjs} +2 -2
- package/dist/{S3StateStore-oCxRs6HM.cjs.map → S3StateStore-BOenb-3o.cjs.map} +1 -1
- package/dist/{S3StateStore-g2P7T_Mo.mjs → S3StateStore-CGK_4hlo.mjs} +2 -2
- package/dist/{S3StateStore-g2P7T_Mo.mjs.map → S3StateStore-CGK_4hlo.mjs.map} +1 -1
- package/dist/{SSMStateStore-CYenunmK.mjs → SSMStateStore-B_5_RqY-.mjs} +2 -2
- package/dist/{SSMStateStore-CYenunmK.mjs.map → SSMStateStore-B_5_RqY-.mjs.map} +1 -1
- package/dist/{SSMStateStore-DXp0m7XI.cjs → SSMStateStore-DYeD__7p.cjs} +2 -2
- package/dist/{SSMStateStore-DXp0m7XI.cjs.map → SSMStateStore-DYeD__7p.cjs.map} +1 -1
- package/dist/{add-BTH7WaH3.mjs → add-B7IMXzou.mjs} +3 -3
- package/dist/{add-BTH7WaH3.mjs.map → add-B7IMXzou.mjs.map} +1 -1
- package/dist/{add-Djrr12Xc.cjs → add-j2yI3cbS.cjs} +3 -3
- package/dist/{add-Djrr12Xc.cjs.map → add-j2yI3cbS.cjs.map} +1 -1
- package/dist/{aws-DojzQnLd.mjs → aws-Bja4zGSs.mjs} +13 -9
- package/dist/aws-Bja4zGSs.mjs.map +1 -0
- package/dist/{aws-DkHdTV-p.cjs → aws-CQAuluiu.cjs} +13 -9
- package/dist/aws-CQAuluiu.cjs.map +1 -0
- package/dist/awsStore-7VmS_cZR.cjs +54 -0
- package/dist/awsStore-7VmS_cZR.cjs.map +1 -0
- package/dist/awsStore-B529csle.mjs +43 -0
- package/dist/awsStore-B529csle.mjs.map +1 -0
- package/dist/{bundler-utHuESvL.cjs → bundler-Cf6OgaOe.cjs} +5 -5
- package/dist/bundler-Cf6OgaOe.cjs.map +1 -0
- package/dist/{bundler-BUojOkof.mjs → bundler-DO6bHhnb.mjs} +5 -5
- package/dist/bundler-DO6bHhnb.mjs.map +1 -0
- package/dist/{cli-CyYceKTS.mjs → cli-BCPOHmg9.mjs} +3 -3
- package/dist/{cli-CyYceKTS.mjs.map → cli-BCPOHmg9.mjs.map} +1 -1
- package/dist/{cli-Bx0sUzxH.cjs → cli-CNanUB7a.cjs} +3 -3
- package/dist/{cli-Bx0sUzxH.cjs.map → cli-CNanUB7a.cjs.map} +1 -1
- package/dist/{compose-DZp8DJ0A.mjs → compose-Dq4VCtu5.mjs} +221 -153
- package/dist/compose-Dq4VCtu5.mjs.map +1 -0
- package/dist/{compose-iuw8wfHk.cjs → compose-h_6oNnHC.cjs} +243 -151
- package/dist/compose-h_6oNnHC.cjs.map +1 -0
- package/dist/{config-B38YWicj.d.cts → config-CWyhLSY1.d.cts} +3 -3
- package/dist/{config-B38YWicj.d.cts.map → config-CWyhLSY1.d.cts.map} +1 -1
- package/dist/{config-DA0kRTQe.d.mts → config-CqAvPP-f.d.mts} +3 -3
- package/dist/{config-DA0kRTQe.d.mts.map → config-CqAvPP-f.d.mts.map} +1 -1
- package/dist/config.cjs +1 -1
- package/dist/config.d.cts +3 -3
- package/dist/config.d.mts +3 -3
- package/dist/config.mjs +1 -1
- package/dist/deploy/public.cjs +7 -6
- package/dist/deploy/public.d.cts +14 -3
- package/dist/deploy/public.d.cts.map +1 -1
- package/dist/deploy/public.d.mts +14 -3
- package/dist/deploy/public.d.mts.map +1 -1
- package/dist/deploy/public.mjs +7 -7
- package/dist/{deploy-eWorhvQp.cjs → deploy-CT3R9de9.cjs} +27 -5
- package/dist/deploy-CT3R9de9.cjs.map +1 -0
- package/dist/{deploy-C17K7Imy.mjs → deploy-CVXEx7Nm.mjs} +22 -6
- package/dist/deploy-CVXEx7Nm.mjs.map +1 -0
- package/dist/{dokploy-DKa49Nqm.mjs → dokploy-CYm2ozFs.mjs} +2 -2
- package/dist/{dokploy-DKa49Nqm.mjs.map → dokploy-CYm2ozFs.mjs.map} +1 -1
- package/dist/{dokploy-DKzcI-RL.cjs → dokploy-eSGmlhhj.cjs} +2 -2
- package/dist/{dokploy-DKzcI-RL.cjs.map → dokploy-eSGmlhhj.cjs.map} +1 -1
- package/dist/{encryption-sTMz3aWi.mjs → encryption-DC0rsR1W.mjs} +3 -3
- package/dist/{encryption-sTMz3aWi.mjs.map → encryption-DC0rsR1W.mjs.map} +1 -1
- package/dist/{encryption-DSkJdoyk.cjs → encryption-vS3Qzw73.cjs} +3 -3
- package/dist/{encryption-DSkJdoyk.cjs.map → encryption-vS3Qzw73.cjs.map} +1 -1
- package/dist/{engine-B1b4I34Z.mjs → engine-BOO5TWZd.mjs} +193 -5
- package/dist/engine-BOO5TWZd.mjs.map +1 -0
- package/dist/{engine-Bh76sAHy.cjs → engine-C0N2d1i5.cjs} +196 -8
- package/dist/engine-C0N2d1i5.cjs.map +1 -0
- package/dist/{github-C9ODoyZU.mjs → github-CEaFDL6t.mjs} +6 -6
- package/dist/github-CEaFDL6t.mjs.map +1 -0
- package/dist/{github-BvN3CfxM.cjs → github-ClkdCOL9.cjs} +6 -6
- package/dist/github-ClkdCOL9.cjs.map +1 -0
- package/dist/{index-B-1lLGzy.d.mts → index-Ccu0f_2m.d.cts} +2 -2
- package/dist/{index-B-1lLGzy.d.mts.map → index-Ccu0f_2m.d.cts.map} +1 -1
- package/dist/{index-vMidfqhU.d.cts → index-DOxmDKqv.d.mts} +2 -2
- package/dist/{index-vMidfqhU.d.cts.map → index-DOxmDKqv.d.mts.map} +1 -1
- package/dist/index.cjs +106 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +105 -51
- package/dist/index.mjs.map +1 -1
- package/dist/migrate-BRbYtFXG.cjs +93 -0
- package/dist/migrate-BRbYtFXG.cjs.map +1 -0
- package/dist/migrate-D3NAT7Ns.mjs +93 -0
- package/dist/migrate-D3NAT7Ns.mjs.map +1 -0
- package/dist/{migrate-B0FCZNkp.cjs → migrate-D5_-ylI1.cjs} +3 -3
- package/dist/{migrate-B0FCZNkp.cjs.map → migrate-D5_-ylI1.cjs.map} +1 -1
- package/dist/{migrate-CTtJhGV9.mjs → migrate-DrO2p9Rl.mjs} +3 -3
- package/dist/{migrate-CTtJhGV9.mjs.map → migrate-DrO2p9Rl.mjs.map} +1 -1
- package/dist/openapi.cjs +16 -6
- package/dist/openapi.cjs.map +1 -1
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.cts.map +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.d.mts.map +1 -1
- package/dist/openapi.mjs +16 -6
- package/dist/openapi.mjs.map +1 -1
- package/dist/reconcile/public.d.cts +1 -1
- package/dist/reconcile/public.d.mts +1 -1
- package/dist/{resolve-DSAXj_47.mjs → resolve-C1muFos5.mjs} +3 -3
- package/dist/{resolve-DSAXj_47.mjs.map → resolve-C1muFos5.mjs.map} +1 -1
- package/dist/{resolve-D_BU-wKA.cjs → resolve-Fa1Ii0BK.cjs} +3 -3
- package/dist/{resolve-D_BU-wKA.cjs.map → resolve-Fa1Ii0BK.cjs.map} +1 -1
- package/dist/{rollback-DJy3t696.cjs → rollback-C9N5lKVf.cjs} +5 -5
- package/dist/{rollback-DJy3t696.cjs.map → rollback-C9N5lKVf.cjs.map} +1 -1
- package/dist/{rollback-CWYTUhfW.mjs → rollback-DeQzbRqM.mjs} +5 -5
- package/dist/{rollback-CWYTUhfW.mjs.map → rollback-DeQzbRqM.mjs.map} +1 -1
- package/dist/{runtime-BzZD5HHi.d.cts → runtime-BSvzPqXW.d.mts} +2 -2
- package/dist/{runtime-BzZD5HHi.d.cts.map → runtime-BSvzPqXW.d.mts.map} +1 -1
- package/dist/{runtime-Cm6J6L7n.d.mts → runtime-Cm7QA53H.d.cts} +2 -2
- package/dist/{runtime-Cm6J6L7n.d.mts.map → runtime-Cm7QA53H.d.cts.map} +1 -1
- package/dist/secretsManager-DUXW3fQt.cjs +70 -0
- package/dist/secretsManager-DUXW3fQt.cjs.map +1 -0
- package/dist/secretsManager-Ti0oZwsS.mjs +70 -0
- package/dist/secretsManager-Ti0oZwsS.mjs.map +1 -0
- package/dist/{sniffer-BFmdZpZ2.mjs → sniffer-DR8AlRCk.mjs} +67 -15
- package/dist/sniffer-DR8AlRCk.mjs.map +1 -0
- package/dist/{sniffer-C-T7dSMN.cjs → sniffer-Y6GQOCXB.cjs} +83 -13
- package/dist/sniffer-Y6GQOCXB.cjs.map +1 -0
- package/dist/{state-DCwRWyh-.cjs → state-C2qi0iQw.cjs} +241 -334
- package/dist/state-C2qi0iQw.cjs.map +1 -0
- package/dist/{state-DpkxSwzI.mjs → state-CUecOCNJ.mjs} +213 -306
- package/dist/state-CUecOCNJ.mjs.map +1 -0
- package/dist/target/public.cjs +1 -1
- package/dist/target/public.d.cts +2 -2
- package/dist/target/public.d.mts +2 -2
- package/dist/target/public.mjs +1 -1
- package/dist/{types-TzCChNrA.d.cts → types-BdptGBFS.d.cts} +59 -6
- package/dist/types-BdptGBFS.d.cts.map +1 -0
- package/dist/{types-Dp9lgx_S.d.mts → types-OxE0OAn2.d.mts} +59 -6
- package/dist/types-OxE0OAn2.d.mts.map +1 -0
- package/dist/workspace/index.cjs +1 -1
- package/dist/workspace/index.d.cts +2 -2
- package/dist/workspace/index.d.mts +2 -2
- package/dist/workspace/index.mjs +1 -1
- package/dist/{workspace-vdrcRI-m.cjs → workspace-DOm81oUo.cjs} +54 -1
- package/dist/workspace-DOm81oUo.cjs.map +1 -0
- package/dist/{workspace-C7NqCsQF.mjs → workspace-QUTqYmVy.mjs} +43 -2
- package/dist/workspace-QUTqYmVy.mjs.map +1 -0
- package/package.json +18 -17
- package/dist/aws-DkHdTV-p.cjs.map +0 -1
- package/dist/aws-DojzQnLd.mjs.map +0 -1
- package/dist/bundler-BUojOkof.mjs.map +0 -1
- package/dist/bundler-utHuESvL.cjs.map +0 -1
- package/dist/compose-DZp8DJ0A.mjs.map +0 -1
- package/dist/compose-iuw8wfHk.cjs.map +0 -1
- package/dist/deploy-C17K7Imy.mjs.map +0 -1
- package/dist/deploy-eWorhvQp.cjs.map +0 -1
- package/dist/engine-B1b4I34Z.mjs.map +0 -1
- package/dist/engine-Bh76sAHy.cjs.map +0 -1
- package/dist/github-BvN3CfxM.cjs.map +0 -1
- package/dist/github-C9ODoyZU.mjs.map +0 -1
- package/dist/sniffer-BFmdZpZ2.mjs.map +0 -1
- package/dist/sniffer-C-T7dSMN.cjs.map +0 -1
- package/dist/state-DCwRWyh-.cjs.map +0 -1
- package/dist/state-DpkxSwzI.mjs.map +0 -1
- package/dist/types-Dp9lgx_S.d.mts.map +0 -1
- package/dist/types-TzCChNrA.d.cts.map +0 -1
- package/dist/workspace-C7NqCsQF.mjs.map +0 -1
- package/dist/workspace-vdrcRI-m.cjs.map +0 -1
|
@@ -2,9 +2,9 @@ const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
|
|
|
2
2
|
const require_run = require("./run-fVZ-rLnc.cjs");
|
|
3
3
|
const require_discover = require("./discover-D1It5r_h.cjs");
|
|
4
4
|
const require_derive = require("./derive-DAbo49sm.cjs");
|
|
5
|
-
const require_workspace = require("./workspace-
|
|
5
|
+
const require_workspace = require("./workspace-DOm81oUo.cjs");
|
|
6
6
|
const require_define = require("./define-DzRz8FgH.cjs");
|
|
7
|
-
const require_state = require("./state-
|
|
7
|
+
const require_state = require("./state-C2qi0iQw.cjs");
|
|
8
8
|
const require_SubscriberGenerator = require("./SubscriberGenerator-CajwOa5W.cjs");
|
|
9
9
|
const require_drivers = require("./drivers-BdvtCKc7.cjs");
|
|
10
10
|
const require_databases = require("./databases-C2p5LGAp.cjs");
|
|
@@ -64,6 +64,33 @@ var ServicePortUnknown = class extends Error {
|
|
|
64
64
|
this.name = "ServicePortUnknown";
|
|
65
65
|
}
|
|
66
66
|
};
|
|
67
|
+
/**
|
|
68
|
+
* Whether `ref` names a registry on this machine's loopback — which the
|
|
69
|
+
* daemon pulls from and pushes to over plain HTTP by default, and `docker
|
|
70
|
+
* manifest inspect` reaches only when told `--insecure` (without it, a local
|
|
71
|
+
* registry's image is reported as no such manifest).
|
|
72
|
+
*/
|
|
73
|
+
function isLoopbackRegistry(ref) {
|
|
74
|
+
const first = ref.split("/")[0];
|
|
75
|
+
if (!ref.includes("/") || !/[.:]|^localhost$/.test(first)) return false;
|
|
76
|
+
const host = first.replace(/:\d+$/, "");
|
|
77
|
+
return host === "localhost" || /^127(?:\.\d{1,3}){3}$/.test(host);
|
|
78
|
+
}
|
|
79
|
+
/** `docker push` finished without saying what digest the registry stored. */
|
|
80
|
+
var PushDigestUnknown = class extends Error {
|
|
81
|
+
ref;
|
|
82
|
+
output;
|
|
83
|
+
constructor(ref, output) {
|
|
84
|
+
super(`Pushed ${ref}, but docker did not say which digest the registry stored (it said: ${output.trim().split("\n").slice(-3).join(" / ") || "nothing"}). Check the push with \`docker buildx imagetools inspect ${ref}\`.`);
|
|
85
|
+
this.ref = ref;
|
|
86
|
+
this.output = output;
|
|
87
|
+
this.name = "PushDigestUnknown";
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
/** The digest `docker push` reports last: `<tag>: digest: sha256:… size: …`. */
|
|
91
|
+
function pushedDigest(output) {
|
|
92
|
+
return [...output.matchAll(/digest: (sha256:[0-9a-f]{64})/g)].at(-1)?.[1];
|
|
93
|
+
}
|
|
67
94
|
function compose(stack, args) {
|
|
68
95
|
return [
|
|
69
96
|
"compose",
|
|
@@ -127,6 +154,7 @@ const dockerCompose = {
|
|
|
127
154
|
const { code, stdout, stderr } = await capture("docker", [
|
|
128
155
|
"manifest",
|
|
129
156
|
"inspect",
|
|
157
|
+
...isLoopbackRegistry(ref) ? ["--insecure"] : [],
|
|
130
158
|
ref
|
|
131
159
|
]);
|
|
132
160
|
if (code === 0) return {
|
|
@@ -196,6 +224,15 @@ const dockerCompose = {
|
|
|
196
224
|
to
|
|
197
225
|
]), runOptions(stack));
|
|
198
226
|
},
|
|
227
|
+
async push(stack, ref) {
|
|
228
|
+
const output = await require_run.runOutput("docker", ["push", ref], {
|
|
229
|
+
cwd: stack.cwd,
|
|
230
|
+
...stack.signal ? { signal: stack.signal } : {}
|
|
231
|
+
});
|
|
232
|
+
const digest = pushedDigest(output);
|
|
233
|
+
if (!digest) throw new PushDigestUnknown(ref, output);
|
|
234
|
+
return digest;
|
|
235
|
+
},
|
|
199
236
|
async digest(ref) {
|
|
200
237
|
const { code, stdout } = await capture("docker", [
|
|
201
238
|
"image",
|
|
@@ -266,6 +303,92 @@ async function assertImagesExist(docker, tag, images) {
|
|
|
266
303
|
const missing = lookups.filter((lookup) => lookup.status === "missing").map((lookup) => lookup.ref);
|
|
267
304
|
if (missing.length > 0) throw new ImageTagNotFound(tag, missing);
|
|
268
305
|
}
|
|
306
|
+
/**
|
|
307
|
+
* A push or a pull with no `deploy.registry` to push to or pull from.
|
|
308
|
+
*
|
|
309
|
+
* Without one an image is named `<namespace>/<project>-<app>:<tag>`, which
|
|
310
|
+
* Docker resolves to Docker Hub — so a release would be pushed to, or pulled
|
|
311
|
+
* from, somebody else's account. It is never a fallback.
|
|
312
|
+
*/
|
|
313
|
+
var RegistryRequired = class extends Error {
|
|
314
|
+
operation;
|
|
315
|
+
ref;
|
|
316
|
+
constructor(operation, ref) {
|
|
317
|
+
super(`${operation === "push" ? "Pushing" : "Pulling"} images needs a registry, and gkm.config.ts sets no deploy.registry: '${ref}' would be ${operation === "push" ? "pushed to" : "pulled from"} Docker Hub. Set deploy.registry (e.g. registry: 'ghcr.io/acme') in gkm.config.ts.` + (operation === "pull" ? " To run images built here instead, pass --build." : ""));
|
|
318
|
+
this.operation = operation;
|
|
319
|
+
this.ref = ref;
|
|
320
|
+
this.name = "RegistryRequired";
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
/** An image pinned to its digest: `<ref>@sha256:…`. */
|
|
324
|
+
function pinnedRef(ref, digest) {
|
|
325
|
+
return `${ref.split("@")[0]}@${digest}`;
|
|
326
|
+
}
|
|
327
|
+
/** A digests file with no entry for an app the stack runs. */
|
|
328
|
+
var ImageDigestMissing = class extends Error {
|
|
329
|
+
file;
|
|
330
|
+
apps;
|
|
331
|
+
constructor(file, apps) {
|
|
332
|
+
super(`${file} pins no digest for ${apps.join(", ")}. Use the file the same release's \`gkm compose --build --push --digests-file\` wrote, or run without --digests-file to pull by tag.`);
|
|
333
|
+
this.file = file;
|
|
334
|
+
this.apps = apps;
|
|
335
|
+
this.name = "ImageDigestMissing";
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
/** A digests file entry that is not this app's image. */
|
|
339
|
+
var ImageDigestMismatch = class extends Error {
|
|
340
|
+
app;
|
|
341
|
+
expected;
|
|
342
|
+
found;
|
|
343
|
+
constructor(app, expected, found) {
|
|
344
|
+
super(`The digests file pins '${app}' to ${found}, but this release runs ${expected}. It was written for another registry, project, stage or tag; use the file this stage's push of this tag wrote.`);
|
|
345
|
+
this.app = app;
|
|
346
|
+
this.expected = expected;
|
|
347
|
+
this.found = found;
|
|
348
|
+
this.name = "ImageDigestMismatch";
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
/** A digests file that is not a JSON object of app to pinned ref. */
|
|
352
|
+
var ImageDigestsInvalid = class extends Error {
|
|
353
|
+
file;
|
|
354
|
+
detail;
|
|
355
|
+
constructor(file, detail) {
|
|
356
|
+
super(`${file} is not a digests file (${detail}). It should be the JSON object \`gkm compose --build --push --digests-file\` writes: { "api": "<registry>/<image>:<tag>@sha256:…" }.`);
|
|
357
|
+
this.file = file;
|
|
358
|
+
this.detail = detail;
|
|
359
|
+
this.name = "ImageDigestsInvalid";
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
/** Parse a digests file's content, checking its shape. */
|
|
363
|
+
function parseDigests(file, content) {
|
|
364
|
+
let parsed;
|
|
365
|
+
try {
|
|
366
|
+
parsed = JSON.parse(content);
|
|
367
|
+
} catch (error) {
|
|
368
|
+
throw new ImageDigestsInvalid(file, error instanceof Error ? error.message : String(error));
|
|
369
|
+
}
|
|
370
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new ImageDigestsInvalid(file, "not a JSON object");
|
|
371
|
+
for (const [app, value] of Object.entries(parsed)) if (typeof value !== "string" || !/@sha256:[0-9a-f]{64}$/.test(value)) throw new ImageDigestsInvalid(file, `'${app}' is not an <image>:<tag>@sha256:… ref`);
|
|
372
|
+
return parsed;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Each image pinned to the digest the file names for it.
|
|
376
|
+
*
|
|
377
|
+
* @throws {ImageDigestMissing} naming every app the file has no entry for
|
|
378
|
+
* @throws {ImageDigestMismatch} when an entry is another image or tag
|
|
379
|
+
*/
|
|
380
|
+
function pinImages(file, digests, images) {
|
|
381
|
+
const missing = images.filter((image) => !digests[image.app]).map((image) => image.app);
|
|
382
|
+
if (missing.length > 0) throw new ImageDigestMissing(file, missing);
|
|
383
|
+
return images.map((image) => {
|
|
384
|
+
const pinned = digests[image.app];
|
|
385
|
+
if (pinned.split("@")[0] !== image.ref) throw new ImageDigestMismatch(image.app, image.ref, pinned);
|
|
386
|
+
return {
|
|
387
|
+
...image,
|
|
388
|
+
ref: pinned
|
|
389
|
+
};
|
|
390
|
+
});
|
|
391
|
+
}
|
|
269
392
|
//#endregion
|
|
270
393
|
//#region src/compose/logs.ts
|
|
271
394
|
/**
|
|
@@ -950,6 +1073,7 @@ function composeStack(input) {
|
|
|
950
1073
|
if (app.build && Object.keys(args).length > 0) app.build.args = args;
|
|
951
1074
|
continue;
|
|
952
1075
|
}
|
|
1076
|
+
if (input.buildOnly) continue;
|
|
953
1077
|
const keys = require_state.appEnvKeys(manifest, app.name, input.runnables) ?? /* @__PURE__ */ new Set();
|
|
954
1078
|
const values = valuesFor(app, keys);
|
|
955
1079
|
const trusted = (0, _geekmidas_manifest.provideKey)(app.id, "trustedOrigins");
|
|
@@ -970,7 +1094,7 @@ function composeStack(input) {
|
|
|
970
1094
|
};
|
|
971
1095
|
for (const [key, value] of Object.entries(app.env)) if (/[\r\n]/.test(value)) throw new EnvValueMultiline(app.name, key);
|
|
972
1096
|
}
|
|
973
|
-
for (const worker of workers) {
|
|
1097
|
+
for (const worker of input.buildOnly ? [] : workers) {
|
|
974
1098
|
const keys = require_state.workerEnvKeys(manifest, worker.id, input.runnables) ?? /* @__PURE__ */ new Set();
|
|
975
1099
|
worker.env = {
|
|
976
1100
|
...valuesFor({
|
|
@@ -1003,7 +1127,8 @@ function composeStack(input) {
|
|
|
1003
1127
|
http,
|
|
1004
1128
|
composeDir: (0, node_path.join)(workspace.root, stackDir(stage)),
|
|
1005
1129
|
buildRoot: layout.buildRoot,
|
|
1006
|
-
workspaceRoot: workspace.root
|
|
1130
|
+
workspaceRoot: workspace.root,
|
|
1131
|
+
envFiles: !input.buildOnly
|
|
1007
1132
|
});
|
|
1008
1133
|
const caddyfile = edgeCaddyfile([
|
|
1009
1134
|
...apps.map((app) => ({
|
|
@@ -1023,6 +1148,7 @@ function composeStack(input) {
|
|
|
1023
1148
|
dockerfiles[app.build.dockerfile] = require_state.appDockerfile(app.name, workspace.apps[app.name], {
|
|
1024
1149
|
layout,
|
|
1025
1150
|
workspaceRoot: workspace.root,
|
|
1151
|
+
apps: workspace.apps,
|
|
1026
1152
|
manifest,
|
|
1027
1153
|
cache: STACK_CACHE
|
|
1028
1154
|
});
|
|
@@ -1254,10 +1380,13 @@ function stackFile(options) {
|
|
|
1254
1380
|
retries: 5
|
|
1255
1381
|
}
|
|
1256
1382
|
};
|
|
1257
|
-
for (const service of Object.values(services))
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1383
|
+
for (const service of Object.values(services)) {
|
|
1384
|
+
if (!options.envFiles) delete service.env_file;
|
|
1385
|
+
service.logging = {
|
|
1386
|
+
driver: LOG_ROTATION.driver,
|
|
1387
|
+
options: { ...LOG_ROTATION.options }
|
|
1388
|
+
};
|
|
1389
|
+
}
|
|
1261
1390
|
return {
|
|
1262
1391
|
name: project,
|
|
1263
1392
|
services,
|
|
@@ -1280,93 +1409,6 @@ function defaultLayout(root) {
|
|
|
1280
1409
|
gkmPaths: ["gkm.config.*"]
|
|
1281
1410
|
};
|
|
1282
1411
|
}
|
|
1283
|
-
/** The id the stack's compose file names an app's build credentials by. */
|
|
1284
|
-
function credentialsSecret(app) {
|
|
1285
|
-
return `${app}_credentials`;
|
|
1286
|
-
}
|
|
1287
|
-
/** The file beside the compose file an app's build credentials are read from. */
|
|
1288
|
-
function credentialsFile(app) {
|
|
1289
|
-
return `${app}.credentials`;
|
|
1290
|
-
}
|
|
1291
|
-
/**
|
|
1292
|
-
* The stack with each backend's image built with its encrypted credentials:
|
|
1293
|
-
* a BuildKit secret per app — the file `credentialsFile` names, mounted as
|
|
1294
|
-
* `gkm_credentials` — and the hash naming them as a build arg, so a new key
|
|
1295
|
-
* rebuilds the layer that embeds them. Each backend's env file gains the
|
|
1296
|
-
* `GKM_MASTER_KEY` that decrypts them, the way a Dokploy deploy injects it.
|
|
1297
|
-
*
|
|
1298
|
-
* Pure: the caller encrypted them.
|
|
1299
|
-
*/
|
|
1300
|
-
function withBuildCredentials(stack, credentials) {
|
|
1301
|
-
const services = { ...stack.compose.services };
|
|
1302
|
-
const secrets = { ...stack.compose.secrets };
|
|
1303
|
-
const apps = stack.apps.map((app) => {
|
|
1304
|
-
const own = credentials[app.name];
|
|
1305
|
-
const service = services[app.name];
|
|
1306
|
-
if (!own || !service?.build) return app;
|
|
1307
|
-
const [key, value] = own.buildArg.split("=");
|
|
1308
|
-
services[app.name] = {
|
|
1309
|
-
...service,
|
|
1310
|
-
build: {
|
|
1311
|
-
...service.build,
|
|
1312
|
-
args: {
|
|
1313
|
-
...service.build.args,
|
|
1314
|
-
[key]: value
|
|
1315
|
-
},
|
|
1316
|
-
secrets: [{
|
|
1317
|
-
source: credentialsSecret(app.name),
|
|
1318
|
-
target: "gkm_credentials"
|
|
1319
|
-
}]
|
|
1320
|
-
}
|
|
1321
|
-
};
|
|
1322
|
-
secrets[credentialsSecret(app.name)] = { file: `./${credentialsFile(app.name)}` };
|
|
1323
|
-
return {
|
|
1324
|
-
...app,
|
|
1325
|
-
env: {
|
|
1326
|
-
...app.env,
|
|
1327
|
-
GKM_MASTER_KEY: own.masterKey
|
|
1328
|
-
}
|
|
1329
|
-
};
|
|
1330
|
-
});
|
|
1331
|
-
const workers = stack.workers.map((worker) => {
|
|
1332
|
-
const own = credentials[worker.name];
|
|
1333
|
-
const service = services[worker.name];
|
|
1334
|
-
if (!own || !service?.build) return worker;
|
|
1335
|
-
const [key, value] = own.buildArg.split("=");
|
|
1336
|
-
services[worker.name] = {
|
|
1337
|
-
...service,
|
|
1338
|
-
build: {
|
|
1339
|
-
...service.build,
|
|
1340
|
-
args: {
|
|
1341
|
-
...service.build.args,
|
|
1342
|
-
[key]: value
|
|
1343
|
-
},
|
|
1344
|
-
secrets: [{
|
|
1345
|
-
source: credentialsSecret(worker.name),
|
|
1346
|
-
target: "gkm_credentials"
|
|
1347
|
-
}]
|
|
1348
|
-
}
|
|
1349
|
-
};
|
|
1350
|
-
secrets[credentialsSecret(worker.name)] = { file: `./${credentialsFile(worker.name)}` };
|
|
1351
|
-
return {
|
|
1352
|
-
...worker,
|
|
1353
|
-
env: {
|
|
1354
|
-
...worker.env,
|
|
1355
|
-
GKM_MASTER_KEY: own.masterKey
|
|
1356
|
-
}
|
|
1357
|
-
};
|
|
1358
|
-
});
|
|
1359
|
-
return {
|
|
1360
|
-
...stack,
|
|
1361
|
-
apps,
|
|
1362
|
-
workers,
|
|
1363
|
-
compose: {
|
|
1364
|
-
...stack.compose,
|
|
1365
|
-
services,
|
|
1366
|
-
...Object.keys(secrets).length ? { secrets } : {}
|
|
1367
|
-
}
|
|
1368
|
-
};
|
|
1369
|
-
}
|
|
1370
1412
|
/** Render an app's env file: one `KEY=value` per line, read raw by compose. */
|
|
1371
1413
|
function envFile(env) {
|
|
1372
1414
|
return `${Object.entries(env).sort(([a], [b]) => a.localeCompare(b)).map(([key, value]) => `${key}=${value}`).join("\n")}\n`;
|
|
@@ -1462,6 +1504,20 @@ var ComposeAppsUnhealthy = class extends Error {
|
|
|
1462
1504
|
* injected, so the rules are asserted without a daemon; the defaults are the
|
|
1463
1505
|
* real ones.
|
|
1464
1506
|
*/
|
|
1507
|
+
/** `--push` without `--build`: there is nothing built here to push. */
|
|
1508
|
+
var ComposePushNeedsBuild = class extends Error {
|
|
1509
|
+
constructor() {
|
|
1510
|
+
super("--push pushes the images this checkout builds, so it needs --build (and never --pull): gkm compose --stage <stage> --build --push --tag <tag>.");
|
|
1511
|
+
this.name = "ComposePushNeedsBuild";
|
|
1512
|
+
}
|
|
1513
|
+
};
|
|
1514
|
+
/** Digests to run by, on a run that pulls nothing. */
|
|
1515
|
+
var ComposePinNeedsPull = class extends Error {
|
|
1516
|
+
constructor() {
|
|
1517
|
+
super("--digests-file pins the images a release pulls, so it needs --tag (or --pull) — or, with --build --push, it is where the pushed digests are written.");
|
|
1518
|
+
this.name = "ComposePinNeedsPull";
|
|
1519
|
+
}
|
|
1520
|
+
};
|
|
1465
1521
|
/** A port variable that does not hold a port. */
|
|
1466
1522
|
var EdgePortInvalid = class extends Error {
|
|
1467
1523
|
variable;
|
|
@@ -1540,10 +1596,15 @@ const defaultDeps = {
|
|
|
1540
1596
|
* every image it names exists. Nothing is written: a missing image stops the
|
|
1541
1597
|
* run here, before a file, a secret or a container is touched.
|
|
1542
1598
|
*/
|
|
1543
|
-
async function validateCompose(ctx, deps,
|
|
1599
|
+
async function validateCompose(ctx, deps, options = {}) {
|
|
1544
1600
|
const { workspace, stage, identity, tag } = ctx;
|
|
1545
1601
|
const root = workspace.root;
|
|
1546
|
-
const mode =
|
|
1602
|
+
const mode = options.mode ?? (ctx.tagGiven ? "pull" : "build");
|
|
1603
|
+
const push = options.push === true;
|
|
1604
|
+
if (push && mode !== "build") throw new ComposePushNeedsBuild();
|
|
1605
|
+
if (options.pin && mode !== "pull") throw new ComposePinNeedsPull();
|
|
1606
|
+
const registry = workspace.deploy?.registry;
|
|
1607
|
+
if (!registry && (push || mode === "pull")) throw new RegistryRequired(push ? "push" : "pull", require_state.imageRef(identity, ctx.apps[0] ?? workspace.name, void 0, tag));
|
|
1547
1608
|
const runnables = {};
|
|
1548
1609
|
const background = {};
|
|
1549
1610
|
const manifest = await require_discover.discover({
|
|
@@ -1553,14 +1614,13 @@ async function validateCompose(ctx, deps, forced) {
|
|
|
1553
1614
|
background
|
|
1554
1615
|
});
|
|
1555
1616
|
const { secrets, generated } = await stageSecrets(ctx, manifest);
|
|
1556
|
-
await require_credentialSchemas.assertStageCredentials({
|
|
1617
|
+
if (!push) await require_credentialSchemas.assertStageCredentials({
|
|
1557
1618
|
root,
|
|
1558
1619
|
patterns: require_state.constructGlobs(workspace),
|
|
1559
1620
|
manifest,
|
|
1560
1621
|
stage,
|
|
1561
1622
|
supplied: secrets?.custom ?? {}
|
|
1562
1623
|
});
|
|
1563
|
-
const masterKeys = {};
|
|
1564
1624
|
const layout = mode === "build" ? require_state.imageLayout(workspace) : void 0;
|
|
1565
1625
|
const composed = composeStack({
|
|
1566
1626
|
workspace,
|
|
@@ -1572,51 +1632,17 @@ async function validateCompose(ctx, deps, forced) {
|
|
|
1572
1632
|
images: {
|
|
1573
1633
|
mode,
|
|
1574
1634
|
tag,
|
|
1575
|
-
...
|
|
1635
|
+
...registry ? { registry } : {}
|
|
1576
1636
|
},
|
|
1577
1637
|
secrets,
|
|
1578
1638
|
allowDevServices: ctx.allowDevServices,
|
|
1579
1639
|
ports: edgePorts(deps.env),
|
|
1580
|
-
...layout ? { layout } : {}
|
|
1640
|
+
...layout ? { layout } : {},
|
|
1641
|
+
...push ? { buildOnly: true } : {}
|
|
1581
1642
|
});
|
|
1582
1643
|
require_state.reportDevServices(ctx, composed.devServices);
|
|
1583
1644
|
if (mode === "build") assertRedisClient(workspace, composed);
|
|
1584
|
-
const
|
|
1585
|
-
if (mode === "build") {
|
|
1586
|
-
for (const app of composed.apps) {
|
|
1587
|
-
if (app.kind !== "rest-api" || !app.env || !app.build) continue;
|
|
1588
|
-
const { encrypted, iv, masterKey } = require_state.encryptSecrets(app.env);
|
|
1589
|
-
credentials[app.name] = {
|
|
1590
|
-
encrypted,
|
|
1591
|
-
iv
|
|
1592
|
-
};
|
|
1593
|
-
ctx.secrets.mask(masterKey);
|
|
1594
|
-
masterKeys[app.name] = {
|
|
1595
|
-
masterKey,
|
|
1596
|
-
buildArg: require_state.credentialsBuildArg({
|
|
1597
|
-
encrypted,
|
|
1598
|
-
iv
|
|
1599
|
-
})
|
|
1600
|
-
};
|
|
1601
|
-
}
|
|
1602
|
-
for (const worker of composed.workers) {
|
|
1603
|
-
if (!worker.env || !worker.build) continue;
|
|
1604
|
-
const { encrypted, iv, masterKey } = require_state.encryptSecrets(worker.env);
|
|
1605
|
-
credentials[worker.name] = {
|
|
1606
|
-
encrypted,
|
|
1607
|
-
iv
|
|
1608
|
-
};
|
|
1609
|
-
ctx.secrets.mask(masterKey);
|
|
1610
|
-
masterKeys[worker.name] = {
|
|
1611
|
-
masterKey,
|
|
1612
|
-
buildArg: require_state.credentialsBuildArg({
|
|
1613
|
-
encrypted,
|
|
1614
|
-
iv
|
|
1615
|
-
})
|
|
1616
|
-
};
|
|
1617
|
-
}
|
|
1618
|
-
}
|
|
1619
|
-
const stack = withBuildCredentials(composed, masterKeys);
|
|
1645
|
+
const stack = options.pin ? withPinnedImages(composed, options.pin.file, options.pin.digests) : composed;
|
|
1620
1646
|
if (mode === "pull" && !ctx.dryRun) await assertImagesExist(deps.docker, tag, [...stack.apps, ...stack.workers]);
|
|
1621
1647
|
if (stack.redis && !stack.local) ctx.secrets.mask(stack.redis.password);
|
|
1622
1648
|
if (stack.logs && (!stack.local || stack.logs.passwordFromSecrets)) {
|
|
@@ -1627,7 +1653,8 @@ async function validateCompose(ctx, deps, forced) {
|
|
|
1627
1653
|
const override = stackOverrideFile(root, stage);
|
|
1628
1654
|
const overrides = (0, node_fs.existsSync)(override) ? [override] : [];
|
|
1629
1655
|
if (overrides.length > 0) ctx.logger.info(`🧩 Merging docker-compose.${stage}.yml over the generated stack`);
|
|
1630
|
-
const
|
|
1656
|
+
const recorded = push ? void 0 : await ctx.state.read(stage);
|
|
1657
|
+
const previous = Object.fromEntries(Object.entries(recorded?.state.releases ?? {}).map(([name, releases]) => {
|
|
1631
1658
|
const { ref, tag, digest } = releases.current;
|
|
1632
1659
|
return [name, {
|
|
1633
1660
|
ref,
|
|
@@ -1637,6 +1664,7 @@ async function validateCompose(ctx, deps, forced) {
|
|
|
1637
1664
|
}));
|
|
1638
1665
|
return {
|
|
1639
1666
|
mode,
|
|
1667
|
+
push,
|
|
1640
1668
|
stack,
|
|
1641
1669
|
dir,
|
|
1642
1670
|
ref: {
|
|
@@ -1651,7 +1679,6 @@ async function validateCompose(ctx, deps, forced) {
|
|
|
1651
1679
|
generated,
|
|
1652
1680
|
previous,
|
|
1653
1681
|
files: [],
|
|
1654
|
-
credentials,
|
|
1655
1682
|
images: {},
|
|
1656
1683
|
changes: []
|
|
1657
1684
|
};
|
|
@@ -1713,13 +1740,36 @@ async function stageSecrets(ctx, manifest) {
|
|
|
1713
1740
|
};
|
|
1714
1741
|
}
|
|
1715
1742
|
/**
|
|
1743
|
+
* The stack with each app's and worker's image pinned to the digest the file
|
|
1744
|
+
* names: the refs it is checked, pulled and recorded by, and the image each
|
|
1745
|
+
* compose service runs.
|
|
1746
|
+
*/
|
|
1747
|
+
function withPinnedImages(stack, file, digests) {
|
|
1748
|
+
const apps = pinImages(file, digests, stack.apps);
|
|
1749
|
+
const workers = pinImages(file, digests, stack.workers);
|
|
1750
|
+
const services = { ...stack.compose.services };
|
|
1751
|
+
for (const image of [...apps, ...workers]) services[image.name] = {
|
|
1752
|
+
...services[image.name],
|
|
1753
|
+
image: image.ref
|
|
1754
|
+
};
|
|
1755
|
+
return {
|
|
1756
|
+
...stack,
|
|
1757
|
+
apps,
|
|
1758
|
+
workers,
|
|
1759
|
+
compose: {
|
|
1760
|
+
...stack.compose,
|
|
1761
|
+
services
|
|
1762
|
+
}
|
|
1763
|
+
};
|
|
1764
|
+
}
|
|
1765
|
+
/**
|
|
1716
1766
|
* A dry run: the stack's files, written so they can be read, and what a real
|
|
1717
1767
|
* run would do — no image is built or pulled, no container touched, nothing
|
|
1718
1768
|
* recorded and no secret kept.
|
|
1719
1769
|
*/
|
|
1720
1770
|
async function planCompose(ctx, run) {
|
|
1721
1771
|
if (run.generated.length > 0) ctx.logger.info(`🔑 "${ctx.stage}" has no ${run.generated.join(", ")} yet; this dry run used values it did not keep.`);
|
|
1722
|
-
run.files = await writeStack(ctx.cwd, run.dir, run.stack
|
|
1772
|
+
run.files = await writeStack(ctx.cwd, run.dir, run.stack);
|
|
1723
1773
|
printPlan(ctx, run);
|
|
1724
1774
|
const planned = (change) => {
|
|
1725
1775
|
run.changes.push(change);
|
|
@@ -1728,7 +1778,7 @@ async function planCompose(ctx, run) {
|
|
|
1728
1778
|
...change
|
|
1729
1779
|
});
|
|
1730
1780
|
};
|
|
1731
|
-
for (const service of run.stack.infra) planned({
|
|
1781
|
+
for (const service of run.push ? [] : run.stack.infra) planned({
|
|
1732
1782
|
key: `service:${service}`,
|
|
1733
1783
|
resourceType: "service",
|
|
1734
1784
|
action: "ensure"
|
|
@@ -1740,6 +1790,7 @@ async function planCompose(ctx, run) {
|
|
|
1740
1790
|
action: run.mode === "build" ? "build" : "reuse",
|
|
1741
1791
|
id: app.ref
|
|
1742
1792
|
});
|
|
1793
|
+
if (run.push) continue;
|
|
1743
1794
|
planned({
|
|
1744
1795
|
key: `service:${app.name}`,
|
|
1745
1796
|
resourceType: "service",
|
|
@@ -1753,13 +1804,14 @@ async function planCompose(ctx, run) {
|
|
|
1753
1804
|
action: run.mode === "build" ? "build" : "reuse",
|
|
1754
1805
|
id: worker.ref
|
|
1755
1806
|
});
|
|
1807
|
+
if (run.push) continue;
|
|
1756
1808
|
planned({
|
|
1757
1809
|
key: `service:${worker.name}`,
|
|
1758
1810
|
resourceType: "service",
|
|
1759
1811
|
action: run.previous[worker.name] ? "reuse" : "create"
|
|
1760
1812
|
});
|
|
1761
1813
|
}
|
|
1762
|
-
planned({
|
|
1814
|
+
if (!run.push) planned({
|
|
1763
1815
|
key: "service:caddy",
|
|
1764
1816
|
resourceType: "service",
|
|
1765
1817
|
action: "ensure"
|
|
@@ -1772,11 +1824,12 @@ async function planCompose(ctx, run) {
|
|
|
1772
1824
|
*/
|
|
1773
1825
|
async function provisionCompose(ctx, run, deps) {
|
|
1774
1826
|
const { stack, ref } = run;
|
|
1827
|
+
if (run.push) return;
|
|
1775
1828
|
if (run.generated.length > 0 && run.secrets) {
|
|
1776
1829
|
await ctx.secrets.write(run.secrets);
|
|
1777
1830
|
ctx.logger.info(`🔑 Generated for "${ctx.stage}" (${ctx.secrets.store}): ${run.generated.join(", ")}`);
|
|
1778
1831
|
}
|
|
1779
|
-
run.files = await writeStack(ctx.cwd, run.dir, stack
|
|
1832
|
+
run.files = await writeStack(ctx.cwd, run.dir, stack);
|
|
1780
1833
|
printPlan(ctx, run);
|
|
1781
1834
|
if (stack.infra.length > 0) {
|
|
1782
1835
|
ctx.logger.info(`\n🗄️ Starting ${stack.infra.join(", ")}…`);
|
|
@@ -1844,6 +1897,10 @@ async function buildCompose(ctx, run, deps) {
|
|
|
1844
1897
|
const { stack, ref } = run;
|
|
1845
1898
|
const images = [...stack.apps, ...stack.workers];
|
|
1846
1899
|
const apps = images.map((image) => image.app);
|
|
1900
|
+
if (run.push) {
|
|
1901
|
+
run.files = await writeStack(ctx.cwd, run.dir, stack);
|
|
1902
|
+
printPlan(ctx, run);
|
|
1903
|
+
}
|
|
1847
1904
|
if (run.mode === "build") {
|
|
1848
1905
|
ctx.logger.info("\n🐳 Building images…");
|
|
1849
1906
|
await deps.docker.build(ref, apps);
|
|
@@ -1851,8 +1908,10 @@ async function buildCompose(ctx, run, deps) {
|
|
|
1851
1908
|
ctx.logger.info(`\n🐳 Pulling ${ctx.tag}…`);
|
|
1852
1909
|
await deps.docker.pull(ref, apps);
|
|
1853
1910
|
}
|
|
1911
|
+
if (run.push) ctx.logger.info("\n📤 Pushing images…");
|
|
1854
1912
|
for (const image of images) {
|
|
1855
|
-
const digest = await deps.docker.digest(image.ref);
|
|
1913
|
+
const digest = run.push ? await deps.docker.push(ref, image.ref) : await deps.docker.digest(image.ref);
|
|
1914
|
+
if (run.push) ctx.logger.info(` ${image.app.padEnd(12)} ${image.ref}@${digest}`);
|
|
1856
1915
|
run.images[image.app] = {
|
|
1857
1916
|
ref: image.ref,
|
|
1858
1917
|
tag: image.tag,
|
|
@@ -1878,6 +1937,7 @@ async function buildCompose(ctx, run, deps) {
|
|
|
1878
1937
|
*/
|
|
1879
1938
|
async function releaseCompose(ctx, run, deps) {
|
|
1880
1939
|
const { stack, ref } = run;
|
|
1940
|
+
if (run.push) return;
|
|
1881
1941
|
ctx.logger.info("\n🚀 Starting the stack…");
|
|
1882
1942
|
await deps.docker.up(ref);
|
|
1883
1943
|
if (stack.local) await deps.docker.copyOut(ref, "caddy", "/data/caddy/pki/authorities/local/root.crt", caFile(run)).catch(() => {});
|
|
@@ -1936,6 +1996,7 @@ async function recordImages(ctx, run) {
|
|
|
1936
1996
|
*/
|
|
1937
1997
|
async function verifyCompose(ctx, run, deps) {
|
|
1938
1998
|
const { stack } = run;
|
|
1999
|
+
if (run.push) return;
|
|
1939
2000
|
const ca = stack.local ? await (0, node_fs_promises.readFile)(caFile(run), "utf-8").catch(() => void 0) : void 0;
|
|
1940
2001
|
ctx.logger.info("\n🩺 Checking each app through Caddy…");
|
|
1941
2002
|
const results = await Promise.all(stack.apps.map((app) => checkApp(ctx, app, deps, {
|
|
@@ -2115,7 +2176,7 @@ function applied(ctx, run, change) {
|
|
|
2115
2176
|
});
|
|
2116
2177
|
}
|
|
2117
2178
|
/** Write the stack's files: owner-only, since the env files hold secrets. */
|
|
2118
|
-
async function writeStack(root, dir, stack
|
|
2179
|
+
async function writeStack(root, dir, stack) {
|
|
2119
2180
|
await (0, node_fs_promises.mkdir)(dir, {
|
|
2120
2181
|
recursive: true,
|
|
2121
2182
|
mode: 448
|
|
@@ -2131,9 +2192,9 @@ async function writeStack(root, dir, stack, credentials = {}) {
|
|
|
2131
2192
|
await write((0, node_path.join)(dir, "docker-compose.yml"), composeYaml(stack));
|
|
2132
2193
|
await write((0, node_path.join)(dir, "Caddyfile"), stack.caddyfile);
|
|
2133
2194
|
for (const app of [...stack.apps, ...stack.workers]) if (app.env) await write((0, node_path.join)(dir, `${app.name}.env`), envFile(app.env), 384);
|
|
2134
|
-
if (stack.logs) await write((0, node_path.join)(dir, `${LOGS_SERVICE}.env`), envFile(stack.logs.env), 384);
|
|
2135
|
-
if (stack.redis) await write((0, node_path.join)(dir, `${REDIS_SERVICE}.env`), envFile(stack.redis.env), 384);
|
|
2136
|
-
for (const
|
|
2195
|
+
if (stack.logs && stack.compose.services["openobserve"]?.env_file) await write((0, node_path.join)(dir, `${LOGS_SERVICE}.env`), envFile(stack.logs.env), 384);
|
|
2196
|
+
if (stack.redis && stack.compose.services["redis"]?.env_file) await write((0, node_path.join)(dir, `${REDIS_SERVICE}.env`), envFile(stack.redis.env), 384);
|
|
2197
|
+
for (const entry of await (0, node_fs_promises.readdir)(dir)) if (entry.endsWith(".credentials")) await (0, node_fs_promises.rm)((0, node_path.join)(dir, entry));
|
|
2137
2198
|
for (const [path, content] of Object.entries(stack.dockerfiles)) await write((0, node_path.join)(root, path), content);
|
|
2138
2199
|
await require_state.ensureDockerignore(require_state.findBuildRoot(root));
|
|
2139
2200
|
return files;
|
|
@@ -2183,13 +2244,16 @@ function printPlan(ctx, run) {
|
|
|
2183
2244
|
* digest in the stage's state
|
|
2184
2245
|
* - `verify`: each app asked through Caddy over HTTPS
|
|
2185
2246
|
*
|
|
2247
|
+
* With `push` (`gkm compose --build --push`), run with `buildOnly`, it builds
|
|
2248
|
+
* every image and pushes it to `deploy.registry`, and does nothing else.
|
|
2249
|
+
*
|
|
2186
2250
|
* `gkm compose` is this target with a few more switches (`--build`, `--pull`,
|
|
2187
2251
|
* `--down`), run through the same `deploy()`.
|
|
2188
2252
|
*/
|
|
2189
2253
|
var compose_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({ composeTarget: () => composeTarget });
|
|
2190
2254
|
/** The compose target, with its Docker, bundler and probe as given. */
|
|
2191
2255
|
function composeTarget(options = {}) {
|
|
2192
|
-
const { mode, report, ...given } = options;
|
|
2256
|
+
const { mode, push, pin, report, ...given } = options;
|
|
2193
2257
|
const deps = {
|
|
2194
2258
|
...defaultDeps,
|
|
2195
2259
|
...given
|
|
@@ -2205,7 +2269,11 @@ function composeTarget(options = {}) {
|
|
|
2205
2269
|
},
|
|
2206
2270
|
credentials: [],
|
|
2207
2271
|
tag: ({ cwd }) => deps.revision(cwd),
|
|
2208
|
-
validate: (ctx) => validateCompose(ctx, deps,
|
|
2272
|
+
validate: (ctx) => validateCompose(ctx, deps, {
|
|
2273
|
+
...mode ? { mode } : {},
|
|
2274
|
+
...push ? { push } : {},
|
|
2275
|
+
...pin ? { pin } : {}
|
|
2276
|
+
}),
|
|
2209
2277
|
plan: (ctx, run) => planCompose(ctx, run),
|
|
2210
2278
|
provision: (ctx, run) => provisionCompose(ctx, run, deps),
|
|
2211
2279
|
build: (ctx, run) => buildCompose(ctx, run, deps),
|
|
@@ -2218,6 +2286,18 @@ function composeTarget(options = {}) {
|
|
|
2218
2286
|
});
|
|
2219
2287
|
}
|
|
2220
2288
|
//#endregion
|
|
2289
|
+
Object.defineProperty(exports, "ComposePinNeedsPull", {
|
|
2290
|
+
enumerable: true,
|
|
2291
|
+
get: function() {
|
|
2292
|
+
return ComposePinNeedsPull;
|
|
2293
|
+
}
|
|
2294
|
+
});
|
|
2295
|
+
Object.defineProperty(exports, "ComposePushNeedsBuild", {
|
|
2296
|
+
enumerable: true,
|
|
2297
|
+
get: function() {
|
|
2298
|
+
return ComposePushNeedsBuild;
|
|
2299
|
+
}
|
|
2300
|
+
});
|
|
2221
2301
|
Object.defineProperty(exports, "composeProject", {
|
|
2222
2302
|
enumerable: true,
|
|
2223
2303
|
get: function() {
|
|
@@ -2242,6 +2322,18 @@ Object.defineProperty(exports, "dockerCompose", {
|
|
|
2242
2322
|
return dockerCompose;
|
|
2243
2323
|
}
|
|
2244
2324
|
});
|
|
2325
|
+
Object.defineProperty(exports, "parseDigests", {
|
|
2326
|
+
enumerable: true,
|
|
2327
|
+
get: function() {
|
|
2328
|
+
return parseDigests;
|
|
2329
|
+
}
|
|
2330
|
+
});
|
|
2331
|
+
Object.defineProperty(exports, "pinnedRef", {
|
|
2332
|
+
enumerable: true,
|
|
2333
|
+
get: function() {
|
|
2334
|
+
return pinnedRef;
|
|
2335
|
+
}
|
|
2336
|
+
});
|
|
2245
2337
|
Object.defineProperty(exports, "stackDir", {
|
|
2246
2338
|
enumerable: true,
|
|
2247
2339
|
get: function() {
|
|
@@ -2255,4 +2347,4 @@ Object.defineProperty(exports, "stackOverrideFile", {
|
|
|
2255
2347
|
}
|
|
2256
2348
|
});
|
|
2257
2349
|
|
|
2258
|
-
//# sourceMappingURL=compose-
|
|
2350
|
+
//# sourceMappingURL=compose-h_6oNnHC.cjs.map
|