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.
Files changed (67) hide show
  1. package/dist/bare-FA66N7GC.js +29 -0
  2. package/dist/{chunk-LHFXSC36.js → chunk-3MP6ACKM.js} +183 -87
  3. package/dist/{chunk-MEE6OZFP.js → chunk-5DJOB7IX.js} +3 -3
  4. package/dist/{chunk-PPEBIY5F.js → chunk-5I3COAFH.js} +35 -12
  5. package/dist/{chunk-VQM6JHJB.js → chunk-5UXHT6ED.js} +9 -9
  6. package/dist/{chunk-XWHWTHEL.js → chunk-6GU6JSK6.js} +21 -2
  7. package/dist/{chunk-QHMDCYZ3.js → chunk-7PEXM2UI.js} +213 -45
  8. package/dist/{chunk-RDXT4BQB.js → chunk-7YBWXEM6.js} +4 -4
  9. package/dist/{chunk-H4FS5BED.js → chunk-AHJYP7DG.js} +13 -11
  10. package/dist/{chunk-VSTFHUCV.js → chunk-BO6CY4V2.js} +109 -23
  11. package/dist/{chunk-J3K6XABC.js → chunk-D3OEMXYP.js} +3 -3
  12. package/dist/{chunk-UWEV6XTS.js → chunk-D6HU4VUZ.js} +1 -1
  13. package/dist/{chunk-S6B2Z3OO.js → chunk-ENKJ7XIF.js} +21 -11
  14. package/dist/{chunk-BLEXTYRK.js → chunk-GNOMEMNI.js} +1 -1
  15. package/dist/{chunk-NRTJRNAE.js → chunk-IAMOUDHY.js} +138 -54
  16. package/dist/{chunk-CIJV43LH.js → chunk-MUWVC5R4.js} +161 -39
  17. package/dist/{chunk-ZPJ74LXE.js → chunk-NIYD7MD2.js} +197 -45
  18. package/dist/{chunk-FZ6QCF6B.js → chunk-NPSRGIHV.js} +2 -2
  19. package/dist/{chunk-2GWYYHOR.js → chunk-NRU2EBYZ.js} +2 -2
  20. package/dist/{chunk-J2XM3QSP.js → chunk-NUT6HKK6.js} +5 -5
  21. package/dist/{chunk-H3WT3A6R.js → chunk-P7RCYELG.js} +1 -1
  22. package/dist/{chunk-FYPFEDPZ.js → chunk-R5DC5PEF.js} +1 -1
  23. package/dist/{chunk-DDFUESPJ.js → chunk-RCMERVBL.js} +9 -9
  24. package/dist/{chunk-RXQBD4ZY.js → chunk-RHLNVZMS.js} +2 -2
  25. package/dist/{chunk-WU54BXFE.js → chunk-SK4FFCFR.js} +1 -1
  26. package/dist/{chunk-PVP4RGWT.js → chunk-T46BQOLY.js} +3 -3
  27. package/dist/{chunk-E2X26PXR.js → chunk-T6DVUX4F.js} +1 -1
  28. package/dist/{chunk-5T4UVOM3.js → chunk-TAZZZKYO.js} +1 -1
  29. package/dist/{chunk-GGIAIGUL.js → chunk-UAWY6X7V.js} +34 -12
  30. package/dist/{chunk-2ANV5ZQ5.js → chunk-VAI5VOOI.js} +1 -1
  31. package/dist/{chunk-2VSW6Q6C.js → chunk-WEZFTL4V.js} +655 -62
  32. package/dist/{chunk-GIPJNNI5.js → chunk-X53JXRS4.js} +3 -3
  33. package/dist/{cloud-KRTZ2IL5.js → cloud-2CRDKOWQ.js} +1 -1
  34. package/dist/cloud-REV3DPJH.js +42 -0
  35. package/dist/{detect-G4DR3U2N.js → detect-BBFT5GEU.js} +4 -4
  36. package/dist/{docker-YOVPCIB4.js → docker-EG3QSE6I.js} +10 -10
  37. package/dist/{docker-edge-executor-QFXD3337.js → docker-edge-executor-E5TOTLMR.js} +7 -7
  38. package/dist/edge-import-YJVJUGYC.js +56 -0
  39. package/dist/{edge-preflight-MXERVAMG.js → edge-preflight-QUW4BM7N.js} +13 -13
  40. package/dist/{ensure-container-edge-F4JUNQIK.js → ensure-container-edge-FOEFQ3PI.js} +13 -11
  41. package/dist/{executor-CVPAYYHR.js → executor-NTWDJ3DB.js} +6 -6
  42. package/dist/host-channel-preflight-OMCZMMKR.js +54 -0
  43. package/dist/index.js +158 -72
  44. package/dist/{local-executor-ODC6RANU.js → local-executor-OQ2GRN7K.js} +3 -3
  45. package/dist/{nginx-KLFF43TC.js → nginx-4U4C2XUS.js} +9 -9
  46. package/dist/{noop-NJ72F46T.js → noop-CLLJHCPL.js} +1 -1
  47. package/dist/{openresty-lua-VKWUV4GB.js → openresty-lua-LLWT5XQW.js} +7 -5
  48. package/dist/{privilege-7D3SSOL3.js → privilege-MNDVMDST.js} +5 -5
  49. package/dist/server/index.js +31643 -25553
  50. package/dist/server/migrations/0109_service_build_args.sql +9 -0
  51. package/dist/server/migrations/0110_service_deployment_host_ports.sql +18 -0
  52. package/dist/server/migrations/0111_host_port_claim.sql +381 -0
  53. package/dist/server/migrations/0112_backup_run_execution_lease.sql +12 -0
  54. package/dist/server/migrations/0113_docker_migration_execution_lease.sql +11 -0
  55. package/dist/server/migrations/0114_build_session_execution_lease_index.sql +6 -0
  56. package/dist/server/migrations/0115_orphan_target_key.sql +3 -0
  57. package/dist/server/migrations/0116_domain_ssl_challenge.sql +2 -0
  58. package/dist/server/migrations/meta/_journal.json +56 -0
  59. package/dist/{setup-I5AJC6NJ.js → setup-IFIMPQZJ.js} +12 -12
  60. package/dist/{ssh-client-625VWGKP.js → ssh-client-2XWZCMGI.js} +2 -2
  61. package/dist/up-HQS7IR7H.js +61 -0
  62. package/package.json +1 -1
  63. package/dist/bare-7QD623QV.js +0 -29
  64. package/dist/cloud-KNNABE3O.js +0 -40
  65. package/dist/edge-import-CRFVSR6P.js +0 -56
  66. package/dist/host-channel-preflight-QTDNGLCK.js +0 -54
  67. package/dist/up-QXTOOVXC.js +0 -61
