openship 0.6.1 → 0.6.5
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/README.md +7 -2
- package/dist/{bare-IWS2QHJ3.js → bare-XQIPDO4R.js} +10 -9
- package/dist/{chunk-RRJJGVKE.js → chunk-3ZAGC5NT.js} +64 -17
- package/dist/{chunk-6ODUBKUB.js → chunk-5OUWIPOB.js} +69 -7
- package/dist/chunk-6HOA5JT7.js +124 -0
- package/dist/{chunk-TWJCLD4W.js → chunk-6JELW75A.js} +4 -4
- package/dist/{chunk-IOT5ZX23.js → chunk-7334NSJL.js} +399 -369
- package/dist/chunk-7S4USQYF.js +1753 -0
- package/dist/{chunk-3LDWWY7U.js → chunk-A7EWM2KA.js} +41 -7
- package/dist/chunk-ELGRMZOW.js +25 -0
- package/dist/chunk-EZPPTWJQ.js +292 -0
- package/dist/{chunk-IXM5245F.js → chunk-GRTXMUHA.js} +553 -538
- package/dist/chunk-HPXP6LXZ.js +428 -0
- package/dist/{chunk-OTLSJYAC.js → chunk-LEYSL46B.js} +2135 -85
- package/dist/{chunk-EMXI4UCU.js → chunk-LFCSC4IU.js} +29 -10
- package/dist/{chunk-JIMUYEKN.js → chunk-MSZUCNPV.js} +1 -1
- package/dist/{chunk-YIPMDGG6.js → chunk-PZRRL5PC.js} +68 -23
- package/dist/{chunk-2NZSUXOB.js → chunk-QLX7NBEA.js} +1208 -599
- package/dist/chunk-RFWJE7ZN.js +68 -0
- package/dist/{chunk-VDDMADOF.js → chunk-TM2IQPYU.js} +16 -2
- package/dist/{chunk-3FYIXVX5.js → chunk-VDESJSG6.js} +451 -106
- package/dist/{chunk-UC7YIEHT.js → chunk-VHMOQL5Y.js} +254 -45
- package/dist/{chunk-EW6KB2J7.js → chunk-VLQ3UIVO.js} +393 -53
- package/dist/{chunk-VZ2ZHPS2.js → chunk-WE7BXW6L.js} +3 -9
- package/dist/chunk-WFRXYWK2.js +444 -0
- package/dist/chunk-XRNRT37W.js +316 -0
- package/dist/{chunk-3NZICQHF.js → chunk-XVOBL7BC.js} +31 -8
- package/dist/cloud-3DODOWTR.js +36 -0
- package/dist/{detect-ALF4GXRX.js → detect-P4CIQBRH.js} +3 -3
- package/dist/{docker-QECQJ5P4.js → docker-3K2NEBD6.js} +15 -8
- package/dist/{docker-edge-executor-62N64MGS.js → docker-edge-executor-YZZ6P7IC.js} +5 -5
- package/dist/{edge-import-SAYTRJLO.js → edge-import-MCJNVTZ2.js} +26 -23
- package/dist/edge-preflight-ES6FH4JK.js +42 -0
- package/dist/{ensure-container-edge-CFSCPGZK.js → ensure-container-edge-YPITNH45.js} +9 -8
- package/dist/{executor-PT6UEJ5M.js → executor-DZGX55K2.js} +12 -5
- package/dist/host-channel-preflight-MUXE3KZU.js +49 -0
- package/dist/index.js +4089 -4538
- package/dist/{nginx-YOEEFBTE.js → nginx-NSAHWGJV.js} +11 -5
- package/dist/node-bootstrap.js +241 -0
- package/dist/node-entry.js +52 -1
- package/dist/{openresty-lua-WGBO2M3Z.js → openresty-lua-DR4D3EZ6.js} +6 -2
- package/dist/privilege-YTVI4SKF.js +19 -0
- package/dist/server/engine/samples/fail2ban/jail.d/sshd.local +4 -1
- package/dist/server/index.js +21391 -13110
- package/dist/server/migrations/0098_instance_product_mode.sql +12 -0
- package/dist/server/migrations/0099_mail_webmail_project.sql +24 -0
- package/dist/server/migrations/0100_server_ssh_private_key.sql +11 -0
- package/dist/server/migrations/0101_mail_resume_step.sql +12 -0
- package/dist/server/migrations/0102_project_workload_axes.sql +19 -0
- package/dist/server/migrations/0103_dns_credential.sql +41 -0
- package/dist/server/migrations/0104_instance_host_control.sql +15 -0
- package/dist/server/migrations/meta/_journal.json +49 -0
- package/dist/{setup-M2ZDGH3O.js → setup-WUUZURHS.js} +10 -9
- package/dist/up-XEO3SR6Z.js +58 -0
- package/package.json +4 -2
- package/dist/chunk-IW2UKBVF.js +0 -144
- package/dist/chunk-ZCFVHA25.js +0 -89
- package/dist/cloud-M2YLWEXO.js +0 -31
- /package/dist/{dist-es-JGBPABJI.js → dist-es-ZP5QDSJ3.js} +0 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
-- Openship Mail: which product this instance presents itself as.
|
|
2
|
+
--
|
|
3
|
+
-- Nullable with NO default, deliberately. The instance_settings row exists on
|
|
4
|
+
-- every instance, so a NOT NULL DEFAULT 'platform' would write a concrete value
|
|
5
|
+
-- everywhere and permanently shadow the OPENSHIP_PRODUCT env var — the resolver
|
|
6
|
+
-- reads `settings.product_mode ?? env.OPENSHIP_PRODUCT`, so "unset" has to stay
|
|
7
|
+
-- representable. NULL means "no instance override".
|
|
8
|
+
--
|
|
9
|
+
-- Presentation scope only: this hides nav entries and rebrands the shell. It is
|
|
10
|
+
-- not an authorization boundary and no route reads it — webmail deploys through
|
|
11
|
+
-- the ordinary project pipeline, so the platform endpoints stay live in mail mode.
|
|
12
|
+
ALTER TABLE "instance_settings" ADD COLUMN IF NOT EXISTS "product_mode" text;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
-- The webmail project serving a mail server, as a stored FK.
|
|
2
|
+
--
|
|
3
|
+
-- Webmail is now an ordinary catalog app (packages/core/src/apps/catalog/webmail.json)
|
|
4
|
+
-- installed through the SAME generic installer as every other app, so its slug is
|
|
5
|
+
-- derived from the project NAME the operator typed. The link therefore cannot be a
|
|
6
|
+
-- naming convention any more: the old lookup parsed `webmail-<serverId>` back out of
|
|
7
|
+
-- the slug, which the generic installer never produces — and which, while it existed,
|
|
8
|
+
-- mislinked any project a user happened to name "Webmail Prod" (slug `webmail-prod`,
|
|
9
|
+
-- read back as mail server "prod").
|
|
10
|
+
--
|
|
11
|
+
-- Nullable: most servers have no webmail, and an operator may run one outside
|
|
12
|
+
-- openship. ON DELETE SET NULL so deleting the webmail project clears the link and
|
|
13
|
+
-- /emails falls back to the install CTA rather than pointing at a row that is gone.
|
|
14
|
+
--
|
|
15
|
+
-- No backfill. A pre-existing webmail project still carries the retired
|
|
16
|
+
-- `mail-webmail` template id and the `webmail-<serverId>` slug; the mail status
|
|
17
|
+
-- resolver keeps that legacy slug lookup as a fallback for exactly those rows, and
|
|
18
|
+
-- stamps this column the first time it resolves one.
|
|
19
|
+
ALTER TABLE "mail_servers" ADD COLUMN IF NOT EXISTS "webmail_project_id" text;--> statement-breakpoint
|
|
20
|
+
|
|
21
|
+
DO $$ BEGIN
|
|
22
|
+
ALTER TABLE "mail_servers" ADD CONSTRAINT "mail_servers_webmail_project_id_project_id_fk"
|
|
23
|
+
FOREIGN KEY ("webmail_project_id") REFERENCES "public"."project"("id") ON DELETE set null ON UPDATE no action;
|
|
24
|
+
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
-- Pasted / uploaded SSH private-key material, stored encrypted at rest (enc1:).
|
|
2
|
+
--
|
|
3
|
+
-- Nullable with no default. The existing `ssh_key_path` points at a key file on
|
|
4
|
+
-- the API host — useless on a remote / VPS instance where the operator's key
|
|
5
|
+
-- lives on their own machine. This column holds the key bytes themselves so the
|
|
6
|
+
-- dashboard can paste or upload a key from any browser; buildSshConfig() prefers
|
|
7
|
+
-- it (decrypted) over reading `ssh_key_path` off disk.
|
|
8
|
+
--
|
|
9
|
+
-- Write-only: never serialized back to the client, and listed in
|
|
10
|
+
-- ENCRYPTED_COLUMNS so it is stripped from any cross-host dump/restore.
|
|
11
|
+
ALTER TABLE "servers" ADD COLUMN IF NOT EXISTS "ssh_private_key" text;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
-- The setup step an incomplete mail install is paused at, mirrored from the
|
|
2
|
+
-- on-host state file's `resumeStep` whenever the wizard halts (a failed step,
|
|
3
|
+
-- or a DNS/PTR hold). NULL once the install completes or before it ever halts.
|
|
4
|
+
--
|
|
5
|
+
-- Lets the /emails server list surface WHERE an incomplete install stopped
|
|
6
|
+
-- ("Stopped · step 6: Retrieve DKIM Keys") without the per-server SSH probe
|
|
7
|
+
-- this table exists to avoid — only the step id is stored; the human label is
|
|
8
|
+
-- derived from it against MAIL_SETUP_STEPS.
|
|
9
|
+
--
|
|
10
|
+
-- Nullable, no default, no backfill: a pre-existing incomplete install gets its
|
|
11
|
+
-- step stamped the next time the wizard halts (or cleared on completion).
|
|
12
|
+
ALTER TABLE "mail_servers" ADD COLUMN IF NOT EXISTS "resume_step" integer;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
-- Deployment-class axes — deconflate the legacy `has_server` / `has_build`
|
|
2
|
+
-- booleans, which each mixed two independent concerns (issue #538). See
|
|
3
|
+
-- @repo/core deployment-class.ts.
|
|
4
|
+
--
|
|
5
|
+
-- All three are EXPLICIT OVERRIDES: NULL means "derive from the legacy flags +
|
|
6
|
+
-- framework + source", so every pre-existing project keeps classifying exactly
|
|
7
|
+
-- as before and no backfill is needed. `has_server` / `has_build` are kept and
|
|
8
|
+
-- written in sync, never dropped — rollback snapshots and every legacy reader
|
|
9
|
+
-- still depend on them.
|
|
10
|
+
--
|
|
11
|
+
-- source_kind text "git" | "image" | "upload" (git needs a clone)
|
|
12
|
+
-- build_kind text "dockerfile" | "buildpack" | "static" | "prebuilt"
|
|
13
|
+
-- workload_type text "web" | "worker" | "static" (worker = portless
|
|
14
|
+
-- long-running container: no port, no route)
|
|
15
|
+
ALTER TABLE "project" ADD COLUMN IF NOT EXISTS "source_kind" text;
|
|
16
|
+
--> statement-breakpoint
|
|
17
|
+
ALTER TABLE "project" ADD COLUMN IF NOT EXISTS "build_kind" text;
|
|
18
|
+
--> statement-breakpoint
|
|
19
|
+
ALTER TABLE "project" ADD COLUMN IF NOT EXISTS "workload_type" text;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
-- DNS provider credentials — the token that lets Openship write a domain's records.
|
|
2
|
+
--
|
|
3
|
+
-- Adding a custom domain has always ended the same way: Openship computes the exact
|
|
4
|
+
-- A/CNAME + `_openship-challenge` TXT records and then asks the operator to go paste
|
|
5
|
+
-- them somewhere else. Every minute between "added" and "pasted" is a domain that
|
|
6
|
+
-- doesn't resolve, can't pass ACME, and looks broken. With a scoped provider token we
|
|
7
|
+
-- write those records ourselves and the domain verifies on its own.
|
|
8
|
+
--
|
|
9
|
+
-- The token is the sensitive part: Zone:Read + DNS:Edit can rewrite every record in
|
|
10
|
+
-- every zone it can see, so it is stored ONLY as an `enc1:` AES-256-GCM envelope
|
|
11
|
+
-- (`encryptSecretField`) and is never returned by the API — not in full, not as a
|
|
12
|
+
-- prefix. `status` exists so a token that gets revoked upstream becomes visible in the
|
|
13
|
+
-- UI instead of silently turning auto-provisioning off forever.
|
|
14
|
+
CREATE TABLE IF NOT EXISTS "dns_credential" (
|
|
15
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
16
|
+
"organization_id" text NOT NULL REFERENCES "organization"("id") ON DELETE CASCADE,
|
|
17
|
+
-- Provider name ("cloudflare"). Text, not an enum: adding a provider should be a
|
|
18
|
+
-- registry entry, not a migration.
|
|
19
|
+
"provider" text NOT NULL,
|
|
20
|
+
-- Operator-facing label, e.g. "Cloudflare production".
|
|
21
|
+
"name" text NOT NULL,
|
|
22
|
+
"api_token_enc" text NOT NULL,
|
|
23
|
+
-- active | invalid. Flipped to 'invalid' by the provisioning path when the provider
|
|
24
|
+
-- answers 401/403, which is the only moment we learn a stored token stopped working.
|
|
25
|
+
"status" text NOT NULL DEFAULT 'active',
|
|
26
|
+
"last_verified_at" timestamp,
|
|
27
|
+
"created_at" timestamp NOT NULL DEFAULT now(),
|
|
28
|
+
"updated_at" timestamp NOT NULL DEFAULT now()
|
|
29
|
+
);
|
|
30
|
+
--> statement-breakpoint
|
|
31
|
+
-- Zone resolution runs on EVERY domain add and remove and asks one question: "this
|
|
32
|
+
-- org's active credentials". Leading org column means the plain org-wide listing rides
|
|
33
|
+
-- the same index as a prefix, so this is the only one the table needs.
|
|
34
|
+
CREATE INDEX IF NOT EXISTS "idx_dns_credential_org_status"
|
|
35
|
+
ON "dns_credential" ("organization_id", "status");
|
|
36
|
+
--> statement-breakpoint
|
|
37
|
+
-- One label per provider per org. A second "Cloudflare production" is a double-submit,
|
|
38
|
+
-- and two credentials that resolve the same zone makes "which token wrote this record"
|
|
39
|
+
-- unanswerable at cleanup time.
|
|
40
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "uq_dns_credential_org_provider_name"
|
|
41
|
+
ON "dns_credential" ("organization_id", "provider", "name");
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
-- Runtime host-control toggle (#527): may OpenShip deploy to the machine it runs on?
|
|
2
|
+
--
|
|
3
|
+
-- Nullable with NO default, deliberately — the same contract as product_mode
|
|
4
|
+
-- (0098). The instance_settings row exists on every instance, so a NOT NULL
|
|
5
|
+
-- DEFAULT would write a concrete value everywhere and permanently shadow the
|
|
6
|
+
-- OPENSHIP_HOST_CONTROL env var (written by `openship up --no-host-control`).
|
|
7
|
+
-- The resolver reads `settings.host_control_enabled ?? env`, so "unset" has to
|
|
8
|
+
-- stay representable. NULL means "no instance override, use env".
|
|
9
|
+
--
|
|
10
|
+
-- Unlike product_mode this DOES gate privileged behavior (host-root deploys via
|
|
11
|
+
-- the container->host SSH channel + mounted docker socket), so the WRITE path is
|
|
12
|
+
-- gated to the box-owning org's owner. The precedence still lets the DB override
|
|
13
|
+
-- env: the operator's need is to re-enable from Settings what --no-host-control
|
|
14
|
+
-- turned off.
|
|
15
|
+
ALTER TABLE "instance_settings" ADD COLUMN IF NOT EXISTS "host_control_enabled" boolean;
|
|
@@ -687,6 +687,55 @@
|
|
|
687
687
|
"when": 1787350907325,
|
|
688
688
|
"tag": "0097_update_status_upstream_only",
|
|
689
689
|
"breakpoints": true
|
|
690
|
+
},
|
|
691
|
+
{
|
|
692
|
+
"idx": 98,
|
|
693
|
+
"version": "7",
|
|
694
|
+
"when": 1787437307325,
|
|
695
|
+
"tag": "0098_instance_product_mode",
|
|
696
|
+
"breakpoints": true
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
"idx": 99,
|
|
700
|
+
"version": "7",
|
|
701
|
+
"when": 1787523707325,
|
|
702
|
+
"tag": "0099_mail_webmail_project",
|
|
703
|
+
"breakpoints": true
|
|
704
|
+
},
|
|
705
|
+
{
|
|
706
|
+
"idx": 100,
|
|
707
|
+
"version": "7",
|
|
708
|
+
"when": 1787610107325,
|
|
709
|
+
"tag": "0100_server_ssh_private_key",
|
|
710
|
+
"breakpoints": true
|
|
711
|
+
},
|
|
712
|
+
{
|
|
713
|
+
"idx": 101,
|
|
714
|
+
"version": "7",
|
|
715
|
+
"when": 1787696507325,
|
|
716
|
+
"tag": "0101_mail_resume_step",
|
|
717
|
+
"breakpoints": true
|
|
718
|
+
},
|
|
719
|
+
{
|
|
720
|
+
"idx": 102,
|
|
721
|
+
"version": "7",
|
|
722
|
+
"when": 1787782907325,
|
|
723
|
+
"tag": "0102_project_workload_axes",
|
|
724
|
+
"breakpoints": true
|
|
725
|
+
},
|
|
726
|
+
{
|
|
727
|
+
"idx": 103,
|
|
728
|
+
"version": "7",
|
|
729
|
+
"when": 1787869307325,
|
|
730
|
+
"tag": "0103_dns_credential",
|
|
731
|
+
"breakpoints": true
|
|
732
|
+
},
|
|
733
|
+
{
|
|
734
|
+
"idx": 104,
|
|
735
|
+
"version": "7",
|
|
736
|
+
"when": 1787955707325,
|
|
737
|
+
"tag": "0104_instance_host_control",
|
|
738
|
+
"breakpoints": true
|
|
690
739
|
}
|
|
691
740
|
]
|
|
692
741
|
}
|
|
@@ -4,17 +4,18 @@ 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-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-ZCFVHA25.js";
|
|
11
|
-
import "./chunk-EW6KB2J7.js";
|
|
7
|
+
} from "./chunk-XVOBL7BC.js";
|
|
8
|
+
import "./chunk-7334NSJL.js";
|
|
9
|
+
import "./chunk-VLQ3UIVO.js";
|
|
12
10
|
import "./chunk-I3DPMTSF.js";
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-RFWJE7ZN.js";
|
|
12
|
+
import "./chunk-WE7BXW6L.js";
|
|
13
|
+
import "./chunk-A7EWM2KA.js";
|
|
14
|
+
import "./chunk-PZRRL5PC.js";
|
|
15
|
+
import "./chunk-EZPPTWJQ.js";
|
|
16
|
+
import "./chunk-WFRXYWK2.js";
|
|
16
17
|
import "./chunk-ZFJXPCQP.js";
|
|
17
|
-
import "./chunk-
|
|
18
|
+
import "./chunk-LEYSL46B.js";
|
|
18
19
|
import "./chunk-PXKCZB2I.js";
|
|
19
20
|
export {
|
|
20
21
|
SystemManager
|
|
@@ -0,0 +1,58 @@
|
|
|
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
|
+
ensureInternalToken,
|
|
7
|
+
normalizeUrl,
|
|
8
|
+
runHeadlessProvision,
|
|
9
|
+
startService,
|
|
10
|
+
upCommand
|
|
11
|
+
} from "./chunk-7S4USQYF.js";
|
|
12
|
+
import "./chunk-6HOA5JT7.js";
|
|
13
|
+
import "./chunk-HPXP6LXZ.js";
|
|
14
|
+
import "./chunk-XRNRT37W.js";
|
|
15
|
+
import "./chunk-QLX7NBEA.js";
|
|
16
|
+
import "./chunk-QWHBRY2K.js";
|
|
17
|
+
import "./chunk-ELGRMZOW.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-6JELW75A.js";
|
|
27
|
+
import "./chunk-3ZAGC5NT.js";
|
|
28
|
+
import "./chunk-WNWQBB7F.js";
|
|
29
|
+
import "./chunk-2GWYYHOR.js";
|
|
30
|
+
import "./chunk-RXQBD4ZY.js";
|
|
31
|
+
import "./chunk-XVOBL7BC.js";
|
|
32
|
+
import "./chunk-7334NSJL.js";
|
|
33
|
+
import "./chunk-VLQ3UIVO.js";
|
|
34
|
+
import "./chunk-I3DPMTSF.js";
|
|
35
|
+
import "./chunk-VDESJSG6.js";
|
|
36
|
+
import "./chunk-LFCSC4IU.js";
|
|
37
|
+
import "./chunk-GRTXMUHA.js";
|
|
38
|
+
import "./chunk-MSZUCNPV.js";
|
|
39
|
+
import "./chunk-TM2IQPYU.js";
|
|
40
|
+
import "./chunk-VHMOQL5Y.js";
|
|
41
|
+
import "./chunk-5OUWIPOB.js";
|
|
42
|
+
import "./chunk-6FH4AXVY.js";
|
|
43
|
+
import "./chunk-RFWJE7ZN.js";
|
|
44
|
+
import "./chunk-WE7BXW6L.js";
|
|
45
|
+
import "./chunk-A7EWM2KA.js";
|
|
46
|
+
import "./chunk-PZRRL5PC.js";
|
|
47
|
+
import "./chunk-EZPPTWJQ.js";
|
|
48
|
+
import "./chunk-WFRXYWK2.js";
|
|
49
|
+
import "./chunk-ZFJXPCQP.js";
|
|
50
|
+
import "./chunk-LEYSL46B.js";
|
|
51
|
+
import "./chunk-PXKCZB2I.js";
|
|
52
|
+
export {
|
|
53
|
+
ensureInternalToken,
|
|
54
|
+
normalizeUrl,
|
|
55
|
+
runHeadlessProvision,
|
|
56
|
+
startService,
|
|
57
|
+
upCommand
|
|
58
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openship",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.5",
|
|
4
4
|
"description": "Openship CLI - deploy, manage, and open your Openship platform from the terminal",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -20,6 +20,9 @@
|
|
|
20
20
|
"bin": {
|
|
21
21
|
"openship": "./dist/node-entry.js"
|
|
22
22
|
},
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=22"
|
|
25
|
+
},
|
|
23
26
|
"files": [
|
|
24
27
|
"dist",
|
|
25
28
|
"README.md"
|
|
@@ -42,7 +45,6 @@
|
|
|
42
45
|
"commander": "^14.0.3",
|
|
43
46
|
"dockerode": "^4.0.9",
|
|
44
47
|
"open": "^10.2.0",
|
|
45
|
-
"openship": "^0.5.0",
|
|
46
48
|
"ora": "^9.3.0",
|
|
47
49
|
"ssh2": "^1.17.0"
|
|
48
50
|
},
|
package/dist/chunk-IW2UKBVF.js
DELETED
|
@@ -1,144 +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
|
-
formatDuration,
|
|
7
|
-
isRemoteConnectionError,
|
|
8
|
-
systemDebug
|
|
9
|
-
} from "./chunk-ZCFVHA25.js";
|
|
10
|
-
import {
|
|
11
|
-
safeErrorMessage
|
|
12
|
-
} from "./chunk-OTLSJYAC.js";
|
|
13
|
-
|
|
14
|
-
// ../../packages/adapters/src/system/environment.ts
|
|
15
|
-
var profileCache = /* @__PURE__ */ new WeakMap();
|
|
16
|
-
async function execSafe(executor, command, timeout = 5e3) {
|
|
17
|
-
const startedAt = Date.now();
|
|
18
|
-
systemDebug("environment", `exec:start ${command}`);
|
|
19
|
-
try {
|
|
20
|
-
const result = await executor.exec(command, { timeout });
|
|
21
|
-
systemDebug(
|
|
22
|
-
"environment",
|
|
23
|
-
`exec:ok ${command} (${formatDuration(startedAt)})`
|
|
24
|
-
);
|
|
25
|
-
return result;
|
|
26
|
-
} catch (err) {
|
|
27
|
-
if (isRemoteConnectionError(err)) {
|
|
28
|
-
systemDebug(
|
|
29
|
-
"environment",
|
|
30
|
-
`exec:abort ${command} (${formatDuration(startedAt)}) ${safeErrorMessage(err)}`
|
|
31
|
-
);
|
|
32
|
-
throw err;
|
|
33
|
-
}
|
|
34
|
-
const msg = safeErrorMessage(err);
|
|
35
|
-
systemDebug(
|
|
36
|
-
"environment",
|
|
37
|
-
`exec:fail ${command} (${formatDuration(startedAt)}) ${msg}`
|
|
38
|
-
);
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
function parseOs(uname) {
|
|
43
|
-
const value = uname?.trim().toLowerCase();
|
|
44
|
-
if (value === "linux") return "linux";
|
|
45
|
-
if (value === "darwin") return "darwin";
|
|
46
|
-
return "unknown";
|
|
47
|
-
}
|
|
48
|
-
function parseArch(uname) {
|
|
49
|
-
const value = uname?.trim().toLowerCase() ?? "";
|
|
50
|
-
if (["x86_64", "amd64"].includes(value)) return "amd64";
|
|
51
|
-
if (["aarch64", "arm64"].includes(value)) return "arm64";
|
|
52
|
-
return "unknown";
|
|
53
|
-
}
|
|
54
|
-
function parseDistro(osRelease) {
|
|
55
|
-
if (!osRelease) return null;
|
|
56
|
-
const lower = osRelease.toLowerCase();
|
|
57
|
-
const match = lower.match(/^id=(.+)$/m);
|
|
58
|
-
const id = match?.[1]?.replaceAll('"', "").trim();
|
|
59
|
-
switch (id) {
|
|
60
|
-
case "ubuntu":
|
|
61
|
-
return "ubuntu";
|
|
62
|
-
case "debian":
|
|
63
|
-
return "debian";
|
|
64
|
-
case "fedora":
|
|
65
|
-
return "fedora";
|
|
66
|
-
case "rhel":
|
|
67
|
-
case "rhel server":
|
|
68
|
-
return "rhel";
|
|
69
|
-
case "centos":
|
|
70
|
-
return "centos";
|
|
71
|
-
case "alpine":
|
|
72
|
-
return "alpine";
|
|
73
|
-
default:
|
|
74
|
-
return "unknown";
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
async function detectPackageManager(executor) {
|
|
78
|
-
const checks = [
|
|
79
|
-
["apt", "command -v apt-get"],
|
|
80
|
-
["dnf", "command -v dnf"],
|
|
81
|
-
["yum", "command -v yum"],
|
|
82
|
-
["apk", "command -v apk"],
|
|
83
|
-
["brew", "command -v brew"]
|
|
84
|
-
];
|
|
85
|
-
for (const [pm, command] of checks) {
|
|
86
|
-
if (await execSafe(executor, command)) return pm;
|
|
87
|
-
}
|
|
88
|
-
return "none";
|
|
89
|
-
}
|
|
90
|
-
async function detectServiceManager(executor) {
|
|
91
|
-
if (await execSafe(executor, "command -v systemctl")) return "systemd";
|
|
92
|
-
if (await execSafe(executor, "command -v launchctl")) return "launchd";
|
|
93
|
-
return "none";
|
|
94
|
-
}
|
|
95
|
-
async function detectPrivilege(executor) {
|
|
96
|
-
const uid = await execSafe(executor, "id -u");
|
|
97
|
-
const isRoot = uid?.trim() === "0";
|
|
98
|
-
if (isRoot) return { isRoot: true, canSudo: false };
|
|
99
|
-
const sudo = await execSafe(
|
|
100
|
-
executor,
|
|
101
|
-
"sudo -n true 2>/dev/null && echo yes || echo no"
|
|
102
|
-
);
|
|
103
|
-
return { isRoot: false, canSudo: sudo?.trim() === "yes" };
|
|
104
|
-
}
|
|
105
|
-
async function detectProfile(executor) {
|
|
106
|
-
const startedAt = Date.now();
|
|
107
|
-
systemDebug("environment", "detect:start");
|
|
108
|
-
const unameOs = await execSafe(executor, "uname -s");
|
|
109
|
-
const unameArch = await execSafe(executor, "uname -m");
|
|
110
|
-
const osRelease = await execSafe(executor, "cat /etc/os-release");
|
|
111
|
-
const packageManager = await detectPackageManager(executor);
|
|
112
|
-
const serviceManager = await detectServiceManager(executor);
|
|
113
|
-
const { isRoot, canSudo } = await detectPrivilege(executor);
|
|
114
|
-
const os = parseOs(unameOs);
|
|
115
|
-
const profile = {
|
|
116
|
-
os,
|
|
117
|
-
arch: parseArch(unameArch),
|
|
118
|
-
distro: os === "linux" ? parseDistro(osRelease) : null,
|
|
119
|
-
packageManager,
|
|
120
|
-
serviceManager,
|
|
121
|
-
isRoot,
|
|
122
|
-
canSudo
|
|
123
|
-
};
|
|
124
|
-
systemDebug(
|
|
125
|
-
"environment",
|
|
126
|
-
`detect:done (${formatDuration(startedAt)}) ${JSON.stringify(profile)}`
|
|
127
|
-
);
|
|
128
|
-
return profile;
|
|
129
|
-
}
|
|
130
|
-
async function resolveEnvironment(executor) {
|
|
131
|
-
let promise = profileCache.get(executor);
|
|
132
|
-
if (!promise) {
|
|
133
|
-
systemDebug("environment", "cache:miss");
|
|
134
|
-
promise = detectProfile(executor);
|
|
135
|
-
profileCache.set(executor, promise);
|
|
136
|
-
} else {
|
|
137
|
-
systemDebug("environment", "cache:hit");
|
|
138
|
-
}
|
|
139
|
-
return promise;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export {
|
|
143
|
-
resolveEnvironment
|
|
144
|
-
};
|
package/dist/chunk-ZCFVHA25.js
DELETED
|
@@ -1,89 +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
|
-
|
|
6
|
-
// ../../packages/adapters/src/system/errors.ts
|
|
7
|
-
var SSH_AUTH_ERROR_PATTERNS = [
|
|
8
|
-
"All configured authentication methods failed"
|
|
9
|
-
];
|
|
10
|
-
var RETRYABLE_CONNECTION_ERROR_PATTERNS = [
|
|
11
|
-
"ECONNRESET",
|
|
12
|
-
"ECONNREFUSED",
|
|
13
|
-
"ETIMEDOUT",
|
|
14
|
-
"EHOSTUNREACH",
|
|
15
|
-
"ENETUNREACH",
|
|
16
|
-
"Timed out",
|
|
17
|
-
"Not connected",
|
|
18
|
-
"Connection lost",
|
|
19
|
-
"read ECONNRESET",
|
|
20
|
-
"Handshake failed",
|
|
21
|
-
"keepalive timeout",
|
|
22
|
-
"SSH connection closed before ready",
|
|
23
|
-
// ssh2 emits "Channel open failure: open failed" / "Channel open failure: …"
|
|
24
|
-
// when the SSH SERVER refuses a new channel - typically because the cached
|
|
25
|
-
// connection has gone half-dead (peer-side LOGOUT, network blip,
|
|
26
|
-
// remote sshd MaxSessions). The inner SshExecutor retries `exec`/
|
|
27
|
-
// `streamExec` on this, but `pipeLocal`, `transferIn`, and any other
|
|
28
|
-
// channel-bearing op bubble it up. Listing it here lets `withExecutor`
|
|
29
|
-
// drop the dead connection and retry transparently - fixes the
|
|
30
|
-
// "first redeploy fails, second click works" pattern.
|
|
31
|
-
"Channel open failure",
|
|
32
|
-
"open failed"
|
|
33
|
-
];
|
|
34
|
-
var SshDisconnectedError = class extends Error {
|
|
35
|
-
constructor(message = "SSH connection lost") {
|
|
36
|
-
super(message);
|
|
37
|
-
this.name = "SshDisconnectedError";
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
function isSshDisconnectedError(err) {
|
|
41
|
-
return err instanceof SshDisconnectedError || err instanceof Error && err.name === "SshDisconnectedError";
|
|
42
|
-
}
|
|
43
|
-
function isSshAuthError(err) {
|
|
44
|
-
if (!(err instanceof Error)) return false;
|
|
45
|
-
return SSH_AUTH_ERROR_PATTERNS.some((pattern) => err.message.includes(pattern));
|
|
46
|
-
}
|
|
47
|
-
function isRetryableRemoteConnectionError(err) {
|
|
48
|
-
if (isSshDisconnectedError(err)) return true;
|
|
49
|
-
if (!(err instanceof Error)) return false;
|
|
50
|
-
return RETRYABLE_CONNECTION_ERROR_PATTERNS.some(
|
|
51
|
-
(pattern) => err.message.includes(pattern)
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
function isRemoteConnectionError(err) {
|
|
55
|
-
return isSshAuthError(err) || isRetryableRemoteConnectionError(err);
|
|
56
|
-
}
|
|
57
|
-
function isRuntimeNotFoundError(err) {
|
|
58
|
-
if (!err || typeof err !== "object") return false;
|
|
59
|
-
const e = err;
|
|
60
|
-
if (e.statusCode === 404) return true;
|
|
61
|
-
return typeof e.message === "string" && /no such (container|image|volume|network)/i.test(e.message);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// ../../packages/adapters/src/system/debug.ts
|
|
65
|
-
function isTruthy(value) {
|
|
66
|
-
if (!value) return false;
|
|
67
|
-
return ["1", "true", "yes", "on", "debug"].includes(value.toLowerCase());
|
|
68
|
-
}
|
|
69
|
-
function isSystemDebugEnabled() {
|
|
70
|
-
return isTruthy(process.env.SYSTEM_DEBUG_LOGS);
|
|
71
|
-
}
|
|
72
|
-
function systemDebug(scope, message) {
|
|
73
|
-
if (!isSystemDebugEnabled()) return;
|
|
74
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
75
|
-
console.log(`[system-debug] ${timestamp} [${scope}] ${message}`);
|
|
76
|
-
}
|
|
77
|
-
function formatDuration(startMs) {
|
|
78
|
-
return `${Date.now() - startMs}ms`;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export {
|
|
82
|
-
SshDisconnectedError,
|
|
83
|
-
isSshAuthError,
|
|
84
|
-
isRetryableRemoteConnectionError,
|
|
85
|
-
isRemoteConnectionError,
|
|
86
|
-
isRuntimeNotFoundError,
|
|
87
|
-
systemDebug,
|
|
88
|
-
formatDuration
|
|
89
|
-
};
|
package/dist/cloud-M2YLWEXO.js
DELETED
|
@@ -1,31 +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
|
-
CloudRuntime,
|
|
7
|
-
PAGE_CONTAINER_PREFIX,
|
|
8
|
-
provisionCloudWorkspace
|
|
9
|
-
} from "./chunk-RRJJGVKE.js";
|
|
10
|
-
import "./chunk-IOT5ZX23.js";
|
|
11
|
-
import "./chunk-EMXI4UCU.js";
|
|
12
|
-
import "./chunk-JIMUYEKN.js";
|
|
13
|
-
import "./chunk-IW2UKBVF.js";
|
|
14
|
-
import "./chunk-VDDMADOF.js";
|
|
15
|
-
import "./chunk-UC7YIEHT.js";
|
|
16
|
-
import "./chunk-6ODUBKUB.js";
|
|
17
|
-
import "./chunk-ZCFVHA25.js";
|
|
18
|
-
import "./chunk-6FH4AXVY.js";
|
|
19
|
-
import "./chunk-EW6KB2J7.js";
|
|
20
|
-
import "./chunk-I3DPMTSF.js";
|
|
21
|
-
import "./chunk-VZ2ZHPS2.js";
|
|
22
|
-
import "./chunk-3LDWWY7U.js";
|
|
23
|
-
import "./chunk-YIPMDGG6.js";
|
|
24
|
-
import "./chunk-ZFJXPCQP.js";
|
|
25
|
-
import "./chunk-OTLSJYAC.js";
|
|
26
|
-
import "./chunk-PXKCZB2I.js";
|
|
27
|
-
export {
|
|
28
|
-
CloudRuntime,
|
|
29
|
-
PAGE_CONTAINER_PREFIX,
|
|
30
|
-
provisionCloudWorkspace
|
|
31
|
-
};
|
|
File without changes
|