openship 0.4.6 → 0.4.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.
@@ -30,7 +30,7 @@ import {
30
30
  } from "./chunk-6APULWSU.js";
31
31
 
32
32
  // ../../packages/adapters/src/system/executor.ts
33
- import { readFileSync } from "fs";
33
+ import { existsSync, readFileSync } from "fs";
34
34
 
35
35
  // ../../packages/adapters/src/system/ssh-executor.ts
36
36
  import { createReadStream } from "fs";
@@ -1508,6 +1508,18 @@ function createExecutor(ssh) {
1508
1508
  function hostControlDisabled() {
1509
1509
  return process.env.OPENSHIP_HOST_CONTROL?.trim().toLowerCase() === "false";
1510
1510
  }
1511
+ function runningInContainer() {
1512
+ if (process.env.OPENSHIP_IN_CONTAINER?.trim().toLowerCase() === "true") return true;
1513
+ try {
1514
+ if (existsSync("/.dockerenv")) return true;
1515
+ } catch {
1516
+ }
1517
+ try {
1518
+ return /\b(docker|containerd|podman|kubepods)\b/.test(readFileSync("/proc/1/cgroup", "utf8"));
1519
+ } catch {
1520
+ return false;
1521
+ }
1522
+ }
1511
1523
  function createHostExecutor() {
1512
1524
  if (hostControlDisabled()) {
1513
1525
  throw new Error(
@@ -1515,7 +1527,14 @@ function createHostExecutor() {
1515
1527
  );
1516
1528
  }
1517
1529
  const host = process.env.OPENSHIP_HOST_SSH_HOST?.trim();
1518
- if (!host) return localExecutor;
1530
+ if (!host) {
1531
+ if (runningInContainer()) {
1532
+ throw new Error(
1533
+ "This operation targets the HOST machine, but no host channel is configured (OPENSHIP_HOST_SSH_HOST is unset) and Openship is running in a container \u2014 so it would have run inside the container instead, against the wrong filesystem. Re-run `openship up` to provision the host channel."
1534
+ );
1535
+ }
1536
+ return localExecutor;
1537
+ }
1519
1538
  const keyPath = process.env.OPENSHIP_HOST_SSH_KEY?.trim();
1520
1539
  const portRaw = Number(process.env.OPENSHIP_HOST_SSH_PORT || "22");
1521
1540
  const port = Number.isInteger(portRaw) && portRaw > 0 && portRaw < 65536 ? portRaw : 22;
@@ -6,19 +6,19 @@ import {
6
6
  CloudRuntime,
7
7
  PAGE_CONTAINER_PREFIX,
8
8
  provisionCloudWorkspace
9
- } from "./chunk-5FNIWBFI.js";
10
- import "./chunk-SQ77DZOI.js";
9
+ } from "./chunk-5NYUCONN.js";
10
+ import "./chunk-SLTYVHU7.js";
11
11
  import "./chunk-V6AN6XLZ.js";
12
12
  import "./chunk-MZ2WEHHY.js";
13
13
  import "./chunk-L2VOGB2X.js";
14
14
  import "./chunk-4Z5QO7N6.js";
15
- import "./chunk-4TJC4JZQ.js";
15
+ import "./chunk-XPPZ7B2J.js";
16
16
  import "./chunk-OXWDY22G.js";
17
17
  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-FQGJZ2HS.js";
21
+ import "./chunk-2D3I5G6P.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
+ edgeIsBroken,
9
13
  freeEdgeTargets,
10
14
  invalidateEdgeContainer,
11
15
  isOurEdgeContainer,
@@ -13,17 +17,22 @@ import {
13
17
  ourLuaOnHost,
14
18
  probeEdge,
15
19
  resolveOurEdgeContainer,
20
+ sanitizeEdgeVhosts,
16
21
  sq,
17
22
  stopTargetsForStatus
18
- } from "./chunk-FQGJZ2HS.js";
23
+ } from "./chunk-2D3I5G6P.js";
19
24
  import "./chunk-ILFETZOM.js";
20
25
  import "./chunk-VFINNTUL.js";
21
26
  import "./chunk-6APULWSU.js";
22
27
  import "./chunk-KI2EY3WB.js";
23
28
  export {
29
+ EDGE_CONTAINER_NAME,
24
30
  EdgeConflictError,
25
31
  EdgeMigrateRequested,
26
32
  classifyProxy,
33
+ edgeCrashReason,
34
+ edgeFailureReason,
35
+ edgeIsBroken,
27
36
  freeEdgeTargets,
28
37
  invalidateEdgeContainer,
29
38
  isOurEdgeContainer,
@@ -31,6 +40,7 @@ export {
31
40
  ourLuaOnHost,
32
41
  probeEdge,
33
42
  resolveOurEdgeContainer,
43
+ sanitizeEdgeVhosts,
34
44
  sq,
35
45
  stopTargetsForStatus
36
46
  };
@@ -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-2ZLR7ULL.js";
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-3JQTL4R4.js";
8
+ } from "./chunk-BBHX7T4R.js";
9
9
  import "./chunk-FRNAR33O.js";
10
10
  import "./chunk-EI575GHN.js";
11
11
  import "./chunk-6APIPIJY.js";
@@ -14,27 +14,27 @@ 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-5FNIWBFI.js";
17
+ import "./chunk-5NYUCONN.js";
18
18
  import "./chunk-AVIB7CT7.js";
19
19
  import "./chunk-5MZ624VX.js";
20
20
  import "./chunk-Q2CIRAOK.js";
21
- import "./chunk-C5OHTYEF.js";
22
- import "./chunk-SQ77DZOI.js";
21
+ import "./chunk-GKHUSZCD.js";
22
+ import "./chunk-SLTYVHU7.js";
23
23
  import "./chunk-O6ZZF52V.js";
24
24
  import "./chunk-JYGD5WSN.js";
25
- import "./chunk-2ZLR7ULL.js";
25
+ import "./chunk-SJIFLLX4.js";
26
26
  import "./chunk-V6AN6XLZ.js";
27
27
  import "./chunk-VDMQJHPI.js";
28
28
  import "./chunk-MZ2WEHHY.js";
29
29
  import "./chunk-L2VOGB2X.js";
30
30
  import "./chunk-4Z5QO7N6.js";
31
- import "./chunk-4TJC4JZQ.js";
31
+ import "./chunk-XPPZ7B2J.js";
32
32
  import "./chunk-OXWDY22G.js";
33
33
  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-FQGJZ2HS.js";
37
+ import "./chunk-2D3I5G6P.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-SQ77DZOI.js";
13
+ } from "./chunk-SLTYVHU7.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-FQGJZ2HS.js";
18
+ import "./chunk-2D3I5G6P.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,
@@ -8,7 +8,7 @@ import {
8
8
  createExecutor,
9
9
  createHostExecutor,
10
10
  hostControlDisabled
11
- } from "./chunk-4TJC4JZQ.js";
11
+ } from "./chunk-XPPZ7B2J.js";
12
12
  import "./chunk-OXWDY22G.js";