@@ -0,0 +1,9 @@
1
+ -- Per-service Docker Compose build arguments (#689).
2
+ --
3
+ -- These cannot share `service.environment`: build args configure image creation,
4
+ -- while environment configures the resulting container. Keeping them in a dedicated
5
+ -- JSONB column preserves the compose service boundary (two services may build one
6
+ -- Dockerfile with different args) and lets drift reconciliation compare them without
7
+ -- a schema change for every individual ARG name.
8
+ ALTER TABLE "service"
9
+ ADD COLUMN IF NOT EXISTS "build_args" jsonb DEFAULT '{}'::jsonb NOT NULL;
@@ -0,0 +1,18 @@
1
+ -- Persist every loopback publish owned by a service deployment.
2
+ --
3
+ -- `host_port` only remembers the primary route. A stopped multi-port service can
4
+ -- therefore leave a secondary OpenResty vhost pointing at a port the allocator
5
+ -- believes is free. Keep the scalar for compatibility and add the complete
6
+ -- container-port -> host-port map used by routing and collision prevention.
7
+ ALTER TABLE "service_deployment"
8
+ ADD COLUMN IF NOT EXISTS "host_ports" jsonb;
9
+ --> statement-breakpoint
10
+
11
+ -- The legacy scalar's container-side port is unknown. Preserve it under a
12
+ -- non-numeric key: allocation reads every value, while routing deliberately
13
+ -- consumes numeric container-port keys only and continues using `host_port` as
14
+ -- its legacy fallback.
15
+ UPDATE "service_deployment"
16
+ SET "host_ports" = jsonb_build_object('__legacy__', "host_port")
17
+ WHERE "host_port" IS NOT NULL
18
+ AND "host_ports" IS NULL;
@@ -0,0 +1,381 @@
1
+ -- Durable, host-wide loopback-port reservations.
2
+ --
3
+ -- A port collision domain is a physical target, not an organization. Claims are
4
+ -- also deliberately detached from project/service foreign keys: a stopped app,
5
+ -- record-only delete, or cleanup-pending vhost must keep its reservation until
6
+ -- routing has been explicitly removed.
7
+ CREATE TABLE IF NOT EXISTS "host_port_claim" (
8
+ "id" text PRIMARY KEY NOT NULL,
9
+ "target_key" text NOT NULL,
10
+ "port" integer NOT NULL,
11
+ "project_id" text NOT NULL,
12
+ "service_id" text,
13
+ "container_port" integer,
14
+ "created_at" timestamp DEFAULT now() NOT NULL,
15
+ "updated_at" timestamp DEFAULT now() NOT NULL,
16
+ CONSTRAINT "ck_host_port_claim_target_key"
17
+ CHECK (
18
+ "target_key" = 'local'
19
+ OR "target_key" ~ '^host:[0-9a-f]{64}$'
20
+ OR ("target_key" LIKE 'server:%' AND length("target_key") > 7)
21
+ ),
22
+ CONSTRAINT "ck_host_port_claim_port"
23
+ CHECK ("port" BETWEEN 1 AND 65535),
24
+ CONSTRAINT "ck_host_port_claim_container_port"
25
+ CHECK ("container_port" IS NULL OR "container_port" BETWEEN 1 AND 65535)
26
+ );
27
+ --> statement-breakpoint
28
+ CREATE UNIQUE INDEX IF NOT EXISTS "uq_host_port_claim_target_port"
29
+ ON "host_port_claim" ("target_key", "port");
30
+ --> statement-breakpoint
31
+ -- NULLS NOT DISTINCT expressed with portable sentinels: port zero is rejected
32
+ -- above, and ids generated by Openship are never empty strings.
33
+ CREATE UNIQUE INDEX IF NOT EXISTS "uq_host_port_claim_target_owner"
34
+ ON "host_port_claim" (
35
+ "target_key",
36
+ "project_id",
37
+ COALESCE("service_id", ''),
38
+ COALESCE("container_port", 0)
39
+ );
40
+ --> statement-breakpoint
41
+ CREATE INDEX IF NOT EXISTS "idx_host_port_claim_project"
42
+ ON "host_port_claim" ("project_id");
43
+ --> statement-breakpoint
44
+
45
+ -- Build one canonical candidate set for the whole migration. This is the same
46
+ -- set used to detect legacy ambiguity and to insert ordinary claims, so a source
47
+ -- cannot be considered by one path and silently omitted by the other.
48
+ --
49
+ -- Legacy `deployTarget:server` snapshots could omit serverId. Runtime resolves
50
+ -- those to the org's sole server; this backfill mirrors that exact org-scoped
51
+ -- fallback and collapses an isLocal server row into the local bind namespace.
52
+ WITH "sole_org_servers" AS (
53
+ SELECT
54
+ candidate."organization_id",
55
+ MIN(candidate."id") AS "server_id"
56
+ FROM "servers" candidate
57
+ WHERE candidate."organization_id" IS NOT NULL
58
+ GROUP BY candidate."organization_id"
59
+ HAVING COUNT(*) = 1
60
+ ),
61
+ "target_inputs" AS (
62
+ SELECT
63
+ 'project'::text AS "context_kind",
64
+ p."id" AS "context_id",
65
+ COALESCE(d."organization_id", p."organization_id") AS "organization_id",
66
+ NULLIF(d."meta" ->> 'serverId', '') AS "snapshot_server_id",
67
+ NULLIF(p."server_id", '') AS "project_server_id",
68
+ d."meta" ->> 'deployTarget' AS "deploy_target"
69
+ FROM "project" p
70
+ LEFT JOIN "deployment" d ON d."id" = p."active_deployment_id"
71
+
72
+ UNION ALL
73
+
74
+ SELECT
75
+ 'deployment'::text AS "context_kind",
76
+ d."id" AS "context_id",
77
+ d."organization_id",
78
+ NULLIF(d."meta" ->> 'serverId', '') AS "snapshot_server_id",
79
+ NULLIF(p."server_id", '') AS "project_server_id",
80
+ d."meta" ->> 'deployTarget' AS "deploy_target"
81
+ FROM "deployment" d
82
+ INNER JOIN "project" p ON p."id" = d."project_id"
83
+ WHERE p."active_deployment_id" = d."id"
84
+ OR d."status" IN ('deploying', 'reconciling')
85
+ ),
86
+ "resolved_target_ids" AS (
87
+ SELECT
88
+ input."context_kind",
89
+ input."context_id",
90
+ COALESCE(
91
+ input."snapshot_server_id",
92
+ input."project_server_id",
93
+ CASE
94
+ WHEN input."deploy_target" = 'server' THEN sole."server_id"
95
+ ELSE NULL
96
+ END
97
+ ) AS "server_id"
98
+ FROM "target_inputs" input
99
+ LEFT JOIN "sole_org_servers" sole
100
+ ON sole."organization_id" = input."organization_id"
101
+ ),
102
+ "candidate_targets" AS (
103
+ SELECT
104
+ target."context_kind",
105
+ target."context_id",
106
+ CASE
107
+ WHEN target."server_id" IS NULL OR server."is_local" = true THEN 'local'
108
+ ELSE 'server:' || target."server_id"
109
+ END AS "target_key"
110
+ FROM "resolved_target_ids" target
111
+ LEFT JOIN "servers" server ON server."id" = target."server_id"
112
+ ),
113
+ -- Parse each routed service map once. Only numeric container keys and 0110's
114
+ -- explicit legacy sentinel are meaningful. Nested CASE expressions guarantee a
115
+ -- malformed hand-edited JSON value is never cast before it passes the digit gate.
116
+ "service_port_entries" AS (
117
+ SELECT
118
+ sd."id" AS "service_deployment_id",
119
+ target."target_key",
120
+ p."id" AS "project_id",
121
+ sd."service_id",
122
+ ports."container_key",
123
+ parsed."container_port",
124
+ parsed."host_port"
125
+ FROM "service_deployment" sd
126
+ INNER JOIN "deployment" d ON d."id" = sd."deployment_id"
127
+ INNER JOIN "project" p ON p."id" = d."project_id"
128
+ INNER JOIN "candidate_targets" target
129
+ ON target."context_kind" = 'deployment'
130
+ AND target."context_id" = d."id"
131
+ CROSS JOIN LATERAL jsonb_each_text(COALESCE(sd."host_ports", '{}'::jsonb))
132
+ AS ports("container_key", "host_port_text")
133
+ CROSS JOIN LATERAL (
134
+ SELECT
135
+ CASE
136
+ WHEN ports."container_key" ~ '^[0-9]{1,5}$' THEN
137
+ CASE
138
+ WHEN ports."container_key"::integer BETWEEN 1 AND 65535
139
+ THEN ports."container_key"::integer
140
+ ELSE NULL
141
+ END
142
+ ELSE NULL
143
+ END AS "container_port",
144
+ CASE
145
+ WHEN ports."host_port_text" ~ '^[0-9]{1,5}$' THEN
146
+ CASE
147
+ WHEN ports."host_port_text"::integer BETWEEN 1 AND 65535
148
+ THEN ports."host_port_text"::integer
149
+ ELSE NULL
150
+ END
151
+ ELSE NULL
152
+ END AS "host_port"
153
+ ) parsed
154
+ WHERE (
155
+ p."active_deployment_id" = d."id"
156
+ OR d."status" IN ('deploying', 'reconciling')
157
+ )
158
+ -- Cloud owns its own routing namespace. Persisted/imported hostPorts on a
159
+ -- cloud release are source-host cache, never a claim on this installation.
160
+ AND p."cloud_workspace_id" IS NULL
161
+ AND COALESCE(NULLIF(d."meta" ->> 'deployTarget', ''), '') <> 'cloud'
162
+ AND parsed."host_port" IS NOT NULL
163
+ AND (
164
+ parsed."container_port" IS NOT NULL
165
+ OR ports."container_key" = '__legacy__'
166
+ )
167
+ ),
168
+ "candidate_claims" AS (
169
+ -- Single-app Docker compatibility pin. Cloud bindings are excluded for the
170
+ -- same reason as Compose maps above.
171
+ SELECT
172
+ 'hpc_project_' || p."id" AS "id",
173
+ target."target_key",
174
+ p."host_port" AS "port",
175
+ p."id" AS "project_id",
176
+ NULL::text AS "service_id",
177
+ NULL::integer AS "container_port"
178
+ FROM "project" p
179
+ LEFT JOIN "deployment" d ON d."id" = p."active_deployment_id"
180
+ INNER JOIN "candidate_targets" target
181
+ ON target."context_kind" = 'project'
182
+ AND target."context_id" = p."id"
183
+ WHERE p."host_port" BETWEEN 1 AND 65535
184
+ AND p."cloud_workspace_id" IS NULL
185
+ AND COALESCE(NULLIF(d."meta" ->> 'deployTarget', ''), '') <> 'cloud'
186
+
187
+ UNION ALL
188
+
189
+ -- Bare web processes bind their declared app port directly.
190
+ SELECT
191
+ 'hpc_bare_' || p."id" || '_' || p."port"::text AS "id",
192
+ target."target_key",
193
+ p."port" AS "port",
194
+ p."id" AS "project_id",
195
+ NULL::text AS "service_id",
196
+ p."port" AS "container_port"
197
+ FROM "project" p
198
+ INNER JOIN "deployment" d ON d."id" = p."active_deployment_id"
199
+ INNER JOIN "candidate_targets" target
200
+ ON target."context_kind" = 'project'
201
+ AND target."context_id" = p."id"
202
+ WHERE p."port" BETWEEN 1 AND 65535
203
+ AND p."cloud_workspace_id" IS NULL
204
+ AND COALESCE(NULLIF(d."meta" ->> 'deployTarget', ''), '') <> 'cloud'
205
+ AND COALESCE(
206
+ NULLIF(d."meta" ->> 'runtimeMode', ''),
207
+ NULLIF(p."runtime_mode", '')
208
+ ) = 'bare'
209
+ AND COALESCE(
210
+ NULLIF(d."meta" ->> 'workloadType', ''),
211
+ NULLIF(p."workload_type", ''),
212
+ CASE
213
+ WHEN COALESCE(NULLIF(d."meta" ->> 'hasServer', ''), p."has_server"::text) = 'false'
214
+ THEN 'static'
215
+ ELSE 'web'
216
+ END
217
+ ) = 'web'
218
+
219
+ UNION ALL
220
+
221
+ -- Complete Compose map. A numeric key supersedes 0110's targetless legacy
222
+ -- sentinel when both name the same host port.
223
+ SELECT
224
+ 'hpc_service_' || entry."service_deployment_id" || '_' || entry."container_key" AS "id",
225
+ entry."target_key",
226
+ entry."host_port" AS "port",
227
+ entry."project_id",
228
+ entry."service_id",
229
+ entry."container_port"
230
+ FROM "service_port_entries" entry
231
+ WHERE NOT (
232
+ entry."container_port" IS NULL
233
+ AND EXISTS (
234
+ SELECT 1
235
+ FROM "service_port_entries" numeric_entry
236
+ WHERE numeric_entry."service_deployment_id" = entry."service_deployment_id"
237
+ AND numeric_entry."host_port" = entry."host_port"
238
+ AND numeric_entry."container_port" IS NOT NULL
239
+ )
240
+ )
241
+
242
+ UNION ALL
243
+
244
+ -- Scalar fallback only when the map did not already preserve this port.
245
+ SELECT
246
+ 'hpc_service_' || sd."id" || '_scalar' AS "id",
247
+ target."target_key",
248
+ sd."host_port" AS "port",
249
+ p."id" AS "project_id",
250
+ sd."service_id",
251
+ NULL::integer AS "container_port"
252
+ FROM "service_deployment" sd
253
+ INNER JOIN "deployment" d ON d."id" = sd."deployment_id"
254
+ INNER JOIN "project" p ON p."id" = d."project_id"
255
+ INNER JOIN "candidate_targets" target
256
+ ON target."context_kind" = 'deployment'
257
+ AND target."context_id" = d."id"
258
+ WHERE (
259
+ p."active_deployment_id" = d."id"
260
+ OR d."status" IN ('deploying', 'reconciling')
261
+ )
262
+ AND p."cloud_workspace_id" IS NULL
263
+ AND COALESCE(NULLIF(d."meta" ->> 'deployTarget', ''), '') <> 'cloud'
264
+ AND sd."host_port" BETWEEN 1 AND 65535
265
+ AND NOT EXISTS (
266
+ SELECT 1
267
+ FROM "service_port_entries" entry
268
+ WHERE entry."service_deployment_id" = sd."id"
269
+ AND entry."host_port" = sd."host_port"
270
+ )
271
+ ),
272
+ -- Duplicate records of the exact same claim (for example an active and carried
273
+ -- row agreeing on one port) are harmless. Pick one deterministic id.
274
+ "canonical_candidates" AS (
275
+ SELECT
276
+ MIN(candidate."id") AS "id",
277
+ candidate."target_key",
278
+ candidate."port",
279
+ candidate."project_id",
280
+ candidate."service_id",
281
+ candidate."container_port"
282
+ FROM "candidate_claims" candidate
283
+ GROUP BY
284
+ candidate."target_key",
285
+ candidate."port",
286
+ candidate."project_id",
287
+ candidate."service_id",
288
+ candidate."container_port"
289
+ ),
290
+ "port_conflicts" AS (
291
+ SELECT candidate."target_key", candidate."port"
292
+ FROM "canonical_candidates" candidate
293
+ GROUP BY candidate."target_key", candidate."port"
294
+ HAVING COUNT(*) > 1
295
+ ),
296
+ "owner_conflicts" AS (
297
+ SELECT
298
+ candidate."target_key",
299
+ candidate."project_id",
300
+ candidate."service_id",
301
+ candidate."container_port"
302
+ FROM "canonical_candidates" candidate
303
+ GROUP BY
304
+ candidate."target_key",
305
+ candidate."project_id",
306
+ candidate."service_id",
307
+ candidate."container_port"
308
+ HAVING COUNT(*) > 1
309
+ ),
310
+ "ambiguous_ports" AS (
311
+ SELECT DISTINCT candidate."target_key", candidate."port"
312
+ FROM "canonical_candidates" candidate
313
+ WHERE EXISTS (
314
+ SELECT 1
315
+ FROM "port_conflicts" conflict
316
+ WHERE conflict."target_key" = candidate."target_key"
317
+ AND conflict."port" = candidate."port"
318
+ )
319
+ OR EXISTS (
320
+ SELECT 1
321
+ FROM "owner_conflicts" conflict
322
+ WHERE conflict."target_key" = candidate."target_key"
323
+ AND conflict."project_id" = candidate."project_id"
324
+ AND conflict."service_id" IS NOT DISTINCT FROM candidate."service_id"
325
+ AND conflict."container_port" IS NOT DISTINCT FROM candidate."container_port"
326
+ )
327
+ ),
328
+ "final_claims" AS (
329
+ -- An unambiguous persisted claim keeps its real stable owner.
330
+ SELECT
331
+ candidate."id",
332
+ candidate."target_key",
333
+ candidate."port",
334
+ candidate."project_id",
335
+ candidate."service_id",
336
+ candidate."container_port"
337
+ FROM "canonical_candidates" candidate
338
+ WHERE NOT EXISTS (
339
+ SELECT 1
340
+ FROM "ambiguous_ports" ambiguous
341
+ WHERE ambiguous."target_key" = candidate."target_key"
342
+ AND ambiguous."port" = candidate."port"
343
+ )
344
+
345
+ UNION ALL
346
+
347
+ -- Ambiguity is fail-closed. The reserved identity cannot match a generated
348
+ -- project/service id, and container_port=port makes every owner tuple unique.
349
+ SELECT
350
+ 'hpc_quarantine_' || ambiguous."target_key" || '_' || ambiguous."port"::text AS "id",
351
+ ambiguous."target_key",
352
+ ambiguous."port",
353
+ '__host_port_quarantine__' AS "project_id",
354
+ '__host_port_quarantine__' AS "service_id",
355
+ ambiguous."port" AS "container_port"
356
+ FROM "ambiguous_ports" ambiguous
357
+ )
358
+ INSERT INTO "host_port_claim" (
359
+ "id",
360
+ "target_key",
361
+ "port",
362
+ "project_id",
363
+ "service_id",
364
+ "container_port"
365
+ )
366
+ SELECT
367
+ claim."id",
368
+ claim."target_key",
369
+ claim."port",
370
+ claim."project_id",
371
+ claim."service_id",
372
+ claim."container_port"
373
+ FROM "final_claims" claim
374
+ ORDER BY
375
+ claim."target_key",
376
+ claim."port",
377
+ claim."project_id",
378
+ claim."service_id" NULLS FIRST,
379
+ claim."container_port" NULLS FIRST,
380
+ claim."id"
381
+ ON CONFLICT DO NOTHING;
@@ -0,0 +1,12 @@
1
+ -- Separate a backup run's durable worker liveness from its public FSM outcome.
2
+ -- A timeout may record server_error while the original worker is still unwinding;
3
+ -- project deletion must keep waiting until that worker's outermost finally closes
4
+ -- this lease.
5
+ ALTER TABLE "backup_run"
6
+ ADD COLUMN "execution_started_at" timestamp,
7
+ ADD COLUMN "execution_finished_at" timestamp;
8
+ --> statement-breakpoint
9
+ CREATE INDEX "idx_backup_run_execution_in_flight"
10
+ ON "backup_run" ("project_id")
11
+ WHERE "execution_started_at" IS NOT NULL
12
+ AND "execution_finished_at" IS NULL;
@@ -0,0 +1,11 @@
1
+ -- A parked migration can be resumed/cut over by any API replica. Persist the
2
+ -- winning callback's liveness separately from its public FSM status so project
3
+ -- deletion never mistakes an early terminal outcome for a stopped worker.
4
+ ALTER TABLE "docker_migration_run"
5
+ ADD COLUMN "execution_started_at" timestamp,
6
+ ADD COLUMN "execution_finished_at" timestamp;
7
+ --> statement-breakpoint
8
+ CREATE INDEX "idx_docker_migration_execution_in_flight"
9
+ ON "docker_migration_run" ("project_id")
10
+ WHERE "execution_started_at" IS NOT NULL
11
+ AND "execution_finished_at" IS NULL;
@@ -0,0 +1,6 @@
1
+ -- Project deletion and deployment admission query the durable build-worker
2
+ -- lease, including after the deployment status has already become terminal.
3
+ CREATE INDEX "idx_build_session_live_project_deployment"
4
+ ON "build_session" ("project_id", "deployment_id")
5
+ WHERE "started_at" IS NOT NULL
6
+ AND "finished_at" IS NULL;
@@ -0,0 +1,3 @@
1
+ -- Keep deferred cleanup ordered by immutable physical target identity. Server
2
+ -- rows are aliases and two aliases may reach the same bind namespace.
3
+ ALTER TABLE "orphaned_resource" ADD COLUMN "target_key" text;
@@ -0,0 +1,2 @@
1
+ -- Add ssl_challenge column to domain table for DNS-01 ACME challenge support
2
+ ALTER TABLE "domain" ADD COLUMN IF NOT EXISTS "ssl_challenge" text DEFAULT 'http-01' NOT NULL;
@@ -764,6 +764,62 @@
764
764
  "when": 1788301307325,
765
765
  "tag": "0108_credential",
766
766
  "breakpoints": true
767
+ },
768
+ {
769
+ "idx": 109,
770
+ "version": "7",
771
+ "when": 1788387707325,
772
+ "tag": "0109_service_build_args",
773
+ "breakpoints": true
774
+ },
775
+ {
776
+ "idx": 110,
777
+ "version": "7",
778
+ "when": 1788474107325,
779
+ "tag": "0110_service_deployment_host_ports",
780
+ "breakpoints": true
781
+ },
782
+ {
783
+ "idx": 111,
784
+ "version": "7",
785
+ "when": 1788560507325,
786
+ "tag": "0111_host_port_claim",
787
+ "breakpoints": true
788
+ },
789
+ {
790
+ "idx": 112,
791
+ "version": "7",
792
+ "when": 1788646907325,
793
+ "tag": "0112_backup_run_execution_lease",
794
+ "breakpoints": true
795
+ },
796
+ {
797
+ "idx": 113,
798
+ "version": "7",
799
+ "when": 1788733307325,
800
+ "tag": "0113_docker_migration_execution_lease",
801
+ "breakpoints": true
802
+ },
803
+ {
804
+ "idx": 114,
805
+ "version": "7",
806
+ "when": 1788819707325,
807
+ "tag": "0114_build_session_execution_lease_index",
808
+ "breakpoints": true
809
+ },
810
+ {
811
+ "idx": 115,
812
+ "version": "7",
813
+ "when": 1788906107325,
814
+ "tag": "0115_orphan_target_key",
815
+ "breakpoints": true
816
+ },
817
+ {
818
+ "idx": 116,
819
+ "version": "7",
820
+ "when": 1788992507325,
821
+ "tag": "0116_domain_ssl_challenge",
822
+ "breakpoints": true
767
823
  }
