openship 0.6.6 → 0.6.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.
Files changed (58) hide show
  1. package/dist/bare-7QD623QV.js +29 -0
  2. package/dist/{chunk-Q7WGTQQ5.js → chunk-2ANV5ZQ5.js} +1 -1
  3. package/dist/{chunk-UJ6JZM65.js → chunk-2VSW6Q6C.js} +601 -382
  4. package/dist/{chunk-PCPVTH6M.js → chunk-5T4UVOM3.js} +6 -4
  5. package/dist/{chunk-YMMQRE5J.js → chunk-BLEXTYRK.js} +1 -1
  6. package/dist/{chunk-OBPKYXQL.js → chunk-CIJV43LH.js} +71 -32
  7. package/dist/{chunk-NK5N5LXN.js → chunk-DDFUESPJ.js} +24 -9
  8. package/dist/{chunk-6FH4AXVY.js → chunk-E2X26PXR.js} +1 -1
  9. package/dist/{chunk-HKRQXPTI.js → chunk-FYPFEDPZ.js} +1 -1
  10. package/dist/{chunk-UVNMQM7W.js → chunk-FZ6QCF6B.js} +8 -6
  11. package/dist/{chunk-MLYSEZQB.js → chunk-GGIAIGUL.js} +15 -66
  12. package/dist/{chunk-2YM3NI2E.js → chunk-GIPJNNI5.js} +38 -44
  13. package/dist/{chunk-ZFJXPCQP.js → chunk-H3WT3A6R.js} +4 -3
  14. package/dist/chunk-H4FS5BED.js +936 -0
  15. package/dist/{chunk-CBLD2HS5.js → chunk-J2XM3QSP.js} +8 -5
  16. package/dist/{chunk-FE7ZZQSE.js → chunk-J3K6XABC.js} +3 -3
  17. package/dist/{chunk-77QDF6UD.js → chunk-LHFXSC36.js} +428 -93
  18. package/dist/{chunk-YIMOCZBZ.js → chunk-MEE6OZFP.js} +3 -3
  19. package/dist/chunk-N5YZMO33.js +111 -0
  20. package/dist/{chunk-QVW76WDL.js → chunk-NRTJRNAE.js} +58 -16
  21. package/dist/{chunk-WVAML4H6.js → chunk-PPEBIY5F.js} +247 -61
  22. package/dist/{chunk-4I2BM2DT.js → chunk-PVP4RGWT.js} +3 -3
  23. package/dist/{chunk-RSR7PFIQ.js → chunk-QHMDCYZ3.js} +4 -4
  24. package/dist/chunk-R4VDPFLS.js +106 -0
  25. package/dist/{chunk-VTGPEC6B.js → chunk-RDXT4BQB.js} +6 -4
  26. package/dist/{chunk-LFE5KQ7Y.js → chunk-S6B2Z3OO.js} +142 -57
  27. package/dist/chunk-UWEV6XTS.js +249 -0
  28. package/dist/{chunk-5DMWSTOM.js → chunk-VQM6JHJB.js} +940 -224
  29. package/dist/{chunk-SM26HDS2.js → chunk-VSTFHUCV.js} +44 -50
  30. package/dist/chunk-WU54BXFE.js +70 -0
  31. package/dist/{chunk-LUKYPVJ4.js → chunk-XWHWTHEL.js} +313 -469
  32. package/dist/{chunk-A4GXYE4L.js → chunk-ZPJ74LXE.js} +22 -20
  33. package/dist/cloud-KNNABE3O.js +40 -0
  34. package/dist/{detect-OIE5V3VZ.js → detect-G4DR3U2N.js} +9 -6
  35. package/dist/{docker-VTR2GK5Y.js → docker-YOVPCIB4.js} +11 -8
  36. package/dist/{docker-edge-executor-22IBXNYJ.js → docker-edge-executor-QFXD3337.js} +8 -6
  37. package/dist/edge-import-CRFVSR6P.js +56 -0
  38. package/dist/{edge-preflight-GBNCPNVU.js → edge-preflight-MXERVAMG.js} +15 -12
  39. package/dist/{ensure-container-edge-KPI2CVXJ.js → ensure-container-edge-F4JUNQIK.js} +13 -10
  40. package/dist/{executor-7LXXZPBR.js → executor-CVPAYYHR.js} +8 -6
  41. package/dist/host-channel-preflight-QTDNGLCK.js +54 -0
  42. package/dist/index.js +84 -48
  43. package/dist/{local-executor-WOFZD72X.js → local-executor-ODC6RANU.js} +3 -2
  44. package/dist/{nginx-KUFMLMAC.js → nginx-KLFF43TC.js} +11 -8
  45. package/dist/{openresty-lua-ATTH35BE.js → openresty-lua-VKWUV4GB.js} +6 -5
  46. package/dist/{privilege-I4W3ZNZK.js → privilege-7D3SSOL3.js} +6 -5
  47. package/dist/server/index.js +8813 -5232
  48. package/dist/setup-I5AJC6NJ.js +25 -0
  49. package/dist/{ssh-client-JBMA7SN4.js → ssh-client-625VWGKP.js} +3 -2
  50. package/dist/up-QXTOOVXC.js +61 -0
  51. package/package.json +1 -1
  52. package/dist/bare-OXJVW3AK.js +0 -25
  53. package/dist/chunk-LH2PLRQO.js +0 -434
  54. package/dist/cloud-75VIT4KV.js +0 -37
  55. package/dist/edge-import-WJUB4M7F.js +0 -52
  56. package/dist/host-channel-preflight-KE6OONYK.js +0 -50
  57. package/dist/setup-XGLGUUFW.js +0 -22
  58. package/dist/up-K4BV7466.js +0 -57
