openship 0.4.6 → 0.4.7
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/{chunk-3JQTL4R4.js → chunk-IMBD5PZ5.js} +24 -13
- package/dist/{chunk-C5OHTYEF.js → chunk-IPYPMI3S.js} +1 -1
- package/dist/{chunk-FQGJZ2HS.js → chunk-R5BHFFAV.js} +34 -0
- package/dist/{chunk-2ZLR7ULL.js → chunk-SJIFLLX4.js} +144 -20
- package/dist/{chunk-SQ77DZOI.js → chunk-UXWAVM4C.js} +70 -8
- package/dist/{chunk-5FNIWBFI.js → chunk-XFCDYZUQ.js} +1 -1
- package/dist/{cloud-ZSKOS4GY.js → cloud-2KXREXMO.js} +3 -3
- package/dist/{detect-SH4FHFBI.js → detect-2XSCFFTF.js} +9 -1
- package/dist/{docker-U7AF5PTA.js → docker-LODK5Y2S.js} +1 -1
- package/dist/{edge-import-V5CBA47C.js → edge-import-ZQ4Y5HEA.js} +6 -6
- package/dist/{ensure-container-edge-CMYROUSI.js → ensure-container-edge-ED25XL3Z.js} +2 -4
- package/dist/index.js +34 -11
- package/dist/{nginx-2GTRUIDE.js → nginx-XWJAOGS4.js} +1 -1
- package/dist/server/index.js +228 -35
- package/dist/{setup-HQIZLUOJ.js → setup-2DMFIA74.js} +3 -3
- package/package.json +1 -1
|
@@ -101,10 +101,10 @@ import {
|
|
|
101
101
|
} from "./chunk-W73X43R7.js";
|
|
102
102
|
import {
|
|
103
103
|
CloudRuntime
|
|
104
|
-
} from "./chunk-
|
|
104
|
+
} from "./chunk-XFCDYZUQ.js";
|
|
105
105
|
import {
|
|
106
106
|
systemCatalog
|
|
107
|
-
} from "./chunk-
|
|
107
|
+
} from "./chunk-UXWAVM4C.js";
|
|
108
108
|
import {
|
|
109
109
|
AwsCrc32,
|
|
110
110
|
__awaiter,
|
|
@@ -139,13 +139,18 @@ import {
|
|
|
139
139
|
DockerRuntime,
|
|
140
140
|
isHostPathSource,
|
|
141
141
|
scopedVolumeName
|
|
142
|
-
} from "./chunk-
|
|
142
|
+
} from "./chunk-SJIFLLX4.js";
|
|
143
143
|
import {
|
|
144
144
|
BareRuntime
|
|
145
145
|
} from "./chunk-VDMQJHPI.js";
|
|
146
146
|
import {
|
|
147
|
+
LocalExecutor
|
|
148
|
+
} from "./chunk-TYVME3XD.js";
|
|
149
|
+
import {
|
|
150
|
+
EDGE_CONTAINER_NAME,
|
|
151
|
+
edgeCrashReason,
|
|
147
152
|
invalidateEdgeContainer
|
|
148
|
-
} from "./chunk-
|
|
153
|
+
} from "./chunk-R5BHFFAV.js";
|
|
149
154
|
import {
|
|
150
155
|
EDGE_CONTAINER_MOUNTS,
|
|
151
156
|
EDGE_HOST_STATE_DIR
|
|
@@ -159,13 +164,6 @@ import {
|
|
|
159
164
|
import chalk from "chalk";
|
|
160
165
|
import ora from "ora";
|
|
161
166
|
|
|
162
|
-
// src/lib/compose.ts
|
|
163
|
-
import { spawnSync as spawnSync3 } from "child_process";
|
|
164
|
-
import { randomBytes as randomBytes5 } from "crypto";
|
|
165
|
-
import { chmodSync, existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
166
|
-
import { homedir as homedir2, userInfo } from "os";
|
|
167
|
-
import { join as join6 } from "path";
|
|
168
|
-
|
|
169
167
|
// ../../packages/adapters/src/runtime/image-transfer.ts
|
|
170
168
|
import { Transform } from "stream";
|
|
171
169
|
|
|
@@ -12668,6 +12666,13 @@ var SftpDestinationImpl = class {
|
|
|
12668
12666
|
registerDestination("sftp", (row) => new SftpDestinationImpl(row));
|
|
12669
12667
|
registerDestination("openship_server", (row) => new SftpDestinationImpl(row));
|
|
12670
12668
|
|
|
12669
|
+
// src/lib/compose.ts
|
|
12670
|
+
import { spawnSync as spawnSync3 } from "child_process";
|
|
12671
|
+
import { randomBytes as randomBytes5 } from "crypto";
|
|
12672
|
+
import { chmodSync, existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
12673
|
+
import { homedir as homedir2, userInfo } from "os";
|
|
12674
|
+
import { join as join6 } from "path";
|
|
12675
|
+
|
|
12671
12676
|
// src/lib/paths.ts
|
|
12672
12677
|
import { homedir } from "os";
|
|
12673
12678
|
import { join as join3, resolve as resolve2 } from "path";
|
|
@@ -13229,7 +13234,7 @@ function renderEnv(opts, host, cfg) {
|
|
|
13229
13234
|
// (hides the local row). Written explicitly so the policy is visible in .env.
|
|
13230
13235
|
`OPENSHIP_HOST_CONTROL=${cfg.hostControl ? "true" : "false"}`,
|
|
13231
13236
|
`OPENSHIP_IMAGE_REGISTRY=${cfg.registry}`,
|
|
13232
|
-
`OPENSHIP_VERSION=${opts.version || (true ? "0.4.
|
|
13237
|
+
`OPENSHIP_VERSION=${opts.version || (true ? "0.4.7" : "latest")}`,
|
|
13233
13238
|
`POSTGRES_PASSWORD=${keepSecret(prev, "POSTGRES_PASSWORD")}`,
|
|
13234
13239
|
`BETTER_AUTH_SECRET=${keepSecret(prev, "BETTER_AUTH_SECRET")}`,
|
|
13235
13240
|
`INTERNAL_TOKEN=${keepSecret(prev, "INTERNAL_TOKEN")}`,
|
|
@@ -13435,11 +13440,17 @@ async function importMigratedSites(apiPort, sites, certPems) {
|
|
|
13435
13440
|
`Migrated NONE of the ${sites.length} site${sites.length === 1 ? "" : "s"} \u2014 Openship holds :80/:443 and ${sites.length === 1 ? "that hostname is" : "those hostnames are"} NOT being served.`
|
|
13436
13441
|
);
|
|
13437
13442
|
for (const w2 of warnings.slice(0, 8)) console.log(chalk.red(` \u2022 ${w2}`));
|
|
13443
|
+
const edgeLog = await edgeCrashReason(new LocalExecutor());
|
|
13444
|
+
if (edgeLog) {
|
|
13445
|
+
console.log(chalk.red(`
|
|
13446
|
+
The edge container is not running. Its log says:`));
|
|
13447
|
+
console.log(chalk.red(` ${edgeLog}`));
|
|
13448
|
+
}
|
|
13438
13449
|
console.log(
|
|
13439
13450
|
chalk.yellow(
|
|
13440
13451
|
`
|
|
13441
13452
|
Retry the import with \`openship up\` once the cause above is fixed, or put your
|
|
13442
|
-
previous proxy back: docker stop
|
|
13453
|
+
previous proxy back: docker stop ${EDGE_CONTAINER_NAME} && sudo systemctl enable --now nginx
|
|
13443
13454
|
`
|
|
13444
13455
|
)
|
|
13445
13456
|
);
|
|
@@ -59,6 +59,36 @@ function sq(value) {
|
|
|
59
59
|
function isOurEdgeContainer(name, image) {
|
|
60
60
|
return /openship-edge/i.test(`${name ?? ""} ${image ?? ""}`);
|
|
61
61
|
}
|
|
62
|
+
async function edgeIsServing(executor, port = 80) {
|
|
63
|
+
const running = await tryExec(
|
|
64
|
+
executor,
|
|
65
|
+
`docker inspect -f '{{.State.Running}}' ${sq(EDGE_CONTAINER_NAME)} 2>/dev/null`
|
|
66
|
+
);
|
|
67
|
+
if ((running ?? "").trim() !== "true") return false;
|
|
68
|
+
const probe = await tryExec(
|
|
69
|
+
executor,
|
|
70
|
+
containerShell(`wget -q -O /dev/null -T 3 http://127.0.0.1:${port}/ >/dev/null 2>&1; echo $?`)
|
|
71
|
+
);
|
|
72
|
+
const code = (probe ?? "").trim().split("\n").pop() ?? "1";
|
|
73
|
+
return code === "0" || code === "8";
|
|
74
|
+
}
|
|
75
|
+
function containerShell(command) {
|
|
76
|
+
return `docker exec ${sq(EDGE_CONTAINER_NAME)} sh -c ${sq(command)}`;
|
|
77
|
+
}
|
|
78
|
+
async function edgeCrashReason(executor) {
|
|
79
|
+
const logs = await tryExec(
|
|
80
|
+
executor,
|
|
81
|
+
`docker logs --tail 40 ${sq(EDGE_CONTAINER_NAME)} 2>&1`
|
|
82
|
+
);
|
|
83
|
+
return logs ? edgeFailureReason(logs) : null;
|
|
84
|
+
}
|
|
85
|
+
function edgeFailureReason(containerLog) {
|
|
86
|
+
const lines = containerLog.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
87
|
+
const emerg = lines.find((l) => l.includes("[emerg]"));
|
|
88
|
+
if (emerg) return emerg.replace(/^.*\[emerg\]\s*\d*#\d*:\s*/, "");
|
|
89
|
+
return lines.at(-1) ?? null;
|
|
90
|
+
}
|
|
91
|
+
var EDGE_CONTAINER_NAME = "openship-edge";
|
|
62
92
|
async function ourEdgeContainerRunning(executor) {
|
|
63
93
|
return Boolean(await resolveOurEdgeContainer(executor));
|
|
64
94
|
}
|
|
@@ -238,6 +268,10 @@ export {
|
|
|
238
268
|
classifyProxy,
|
|
239
269
|
sq,
|
|
240
270
|
isOurEdgeContainer,
|
|
271
|
+
edgeIsServing,
|
|
272
|
+
edgeCrashReason,
|
|
273
|
+
edgeFailureReason,
|
|
274
|
+
EDGE_CONTAINER_NAME,
|
|
241
275
|
ourEdgeContainerRunning,
|
|
242
276
|
invalidateEdgeContainer,
|
|
243
277
|
resolveOurEdgeContainer,
|
|
@@ -207,6 +207,8 @@ var DEFAULT_REMOTE_DOCKER_SOCKET_PATH = "/var/run/docker.sock";
|
|
|
207
207
|
var resolvedDockerSocketPathCache = /* @__PURE__ */ new WeakMap();
|
|
208
208
|
var DOCKER_DIAL_STDIO_COMMAND = "docker system dial-stdio";
|
|
209
209
|
var STREAMLOCAL_PROBE_TIMEOUT_MS = 8e3;
|
|
210
|
+
var STREAMLOCAL_DATA_VERIFY_TIMEOUT_MS = 3e3;
|
|
211
|
+
var VERIFY_BUFFER_CAP_BYTES = 8 * 1024 * 1024;
|
|
210
212
|
function toSshConfig(opts) {
|
|
211
213
|
return {
|
|
212
214
|
host: opts.host ?? "",
|
|
@@ -304,13 +306,107 @@ async function openStreamlocalUpstream(opts) {
|
|
|
304
306
|
throw error;
|
|
305
307
|
}
|
|
306
308
|
}
|
|
309
|
+
function pipeThrough(client, upstream) {
|
|
310
|
+
const teardown = () => {
|
|
311
|
+
client.destroy();
|
|
312
|
+
upstream.destroy();
|
|
313
|
+
};
|
|
314
|
+
client.on("error", teardown);
|
|
315
|
+
upstream.on("error", teardown);
|
|
316
|
+
client.once("close", () => upstream.destroy());
|
|
317
|
+
upstream.once("close", () => client.destroy());
|
|
318
|
+
client.pipe(upstream);
|
|
319
|
+
upstream.pipe(client);
|
|
320
|
+
}
|
|
321
|
+
function awaitFirstByte(upstream, ms) {
|
|
322
|
+
return new Promise((resolve) => {
|
|
323
|
+
const finish = (chunk) => {
|
|
324
|
+
clearTimeout(timer);
|
|
325
|
+
upstream.removeListener("data", onData);
|
|
326
|
+
upstream.removeListener("error", onFail);
|
|
327
|
+
upstream.removeListener("close", onFail);
|
|
328
|
+
resolve(chunk);
|
|
329
|
+
};
|
|
330
|
+
const onData = (chunk) => finish(chunk);
|
|
331
|
+
const onFail = () => finish(null);
|
|
332
|
+
const timer = setTimeout(() => finish(null), ms);
|
|
333
|
+
upstream.on("data", onData);
|
|
334
|
+
upstream.once("error", onFail);
|
|
335
|
+
upstream.once("close", onFail);
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
function captureClient(client) {
|
|
339
|
+
const chunks = [];
|
|
340
|
+
let bytes = 0;
|
|
341
|
+
let overflowed = false;
|
|
342
|
+
let closed = false;
|
|
343
|
+
let live = null;
|
|
344
|
+
const onData = (chunk) => {
|
|
345
|
+
if (live) live.write(chunk);
|
|
346
|
+
if (overflowed) return;
|
|
347
|
+
chunks.push(chunk);
|
|
348
|
+
bytes += chunk.length;
|
|
349
|
+
if (bytes >= VERIFY_BUFFER_CAP_BYTES) {
|
|
350
|
+
overflowed = true;
|
|
351
|
+
client.pause();
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
const onGone = () => {
|
|
355
|
+
closed = true;
|
|
356
|
+
};
|
|
357
|
+
client.on("data", onData);
|
|
358
|
+
client.once("error", onGone);
|
|
359
|
+
client.once("close", onGone);
|
|
360
|
+
const detach = () => {
|
|
361
|
+
client.removeListener("data", onData);
|
|
362
|
+
client.removeListener("error", onGone);
|
|
363
|
+
client.removeListener("close", onGone);
|
|
364
|
+
};
|
|
365
|
+
return {
|
|
366
|
+
get closed() {
|
|
367
|
+
return closed;
|
|
368
|
+
},
|
|
369
|
+
get overflowed() {
|
|
370
|
+
return overflowed;
|
|
371
|
+
},
|
|
372
|
+
/** Replay everything buffered so far onto `upstream` and forward the rest
|
|
373
|
+
* live. Safe to call again on a different upstream (the fallback): the full
|
|
374
|
+
* buffer is retained until `commit`, so the replay is complete each time. */
|
|
375
|
+
feed(upstream) {
|
|
376
|
+
for (const chunk of chunks) upstream.write(chunk);
|
|
377
|
+
live = upstream;
|
|
378
|
+
},
|
|
379
|
+
/** Stop forwarding to the current upstream (keep buffering) — used before
|
|
380
|
+
* destroying a dead channel so late bytes never hit a torn-down stream. */
|
|
381
|
+
stop() {
|
|
382
|
+
live = null;
|
|
383
|
+
},
|
|
384
|
+
/** Terminal: detach and hand the socket to the (already-fed) `upstream` via a
|
|
385
|
+
* bidi pipe, or destroy it if the client already went away. */
|
|
386
|
+
commit(upstream) {
|
|
387
|
+
detach();
|
|
388
|
+
chunks.length = 0;
|
|
389
|
+
if (closed) {
|
|
390
|
+
upstream.destroy();
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
pipeThrough(client, upstream);
|
|
394
|
+
},
|
|
395
|
+
/** Terminal: no usable upstream — surface the error to dockerode. */
|
|
396
|
+
fail(err) {
|
|
397
|
+
detach();
|
|
398
|
+
client.destroy(err instanceof Error ? err : new Error(String(err)));
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
}
|
|
307
402
|
function createDockerSshBridge(opts) {
|
|
308
403
|
const clients = /* @__PURE__ */ new Set();
|
|
309
404
|
let upstreamMode = null;
|
|
310
405
|
let modeDecision = null;
|
|
311
406
|
let dialClient = null;
|
|
312
|
-
|
|
313
|
-
|
|
407
|
+
let pooledUnreliable = false;
|
|
408
|
+
const openDialStdioUpstream = async (forceEphemeral = false) => {
|
|
409
|
+
if (!forceEphemeral && opts.executor?.openDockerDialStdio) {
|
|
314
410
|
const stream = await opts.executor.openDockerDialStdio();
|
|
315
411
|
stream.once(
|
|
316
412
|
"error",
|
|
@@ -373,29 +469,57 @@ function createDockerSshBridge(opts) {
|
|
|
373
469
|
modeDecision ??= decideMode().then((mode) => upstreamMode = mode);
|
|
374
470
|
return modeDecision;
|
|
375
471
|
};
|
|
376
|
-
const
|
|
377
|
-
|
|
378
|
-
|
|
472
|
+
const downgradeToDialStdio = async (capture, reason) => {
|
|
473
|
+
console.warn(
|
|
474
|
+
`[docker-ssh] streamlocal unusable (${opts.host ?? "?"}): ${reason} \u2014 downgrading this bridge to dial-stdio (fresh connection) and replaying the buffered request.`
|
|
475
|
+
);
|
|
476
|
+
upstreamMode = "dialstdio";
|
|
477
|
+
pooledUnreliable = true;
|
|
478
|
+
const upstream = await openDialStdioUpstream(true);
|
|
479
|
+
capture.feed(upstream);
|
|
480
|
+
capture.commit(upstream);
|
|
481
|
+
};
|
|
482
|
+
const bridgeClient = async (client) => {
|
|
483
|
+
const capture = captureClient(client);
|
|
484
|
+
try {
|
|
485
|
+
const mode = await ensureMode();
|
|
486
|
+
if (mode === "dialstdio") {
|
|
487
|
+
const upstream = await openDialStdioUpstream(pooledUnreliable);
|
|
488
|
+
capture.feed(upstream);
|
|
489
|
+
capture.commit(upstream);
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
let channel;
|
|
493
|
+
try {
|
|
494
|
+
channel = await withTimeout(
|
|
495
|
+
openStreamlocalUpstream(opts),
|
|
496
|
+
STREAMLOCAL_DATA_VERIFY_TIMEOUT_MS,
|
|
497
|
+
`channel open timed out after ${STREAMLOCAL_DATA_VERIFY_TIMEOUT_MS / 1e3}s`
|
|
498
|
+
);
|
|
499
|
+
} catch (err) {
|
|
500
|
+
await downgradeToDialStdio(capture, safeErrorMessage(err));
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
capture.feed(channel);
|
|
504
|
+
const firstByte = capture.overflowed ? null : await awaitFirstByte(channel, STREAMLOCAL_DATA_VERIFY_TIMEOUT_MS);
|
|
505
|
+
if (capture.overflowed || firstByte) {
|
|
506
|
+
if (firstByte) client.write(firstByte);
|
|
507
|
+
capture.commit(channel);
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
capture.stop();
|
|
511
|
+
channel.destroy();
|
|
512
|
+
await downgradeToDialStdio(capture, "channel opened but no data flowed");
|
|
513
|
+
} catch (err) {
|
|
514
|
+
console.warn(`[docker-ssh] bridge client failed (${opts.host ?? "?"}): ${safeErrorMessage(err)}`);
|
|
515
|
+
capture.fail(err);
|
|
516
|
+
}
|
|
379
517
|
};
|
|
380
518
|
const server = net2.createServer((client) => {
|
|
381
519
|
clients.add(client);
|
|
382
520
|
client.setNoDelay(true);
|
|
383
521
|
client.once("close", () => clients.delete(client));
|
|
384
|
-
|
|
385
|
-
const teardown = () => {
|
|
386
|
-
client.destroy();
|
|
387
|
-
upstream.destroy();
|
|
388
|
-
};
|
|
389
|
-
client.on("error", teardown);
|
|
390
|
-
upstream.on("error", teardown);
|
|
391
|
-
client.once("close", () => upstream.destroy());
|
|
392
|
-
upstream.once("close", () => client.destroy());
|
|
393
|
-
client.pipe(upstream);
|
|
394
|
-
upstream.pipe(client);
|
|
395
|
-
}).catch((error) => {
|
|
396
|
-
console.warn(`[docker-ssh] bridge upstream open failed: ${safeErrorMessage(error)}`);
|
|
397
|
-
client.destroy(error instanceof Error ? error : new Error(String(error)));
|
|
398
|
-
});
|
|
522
|
+
void bridgeClient(client);
|
|
399
523
|
});
|
|
400
524
|
return {
|
|
401
525
|
start: () => new Promise((resolve, reject) => {
|
|
@@ -22,8 +22,10 @@ import {
|
|
|
22
22
|
sq
|
|
23
23
|
} from "./chunk-FPRHYBY2.js";
|
|
24
24
|
import {
|
|
25
|
+
EDGE_CONTAINER_NAME,
|
|
25
26
|
EdgeConflictError,
|
|
26
27
|
EdgeMigrateRequested,
|
|
28
|
+
edgeFailureReason,
|
|
27
29
|
freeEdgeTargets,
|
|
28
30
|
invalidateEdgeContainer,
|
|
29
31
|
ourLuaOnHost,
|
|
@@ -31,7 +33,7 @@ import {
|
|
|
31
33
|
resolveOurEdgeContainer,
|
|
32
34
|
sq as sq2,
|
|
33
35
|
stopTargetsForStatus
|
|
34
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-R5BHFFAV.js";
|
|
35
37
|
import {
|
|
36
38
|
waitForPortListening
|
|
37
39
|
} from "./chunk-ILFETZOM.js";
|
|
@@ -976,6 +978,8 @@ async function readJournal(executor) {
|
|
|
976
978
|
}
|
|
977
979
|
async function rollback(executor, journal, onLog) {
|
|
978
980
|
onLog(log("Rolling back \u2014 restoring the previous proxy...", "warn"));
|
|
981
|
+
await tryExec2(executor, `docker update --restart=no ${sq2(EDGE_CONTAINER_NAME)} 2>/dev/null || true`);
|
|
982
|
+
await tryExec2(executor, `docker stop ${sq2(EDGE_CONTAINER_NAME)} 2>/dev/null || true`);
|
|
979
983
|
await tryExec2(
|
|
980
984
|
executor,
|
|
981
985
|
"systemctl disable --now openresty 2>/dev/null || systemctl stop openresty 2>/dev/null || true; systemctl reset-failed openresty 2>/dev/null || true"
|
|
@@ -1000,6 +1004,24 @@ async function rollback(executor, journal, onLog) {
|
|
|
1000
1004
|
onLog(log(`Could not restore process ${p.pid} \u2014 no command captured.`, "warn"));
|
|
1001
1005
|
}
|
|
1002
1006
|
}
|
|
1007
|
+
const restored = await portIsServed(executor, 80);
|
|
1008
|
+
if (!restored) {
|
|
1009
|
+
onLog(
|
|
1010
|
+
log(
|
|
1011
|
+
"Nothing is listening on :80 after the restore \u2014 the box is NOT serving. Start your proxy by hand (e.g. `systemctl start nginx`, or `docker start <name>`).",
|
|
1012
|
+
"error"
|
|
1013
|
+
)
|
|
1014
|
+
);
|
|
1015
|
+
}
|
|
1016
|
+
return restored;
|
|
1017
|
+
}
|
|
1018
|
+
async function portIsServed(executor, port) {
|
|
1019
|
+
const hex = port.toString(16).toUpperCase().padStart(4, "0");
|
|
1020
|
+
const out = await tryExec2(
|
|
1021
|
+
executor,
|
|
1022
|
+
`(command -v ss >/dev/null 2>&1 && ss -ltn 2>/dev/null | grep -qE ':${port}[[:space:]]' && echo yes) || (grep -qiE '^[[:space:]]*[0-9]+:[[:space:]]*[0-9A-F]{8}:${hex}[[:space:]]+[0-9A-F]{8}:0000[[:space:]]+0A' /proc/net/tcp 2>/dev/null && echo yes) || true`
|
|
1023
|
+
);
|
|
1024
|
+
return (out ?? "").includes("yes");
|
|
1003
1025
|
}
|
|
1004
1026
|
async function beginEdgeTakeover(executor, status, onLog) {
|
|
1005
1027
|
await writeJournal(executor, await buildJournal(executor, status));
|
|
@@ -1008,9 +1030,9 @@ async function beginEdgeTakeover(executor, status, onLog) {
|
|
|
1008
1030
|
async function rollbackEdgeTakeover(executor, onLog) {
|
|
1009
1031
|
const journal = await readJournal(executor);
|
|
1010
1032
|
if (!journal || journal.completed) return false;
|
|
1011
|
-
await rollback(executor, journal, onLog);
|
|
1033
|
+
const restored = await rollback(executor, journal, onLog);
|
|
1012
1034
|
await clearJournal(executor);
|
|
1013
|
-
return
|
|
1035
|
+
return restored;
|
|
1014
1036
|
}
|
|
1015
1037
|
async function completeEdgeTakeover(executor) {
|
|
1016
1038
|
const journal = await readJournal(executor);
|
|
@@ -1802,7 +1824,6 @@ async function ensureEdgeClear(executor, config, onLog) {
|
|
|
1802
1824
|
}
|
|
1803
1825
|
|
|
1804
1826
|
// ../../packages/adapters/src/system/proxy/ensure-container-edge.ts
|
|
1805
|
-
var EDGE_CONTAINER_NAME = "openship-edge";
|
|
1806
1827
|
function log4(message, level = "info") {
|
|
1807
1828
|
return { timestamp: (/* @__PURE__ */ new Date()).toISOString(), message, level };
|
|
1808
1829
|
}
|
|
@@ -1821,7 +1842,7 @@ async function runningImage(executor, container) {
|
|
|
1821
1842
|
return out.trim() || null;
|
|
1822
1843
|
}
|
|
1823
1844
|
async function containerEdgeProvider(executor, container, opts) {
|
|
1824
|
-
const { NginxProvider: Provider } = await import("./nginx-
|
|
1845
|
+
const { NginxProvider: Provider } = await import("./nginx-XWJAOGS4.js");
|
|
1825
1846
|
return new Provider({
|
|
1826
1847
|
...opts,
|
|
1827
1848
|
// Vhosts go to the BIND-MOUNTED HOST dir (so every host-side reader — the
|
|
@@ -1836,7 +1857,7 @@ async function containerEdgeProvider(executor, container, opts) {
|
|
|
1836
1857
|
}
|
|
1837
1858
|
async function localContainerEdgeProvider(container, opts) {
|
|
1838
1859
|
const { DockerEdgeExecutor } = await import("./docker-edge-executor-VHW3JPJS.js");
|
|
1839
|
-
const { NginxProvider: Provider } = await import("./nginx-
|
|
1860
|
+
const { NginxProvider: Provider } = await import("./nginx-XWJAOGS4.js");
|
|
1840
1861
|
return new Provider({
|
|
1841
1862
|
...opts,
|
|
1842
1863
|
paths: OPENRESTY_DEFAULT_PATHS,
|
|
@@ -1893,6 +1914,35 @@ async function swapEdgeImage(executor, container, from, to, opts) {
|
|
|
1893
1914
|
onLog(log4(`Rollback to ${from} ALSO failed \u2014 the edge is down on this server.`, "error"));
|
|
1894
1915
|
return { swapped: false, edgeDown: true };
|
|
1895
1916
|
}
|
|
1917
|
+
async function listDir(executor, dir) {
|
|
1918
|
+
const out = await executor.exec(`ls -1 ${sq(dir)} 2>/dev/null || true`).catch(() => "");
|
|
1919
|
+
return new Set(
|
|
1920
|
+
out.split("\n").map((l) => l.trim()).filter(Boolean)
|
|
1921
|
+
);
|
|
1922
|
+
}
|
|
1923
|
+
async function sanitizeCarriedVhosts(executor, sitesDir, onLog) {
|
|
1924
|
+
const script = [
|
|
1925
|
+
`for f in ${sq(sitesDir)}/*.conf; do`,
|
|
1926
|
+
` [ -f "$f" ] || continue;`,
|
|
1927
|
+
// A real server_name is anything that isn't the `_` wildcard.
|
|
1928
|
+
` if ! grep -qE '^[[:space:]]*server_name[[:space:]]+[^_;[:space:]]' "$f"; then`,
|
|
1929
|
+
` echo "dropped-catchall $f"; rm -f "$f"; continue;`,
|
|
1930
|
+
` fi;`,
|
|
1931
|
+
` if grep -qE '[[:space:]]default_server' "$f"; then`,
|
|
1932
|
+
` sed -i -E 's/([[:space:]]listen[^;]*)[[:space:]]+default_server/\\1/g' "$f" && echo "unset-default $f";`,
|
|
1933
|
+
` fi;`,
|
|
1934
|
+
`done`
|
|
1935
|
+
].join(" ");
|
|
1936
|
+
const out = await executor.exec(script).catch(() => "");
|
|
1937
|
+
for (const line of out.split("\n").map((l) => l.trim()).filter(Boolean)) {
|
|
1938
|
+
const [action, file] = [line.slice(0, line.indexOf(" ")), line.slice(line.indexOf(" ") + 1)];
|
|
1939
|
+
if (action === "dropped-catchall") {
|
|
1940
|
+
onLog(log4(`Dropped the bare edge's catch-all ${file} \u2014 the edge image provides it.`, "warn"));
|
|
1941
|
+
} else if (action === "unset-default") {
|
|
1942
|
+
onLog(log4(`Removed default_server from ${file} \u2014 the edge image owns it.`, "warn"));
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1896
1946
|
async function ensureContainerEdge(executor, opts) {
|
|
1897
1947
|
const { onLog } = opts;
|
|
1898
1948
|
const container = opts.container?.trim() || EDGE_CONTAINER_NAME;
|
|
@@ -1931,16 +1981,28 @@ async function ensureContainerEdge(executor, opts) {
|
|
|
1931
1981
|
});
|
|
1932
1982
|
}
|
|
1933
1983
|
const sitesTarget = EDGE_HOST_PATHS.sitesDir;
|
|
1984
|
+
let beforeCarry = null;
|
|
1934
1985
|
if (bareWasOurs) {
|
|
1935
1986
|
const barePaths = await detectOpenRestyPaths(executor).catch(() => OPENRESTY_DEFAULT_PATHS);
|
|
1936
1987
|
if (barePaths.sitesDir !== sitesTarget && await executor.exists(barePaths.sitesDir)) {
|
|
1937
1988
|
onLog(log4(`Carrying vhosts from ${barePaths.sitesDir}...`));
|
|
1989
|
+
beforeCarry = await listDir(executor, sitesTarget);
|
|
1938
1990
|
await executor.exec(`cp -a ${sq(`${barePaths.sitesDir}/.`)} ${sq(`${sitesTarget}/`)} 2>/dev/null || true`).catch(() => {
|
|
1939
1991
|
});
|
|
1992
|
+
await sanitizeCarriedVhosts(executor, sitesTarget, onLog);
|
|
1940
1993
|
}
|
|
1941
1994
|
}
|
|
1942
1995
|
const restoreBare = async () => {
|
|
1943
1996
|
if (!bareWasOurs) return;
|
|
1997
|
+
if (beforeCarry) {
|
|
1998
|
+
const now = await listDir(executor, sitesTarget);
|
|
1999
|
+
const added = [...now].filter((name) => !beforeCarry.has(name));
|
|
2000
|
+
if (added.length > 0) {
|
|
2001
|
+
await executor.exec(`rm -f ${added.map((n) => sq(`${sitesTarget}/${n}`)).join(" ")}`).catch(() => {
|
|
2002
|
+
});
|
|
2003
|
+
onLog(log4(`Removed ${added.length} carried vhost(s) so the next edge start is clean.`, "warn"));
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
1944
2006
|
onLog(log4("Restoring the host OpenResty edge...", "warn"));
|
|
1945
2007
|
await executor.exec("systemctl enable --now openresty 2>/dev/null || true").catch(() => {
|
|
1946
2008
|
});
|
|
@@ -1982,7 +2044,8 @@ ${logs}`, "error"));
|
|
|
1982
2044
|
});
|
|
1983
2045
|
invalidateEdgeContainer(executor);
|
|
1984
2046
|
await restoreBare();
|
|
1985
|
-
|
|
2047
|
+
const reason = edgeFailureReason(logs);
|
|
2048
|
+
throw new Error(`Edge container setup failed: ${reason ? `${reason} (${msg})` : msg}`);
|
|
1986
2049
|
}
|
|
1987
2050
|
}
|
|
1988
2051
|
|
|
@@ -2000,7 +2063,6 @@ export {
|
|
|
2000
2063
|
rollbackEdgeTakeover,
|
|
2001
2064
|
completeEdgeTakeover,
|
|
2002
2065
|
recoverInterruptedTakeover,
|
|
2003
|
-
EDGE_CONTAINER_NAME,
|
|
2004
2066
|
setDefaultEdgeImage,
|
|
2005
2067
|
resolveEdgeImage,
|
|
2006
2068
|
dockerAvailable,
|
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
CloudRuntime,
|
|
7
7
|
PAGE_CONTAINER_PREFIX,
|
|
8
8
|
provisionCloudWorkspace
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-XFCDYZUQ.js";
|
|
10
|
+
import "./chunk-UXWAVM4C.js";
|
|
11
11
|
import "./chunk-V6AN6XLZ.js";
|
|
12
12
|
import "./chunk-MZ2WEHHY.js";
|
|
13
13
|
import "./chunk-L2VOGB2X.js";
|
|
@@ -18,7 +18,7 @@ import "./chunk-RPHRPFEH.js";
|
|
|
18
18
|
import "./chunk-TYVME3XD.js";
|
|
19
19
|
import "./chunk-FXTBHTWY.js";
|
|
20
20
|
import "./chunk-FPRHYBY2.js";
|
|
21
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-R5BHFFAV.js";
|
|
22
22
|
import "./chunk-ILFETZOM.js";
|
|
23
23
|
import "./chunk-VFINNTUL.js";
|
|
24
24
|
import "./chunk-6APULWSU.js";
|
|
@@ -3,9 +3,13 @@
|
|
|
3
3
|
import { createRequire as __ospCreateRequire } from "node:module";
|
|
4
4
|
const require = __ospCreateRequire(import.meta.url);
|
|
5
5
|
import {
|
|
6
|
+
EDGE_CONTAINER_NAME,
|
|
6
7
|
EdgeConflictError,
|
|
7
8
|
EdgeMigrateRequested,
|
|
8
9
|
classifyProxy,
|
|
10
|
+
edgeCrashReason,
|
|
11
|
+
edgeFailureReason,
|
|
12
|
+
edgeIsServing,
|
|
9
13
|
freeEdgeTargets,
|
|
10
14
|
invalidateEdgeContainer,
|
|
11
15
|
isOurEdgeContainer,
|
|
@@ -15,15 +19,19 @@ import {
|
|
|
15
19
|
resolveOurEdgeContainer,
|
|
16
20
|
sq,
|
|
17
21
|
stopTargetsForStatus
|
|
18
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-R5BHFFAV.js";
|
|
19
23
|
import "./chunk-ILFETZOM.js";
|
|
20
24
|
import "./chunk-VFINNTUL.js";
|
|
21
25
|
import "./chunk-6APULWSU.js";
|
|
22
26
|
import "./chunk-KI2EY3WB.js";
|
|
23
27
|
export {
|
|
28
|
+
EDGE_CONTAINER_NAME,
|
|
24
29
|
EdgeConflictError,
|
|
25
30
|
EdgeMigrateRequested,
|
|
26
31
|
classifyProxy,
|
|
32
|
+
edgeCrashReason,
|
|
33
|
+
edgeFailureReason,
|
|
34
|
+
edgeIsServing,
|
|
27
35
|
freeEdgeTargets,
|
|
28
36
|
invalidateEdgeContainer,
|
|
29
37
|
isOurEdgeContainer,
|
|
@@ -4,7 +4,7 @@ import { createRequire as __ospCreateRequire } from "node:module";
|
|
|
4
4
|
const require = __ospCreateRequire(import.meta.url);
|
|
5
5
|
import {
|
|
6
6
|
DockerRuntime
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-SJIFLLX4.js";
|
|
8
8
|
import "./chunk-V6AN6XLZ.js";
|
|
9
9
|
import "./chunk-4Z5QO7N6.js";
|
|
10
10
|
import "./chunk-OXWDY22G.js";
|
|
@@ -5,7 +5,7 @@ const require = __ospCreateRequire(import.meta.url);
|
|
|
5
5
|
import {
|
|
6
6
|
importMigratedSites,
|
|
7
7
|
waitForApiHealth
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-IMBD5PZ5.js";
|
|
9
9
|
import "./chunk-FRNAR33O.js";
|
|
10
10
|
import "./chunk-EI575GHN.js";
|
|
11
11
|
import "./chunk-6APIPIJY.js";
|
|
@@ -14,15 +14,15 @@ import "./chunk-OWED2GRM.js";
|
|
|
14
14
|
import "./chunk-VWPEKOH6.js";
|
|
15
15
|
import "./chunk-W73X43R7.js";
|
|
16
16
|
import "./chunk-TGIINPVM.js";
|
|
17
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-XFCDYZUQ.js";
|
|
18
18
|
import "./chunk-AVIB7CT7.js";
|
|
19
19
|
import "./chunk-5MZ624VX.js";
|
|
20
20
|
import "./chunk-Q2CIRAOK.js";
|
|
21
|
-
import "./chunk-
|
|
22
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-IPYPMI3S.js";
|
|
22
|
+
import "./chunk-UXWAVM4C.js";
|
|
23
23
|
import "./chunk-O6ZZF52V.js";
|
|
24
24
|
import "./chunk-JYGD5WSN.js";
|
|
25
|
-
import "./chunk-
|
|
25
|
+
import "./chunk-SJIFLLX4.js";
|
|
26
26
|
import "./chunk-V6AN6XLZ.js";
|
|
27
27
|
import "./chunk-VDMQJHPI.js";
|
|
28
28
|
import "./chunk-MZ2WEHHY.js";
|
|
@@ -34,7 +34,7 @@ import "./chunk-RPHRPFEH.js";
|
|
|
34
34
|
import "./chunk-TYVME3XD.js";
|
|
35
35
|
import "./chunk-FXTBHTWY.js";
|
|
36
36
|
import "./chunk-FPRHYBY2.js";
|
|
37
|
-
import "./chunk-
|
|
37
|
+
import "./chunk-R5BHFFAV.js";
|
|
38
38
|
import "./chunk-ILFETZOM.js";
|
|
39
39
|
import "./chunk-VFINNTUL.js";
|
|
40
40
|
import "./chunk-6APULWSU.js";
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
import { createRequire as __ospCreateRequire } from "node:module";
|
|
4
4
|
const require = __ospCreateRequire(import.meta.url);
|
|
5
5
|
import {
|
|
6
|
-
EDGE_CONTAINER_NAME,
|
|
7
6
|
buildEdgeRunCommand,
|
|
8
7
|
containerEdgeProvider,
|
|
9
8
|
dockerAvailable,
|
|
@@ -11,18 +10,17 @@ import {
|
|
|
11
10
|
localContainerEdgeProvider,
|
|
12
11
|
resolveEdgeImage,
|
|
13
12
|
setDefaultEdgeImage
|
|
14
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-UXWAVM4C.js";
|
|
15
14
|
import "./chunk-L2VOGB2X.js";
|
|
16
15
|
import "./chunk-RPHRPFEH.js";
|
|
17
16
|
import "./chunk-FXTBHTWY.js";
|
|
18
17
|
import "./chunk-FPRHYBY2.js";
|
|
19
|
-
import "./chunk-
|
|
18
|
+
import "./chunk-R5BHFFAV.js";
|
|
20
19
|
import "./chunk-ILFETZOM.js";
|
|
21
20
|
import "./chunk-VFINNTUL.js";
|
|
22
21
|
import "./chunk-6APULWSU.js";
|
|
23
22
|
import "./chunk-KI2EY3WB.js";
|
|
24
23
|
export {
|
|
25
|
-
EDGE_CONTAINER_NAME,
|
|
26
24
|
buildEdgeRunCommand,
|
|
27
25
|
containerEdgeProvider,
|
|
28
26
|
dockerAvailable,
|
package/dist/index.js
CHANGED
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
remoteSha,
|
|
26
26
|
shortSha,
|
|
27
27
|
sourceBuildDir
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-IMBD5PZ5.js";
|
|
29
29
|
import "./chunk-FRNAR33O.js";
|
|
30
30
|
import "./chunk-EI575GHN.js";
|
|
31
31
|
import "./chunk-6APIPIJY.js";
|
|
@@ -34,11 +34,11 @@ import "./chunk-OWED2GRM.js";
|
|
|
34
34
|
import "./chunk-VWPEKOH6.js";
|
|
35
35
|
import "./chunk-W73X43R7.js";
|
|
36
36
|
import "./chunk-TGIINPVM.js";
|
|
37
|
-
import "./chunk-
|
|
37
|
+
import "./chunk-XFCDYZUQ.js";
|
|
38
38
|
import "./chunk-AVIB7CT7.js";
|
|
39
39
|
import "./chunk-5MZ624VX.js";
|
|
40
40
|
import "./chunk-Q2CIRAOK.js";
|
|
41
|
-
import "./chunk-
|
|
41
|
+
import "./chunk-IPYPMI3S.js";
|
|
42
42
|
import {
|
|
43
43
|
beginEdgeTakeover,
|
|
44
44
|
collectProxyCerts,
|
|
@@ -51,10 +51,10 @@ import {
|
|
|
51
51
|
recoverInterruptedTakeover,
|
|
52
52
|
rollbackEdgeTakeover,
|
|
53
53
|
scanImportableSites
|
|
54
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-UXWAVM4C.js";
|
|
55
55
|
import "./chunk-O6ZZF52V.js";
|
|
56
56
|
import "./chunk-JYGD5WSN.js";
|
|
57
|
-
import "./chunk-
|
|
57
|
+
import "./chunk-SJIFLLX4.js";
|
|
58
58
|
import "./chunk-V6AN6XLZ.js";
|
|
59
59
|
import "./chunk-VDMQJHPI.js";
|
|
60
60
|
import "./chunk-MZ2WEHHY.js";
|
|
@@ -69,8 +69,10 @@ import {
|
|
|
69
69
|
import "./chunk-FXTBHTWY.js";
|
|
70
70
|
import "./chunk-FPRHYBY2.js";
|
|
71
71
|
import {
|
|
72
|
+
edgeCrashReason,
|
|
73
|
+
edgeIsServing,
|
|
72
74
|
ourEdgeContainerRunning
|
|
73
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-R5BHFFAV.js";
|
|
74
76
|
import "./chunk-ILFETZOM.js";
|
|
75
77
|
import "./chunk-VFINNTUL.js";
|
|
76
78
|
import {
|
|
@@ -1722,6 +1724,27 @@ async function runCompose(opts) {
|
|
|
1722
1724
|
process.exit(1);
|
|
1723
1725
|
}
|
|
1724
1726
|
spinner5.succeed("Openship is running via Docker Compose.");
|
|
1727
|
+
if (edgePlan.action && !await edgeIsServing(new LocalExecutor())) {
|
|
1728
|
+
const reason = await edgeCrashReason(new LocalExecutor());
|
|
1729
|
+
console.error(
|
|
1730
|
+
chalk6.red(`
|
|
1731
|
+
Openship's edge is not serving :80${reason ? ` \u2014 ${reason}` : "."}`)
|
|
1732
|
+
);
|
|
1733
|
+
const restored = await rollbackHostEdge();
|
|
1734
|
+
console.error(
|
|
1735
|
+
restored ? chalk6.yellow(
|
|
1736
|
+
` Your previous proxy has been restarted \u2014 the box is serving again, on it.
|
|
1737
|
+
Nothing was migrated. Fix the cause above, then re-run \`openship up\`.
|
|
1738
|
+
`
|
|
1739
|
+
) : chalk6.red(
|
|
1740
|
+
` AND your previous proxy could NOT be restarted automatically \u2014 the box is
|
|
1741
|
+
serving nothing right now. Start it by hand:
|
|
1742
|
+
docker stop openship-edge && sudo systemctl enable --now nginx
|
|
1743
|
+
`
|
|
1744
|
+
)
|
|
1745
|
+
);
|
|
1746
|
+
process.exit(1);
|
|
1747
|
+
}
|
|
1725
1748
|
let importedOk = true;
|
|
1726
1749
|
if (edgePlan.action === "migrate" && edgePlan.sites?.length) {
|
|
1727
1750
|
const outcome = await importMigratedSites(res.apiPort, edgePlan.sites, edgePlan.certPems);
|
|
@@ -1973,7 +1996,7 @@ async function runForeground(opts, source) {
|
|
|
1973
1996
|
const uiSpinner = ora("Preparing the dashboard\u2026").start();
|
|
1974
1997
|
try {
|
|
1975
1998
|
const bundle = await ensureDashboard({
|
|
1976
|
-
tag: source ? "local" : opts.uiVersion || `v${"0.4.
|
|
1999
|
+
tag: source ? "local" : opts.uiVersion || `v${"0.4.7"}`,
|
|
1977
2000
|
onProgress: (received, total) => {
|
|
1978
2001
|
if (total) {
|
|
1979
2002
|
uiSpinner.text = `Downloading dashboard\u2026 ${Math.round(received / total * 100)}%`;
|
|
@@ -6582,7 +6605,7 @@ function detectPackageManager2(override) {
|
|
|
6582
6605
|
var updateCommand = new Command26("update").description("Update the Openship CLI + bundled server to the latest release").option("--check", "Only report the current + latest version; don't install").option("--via <manager>", "Package manager to update with: bun | npm").option("--rebuild", "From-source installs: rebuild even if already at the remote tip").action(async (opts) => {
|
|
6583
6606
|
const source = readSourceInstall();
|
|
6584
6607
|
if (source) return runSourceUpdate(source, opts);
|
|
6585
|
-
const current = "0.4.
|
|
6608
|
+
const current = "0.4.7";
|
|
6586
6609
|
let latest;
|
|
6587
6610
|
try {
|
|
6588
6611
|
latest = (await resolveLatestTag()).replace(/^v/, "");
|
|
@@ -7149,7 +7172,7 @@ async function runWizard() {
|
|
|
7149
7172
|
}
|
|
7150
7173
|
}
|
|
7151
7174
|
}
|
|
7152
|
-
const uiTag = `v${"0.4.
|
|
7175
|
+
const uiTag = `v${"0.4.7"}`;
|
|
7153
7176
|
if (method === "bare") {
|
|
7154
7177
|
const dl = spinner4();
|
|
7155
7178
|
dl.start("Pulling the Openship dist from GitHub");
|
|
@@ -7217,7 +7240,7 @@ async function runWizard() {
|
|
|
7217
7240
|
const up = composeUp({
|
|
7218
7241
|
publicUrl,
|
|
7219
7242
|
trustProxy: behindProxy,
|
|
7220
|
-
version: "0.4.
|
|
7243
|
+
version: "0.4.7",
|
|
7221
7244
|
noHostControl: !allowHostControl
|
|
7222
7245
|
});
|
|
7223
7246
|
if (!up.ok) {
|
|
@@ -7554,7 +7577,7 @@ ${chalk20.dim("Dashboard".padEnd(11))}${dashUrl}
|
|
|
7554
7577
|
|
|
7555
7578
|
// src/index.ts
|
|
7556
7579
|
var program = new Command28();
|
|
7557
|
-
program.name("openship").description("Openship CLI \u2014 install, run, and manage Openship from your terminal").version("0.4.
|
|
7580
|
+
program.name("openship").description("Openship CLI \u2014 install, run, and manage Openship from your terminal").version("0.4.7").option("--json", "Machine-readable JSON output (stdout data only)").hook("preAction", (thisCommand) => {
|
|
7558
7581
|
if (thisCommand.opts().json) setJsonMode(true);
|
|
7559
7582
|
}).action(async () => {
|
|
7560
7583
|
const installed = serviceStatus().installed || readInstallMethod() === "compose";
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
summarizeCertbotFailure
|
|
11
11
|
} from "./chunk-FXTBHTWY.js";
|
|
12
12
|
import "./chunk-FPRHYBY2.js";
|
|
13
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-R5BHFFAV.js";
|
|
14
14
|
import "./chunk-ILFETZOM.js";
|
|
15
15
|
import "./chunk-VFINNTUL.js";
|
|
16
16
|
import "./chunk-6APULWSU.js";
|
package/dist/server/index.js
CHANGED
|
@@ -21998,13 +21998,102 @@ async function openStreamlocalUpstream(opts) {
|
|
|
21998
21998
|
throw error51;
|
|
21999
21999
|
}
|
|
22000
22000
|
}
|
|
22001
|
+
function pipeThrough(client, upstream) {
|
|
22002
|
+
const teardown = () => {
|
|
22003
|
+
client.destroy();
|
|
22004
|
+
upstream.destroy();
|
|
22005
|
+
};
|
|
22006
|
+
client.on("error", teardown);
|
|
22007
|
+
upstream.on("error", teardown);
|
|
22008
|
+
client.once("close", () => upstream.destroy());
|
|
22009
|
+
upstream.once("close", () => client.destroy());
|
|
22010
|
+
client.pipe(upstream);
|
|
22011
|
+
upstream.pipe(client);
|
|
22012
|
+
}
|
|
22013
|
+
function awaitFirstByte(upstream, ms) {
|
|
22014
|
+
return new Promise((resolve2) => {
|
|
22015
|
+
const finish = (chunk) => {
|
|
22016
|
+
clearTimeout(timer);
|
|
22017
|
+
upstream.removeListener("data", onData);
|
|
22018
|
+
upstream.removeListener("error", onFail);
|
|
22019
|
+
upstream.removeListener("close", onFail);
|
|
22020
|
+
resolve2(chunk);
|
|
22021
|
+
};
|
|
22022
|
+
const onData = (chunk) => finish(chunk);
|
|
22023
|
+
const onFail = () => finish(null);
|
|
22024
|
+
const timer = setTimeout(() => finish(null), ms);
|
|
22025
|
+
upstream.on("data", onData);
|
|
22026
|
+
upstream.once("error", onFail);
|
|
22027
|
+
upstream.once("close", onFail);
|
|
22028
|
+
});
|
|
22029
|
+
}
|
|
22030
|
+
function captureClient(client) {
|
|
22031
|
+
const chunks = [];
|
|
22032
|
+
let bytes = 0;
|
|
22033
|
+
let overflowed = false;
|
|
22034
|
+
let closed = false;
|
|
22035
|
+
let live = null;
|
|
22036
|
+
const onData = (chunk) => {
|
|
22037
|
+
if (live)
|
|
22038
|
+
live.write(chunk);
|
|
22039
|
+
if (overflowed)
|
|
22040
|
+
return;
|
|
22041
|
+
chunks.push(chunk);
|
|
22042
|
+
bytes += chunk.length;
|
|
22043
|
+
if (bytes >= VERIFY_BUFFER_CAP_BYTES) {
|
|
22044
|
+
overflowed = true;
|
|
22045
|
+
client.pause();
|
|
22046
|
+
}
|
|
22047
|
+
};
|
|
22048
|
+
const onGone = () => {
|
|
22049
|
+
closed = true;
|
|
22050
|
+
};
|
|
22051
|
+
client.on("data", onData);
|
|
22052
|
+
client.once("error", onGone);
|
|
22053
|
+
client.once("close", onGone);
|
|
22054
|
+
const detach = () => {
|
|
22055
|
+
client.removeListener("data", onData);
|
|
22056
|
+
client.removeListener("error", onGone);
|
|
22057
|
+
client.removeListener("close", onGone);
|
|
22058
|
+
};
|
|
22059
|
+
return {
|
|
22060
|
+
get closed() {
|
|
22061
|
+
return closed;
|
|
22062
|
+
},
|
|
22063
|
+
get overflowed() {
|
|
22064
|
+
return overflowed;
|
|
22065
|
+
},
|
|
22066
|
+
feed(upstream) {
|
|
22067
|
+
for (const chunk of chunks)
|
|
22068
|
+
upstream.write(chunk);
|
|
22069
|
+
live = upstream;
|
|
22070
|
+
},
|
|
22071
|
+
stop() {
|
|
22072
|
+
live = null;
|
|
22073
|
+
},
|
|
22074
|
+
commit(upstream) {
|
|
22075
|
+
detach();
|
|
22076
|
+
chunks.length = 0;
|
|
22077
|
+
if (closed) {
|
|
22078
|
+
upstream.destroy();
|
|
22079
|
+
return;
|
|
22080
|
+
}
|
|
22081
|
+
pipeThrough(client, upstream);
|
|
22082
|
+
},
|
|
22083
|
+
fail(err2) {
|
|
22084
|
+
detach();
|
|
22085
|
+
client.destroy(err2 instanceof Error ? err2 : new Error(String(err2)));
|
|
22086
|
+
}
|
|
22087
|
+
};
|
|
22088
|
+
}
|
|
22001
22089
|
function createDockerSshBridge(opts) {
|
|
22002
22090
|
const clients = new Set;
|
|
22003
22091
|
let upstreamMode = null;
|
|
22004
22092
|
let modeDecision = null;
|
|
22005
22093
|
let dialClient = null;
|
|
22006
|
-
|
|
22007
|
-
|
|
22094
|
+
let pooledUnreliable = false;
|
|
22095
|
+
const openDialStdioUpstream = async (forceEphemeral = false) => {
|
|
22096
|
+
if (!forceEphemeral && opts.executor?.openDockerDialStdio) {
|
|
22008
22097
|
const stream = await opts.executor.openDockerDialStdio();
|
|
22009
22098
|
stream.once("error", (e) => console.warn(`[docker-ssh] dial-stdio channel error: ${safeErrorMessage(e)}`));
|
|
22010
22099
|
return stream;
|
|
@@ -22061,29 +22150,52 @@ Host: localhost\r
|
|
|
22061
22150
|
modeDecision ??= decideMode().then((mode) => upstreamMode = mode);
|
|
22062
22151
|
return modeDecision;
|
|
22063
22152
|
};
|
|
22064
|
-
const
|
|
22065
|
-
|
|
22066
|
-
|
|
22153
|
+
const downgradeToDialStdio = async (capture, reason) => {
|
|
22154
|
+
console.warn(`[docker-ssh] streamlocal unusable (${opts.host ?? "?"}): ${reason} — ` + "downgrading this bridge to dial-stdio (fresh connection) and replaying the buffered request.");
|
|
22155
|
+
upstreamMode = "dialstdio";
|
|
22156
|
+
pooledUnreliable = true;
|
|
22157
|
+
const upstream = await openDialStdioUpstream(true);
|
|
22158
|
+
capture.feed(upstream);
|
|
22159
|
+
capture.commit(upstream);
|
|
22160
|
+
};
|
|
22161
|
+
const bridgeClient = async (client) => {
|
|
22162
|
+
const capture = captureClient(client);
|
|
22163
|
+
try {
|
|
22164
|
+
const mode = await ensureMode();
|
|
22165
|
+
if (mode === "dialstdio") {
|
|
22166
|
+
const upstream = await openDialStdioUpstream(pooledUnreliable);
|
|
22167
|
+
capture.feed(upstream);
|
|
22168
|
+
capture.commit(upstream);
|
|
22169
|
+
return;
|
|
22170
|
+
}
|
|
22171
|
+
let channel;
|
|
22172
|
+
try {
|
|
22173
|
+
channel = await withTimeout(openStreamlocalUpstream(opts), STREAMLOCAL_DATA_VERIFY_TIMEOUT_MS, `channel open timed out after ${STREAMLOCAL_DATA_VERIFY_TIMEOUT_MS / 1000}s`);
|
|
22174
|
+
} catch (err2) {
|
|
22175
|
+
await downgradeToDialStdio(capture, safeErrorMessage(err2));
|
|
22176
|
+
return;
|
|
22177
|
+
}
|
|
22178
|
+
capture.feed(channel);
|
|
22179
|
+
const firstByte = capture.overflowed ? null : await awaitFirstByte(channel, STREAMLOCAL_DATA_VERIFY_TIMEOUT_MS);
|
|
22180
|
+
if (capture.overflowed || firstByte) {
|
|
22181
|
+
if (firstByte)
|
|
22182
|
+
client.write(firstByte);
|
|
22183
|
+
capture.commit(channel);
|
|
22184
|
+
return;
|
|
22185
|
+
}
|
|
22186
|
+
capture.stop();
|
|
22187
|
+
channel.destroy();
|
|
22188
|
+
await downgradeToDialStdio(capture, "channel opened but no data flowed");
|
|
22189
|
+
} catch (err2) {
|
|
22190
|
+
console.warn(`[docker-ssh] bridge client failed (${opts.host ?? "?"}): ${safeErrorMessage(err2)}`);
|
|
22191
|
+
capture.fail(err2);
|
|
22192
|
+
}
|
|
22067
22193
|
};
|
|
22068
22194
|
const server = net2.createServer((client) => {
|
|
22069
22195
|
clients.add(client);
|
|
22070
22196
|
client.setNoDelay(true);
|
|
22071
22197
|
client.once("close", () => clients.delete(client));
|
|
22072
|
-
|
|
22073
|
-
const teardown = () => {
|
|
22074
|
-
client.destroy();
|
|
22075
|
-
upstream.destroy();
|
|
22076
|
-
};
|
|
22077
|
-
client.on("error", teardown);
|
|
22078
|
-
upstream.on("error", teardown);
|
|
22079
|
-
client.once("close", () => upstream.destroy());
|
|
22080
|
-
upstream.once("close", () => client.destroy());
|
|
22081
|
-
client.pipe(upstream);
|
|
22082
|
-
upstream.pipe(client);
|
|
22083
|
-
}).catch((error51) => {
|
|
22084
|
-
console.warn(`[docker-ssh] bridge upstream open failed: ${safeErrorMessage(error51)}`);
|
|
22085
|
-
client.destroy(error51 instanceof Error ? error51 : new Error(String(error51)));
|
|
22086
|
-
});
|
|
22198
|
+
bridgeClient(client);
|
|
22087
22199
|
});
|
|
22088
22200
|
return {
|
|
22089
22201
|
start: () => new Promise((resolve2, reject) => {
|
|
@@ -22113,11 +22225,12 @@ Host: localhost\r
|
|
|
22113
22225
|
}
|
|
22114
22226
|
};
|
|
22115
22227
|
}
|
|
22116
|
-
var DEFAULT_REMOTE_DOCKER_SOCKET_PATH = "/var/run/docker.sock", resolvedDockerSocketPathCache, DOCKER_DIAL_STDIO_COMMAND = "docker system dial-stdio", STREAMLOCAL_PROBE_TIMEOUT_MS = 8000, DOCKER_SOCKET_DISCOVERY_SCRIPT;
|
|
22228
|
+
var DEFAULT_REMOTE_DOCKER_SOCKET_PATH = "/var/run/docker.sock", resolvedDockerSocketPathCache, DOCKER_DIAL_STDIO_COMMAND = "docker system dial-stdio", STREAMLOCAL_PROBE_TIMEOUT_MS = 8000, STREAMLOCAL_DATA_VERIFY_TIMEOUT_MS = 3000, VERIFY_BUFFER_CAP_BYTES, DOCKER_SOCKET_DISCOVERY_SCRIPT;
|
|
22117
22229
|
var init_docker_ssh_agent = __esm(() => {
|
|
22118
22230
|
init_ssh_client();
|
|
22119
22231
|
init_src();
|
|
22120
22232
|
resolvedDockerSocketPathCache = new WeakMap;
|
|
22233
|
+
VERIFY_BUFFER_CAP_BYTES = 8 * 1024 * 1024;
|
|
22121
22234
|
DOCKER_SOCKET_DISCOVERY_SCRIPT = [
|
|
22122
22235
|
"set -eu",
|
|
22123
22236
|
'uid="$(id -u 2>/dev/null || printf 0)"',
|
|
@@ -29262,9 +29375,13 @@ __export(exports_detect, {
|
|
|
29262
29375
|
isOurEdgeContainer: () => isOurEdgeContainer,
|
|
29263
29376
|
invalidateEdgeContainer: () => invalidateEdgeContainer,
|
|
29264
29377
|
freeEdgeTargets: () => freeEdgeTargets,
|
|
29378
|
+
edgeIsServing: () => edgeIsServing,
|
|
29379
|
+
edgeFailureReason: () => edgeFailureReason,
|
|
29380
|
+
edgeCrashReason: () => edgeCrashReason,
|
|
29265
29381
|
classifyProxy: () => classifyProxy,
|
|
29266
29382
|
EdgeMigrateRequested: () => EdgeMigrateRequested,
|
|
29267
|
-
EdgeConflictError: () => EdgeConflictError
|
|
29383
|
+
EdgeConflictError: () => EdgeConflictError,
|
|
29384
|
+
EDGE_CONTAINER_NAME: () => EDGE_CONTAINER_NAME
|
|
29268
29385
|
});
|
|
29269
29386
|
async function tryExec3(executor, command) {
|
|
29270
29387
|
try {
|
|
@@ -29297,6 +29414,30 @@ function sq3(value) {
|
|
|
29297
29414
|
function isOurEdgeContainer(name2, image) {
|
|
29298
29415
|
return /openship-edge/i.test(`${name2 ?? ""} ${image ?? ""}`);
|
|
29299
29416
|
}
|
|
29417
|
+
async function edgeIsServing(executor, port = 80) {
|
|
29418
|
+
const running = await tryExec3(executor, `docker inspect -f '{{.State.Running}}' ${sq3(EDGE_CONTAINER_NAME)} 2>/dev/null`);
|
|
29419
|
+
if ((running ?? "").trim() !== "true")
|
|
29420
|
+
return false;
|
|
29421
|
+
const probe = await tryExec3(executor, containerShell(`wget -q -O /dev/null -T 3 http://127.0.0.1:${port}/ >/dev/null 2>&1; echo $?`));
|
|
29422
|
+
const code = (probe ?? "").trim().split(`
|
|
29423
|
+
`).pop() ?? "1";
|
|
29424
|
+
return code === "0" || code === "8";
|
|
29425
|
+
}
|
|
29426
|
+
function containerShell(command) {
|
|
29427
|
+
return `docker exec ${sq3(EDGE_CONTAINER_NAME)} sh -c ${sq3(command)}`;
|
|
29428
|
+
}
|
|
29429
|
+
async function edgeCrashReason(executor) {
|
|
29430
|
+
const logs = await tryExec3(executor, `docker logs --tail 40 ${sq3(EDGE_CONTAINER_NAME)} 2>&1`);
|
|
29431
|
+
return logs ? edgeFailureReason(logs) : null;
|
|
29432
|
+
}
|
|
29433
|
+
function edgeFailureReason(containerLog) {
|
|
29434
|
+
const lines = containerLog.split(`
|
|
29435
|
+
`).map((l) => l.trim()).filter(Boolean);
|
|
29436
|
+
const emerg = lines.find((l) => l.includes("[emerg]"));
|
|
29437
|
+
if (emerg)
|
|
29438
|
+
return emerg.replace(/^.*\[emerg\]\s*\d*#\d*:\s*/, "");
|
|
29439
|
+
return lines.at(-1) ?? null;
|
|
29440
|
+
}
|
|
29300
29441
|
async function ourEdgeContainerRunning(executor) {
|
|
29301
29442
|
return Boolean(await resolveOurEdgeContainer(executor));
|
|
29302
29443
|
}
|
|
@@ -29466,7 +29607,7 @@ async function freeEdgeTargets(executor, targets, onLog) {
|
|
|
29466
29607
|
}
|
|
29467
29608
|
await new Promise((r) => setTimeout(r, 1000));
|
|
29468
29609
|
}
|
|
29469
|
-
var EDGE_PORTS, EdgeConflictError, EdgeMigrateRequested, EDGE_CONTAINER_TTL_MS = 20000, edgeContainerMemo, edgeMemoGeneration = 0, WORKER_RE, MASTER_RE;
|
|
29610
|
+
var EDGE_PORTS, EdgeConflictError, EdgeMigrateRequested, EDGE_CONTAINER_NAME = "openship-edge", EDGE_CONTAINER_TTL_MS = 20000, edgeContainerMemo, edgeMemoGeneration = 0, WORKER_RE, MASTER_RE;
|
|
29470
29611
|
var init_detect2 = __esm(() => {
|
|
29471
29612
|
init_src();
|
|
29472
29613
|
init_port_conflict();
|
|
@@ -31222,6 +31363,8 @@ async function readJournal(executor) {
|
|
|
31222
31363
|
}
|
|
31223
31364
|
async function rollback(executor, journal, onLog) {
|
|
31224
31365
|
onLog(log("Rolling back — restoring the previous proxy...", "warn"));
|
|
31366
|
+
await tryExec7(executor, `docker update --restart=no ${sq3(EDGE_CONTAINER_NAME)} 2>/dev/null || true`);
|
|
31367
|
+
await tryExec7(executor, `docker stop ${sq3(EDGE_CONTAINER_NAME)} 2>/dev/null || true`);
|
|
31225
31368
|
await tryExec7(executor, "systemctl disable --now openresty 2>/dev/null || systemctl stop openresty 2>/dev/null || true; " + "systemctl reset-failed openresty 2>/dev/null || true");
|
|
31226
31369
|
for (const u of journal.units) {
|
|
31227
31370
|
await tryExec7(executor, u.wasEnabled ? `systemctl enable --now ${sq3(u.unit)} 2>/dev/null || true` : `systemctl start ${sq3(u.unit)} 2>/dev/null || true`);
|
|
@@ -31237,6 +31380,16 @@ async function rollback(executor, journal, onLog) {
|
|
|
31237
31380
|
onLog(log(`Could not restore process ${p.pid} — no command captured.`, "warn"));
|
|
31238
31381
|
}
|
|
31239
31382
|
}
|
|
31383
|
+
const restored = await portIsServed(executor, 80);
|
|
31384
|
+
if (!restored) {
|
|
31385
|
+
onLog(log("Nothing is listening on :80 after the restore — the box is NOT serving. " + "Start your proxy by hand (e.g. `systemctl start nginx`, or `docker start <name>`).", "error"));
|
|
31386
|
+
}
|
|
31387
|
+
return restored;
|
|
31388
|
+
}
|
|
31389
|
+
async function portIsServed(executor, port) {
|
|
31390
|
+
const hex3 = port.toString(16).toUpperCase().padStart(4, "0");
|
|
31391
|
+
const out2 = await tryExec7(executor, `(command -v ss >/dev/null 2>&1 && ss -ltn 2>/dev/null | grep -qE ':${port}[[:space:]]' && echo yes) || ` + `(grep -qiE '^[[:space:]]*[0-9]+:[[:space:]]*[0-9A-F]{8}:${hex3}[[:space:]]+[0-9A-F]{8}:0000[[:space:]]+0A' /proc/net/tcp 2>/dev/null && echo yes) || true`);
|
|
31392
|
+
return (out2 ?? "").includes("yes");
|
|
31240
31393
|
}
|
|
31241
31394
|
async function beginEdgeTakeover(executor, status, onLog) {
|
|
31242
31395
|
await writeJournal(executor, await buildJournal(executor, status));
|
|
@@ -31246,9 +31399,9 @@ async function rollbackEdgeTakeover(executor, onLog) {
|
|
|
31246
31399
|
const journal = await readJournal(executor);
|
|
31247
31400
|
if (!journal || journal.completed)
|
|
31248
31401
|
return false;
|
|
31249
|
-
await rollback(executor, journal, onLog);
|
|
31402
|
+
const restored = await rollback(executor, journal, onLog);
|
|
31250
31403
|
await clearJournal(executor);
|
|
31251
|
-
return
|
|
31404
|
+
return restored;
|
|
31252
31405
|
}
|
|
31253
31406
|
async function completeEdgeTakeover(executor) {
|
|
31254
31407
|
const journal = await readJournal(executor);
|
|
@@ -32152,8 +32305,7 @@ __export(exports_ensure_container_edge, {
|
|
|
32152
32305
|
ensureContainerEdge: () => ensureContainerEdge,
|
|
32153
32306
|
dockerAvailable: () => dockerAvailable,
|
|
32154
32307
|
containerEdgeProvider: () => containerEdgeProvider,
|
|
32155
|
-
buildEdgeRunCommand: () => buildEdgeRunCommand
|
|
32156
|
-
EDGE_CONTAINER_NAME: () => EDGE_CONTAINER_NAME
|
|
32308
|
+
buildEdgeRunCommand: () => buildEdgeRunCommand
|
|
32157
32309
|
});
|
|
32158
32310
|
function log2(message, level = "info") {
|
|
32159
32311
|
return { timestamp: new Date().toISOString(), message, level };
|
|
@@ -32231,6 +32383,34 @@ async function swapEdgeImage(executor, container, from, to, opts) {
|
|
|
32231
32383
|
onLog(log2(`Rollback to ${from} ALSO failed — the edge is down on this server.`, "error"));
|
|
32232
32384
|
return { swapped: false, edgeDown: true };
|
|
32233
32385
|
}
|
|
32386
|
+
async function listDir(executor, dir) {
|
|
32387
|
+
const out2 = await executor.exec(`ls -1 ${sq2(dir)} 2>/dev/null || true`).catch(() => "");
|
|
32388
|
+
return new Set(out2.split(`
|
|
32389
|
+
`).map((l) => l.trim()).filter(Boolean));
|
|
32390
|
+
}
|
|
32391
|
+
async function sanitizeCarriedVhosts(executor, sitesDir, onLog) {
|
|
32392
|
+
const script = [
|
|
32393
|
+
`for f in ${sq2(sitesDir)}/*.conf; do`,
|
|
32394
|
+
` [ -f "$f" ] || continue;`,
|
|
32395
|
+
` if ! grep -qE '^[[:space:]]*server_name[[:space:]]+[^_;[:space:]]' "$f"; then`,
|
|
32396
|
+
` echo "dropped-catchall $f"; rm -f "$f"; continue;`,
|
|
32397
|
+
` fi;`,
|
|
32398
|
+
` if grep -qE '[[:space:]]default_server' "$f"; then`,
|
|
32399
|
+
` sed -i -E 's/([[:space:]]listen[^;]*)[[:space:]]+default_server/\\1/g' "$f" && echo "unset-default $f";`,
|
|
32400
|
+
` fi;`,
|
|
32401
|
+
`done`
|
|
32402
|
+
].join(" ");
|
|
32403
|
+
const out2 = await executor.exec(script).catch(() => "");
|
|
32404
|
+
for (const line of out2.split(`
|
|
32405
|
+
`).map((l) => l.trim()).filter(Boolean)) {
|
|
32406
|
+
const [action, file3] = [line.slice(0, line.indexOf(" ")), line.slice(line.indexOf(" ") + 1)];
|
|
32407
|
+
if (action === "dropped-catchall") {
|
|
32408
|
+
onLog(log2(`Dropped the bare edge's catch-all ${file3} — the edge image provides it.`, "warn"));
|
|
32409
|
+
} else if (action === "unset-default") {
|
|
32410
|
+
onLog(log2(`Removed default_server from ${file3} — the edge image owns it.`, "warn"));
|
|
32411
|
+
}
|
|
32412
|
+
}
|
|
32413
|
+
}
|
|
32234
32414
|
async function ensureContainerEdge(executor, opts) {
|
|
32235
32415
|
const { onLog } = opts;
|
|
32236
32416
|
const container = opts.container?.trim() || EDGE_CONTAINER_NAME;
|
|
@@ -32264,16 +32444,27 @@ async function ensureContainerEdge(executor, opts) {
|
|
|
32264
32444
|
await executor.exec(`mkdir -p ${sq2(mount.host)}`).catch(() => {});
|
|
32265
32445
|
}
|
|
32266
32446
|
const sitesTarget = EDGE_HOST_PATHS.sitesDir;
|
|
32447
|
+
let beforeCarry = null;
|
|
32267
32448
|
if (bareWasOurs) {
|
|
32268
32449
|
const barePaths = await detectOpenRestyPaths(executor).catch(() => OPENRESTY_DEFAULT_PATHS);
|
|
32269
32450
|
if (barePaths.sitesDir !== sitesTarget && await executor.exists(barePaths.sitesDir)) {
|
|
32270
32451
|
onLog(log2(`Carrying vhosts from ${barePaths.sitesDir}...`));
|
|
32452
|
+
beforeCarry = await listDir(executor, sitesTarget);
|
|
32271
32453
|
await executor.exec(`cp -a ${sq2(`${barePaths.sitesDir}/.`)} ${sq2(`${sitesTarget}/`)} 2>/dev/null || true`).catch(() => {});
|
|
32454
|
+
await sanitizeCarriedVhosts(executor, sitesTarget, onLog);
|
|
32272
32455
|
}
|
|
32273
32456
|
}
|
|
32274
32457
|
const restoreBare = async () => {
|
|
32275
32458
|
if (!bareWasOurs)
|
|
32276
32459
|
return;
|
|
32460
|
+
if (beforeCarry) {
|
|
32461
|
+
const now2 = await listDir(executor, sitesTarget);
|
|
32462
|
+
const added = [...now2].filter((name2) => !beforeCarry.has(name2));
|
|
32463
|
+
if (added.length > 0) {
|
|
32464
|
+
await executor.exec(`rm -f ${added.map((n) => sq2(`${sitesTarget}/${n}`)).join(" ")}`).catch(() => {});
|
|
32465
|
+
onLog(log2(`Removed ${added.length} carried vhost(s) so the next edge start is clean.`, "warn"));
|
|
32466
|
+
}
|
|
32467
|
+
}
|
|
32277
32468
|
onLog(log2("Restoring the host OpenResty edge...", "warn"));
|
|
32278
32469
|
await executor.exec("systemctl enable --now openresty 2>/dev/null || true").catch(() => {});
|
|
32279
32470
|
};
|
|
@@ -32309,10 +32500,11 @@ ${logs}`, "error"));
|
|
|
32309
32500
|
await executor.exec(`docker rm -f ${sq2(container)} 2>/dev/null || true`).catch(() => {});
|
|
32310
32501
|
invalidateEdgeContainer(executor);
|
|
32311
32502
|
await restoreBare();
|
|
32312
|
-
|
|
32503
|
+
const reason = edgeFailureReason(logs);
|
|
32504
|
+
throw new Error(`Edge container setup failed: ${reason ? `${reason} (${msg})` : msg}`);
|
|
32313
32505
|
}
|
|
32314
32506
|
}
|
|
32315
|
-
var
|
|
32507
|
+
var injectedDefaultImage;
|
|
32316
32508
|
var init_ensure_container_edge = __esm(() => {
|
|
32317
32509
|
init_src();
|
|
32318
32510
|
init_openresty_lua();
|
|
@@ -32417,9 +32609,9 @@ async function runEdgeTakeover(executor, opts, onLog) {
|
|
|
32417
32609
|
edgeImage: opts.edgeImage
|
|
32418
32610
|
});
|
|
32419
32611
|
if (!install.success) {
|
|
32420
|
-
await rollback(executor, journal, onLog);
|
|
32612
|
+
const rolledBack = await rollback(executor, journal, onLog);
|
|
32421
32613
|
await clearJournal(executor);
|
|
32422
|
-
return { ok: false, rolledBack
|
|
32614
|
+
return { ok: false, rolledBack, registered: [], warnings: [install.error ?? "Edge install failed"] };
|
|
32423
32615
|
}
|
|
32424
32616
|
try {
|
|
32425
32617
|
const container = await resolveOurEdgeContainer(executor, { fresh: true });
|
|
@@ -32454,9 +32646,11 @@ async function runEdgeTakeover(executor, opts, onLog) {
|
|
|
32454
32646
|
return { ok: true, rolledBack: false, registered, warnings };
|
|
32455
32647
|
} catch (err2) {
|
|
32456
32648
|
warnings.push(safeErrorMessage(err2));
|
|
32457
|
-
await rollback(executor, journal, onLog);
|
|
32649
|
+
const rolledBack = await rollback(executor, journal, onLog);
|
|
32458
32650
|
await clearJournal(executor);
|
|
32459
|
-
|
|
32651
|
+
if (!rolledBack)
|
|
32652
|
+
warnings.push("The previous proxy did NOT come back — nothing is serving :80.");
|
|
32653
|
+
return { ok: false, rolledBack, registered: [], warnings };
|
|
32460
32654
|
}
|
|
32461
32655
|
}
|
|
32462
32656
|
var DOMAIN_RE2;
|
|
@@ -80000,7 +80194,6 @@ __export(exports_src, {
|
|
|
80000
80194
|
EdgeConflictError: () => EdgeConflictError,
|
|
80001
80195
|
EDGE_HOST_STATE_DIR: () => EDGE_HOST_STATE_DIR,
|
|
80002
80196
|
EDGE_HOST_PATHS: () => EDGE_HOST_PATHS,
|
|
80003
|
-
EDGE_CONTAINER_NAME: () => EDGE_CONTAINER_NAME,
|
|
80004
80197
|
EDGE_CONTAINER_MOUNTS: () => EDGE_CONTAINER_MOUNTS,
|
|
80005
80198
|
DockerRuntime: () => DockerRuntime,
|
|
80006
80199
|
DockerEdgeExecutor: () => DockerEdgeExecutor,
|
|
@@ -191353,7 +191546,7 @@ var package_default;
|
|
|
191353
191546
|
var init_package = __esm(() => {
|
|
191354
191547
|
package_default = {
|
|
191355
191548
|
name: "@repo/api",
|
|
191356
|
-
version: "0.4.
|
|
191549
|
+
version: "0.4.7",
|
|
191357
191550
|
license: "Apache-2.0",
|
|
191358
191551
|
private: true,
|
|
191359
191552
|
type: "module",
|
|
@@ -4,13 +4,13 @@ import { createRequire as __ospCreateRequire } from "node:module";
|
|
|
4
4
|
const require = __ospCreateRequire(import.meta.url);
|
|
5
5
|
import {
|
|
6
6
|
SystemManager
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-IPYPMI3S.js";
|
|
8
|
+
import "./chunk-UXWAVM4C.js";
|
|
9
9
|
import "./chunk-L2VOGB2X.js";
|
|
10
10
|
import "./chunk-RPHRPFEH.js";
|
|
11
11
|
import "./chunk-FXTBHTWY.js";
|
|
12
12
|
import "./chunk-FPRHYBY2.js";
|
|
13
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-R5BHFFAV.js";
|
|
14
14
|
import "./chunk-ILFETZOM.js";
|
|
15
15
|
import "./chunk-VFINNTUL.js";
|
|
16
16
|
import "./chunk-6APULWSU.js";
|