768
824
  ]
769
825
  }
@@ -4,21 +4,21 @@ import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
  import {
6
6
  SystemManager
7
- } from "./chunk-FYPFEDPZ.js";
8
- import "./chunk-ZPJ74LXE.js";
9
- import "./chunk-NRTJRNAE.js";
10
- import "./chunk-QHMDCYZ3.js";
7
+ } from "./chunk-R5DC5PEF.js";
8
+ import "./chunk-NIYD7MD2.js";
9
+ import "./chunk-IAMOUDHY.js";
10
+ import "./chunk-7PEXM2UI.js";
11
11
  import "./chunk-I3DPMTSF.js";
12
12
  import "./chunk-R4VDPFLS.js";
13
- import "./chunk-PVP4RGWT.js";
14
- import "./chunk-BLEXTYRK.js";
15
- import "./chunk-FZ6QCF6B.js";
16
- import "./chunk-H3WT3A6R.js";
17
- import "./chunk-GIPJNNI5.js";
18
- import "./chunk-VSTFHUCV.js";
19
- import "./chunk-UWEV6XTS.js";
13
+ import "./chunk-T46BQOLY.js";
14
+ import "./chunk-GNOMEMNI.js";
15
+ import "./chunk-NPSRGIHV.js";
16
+ import "./chunk-P7RCYELG.js";
17
+ import "./chunk-X53JXRS4.js";
18
+ import "./chunk-BO6CY4V2.js";
19
+ import "./chunk-D6HU4VUZ.js";
20
20
  import "./chunk-N5YZMO33.js";