@@ -5,12 +5,22 @@ const require = __ospCreateRequire(import.meta.url);
5
5
  import {
6
6
  describeProcess,
7
7
  probeListeningPort,
8
- tryExec,
9
8
  waitForPortFree
10
- } from "./chunk-SM26HDS2.js";
9
+ } from "./chunk-VSTFHUCV.js";
11
10
  import {
12
- AppError
13
- } from "./chunk-UJ6JZM65.js";
11
+ EDGE_CONTAINER_NAME,
12
+ classifyProxy,
13
+ describeContainerById,
14
+ isOurEdgeContainer,
15
+ mayStopUnitForEdgeTakeover,
16
+ resolveContainerPublishingPort,
17
+ stopContainerDurably,
18
+ tryExec
19
+ } from "./chunk-UWEV6XTS.js";
20
+ import {
21
+ AppError,
22
+ shellQuote
23
+ } from "./chunk-2VSW6Q6C.js";
14
24
 
15
25
  // ../../packages/adapters/src/system/proxy/detect.ts
16
26
  var EDGE_PORTS = [80, 443];
@@ -34,23 +44,7 @@ var EdgeMigrateRequested = class extends Error {
34
44
  this.name = "EdgeMigrateRequested";
35
45
  }
36
46
  };
37
- function classifyProxy(text) {
38
- if (!text) return void 0;
39
- const t = text.toLowerCase();
40
- if (t.includes("openresty")) return "openresty";
41
- if (/(^|[\s/:])nginx/.test(t)) return "nginx";
42
- if (/(^|[\s/:])caddy/.test(t)) return "caddy";
43
- if (/(apache2|httpd)/.test(t)) return "apache";
44
- if (/(^|[\s/:])traefik/.test(t)) return "traefik";
45
- if (/(^|[\s/:])haproxy/.test(t)) return "haproxy";
46
- return void 0;
47
- }
48
- function sq(value) {
49
- return `'${value.replace(/'/g, "'\\''")}'`;
50
- }
51
- function isOurEdgeContainer(name, image) {
52
- return /openship-edge/i.test(`${name ?? ""} ${image ?? ""}`);
53
- }
47
+ var sq = shellQuote;
54
48
  function vhostLog(message, level = "info") {
55
49
  return { timestamp: (/* @__PURE__ */ new Date()).toISOString(), message, level };
56
50
  }