13
13
  import "./chunk-RPHRPFEH.js";
14
14
  import {
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@ import {
8
8
  composeDown,
9
9
  composeInternalToken,
10
10
  composeIsViableDefault,
11
+ composePrefetch,
11
12
  composePs,
12
13
  composeRestart,
13
14
  composeRunning,
@@ -25,7 +26,7 @@ import {
25
26
  remoteSha,
26
27
  shortSha,
27
28
  sourceBuildDir
28
- } from "./chunk-3JQTL4R4.js";
29
+ } from "./chunk-BBHX7T4R.js";
29
30
  import "./chunk-FRNAR33O.js";
30
31
  import "./chunk-EI575GHN.js";
31
32
  import "./chunk-6APIPIJY.js";
@@ -34,11 +35,11 @@ import "./chunk-OWED2GRM.js";
34
35
  import "./chunk-VWPEKOH6.js";
35
36
  import "./chunk-W73X43R7.js";
36
37
  import "./chunk-TGIINPVM.js";
37
- import "./chunk-5FNIWBFI.js";
38
+ import "./chunk-5NYUCONN.js";
38
39
  import "./chunk-AVIB7CT7.js";
39
40
  import "./chunk-5MZ624VX.js";
40
41
  import "./chunk-Q2CIRAOK.js";
41
- import "./chunk-C5OHTYEF.js";
42
+ import "./chunk-GKHUSZCD.js";
42
43
  import {
43
44
  beginEdgeTakeover,
44
45
  collectProxyCerts,
@@ -51,16 +52,16 @@ import {
51
52
  recoverInterruptedTakeover,
52
53
  rollbackEdgeTakeover,
53
54
  scanImportableSites
54
- } from "./chunk-SQ77DZOI.js";
55
+ } from "./chunk-SLTYVHU7.js";
55
56
  import "./chunk-O6ZZF52V.js";
56
57
  import "./chunk-JYGD5WSN.js";
57
- import "./chunk-2ZLR7ULL.js";
58
+ import "./chunk-SJIFLLX4.js";
58
59
  import "./chunk-V6AN6XLZ.js";
59
60
  import "./chunk-VDMQJHPI.js";
60
61
  import "./chunk-MZ2WEHHY.js";
61
62
  import "./chunk-L2VOGB2X.js";
62
63
  import "./chunk-4Z5QO7N6.js";
63
- import "./chunk-4TJC4JZQ.js";
64
+ import "./chunk-XPPZ7B2J.js";
64
65
  import "./chunk-OXWDY22G.js";
65
66
  import "./chunk-RPHRPFEH.js";
66
67
  import {
@@ -69,8 +70,10 @@ import {
69
70
  import "./chunk-FXTBHTWY.js";
70
71
  import "./chunk-FPRHYBY2.js";
71
72
  import {
73
+ edgeCrashReason,
74
+ edgeIsBroken,
72
75
  ourEdgeContainerRunning
73
- } from "./chunk-FQGJZ2HS.js";
76
+ } from "./chunk-2D3I5G6P.js";
74
77
  import "./chunk-ILFETZOM.js";
75
78
  import "./chunk-VFINNTUL.js";
76
79
  import {
@@ -1681,6 +1684,25 @@ async function runCompose(opts) {
1681
1684
  );
1682
1685
  process.exit(1);
1683
1686
  }
1687
+ const publicUrl = effectivePublicUrl(opts.publicUrl);
1688
+ const prefetch = ora(
1689
+ sourceBuildDir() ? "Building images before touching :80/:443\u2026" : "Pulling images before touching :80/:443\u2026"
1690
+ ).start();
1691
+ const fetched = composePrefetch({
1692
+ apiPort: opts.port,
1693
+ dashboardPort: opts.dashboardPort,
1694
+ publicUrl,
1695
+ trustProxy: opts.trustProxy,
1696
+ noHostControl: opts.hostControl === false ? true : void 0
1697
+ });
1698
+ if (!fetched) {
1699
+ prefetch.fail("Couldn't fetch the stack's images \u2014 nothing was changed on this box.");
1700
+ console.error(
1701
+ chalk6.dim("\n Your current proxy is untouched and still serving. Fix the pull/build error above and re-run.\n")
1702
+ );
1703
+ process.exit(1);
1704
+ }
1705
+ prefetch.succeed("Images ready \u2014 nothing on :80/:443 has changed yet.");
1684
1706
  let edgePlan;
1685
1707
  try {
1686
1708
  edgePlan = await planAndApplyHostEdge({ edge: opts.edge });
@@ -1698,12 +1720,13 @@ async function runCompose(opts) {
1698
1720
  );
1699
1721
  process.exit(1);
1700
1722
  }
1701
- const publicUrl = effectivePublicUrl(opts.publicUrl);
1702
1723
  const fromSource = sourceBuildDir();
1703
1724
  const spinner5 = ora(
1704
1725
  fromSource ? `Building Openship from ${fromSource} and starting the stack\u2026` : "Starting Openship via Docker Compose\u2026"
1705
1726
  ).start();
1706
- const res = composeUp({
1727
+ const res = await composeUp({
1728
+ // Prefetched above, before the preflight stopped anything.
1729
+ alreadyFetched: true,
1707
1730
  apiPort: opts.port,
1708
1731
  dashboardPort: opts.dashboardPort,
1709
1732
  publicUrl,
@@ -1722,6 +1745,27 @@ async function runCompose(opts) {
1722
1745
  process.exit(1);
1723
1746
  }
1724
1747
  spinner5.succeed("Openship is running via Docker Compose.");
1748
+ if (edgePlan.action && await edgeIsBroken(new LocalExecutor())) {
1749
+ const reason = await edgeCrashReason(new LocalExecutor());
1750
+ console.error(
1751
+ chalk6.red(`
1752
+ Openship's edge container is not running${reason ? ` \u2014 ${reason}` : "."}`)
1753
+ );
1754
+ const restored = await rollbackHostEdge();
1755
+ console.error(
1756
+ restored ? chalk6.yellow(
1757
+ ` Your previous proxy has been restarted \u2014 the box is serving again, on it.
1758
+ Nothing was migrated. Fix the cause above, then re-run \`openship up\`.
1759
+ `
1760
+ ) : chalk6.red(
1761
+ ` AND your previous proxy could NOT be restarted automatically \u2014 the box is
1762
+ serving nothing right now. Start it by hand:
1763
+ docker stop openship-edge && sudo systemctl enable --now nginx
1764
+ `
1765
+ )
1766
+ );
1767
+ process.exit(1);
1768
+ }
1725
1769
  let importedOk = true;
1726
1770
  if (edgePlan.action === "migrate" && edgePlan.sites?.length) {
1727
1771
  const outcome = await importMigratedSites(res.apiPort, edgePlan.sites, edgePlan.certPems);
@@ -1973,7 +2017,7 @@ async function runForeground(opts, source) {
1973
2017
  const uiSpinner = ora("Preparing the dashboard\u2026").start();
1974
2018
  try {
1975
2019
  const bundle = await ensureDashboard({
1976
- tag: source ? "local" : opts.uiVersion || `v${"0.4.6"}`,
2020
+ tag: source ? "local" : opts.uiVersion || `v${"0.4.8"}`,
1977
2021
  onProgress: (received, total) => {
1978
2022
  if (total) {
1979
2023
  uiSpinner.text = `Downloading dashboard\u2026 ${Math.round(received / total * 100)}%`;
@@ -6582,7 +6626,7 @@ function detectPackageManager2(override) {
6582
6626
  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
6627
  const source = readSourceInstall();
6584
6628
  if (source) return runSourceUpdate(source, opts);
6585
- const current = "0.4.6";
6629
+ const current = "0.4.8";
6586
6630
  let latest;
6587
6631
  try {
6588
6632
  latest = (await resolveLatestTag()).replace(/^v/, "");
@@ -6617,7 +6661,7 @@ var updateCommand = new Command26("update").description("Update the Openship CLI
6617
6661
  return;
6618
6662
  }
6619
6663
  if (readInstallMethod() === "compose") {
6620
- const applied = composeUpdate(latest);
6664
+ const applied = await composeUpdate(latest);
6621
6665
  if (isJsonMode()) {
6622
6666
  printJson({ updated: true, from: current, to: latest, via: pm, method: "compose", applied });
6623
6667
  } else if (applied) {
@@ -7149,7 +7193,7 @@ async function runWizard() {
7149
7193
  }
7150
7194
  }
7151
7195
  }
7152
- const uiTag = `v${"0.4.6"}`;
7196
+ const uiTag = `v${"0.4.8"}`;
7153
7197
  if (method === "bare") {
7154
7198
  const dl = spinner4();
7155
7199
  dl.start("Pulling the Openship dist from GitHub");
@@ -7203,6 +7247,18 @@ async function runWizard() {
7203
7247
  }
7204
7248
  }
7205
7249
  if (method === "compose") {
7250
+ log5.step(
7251
+ sourceBuildDir() ? "Building the Openship images before touching :80/:443 (first run takes a few minutes)\u2026" : "Pulling images before touching :80/:443\u2026"
7252
+ );
7253
+ if (!composePrefetch({
7254
+ publicUrl,
7255
+ trustProxy: behindProxy,
7256
+ version: "0.4.8",
7257
+ noHostControl: !allowHostControl
7258
+ })) {
7259
+ cancel4("Couldn't fetch the Openship images \u2014 nothing on this box was changed.");
7260
+ process.exit(1);
7261
+ }
7206
7262
  const edgePlan = await planAndApplyHostEdge({});
7207
7263
  if (!edgePlan.proceed) {
7208
7264
  cancel4("Left the existing proxy on 80/443 running \u2014 re-run and choose migrate/takeover when ready.");
@@ -7211,13 +7267,13 @@ async function runWizard() {
7211
7267
  edgeAction = edgePlan.action;
7212
7268
  migratedSites = edgePlan.sites;
7213
7269
  migratedCertPems = edgePlan.certPems;
7214
- log5.step(
7215
- sourceBuildDir() ? "Building the Openship images from your source checkout (first run takes a few minutes)\u2026" : "Pulling images and starting the Docker Compose stack\u2026"
7216
- );
7217
- const up = composeUp({
7270
+ log5.step("Starting the Docker Compose stack\u2026");
7271
+ const up = await composeUp({
7272
+ // Prefetched above, before the preflight stopped anything.
7273
+ alreadyFetched: true,
7218
7274
  publicUrl,
7219
7275
  trustProxy: behindProxy,
7220
- version: "0.4.6",
7276
+ version: "0.4.8",
7221
7277
  noHostControl: !allowHostControl
7222
7278
  });
7223
7279
  if (!up.ok) {
@@ -7554,7 +7610,7 @@ ${chalk20.dim("Dashboard".padEnd(11))}${dashUrl}
7554
7610
 
7555
7611
  // src/index.ts
7556
7612
  var program = new Command28();
7557
- program.name("openship").description("Openship CLI \u2014 install, run, and manage Openship from your terminal").version("0.4.6").option("--json", "Machine-readable JSON output (stdout data only)").hook("preAction", (thisCommand) => {
7613
+ program.name("openship").description("Openship CLI \u2014 install, run, and manage Openship from your terminal").version("0.4.8").option("--json", "Machine-readable JSON output (stdout data only)").hook("preAction", (thisCommand) => {
7558
7614
  if (thisCommand.opts().json) setJsonMode(true);
7559
7615
  }).action(async () => {
7560
7616
  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-FQGJZ2HS.js";
13
+ import "./chunk-2D3I5G6P.js";
14
14
  import "./chunk-ILFETZOM.js";
15
15
  import "./chunk-VFINNTUL.js";
16
16
  import "./chunk-6APULWSU.js";