21
- import "./chunk-2VSW6Q6C.js";
21
+ import "./chunk-WEZFTL4V.js";
22
22
  import "./chunk-PXKCZB2I.js";
23
23
  export {
24
24
  SystemManager
@@ -12,9 +12,9 @@ import {
12
12
  openSftp,
13
13
  openSshExecChannel,
14
14
  openSshUnixSocket
15
- } from "./chunk-5T4UVOM3.js";
15
+ } from "./chunk-TAZZZKYO.js";
16
16
  import "./chunk-N5YZMO33.js";
17
- import "./chunk-2VSW6Q6C.js";
17
+ import "./chunk-WEZFTL4V.js";
18
18
  import "./chunk-PXKCZB2I.js";
19
19
  export {
20
20
  DOCKER_DIAL_STDIO_COMMAND,
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env sh
2
+ ":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
3
+ import { createRequire as __ospCreateRequire } from "node:module";
4
+ const require = __ospCreateRequire(import.meta.url);
5
+ import {
6
+ normalizeUrl,
7
+ runHeadlessProvision,
8
+ startService,
9
+ upCommand
10
+ } from "./chunk-RCMERVBL.js";
11
+ import "./chunk-5I3COAFH.js";
12
+ import "./chunk-7YBWXEM6.js";
13
+ import "./chunk-5UXHT6ED.js";
14
+ import "./chunk-QWHBRY2K.js";
15
+ import "./chunk-NUT6HKK6.js";
16
+ import "./chunk-ELGRMZOW.js";
17
+ import "./chunk-R5DC5PEF.js";
18
+ import "./chunk-ONKEYSMY.js";
19
+ import "./chunk-XZYFZ6A5.js";
20
+ import "./chunk-PDW4L3NV.js";
21
+ import "./chunk-DOD2BXHQ.js";
22
+ import "./chunk-42WQABXM.js";
23
+ import "./chunk-DRK3MEDS.js";
24
+ import "./chunk-3NQQXMDR.js";
25
+ import "./chunk-ZWLDLTJP.js";
26
+ import "./chunk-D3OEMXYP.js";
27
+ import "./chunk-MUWVC5R4.js";
28
+ import "./chunk-NIYD7MD2.js";
29
+ import "./chunk-IAMOUDHY.js";
30
+ import "./chunk-7PEXM2UI.js";
31
+ import "./chunk-I3DPMTSF.js";
32
+ import "./chunk-WNWQBB7F.js";
33
+ import "./chunk-NRU2EBYZ.js";
34
+ import "./chunk-RHLNVZMS.js";
35
+ import "./chunk-3MP6ACKM.js";
36
+ import "./chunk-6GU6JSK6.js";
37
+ import "./chunk-ENKJ7XIF.js";
38
+ import "./chunk-5DJOB7IX.js";
39
+ import "./chunk-SK4FFCFR.js";
40
+ import "./chunk-AHJYP7DG.js";
41
+ import "./chunk-UAWY6X7V.js";
42
+ import "./chunk-R4VDPFLS.js";
43
+ import "./chunk-VAI5VOOI.js";
44
+ import "./chunk-TAZZZKYO.js";
45
+ import "./chunk-T6DVUX4F.js";
46
+ import "./chunk-T46BQOLY.js";
47
+ import "./chunk-GNOMEMNI.js";
48
+ import "./chunk-NPSRGIHV.js";
49
+ import "./chunk-P7RCYELG.js";
50
+ import "./chunk-X53JXRS4.js";
51
+ import "./chunk-BO6CY4V2.js";
52
+ import "./chunk-D6HU4VUZ.js";
53
+ import "./chunk-N5YZMO33.js";
54
+ import "./chunk-WEZFTL4V.js";
55
+ import "./chunk-PXKCZB2I.js";
56
+ export {
57
+ normalizeUrl,
58
+ runHeadlessProvision,
59
+ startService,
60
+ upCommand
61
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openship",
3
- "version": "0.6.7",
3
+ "version": "0.6.8",
4
4
  "description": "Openship CLI - deploy, manage, and open your Openship platform from the terminal",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env sh
2
- ":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
3
- import { createRequire as __ospCreateRequire } from "node:module";
4
- const require = __ospCreateRequire(import.meta.url);
5
- import {
6
- BareRuntime,
7
- STATIC_RELEASE_BASE
8
- } from "./chunk-S6B2Z3OO.js";
9
- import "./chunk-MEE6OZFP.js";
10
- import "./chunk-WU54BXFE.js";
11
- import "./chunk-H4FS5BED.js";
12
- import "./chunk-GGIAIGUL.js";
13
- import "./chunk-R4VDPFLS.js";
14
- import "./chunk-2ANV5ZQ5.js";
15
- import "./chunk-5T4UVOM3.js";
16
- import "./chunk-E2X26PXR.js";
17
- import "./chunk-PVP4RGWT.js";
18
- import "./chunk-BLEXTYRK.js";
19
- import "./chunk-FZ6QCF6B.js";
20
- import "./chunk-H3WT3A6R.js";
21
- import "./chunk-VSTFHUCV.js";
22
- import "./chunk-UWEV6XTS.js";
23
- import "./chunk-N5YZMO33.js";
24
- import "./chunk-2VSW6Q6C.js";
25
- import "./chunk-PXKCZB2I.js";
26
- export {
27
- BareRuntime,
28
- STATIC_RELEASE_BASE
29
- };