openship 0.6.7 → 0.6.8
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/bare-FA66N7GC.js +29 -0
- package/dist/{chunk-LHFXSC36.js → chunk-3MP6ACKM.js} +183 -87
- package/dist/{chunk-MEE6OZFP.js → chunk-5DJOB7IX.js} +3 -3
- package/dist/{chunk-PPEBIY5F.js → chunk-5I3COAFH.js} +35 -12
- package/dist/{chunk-VQM6JHJB.js → chunk-5UXHT6ED.js} +9 -9
- package/dist/{chunk-XWHWTHEL.js → chunk-6GU6JSK6.js} +21 -2
- package/dist/{chunk-QHMDCYZ3.js → chunk-7PEXM2UI.js} +213 -45
- package/dist/{chunk-RDXT4BQB.js → chunk-7YBWXEM6.js} +4 -4
- package/dist/{chunk-H4FS5BED.js → chunk-AHJYP7DG.js} +13 -11
- package/dist/{chunk-VSTFHUCV.js → chunk-BO6CY4V2.js} +109 -23
- package/dist/{chunk-J3K6XABC.js → chunk-D3OEMXYP.js} +3 -3
- package/dist/{chunk-UWEV6XTS.js → chunk-D6HU4VUZ.js} +1 -1
- package/dist/{chunk-S6B2Z3OO.js → chunk-ENKJ7XIF.js} +21 -11
- package/dist/{chunk-BLEXTYRK.js → chunk-GNOMEMNI.js} +1 -1
- package/dist/{chunk-NRTJRNAE.js → chunk-IAMOUDHY.js} +138 -54
- package/dist/{chunk-CIJV43LH.js → chunk-MUWVC5R4.js} +161 -39
- package/dist/{chunk-ZPJ74LXE.js → chunk-NIYD7MD2.js} +197 -45
- package/dist/{chunk-FZ6QCF6B.js → chunk-NPSRGIHV.js} +2 -2
- package/dist/{chunk-2GWYYHOR.js → chunk-NRU2EBYZ.js} +2 -2
- package/dist/{chunk-J2XM3QSP.js → chunk-NUT6HKK6.js} +5 -5
- package/dist/{chunk-H3WT3A6R.js → chunk-P7RCYELG.js} +1 -1
- package/dist/{chunk-FYPFEDPZ.js → chunk-R5DC5PEF.js} +1 -1
- package/dist/{chunk-DDFUESPJ.js → chunk-RCMERVBL.js} +9 -9
- package/dist/{chunk-RXQBD4ZY.js → chunk-RHLNVZMS.js} +2 -2
- package/dist/{chunk-WU54BXFE.js → chunk-SK4FFCFR.js} +1 -1
- package/dist/{chunk-PVP4RGWT.js → chunk-T46BQOLY.js} +3 -3
- package/dist/{chunk-E2X26PXR.js → chunk-T6DVUX4F.js} +1 -1
- package/dist/{chunk-5T4UVOM3.js → chunk-TAZZZKYO.js} +1 -1
- package/dist/{chunk-GGIAIGUL.js → chunk-UAWY6X7V.js} +34 -12
- package/dist/{chunk-2ANV5ZQ5.js → chunk-VAI5VOOI.js} +1 -1
- package/dist/{chunk-2VSW6Q6C.js → chunk-WEZFTL4V.js} +655 -62
- package/dist/{chunk-GIPJNNI5.js → chunk-X53JXRS4.js} +3 -3
- package/dist/{cloud-KRTZ2IL5.js → cloud-2CRDKOWQ.js} +1 -1
- package/dist/cloud-REV3DPJH.js +42 -0
- package/dist/{detect-G4DR3U2N.js → detect-BBFT5GEU.js} +4 -4
- package/dist/{docker-YOVPCIB4.js → docker-EG3QSE6I.js} +10 -10
- package/dist/{docker-edge-executor-QFXD3337.js → docker-edge-executor-E5TOTLMR.js} +7 -7
- package/dist/edge-import-YJVJUGYC.js +56 -0
- package/dist/{edge-preflight-MXERVAMG.js → edge-preflight-QUW4BM7N.js} +13 -13
- package/dist/{ensure-container-edge-F4JUNQIK.js → ensure-container-edge-FOEFQ3PI.js} +13 -11
- package/dist/{executor-CVPAYYHR.js → executor-NTWDJ3DB.js} +6 -6
- package/dist/host-channel-preflight-OMCZMMKR.js +54 -0
- package/dist/index.js +158 -72
- package/dist/{local-executor-ODC6RANU.js → local-executor-OQ2GRN7K.js} +3 -3
- package/dist/{nginx-KLFF43TC.js → nginx-4U4C2XUS.js} +9 -9
- package/dist/{noop-NJ72F46T.js → noop-CLLJHCPL.js} +1 -1
- package/dist/{openresty-lua-VKWUV4GB.js → openresty-lua-LLWT5XQW.js} +7 -5
- package/dist/{privilege-7D3SSOL3.js → privilege-MNDVMDST.js} +5 -5
- package/dist/server/index.js +31643 -25553
- package/dist/server/migrations/0109_service_build_args.sql +9 -0
- package/dist/server/migrations/0110_service_deployment_host_ports.sql +18 -0
- package/dist/server/migrations/0111_host_port_claim.sql +381 -0
- package/dist/server/migrations/0112_backup_run_execution_lease.sql +12 -0
- package/dist/server/migrations/0113_docker_migration_execution_lease.sql +11 -0
- package/dist/server/migrations/0114_build_session_execution_lease_index.sql +6 -0
- package/dist/server/migrations/0115_orphan_target_key.sql +3 -0
- package/dist/server/migrations/0116_domain_ssl_challenge.sql +2 -0
- package/dist/server/migrations/meta/_journal.json +56 -0
- package/dist/{setup-I5AJC6NJ.js → setup-IFIMPQZJ.js} +12 -12
- package/dist/{ssh-client-625VWGKP.js → ssh-client-2XWZCMGI.js} +2 -2
- package/dist/up-HQS7IR7H.js +61 -0
- package/package.json +1 -1
- package/dist/bare-7QD623QV.js +0 -29
- package/dist/cloud-KNNABE3O.js +0 -40
- package/dist/edge-import-CRFVSR6P.js +0 -56
- package/dist/host-channel-preflight-QTDNGLCK.js +0 -54
- package/dist/up-QXTOOVXC.js +0 -61
|
@@ -9,31 +9,32 @@ import {
|
|
|
9
9
|
readDeclaredPair,
|
|
10
10
|
readMaybeInContainer,
|
|
11
11
|
validateCertFor
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-IAMOUDHY.js";
|
|
13
13
|
import {
|
|
14
14
|
EDGE_CHALLENGE_HOST_DIR,
|
|
15
15
|
EDGE_CONTAINER_MOUNTS,
|
|
16
16
|
EDGE_HOST_PATHS,
|
|
17
17
|
OPENRESTY_DEFAULT_PATHS
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-7PEXM2UI.js";
|
|
19
19
|
import {
|
|
20
20
|
privilegedExecutor,
|
|
21
21
|
rootChecked,
|
|
22
22
|
rootOrDegrade
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-T46BQOLY.js";
|
|
24
24
|
import {
|
|
25
25
|
envOps,
|
|
26
26
|
opScript
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-GNOMEMNI.js";
|
|
28
28
|
import {
|
|
29
29
|
resolveEnvironment
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-NPSRGIHV.js";
|
|
31
31
|
import {
|
|
32
32
|
sq
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-P7RCYELG.js";
|
|
34
34
|
import {
|
|
35
35
|
EdgeConflictError,
|
|
36
36
|
EdgeMigrateRequested,
|
|
37
|
+
detectEdgeContainer,
|
|
37
38
|
edgeCrashReason,
|
|
38
39
|
edgeFailureReason,
|
|
39
40
|
edgeIsBroken,
|
|
@@ -44,16 +45,16 @@ import {
|
|
|
44
45
|
sanitizeEdgeVhosts,
|
|
45
46
|
sq as sq2,
|
|
46
47
|
stopTargetsForStatus
|
|
47
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-X53JXRS4.js";
|
|
48
49
|
import {
|
|
49
50
|
waitForPortListening
|
|
50
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-BO6CY4V2.js";
|
|
51
52
|
import {
|
|
52
53
|
EDGE_CONTAINER_NAME,
|
|
53
54
|
probeExec,
|
|
54
55
|
tryExec,
|
|
55
56
|
withReason
|
|
56
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-D6HU4VUZ.js";
|
|
57
58
|
import {
|
|
58
59
|
formatDuration,
|
|
59
60
|
systemDebug
|
|
@@ -64,11 +65,12 @@ import {
|
|
|
64
65
|
answered,
|
|
65
66
|
buildEdgeImageRef,
|
|
66
67
|
compareSemver,
|
|
68
|
+
isLoopbackHost,
|
|
67
69
|
parseProxyValue,
|
|
68
70
|
safeErrorMessage,
|
|
69
71
|
sanitizeProxySettings,
|
|
70
72
|
shellQuote
|
|
71
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-WEZFTL4V.js";
|
|
72
74
|
|
|
73
75
|
// ../../packages/adapters/src/system/managed-image.ts
|
|
74
76
|
import { posix } from "path";
|
|
@@ -425,8 +427,9 @@ function parseUpstreams(config) {
|
|
|
425
427
|
let m;
|
|
426
428
|
while ((m = re.exec(config)) !== null) {
|
|
427
429
|
const name = m[1];
|
|
428
|
-
const
|
|
429
|
-
|
|
430
|
+
const body = m[2] ?? "";
|
|
431
|
+
const targets = [...body.matchAll(/(?:^|[\s;{])server\s+([^;\s]+)/g)].map((server) => server[1]?.trim()).filter((target) => Boolean(target));
|
|
432
|
+
if (name && targets.length > 0) map.set(name, targets);
|
|
430
433
|
}
|
|
431
434
|
return map;
|
|
432
435
|
}
|
|
@@ -439,14 +442,55 @@ function resolveProxyTarget(proxyPass, upstreams) {
|
|
|
439
442
|
const scheme = m[1];
|
|
440
443
|
const authority = m[2];
|
|
441
444
|
const host = authority.replace(/:\d+$/, "");
|
|
442
|
-
|
|
445
|
+
const declaredUpstream = upstreams.get(authority);
|
|
446
|
+
if (declaredUpstream?.[0]) return { url: `${scheme}${declaredUpstream[0]}` };
|
|
443
447
|
const isIp = /^\d{1,3}(\.\d{1,3}){3}$/.test(host);
|
|
444
448
|
if (host === "localhost" || host === "ip6-localhost") {
|
|
445
449
|
return { url: raw.replace(/^(https?:\/\/)[^/:]+/i, "$1127.0.0.1") };
|
|
446
450
|
}
|
|
447
|
-
if (isIp || host.includes(".")
|
|
451
|
+
if (isIp || host.includes(".") || host.startsWith("[") && host.endsWith("]")) {
|
|
452
|
+
return { url: raw };
|
|
453
|
+
}
|
|
448
454
|
return { reason: `proxy_pass host "${host}" is an undeclared upstream \u2014 not migratable` };
|
|
449
455
|
}
|
|
456
|
+
function strictLoopbackUpstreamPorts(config) {
|
|
457
|
+
const normalized = stripComments(config);
|
|
458
|
+
const upstreams = parseUpstreams(normalized);
|
|
459
|
+
const ports = /* @__PURE__ */ new Set();
|
|
460
|
+
for (const match of normalized.matchAll(/(?:^|[;{}\s])proxy_pass\s+([^;]+);/g)) {
|
|
461
|
+
const raw = match[1]?.trim();
|
|
462
|
+
if (!raw) continue;
|
|
463
|
+
const resolved = resolveProxyTarget(raw, upstreams);
|
|
464
|
+
if ("reason" in resolved) {
|
|
465
|
+
if (/\/\/unix:/i.test(raw)) continue;
|
|
466
|
+
throw new Error(`Cannot inventory Openship edge routes: ${resolved.reason}`);
|
|
467
|
+
}
|
|
468
|
+
const authority = raw.match(/^https?:\/\/([^/]+)/i)?.[1];
|
|
469
|
+
const scheme = raw.match(/^(https?:\/\/)/i)?.[1];
|
|
470
|
+
const targets = authority && scheme && upstreams.has(authority) ? upstreams.get(authority).map((target) => `${scheme}${target}`) : [resolved.url];
|
|
471
|
+
for (const target of targets) {
|
|
472
|
+
let url;
|
|
473
|
+
try {
|
|
474
|
+
url = new URL(target);
|
|
475
|
+
} catch {
|
|
476
|
+
throw new Error(`Cannot inventory Openship edge routes: invalid proxy_pass "${raw}"`);
|
|
477
|
+
}
|
|
478
|
+
if (!isLoopbackHost(url.hostname)) continue;
|
|
479
|
+
const port = url.port ? Number(url.port) : url.protocol === "https:" ? 443 : 80;
|
|
480
|
+
if (!Number.isSafeInteger(port) || port < 1 || port > 65535) {
|
|
481
|
+
throw new Error(`Cannot inventory Openship edge routes: invalid loopback port in "${raw}"`);
|
|
482
|
+
}
|
|
483
|
+
ports.add(port);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
return ports;
|
|
487
|
+
}
|
|
488
|
+
function parseStrictEdgeConfig(raw) {
|
|
489
|
+
return {
|
|
490
|
+
...parseNginxConfig(raw),
|
|
491
|
+
loopbackUpstreamPorts: strictLoopbackUpstreamPorts(raw)
|
|
492
|
+
};
|
|
493
|
+
}
|
|
450
494
|
function locationBlocks(serverBody) {
|
|
451
495
|
const out = [];
|
|
452
496
|
const re = /(?:^|[\s;}])location\s+([^{]+?)\s*\{/g;
|
|
@@ -538,7 +582,9 @@ function resolveStaticRoot(root, prefix) {
|
|
|
538
582
|
}
|
|
539
583
|
function parseServer(body, source, upstreams, prefix) {
|
|
540
584
|
const warnings = [];
|
|
541
|
-
const names = firstDirective(body, "server_name")?.split(/\s+/).filter(
|
|
585
|
+
const names = firstDirective(body, "server_name")?.split(/\s+/).filter(
|
|
586
|
+
(n) => n && n !== "_" && !n.startsWith("~") && !LOOPBACK_SERVER_NAMES.has(n.toLowerCase())
|
|
587
|
+
) ?? [];
|
|
542
588
|
const listens = [...body.matchAll(/(?:^|[;{\s])listen\s+([^;]+);/g)].map((m) => m[1]);
|
|
543
589
|
const ssl = listens.some((l) => /\bssl\b/.test(l) || /\b443\b/.test(l));
|
|
544
590
|
const root = firstDirective(body, "root");
|
|
@@ -634,6 +680,35 @@ async function scanOpenshipEdge(executor) {
|
|
|
634
680
|
const fromContainer = await tryExec(executor, containerCommand(container, cat));
|
|
635
681
|
return parseNginxConfig(fromContainer ?? "");
|
|
636
682
|
}
|
|
683
|
+
async function scanOpenshipEdgeStrict(executor, knownContainer) {
|
|
684
|
+
const detected = await detectEdgeContainer(executor);
|
|
685
|
+
if (!detected) {
|
|
686
|
+
const bareConfig = await dumpResolvedConfig(executor, ["openresty"]);
|
|
687
|
+
if (bareConfig) return parseStrictEdgeConfig(bareConfig);
|
|
688
|
+
throw new Error(
|
|
689
|
+
"Cannot read Openship edge routes: neither Docker nor bare OpenResty inventory is available"
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
if (!detected.exists) {
|
|
693
|
+
const bareConfig = await dumpResolvedConfig(executor, ["openresty"]);
|
|
694
|
+
if (bareConfig) return parseStrictEdgeConfig(bareConfig);
|
|
695
|
+
throw new Error(
|
|
696
|
+
"Cannot read Openship edge routes: no running Openship edge or bare OpenResty inventory is available"
|
|
697
|
+
);
|
|
698
|
+
}
|
|
699
|
+
if (!detected.running) {
|
|
700
|
+
throw new Error("Cannot read Openship edge routes: the edge container is not running");
|
|
701
|
+
}
|
|
702
|
+
const container = knownContainer ?? detected.name;
|
|
703
|
+
if (!container) throw new Error("Cannot read Openship edge routes: container identity missing");
|
|
704
|
+
const fromContainer = await executor.exec(
|
|
705
|
+
containerCommand(container, "openresty -T 2>/dev/null")
|
|
706
|
+
);
|
|
707
|
+
if (!fromContainer.trim() || !/server\s*\{/.test(fromContainer)) {
|
|
708
|
+
throw new Error("Cannot read Openship edge routes: active OpenResty config dump was empty");
|
|
709
|
+
}
|
|
710
|
+
return parseStrictEdgeConfig(fromContainer);
|
|
711
|
+
}
|
|
637
712
|
|
|
638
713
|
// ../../packages/adapters/src/system/proxy/import/caddy.ts
|
|
639
714
|
var CADDYFILE_PATHS = ["/etc/caddy/Caddyfile", "/etc/Caddyfile"];
|
|
@@ -1613,6 +1688,24 @@ function makeApi(exec, kind, ours, container) {
|
|
|
1613
1688
|
}));
|
|
1614
1689
|
return scan;
|
|
1615
1690
|
};
|
|
1691
|
+
let strictLoopbackPorts = null;
|
|
1692
|
+
const listLoopbackUpstreamPortsStrict = (opts = {}) => {
|
|
1693
|
+
if (!ours) {
|
|
1694
|
+
return Promise.reject(
|
|
1695
|
+
new Error("Strict loopback upstream inventory is only available for the Openship edge")
|
|
1696
|
+
);
|
|
1697
|
+
}
|
|
1698
|
+
if (opts.refresh || !strictLoopbackPorts) {
|
|
1699
|
+
const nextScan = scanOpenshipEdgeStrict(exec, container).then(
|
|
1700
|
+
({ loopbackUpstreamPorts }) => loopbackUpstreamPorts
|
|
1701
|
+
);
|
|
1702
|
+
strictLoopbackPorts = nextScan;
|
|
1703
|
+
void nextScan.catch(() => {
|
|
1704
|
+
if (strictLoopbackPorts === nextScan) strictLoopbackPorts = null;
|
|
1705
|
+
});
|
|
1706
|
+
}
|
|
1707
|
+
return strictLoopbackPorts;
|
|
1708
|
+
};
|
|
1616
1709
|
const siteFor = async (host) => {
|
|
1617
1710
|
const target = host.toLowerCase();
|
|
1618
1711
|
const { sites } = await listSites();
|
|
@@ -1644,6 +1737,7 @@ function makeApi(exec, kind, ours, container) {
|
|
|
1644
1737
|
ours,
|
|
1645
1738
|
container,
|
|
1646
1739
|
listSites,
|
|
1740
|
+
listLoopbackUpstreamPortsStrict,
|
|
1647
1741
|
sitesByPort: async () => buildProxyRouteIndex((await listSites()).sites),
|
|
1648
1742
|
siteFor,
|
|
1649
1743
|
certFor: async (host) => (await certCandidateFor(host)).cert,
|
|
@@ -2310,7 +2404,7 @@ function edgeHostExecutor(executor) {
|
|
|
2310
2404
|
});
|
|
2311
2405
|
}
|
|
2312
2406
|
async function containerEdgeProvider(executor, container, opts) {
|
|
2313
|
-
const { NginxProvider: Provider } = await import("./nginx-
|
|
2407
|
+
const { NginxProvider: Provider } = await import("./nginx-4U4C2XUS.js");
|
|
2314
2408
|
return new Provider({
|
|
2315
2409
|
...opts,
|
|
2316
2410
|
// Vhosts go to the BIND-MOUNTED HOST dir (so every host-side reader — the
|
|
@@ -2334,8 +2428,8 @@ async function containerEdgeProvider(executor, container, opts) {
|
|
|
2334
2428
|
});
|
|
2335
2429
|
}
|
|
2336
2430
|
async function localContainerEdgeProvider(container, opts) {
|
|
2337
|
-
const { DockerEdgeExecutor } = await import("./docker-edge-executor-
|
|
2338
|
-
const { NginxProvider: Provider } = await import("./nginx-
|
|
2431
|
+
const { DockerEdgeExecutor } = await import("./docker-edge-executor-E5TOTLMR.js");
|
|
2432
|
+
const { NginxProvider: Provider } = await import("./nginx-4U4C2XUS.js");
|
|
2339
2433
|
return new Provider({
|
|
2340
2434
|
...opts,
|
|
2341
2435
|
paths: OPENRESTY_DEFAULT_PATHS,
|
|
@@ -2356,20 +2450,40 @@ async function localContainerEdgeProvider(container, opts) {
|
|
|
2356
2450
|
containerEdge: true
|
|
2357
2451
|
});
|
|
2358
2452
|
}
|
|
2359
|
-
async function startEdgeContainer(executor, container, image, onLog) {
|
|
2453
|
+
async function startEdgeContainer(executor, container, image, onLog, mounts) {
|
|
2360
2454
|
await sanitizeEdgeVhosts(executor, EDGE_HOST_PATHS.sitesDir, onLog).catch(() => {
|
|
2361
2455
|
});
|
|
2362
2456
|
await executor.exec(`docker rm -f ${sq(container)} 2>/dev/null || true`).catch(() => {
|
|
2363
2457
|
});
|
|
2364
2458
|
const run = await executor.streamExec(
|
|
2365
|
-
buildEdgeRunCommand(container, image),
|
|
2459
|
+
buildEdgeRunCommand(container, image, mounts),
|
|
2366
2460
|
onLog
|
|
2367
2461
|
);
|
|
2368
2462
|
invalidateEdgeContainer(executor);
|
|
2369
2463
|
return run.code === 0;
|
|
2370
2464
|
}
|
|
2371
|
-
function
|
|
2372
|
-
|
|
2465
|
+
async function resolveEdgeContainerMounts(executor) {
|
|
2466
|
+
return Promise.all(
|
|
2467
|
+
EDGE_CONTAINER_MOUNTS.map(async (mount) => {
|
|
2468
|
+
let host;
|
|
2469
|
+
try {
|
|
2470
|
+
host = (await executor.exec(`cd ${sq(mount.host)} && pwd -P`)).trim();
|
|
2471
|
+
} catch (err) {
|
|
2472
|
+
throw new Error(
|
|
2473
|
+
`Could not resolve edge bind-mount source ${mount.host} on the target host: ${safeErrorMessage(err)}`
|
|
2474
|
+
);
|
|
2475
|
+
}
|
|
2476
|
+
if (!host.startsWith("/") || host.includes("\n")) {
|
|
2477
|
+
throw new Error(
|
|
2478
|
+
`Could not resolve edge bind-mount source ${mount.host} on the target host: expected one absolute path, received ${JSON.stringify(host)}.`
|
|
2479
|
+
);
|
|
2480
|
+
}
|
|
2481
|
+
return { host, container: mount.container };
|
|
2482
|
+
})
|
|
2483
|
+
);
|
|
2484
|
+
}
|
|
2485
|
+
function buildEdgeRunCommand(container, image, edgeMounts = EDGE_CONTAINER_MOUNTS) {
|
|
2486
|
+
const mounts = edgeMounts.map(
|
|
2373
2487
|
// `:z` relabels for SELinux-enforcing hosts; a no-op elsewhere.
|
|
2374
2488
|
(m) => `-v ${sq(`${m.host}:${m.container}:z`)}`
|
|
2375
2489
|
).join(" ");
|
|
@@ -2382,10 +2496,27 @@ function buildEdgeRunCommand(container, image) {
|
|
|
2382
2496
|
sq(image)
|
|
2383
2497
|
].join(" ");
|
|
2384
2498
|
}
|
|
2385
|
-
function
|
|
2499
|
+
async function edgeContainerMountsMatch(executor, container, expected) {
|
|
2500
|
+
let raw;
|
|
2501
|
+
try {
|
|
2502
|
+
raw = await executor.exec(
|
|
2503
|
+
`docker inspect -f '{{range .HostConfig.Binds}}{{println .}}{{end}}' ${sq(container)}`
|
|
2504
|
+
);
|
|
2505
|
+
} catch {
|
|
2506
|
+
return null;
|
|
2507
|
+
}
|
|
2508
|
+
const actual = /* @__PURE__ */ new Map();
|
|
2509
|
+
for (const line of raw.split("\n")) {
|
|
2510
|
+
const [source, destination] = line.trim().split(":");
|
|
2511
|
+
if (!source || !destination) continue;
|
|
2512
|
+
actual.set(destination, source);
|
|
2513
|
+
}
|
|
2514
|
+
return expected.every((mount) => actual.get(mount.container) === mount.host);
|
|
2515
|
+
}
|
|
2516
|
+
function makeEdgeStart(executor, container, opts, mounts) {
|
|
2386
2517
|
const { onLog } = opts;
|
|
2387
2518
|
return async (image) => {
|
|
2388
|
-
if (!await startEdgeContainer(executor, container, image, onLog)) return false;
|
|
2519
|
+
if (!await startEdgeContainer(executor, container, image, onLog, mounts)) return false;
|
|
2389
2520
|
const verdict = await verifyEdgeServing(executor, container, {
|
|
2390
2521
|
timeoutMs: opts.verifyTimeoutMs ?? 3e4
|
|
2391
2522
|
});
|
|
@@ -2420,6 +2551,17 @@ async function ensureContainerEdge(executor, opts) {
|
|
|
2420
2551
|
const { onLog } = opts;
|
|
2421
2552
|
const container = opts.container?.trim() || EDGE_CONTAINER_NAME;
|
|
2422
2553
|
const image = resolveEdgeImage(opts.image);
|
|
2554
|
+
let resolvedMounts = null;
|
|
2555
|
+
const targetMounts = async (checked) => {
|
|
2556
|
+
if (resolvedMounts) return resolvedMounts;
|
|
2557
|
+
const host = checked ?? await rootOrDegrade(executor, {
|
|
2558
|
+
purpose: "Resolving the edge's bind-mount sources",
|
|
2559
|
+
consequence: "Docker may mount a different host directory than Openship writes.",
|
|
2560
|
+
report: (message) => onLog(log5(message, "warn"))
|
|
2561
|
+
});
|
|
2562
|
+
resolvedMounts = await resolveEdgeContainerMounts(host);
|
|
2563
|
+
return resolvedMounts;
|
|
2564
|
+
};
|
|
2423
2565
|
const existing = await resolveOurEdgeContainer(executor, { fresh: true });
|
|
2424
2566
|
if (existing) {
|
|
2425
2567
|
const verdict = await verifyEdgeServing(executor, existing);
|
|
@@ -2427,27 +2569,35 @@ async function ensureContainerEdge(executor, opts) {
|
|
|
2427
2569
|
onLog(log5(`The edge container exists but isn't serving: ${verdict.reason}`, "warn"));
|
|
2428
2570
|
onLog(log5("Recreating it...", "warn"));
|
|
2429
2571
|
} else {
|
|
2430
|
-
const
|
|
2431
|
-
const
|
|
2432
|
-
if (
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
start
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2572
|
+
const mounts2 = await targetMounts();
|
|
2573
|
+
const mountsMatch = await edgeContainerMountsMatch(executor, existing, mounts2);
|
|
2574
|
+
if (mountsMatch === false) {
|
|
2575
|
+
onLog(
|
|
2576
|
+
log5("The edge container uses stale or non-canonical bind mounts; recreating it...", "warn")
|
|
2577
|
+
);
|
|
2578
|
+
} else {
|
|
2579
|
+
const current = await containerImageRef(executor, existing);
|
|
2580
|
+
const stale = current != null && current !== image;
|
|
2581
|
+
if (stale) {
|
|
2582
|
+
const start = makeEdgeStart(executor, existing, opts, mounts2);
|
|
2583
|
+
const swap = await swapManagedImage(executor, {
|
|
2584
|
+
kind: "edge",
|
|
2585
|
+
from: current ?? image,
|
|
2586
|
+
to: image,
|
|
2587
|
+
label: "edge",
|
|
2588
|
+
onLog,
|
|
2589
|
+
start
|
|
2590
|
+
});
|
|
2591
|
+
return {
|
|
2592
|
+
container: existing,
|
|
2593
|
+
image,
|
|
2594
|
+
converted: false,
|
|
2595
|
+
updated: swap.swapped,
|
|
2596
|
+
edgeDown: swap.down
|
|
2597
|
+
};
|
|
2598
|
+
}
|
|
2599
|
+
return { container: existing, image, converted: false };
|
|
2449
2600
|
}
|
|
2450
|
-
return { container: existing, image, converted: false };
|
|
2451
2601
|
}
|
|
2452
2602
|
}
|
|
2453
2603
|
if (!await dockerAvailable(executor)) {
|
|
@@ -2482,10 +2632,11 @@ async function ensureContainerEdge(executor, opts) {
|
|
|
2482
2632
|
);
|
|
2483
2633
|
});
|
|
2484
2634
|
}
|
|
2635
|
+
const mounts = await targetMounts(hostState);
|
|
2485
2636
|
const clear = await ensureEdgeClear(executor, opts.config, onLog);
|
|
2486
2637
|
try {
|
|
2487
2638
|
onLog(log5("Starting the edge container..."));
|
|
2488
|
-
if (!await startEdgeContainer(executor, container, image, onLog)) {
|
|
2639
|
+
if (!await startEdgeContainer(executor, container, image, onLog, mounts)) {
|
|
2489
2640
|
throw new Error("the edge container failed to start");
|
|
2490
2641
|
}
|
|
2491
2642
|
const verdict = await verifyEdgeServing(executor, container, {
|
|
@@ -2535,6 +2686,7 @@ export {
|
|
|
2535
2686
|
resolveEdgeImage,
|
|
2536
2687
|
containerEdgeProvider,
|
|
2537
2688
|
localContainerEdgeProvider,
|
|
2689
|
+
resolveEdgeContainerMounts,
|
|
2538
2690
|
buildEdgeRunCommand,
|
|
2539
2691
|
verifyEdgeServing,
|
|
2540
2692
|
ensureContainerEdge,
|
|
@@ -4,7 +4,7 @@ import { createRequire as __ospCreateRequire } from "node:module";
|
|
|
4
4
|
const require = __ospCreateRequire(import.meta.url);
|
|
5
5
|
import {
|
|
6
6
|
sq
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-P7RCYELG.js";
|
|
8
8
|
import {
|
|
9
9
|
formatDuration,
|
|
10
10
|
isRemoteConnectionError,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
parseSystemArch,
|
|
18
18
|
parseSystemOs,
|
|
19
19
|
safeErrorMessage
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-WEZFTL4V.js";
|
|
21
21
|
|
|
22
22
|
// ../../packages/adapters/src/system/elevated-executor.ts
|
|
23
23
|
import { randomBytes } from "crypto";
|
|
@@ -13,11 +13,11 @@ var CloudInfraProvider = class {
|
|
|
13
13
|
async registerRoute(route) {
|
|
14
14
|
void route;
|
|
15
15
|
}
|
|
16
|
-
async removeRoute(domain) {
|
|
16
|
+
async removeRoute(domain, _opts) {
|
|
17
17
|
void domain;
|
|
18
18
|
}
|
|
19
19
|
// ── SSL ──────────────────────────────────────────────────────────────
|
|
20
|
-
async provisionCert(domain) {
|
|
20
|
+
async provisionCert(domain, _opts) {
|
|
21
21
|
return { domain, expiresAt: "", issuer: "oblien", verified: false };
|
|
22
22
|
}
|
|
23
23
|
async renewCert(domain) {
|
|
@@ -19,16 +19,16 @@ import {
|
|
|
19
19
|
rollbackEdgeTakeover,
|
|
20
20
|
scanImportableSites,
|
|
21
21
|
unreachableStaticRoots
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-NIYD7MD2.js";
|
|
23
23
|
import {
|
|
24
24
|
LocalExecutor
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-T6DVUX4F.js";
|
|
26
26
|
import {
|
|
27
27
|
ourEdgeContainerRunning
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-X53JXRS4.js";
|
|
29
29
|
import {
|
|
30
30
|
isOurEdgeContainer
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-D6HU4VUZ.js";
|
|
32
32
|
|
|
33
33
|
// src/lib/edge-preflight.ts
|
|
34
34
|
import { spawnSync } from "child_process";
|
|
@@ -243,7 +243,7 @@ async function repairEdgeConflict(mode, apiPort, onLog) {
|
|
|
243
243
|
}
|
|
244
244
|
spawnSync("docker", ["restart", "openship-edge"], { stdio: "ignore" });
|
|
245
245
|
if (mode === "migrate" && scan.sites.length > 0) {
|
|
246
|
-
const { importMigratedSites } = await import("./edge-import-
|
|
246
|
+
const { importMigratedSites } = await import("./edge-import-YJVJUGYC.js");
|
|
247
247
|
const outcome = await importMigratedSites(apiPort, scan.sites, certPems);
|
|
248
248
|
if (outcome.registered.length === 0) {
|
|
249
249
|
return {
|
|
@@ -4,7 +4,7 @@ import { createRequire as __ospCreateRequire } from "node:module";
|
|
|
4
4
|
const require = __ospCreateRequire(import.meta.url);
|
|
5
5
|
import {
|
|
6
6
|
shellQuote
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-WEZFTL4V.js";
|
|
8
8
|
|
|
9
9
|
// ../../packages/adapters/src/system/local-shell.ts
|
|
10
10
|
import { execFile } from "child_process";
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
resolvePorts,
|
|
29
29
|
sourceBuildDir,
|
|
30
30
|
verifyHostChannel
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-5I3COAFH.js";
|
|
32
32
|
import {
|
|
33
33
|
bootstrapAdmin,
|
|
34
34
|
importMigratedSites,
|
|
@@ -36,18 +36,18 @@ import {
|
|
|
36
36
|
internalPost,
|
|
37
37
|
mintBareInternalToken,
|
|
38
38
|
waitHealthy
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-7YBWXEM6.js";
|
|
40
40
|
import {
|
|
41
41
|
startUnitHint,
|
|
42
42
|
thisHost
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-5UXHT6ED.js";
|
|
44
44
|
import {
|
|
45
45
|
completeHostEdge,
|
|
46
46
|
markStoppedProxyImported,
|
|
47
47
|
planAndApplyHostEdge,
|
|
48
48
|
previewHostEdge,
|
|
49
49
|
rollbackHostEdge
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-NUT6HKK6.js";
|
|
51
51
|
import {
|
|
52
52
|
AUTH_SECRET_FILE,
|
|
53
53
|
DATA_DIR,
|
|
@@ -58,17 +58,17 @@ import {
|
|
|
58
58
|
} from "./chunk-ELGRMZOW.js";
|
|
59
59
|
import {
|
|
60
60
|
LocalExecutor
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-T6DVUX4F.js";
|
|
62
62
|
import {
|
|
63
63
|
edgeCrashReason,
|
|
64
64
|
edgeIsBroken
|
|
65
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-X53JXRS4.js";
|
|
66
66
|
import {
|
|
67
67
|
EDGE_CONTAINER_NAME
|
|
68
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-D6HU4VUZ.js";
|
|
69
69
|
import {
|
|
70
70
|
isValidEmail
|
|
71
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-WEZFTL4V.js";
|
|
72
72
|
|
|
73
73
|
// src/commands/up.ts
|
|
74
74
|
import { Command } from "commander";
|
|
@@ -1564,7 +1564,7 @@ async function runForeground(opts, source) {
|
|
|
1564
1564
|
const uiSpinner = ora("Preparing the dashboard\u2026").start();
|
|
1565
1565
|
try {
|
|
1566
1566
|
const bundle = await ensureDashboard({
|
|
1567
|
-
tag: source ? "local" : opts.uiVersion || `v${"0.6.
|
|
1567
|
+
tag: source ? "local" : opts.uiVersion || `v${"0.6.8"}`,
|
|
1568
1568
|
onProgress: (received, total) => {
|
|
1569
1569
|
if (total) {
|
|
1570
1570
|
uiSpinner.text = `Downloading dashboard\u2026 ${Math.round(received / total * 100)}%`;
|
|
@@ -7,9 +7,9 @@ const require = __ospCreateRequire(import.meta.url);
|
|
|
7
7
|
var NoopInfraProvider = class {
|
|
8
8
|
async registerRoute(_route) {
|
|
9
9
|
}
|
|
10
|
-
async removeRoute(_domain) {
|
|
10
|
+
async removeRoute(_domain, _opts) {
|
|
11
11
|
}
|
|
12
|
-
async provisionCert(domain) {
|
|
12
|
+
async provisionCert(domain, _opts) {
|
|
13
13
|
return { domain, expiresAt: "", issuer: "none", verified: false };
|
|
14
14
|
}
|
|
15
15
|
async renewCert(domain) {
|
|
@@ -4,7 +4,7 @@ import { createRequire as __ospCreateRequire } from "node:module";
|
|
|
4
4
|
const require = __ospCreateRequire(import.meta.url);
|
|
5
5
|
import {
|
|
6
6
|
sq
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-P7RCYELG.js";
|
|
8
8
|
|
|
9
9
|
// ../../packages/adapters/src/runtime/managed-artifact.ts
|
|
10
10
|
var MANAGED_ARTIFACT_BASE = "/opt/openship";
|
|
@@ -4,15 +4,15 @@ import { createRequire as __ospCreateRequire } from "node:module";
|
|
|
4
4
|
const require = __ospCreateRequire(import.meta.url);
|
|
5
5
|
import {
|
|
6
6
|
hostRefusal
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-GNOMEMNI.js";
|
|
8
8
|
import {
|
|
9
9
|
elevatedExecutor,
|
|
10
10
|
resolveEnvironment
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-NPSRGIHV.js";
|
|
12
12
|
import {
|
|
13
13
|
answered,
|
|
14
14
|
refused
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-WEZFTL4V.js";
|
|
16
16
|
|
|
17
17
|
// ../../packages/adapters/src/system/privilege.ts
|
|
18
18
|
function rootChecked(executor, why) {
|