@@ -115,7 +109,6 @@ function edgeFailureReason(containerLog) {
115
109
  if (emerg) return emerg.replace(/^.*\[emerg\]\s*\d*#\d*:\s*/, "");
116
110
  return null;
117
111
  }
118
- var EDGE_CONTAINER_NAME = "openship-edge";
119
112
  async function ourEdgeContainerRunning(executor) {
120
113
  return Boolean(await resolveOurEdgeContainer(executor));
121
114
  }
@@ -172,15 +165,9 @@ async function probeOurEdgeContainer(executor) {
172
165
  return null;
173
166
  }
174
167
  async function detectDockerOnPort(executor, port) {
175
- const out = await tryExec(
176
- executor,
177
- `docker ps --filter publish=${port} --format '{{.Names}} {{.Image}}' 2>/dev/null | head -1`
178
- );
179
- const line = out?.trim();
180
- if (!line) return null;
181
- const [name, image] = line.split(" ");
182
- if (!name) return null;
183
- return { name, image: image ?? "" };
168
+ const onPort = await resolveContainerPublishingPort(executor, port);
169
+ const container = onPort.kind === "one" ? onPort.container : onPort.kind === "ambiguous" ? onPort.containers[0] : null;
170
+ return container ? { id: container.id, name: container.name, image: container.image } : null;
184
171
  }
185
172
  var WORKER_RE = /\b(?:nginx|openresty)\s*:\s*worker process/i;
186
173
  var MASTER_RE = /\b(?:nginx|openresty)\s*:\s*master process/i;
@@ -203,10 +190,11 @@ async function probeEdgePort(executor, port, ours) {
203
190
  const listener = await resolveProxyMaster(executor, await probeListeningPort(executor, port));
204
191
  const docker = await detectDockerOnPort(executor, port);
205
192
  if (!listener && !docker) return null;
193
+ const cgroupContainer = !docker && listener?.containerId ? await describeContainerById(executor, listener.containerId) : null;
206
194
  const proxy = classifyProxy(
207
195
  [
208
- docker?.image,
209
- docker?.name,
196
+ docker?.image ?? cgroupContainer?.image,
197
+ docker?.name ?? cgroupContainer?.name,
210
198
  listener?.rawCommand,
211
199
  listener?.command,
212
200
  listener?.systemdUnit
@@ -221,8 +209,12 @@ async function probeEdgePort(executor, port, ours) {
221
209
  rawCommand: listener?.rawCommand,
222
210
  systemdUnit: listener?.systemdUnit,
223
211
  systemdDescription: listener?.systemdDescription,
224
- isDocker: Boolean(docker),
225
- containerName: docker?.name,
212
+ isDocker: Boolean(docker) || Boolean(listener?.dockerPublished) || Boolean(listener?.containerId),
213
+ containerName: docker?.name ?? cgroupContainer?.name,
214
+ // Without a container the takeover falls through to `kill -9` on a process INSIDE
215
+ // somebody's container, which frees nothing durably.
216
+ containerId: docker?.id ?? listener?.containerId,
217
+ dockerPublished: listener?.dockerPublished,
226
218
  proxy,
227
219
  managedByOpenship
228
220
  };
@@ -251,14 +243,18 @@ function stopTargetsForStatus(status) {
251
243
  const out = [];
252
244
  const seen = /* @__PURE__ */ new Set();
253
245
  for (const o of status.occupants) {
254
- const identity = o.systemdUnit ?? o.containerName ?? (o.pid ? `pid:${o.pid}` : `port:${o.port}`);
246
+ const identity = o.containerName ?? o.containerId ?? o.systemdUnit ?? (o.pid ? `pid:${o.pid}` : `port:${o.port}`);
255
247
  if (seen.has(identity)) continue;
256
248
  seen.add(identity);
257
249
  out.push({
258
250
  port: o.port,
259
251
  unit: o.systemdUnit,
260
- pid: o.pid,
261
- container: o.containerName,
252
+ // A forwarder's pid is dockerd's, not the workload's: killing it severs a live
253
+ // container's port mapping and frees nothing durably. With no container resolved
254
+ // there is nothing here to stop, and freeEdgeTargets reports the port still bound
255
+ // rather than claiming a takeover that did not happen.
256
+ pid: o.dockerPublished && !o.containerName && !o.containerId ? void 0 : o.pid,
257
+ container: o.containerName ?? o.containerId,
262
258
  // Prefer the proxy kind over the raw cmdline — `nginx (PID 123)` reads
263
259
  // better in "Stopping …" than `nginx: master process /usr/sbin/nginx …`.
264
260
  label: o.proxy && o.pid ? `${o.proxy} (PID ${o.pid})` : o.command
@@ -271,14 +267,15 @@ async function freeEdgeTargets(executor, targets, onLog, opts = {}) {
271
267
  const where = t.port ? ` (port ${t.port})` : "";
272
268
  if (t.container) {
273
269
  onLog(`Stopping container ${t.container}${where}...`, "warn");
274
- await tryExec(executor, `docker update --restart=no ${sq(t.container)} 2>/dev/null || true`);
275
- await tryExec(executor, `docker stop ${sq(t.container)} 2>/dev/null || true`);
276
- } else if (t.unit) {
270
+ await stopContainerDurably(executor, t.container);
271
+ } else if (t.unit && mayStopUnitForEdgeTakeover(t.unit)) {
277
272
  onLog(`Stopping & disabling service ${t.unit}${where}...`, "warn");
278
273
  await tryExec(
279
274
  executor,
280
275
  `systemctl disable --now ${sq(t.unit)} 2>/dev/null || systemctl stop ${sq(t.unit)} 2>/dev/null || true; systemctl reset-failed ${sq(t.unit)} 2>/dev/null || true`
281
276
  );
277
+ } else if (t.unit) {
278
+ onLog(`Refusing to stop ${t.unit}${where} \u2014 free that port manually.`, "error");
282
279
  } else if (t.pid) {
283
280
  onLog(`Stopping ${t.label ?? `process ${t.pid}`}${where}...`, "warn");
284
281
  await tryExec(executor, `kill ${t.pid} 2>/dev/null || true`);
@@ -307,14 +304,11 @@ async function freeEdgeTargets(executor, targets, onLog, opts = {}) {
307
304
  export {
308
305
  EdgeConflictError,
309
306
  EdgeMigrateRequested,
310
- classifyProxy,
311
307
  sq,
312
- isOurEdgeContainer,
313
308
  sanitizeEdgeVhosts,
314
309
  edgeIsBroken,
315
310
  edgeCrashReason,
316
311
  edgeFailureReason,
317
- EDGE_CONTAINER_NAME,
318
312
  ourEdgeContainerRunning,
319
313
  invalidateEdgeContainer,
320
314
  resolveOurEdgeContainer,
@@ -2,6 +2,9 @@
2
2
  ":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
3
3
  import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
+ import {
6
+ shellQuote
7
+ } from "./chunk-2VSW6Q6C.js";
5
8
 
6
9
  // ../../packages/adapters/src/system/local-shell.ts
7
10
  import { execFile } from "child_process";
@@ -28,9 +31,7 @@ var LOCAL_BUILD_ENV_KEYS = [
28
31
  "XDG_CACHE_HOME",
29
32
  "XDG_DATA_HOME"
30
33
  ];
31
- function sq(value) {
32
- return `'${value.replace(/'/g, "'\\''")}'`;
33
- }
34
+ var sq = shellQuote;
34
35
  function logEntry(message, level = "info", rawData) {
35
36
  return { timestamp: (/* @__PURE__ */ new Date()).toISOString(), message, level, ...rawData ? { rawData } : {} };
36
37
  }