openship 0.6.9 → 0.7.0
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/bare-3POKLHTW.js +29 -0
- package/dist/{chunk-UAWY6X7V.js → chunk-3KUW2UC6.js} +470 -59
- package/dist/{chunk-GNOMEMNI.js → chunk-3LWGDMJU.js} +1 -1
- package/dist/{chunk-ENKJ7XIF.js → chunk-5CFUYMPE.js} +11 -11
- package/dist/{chunk-NUT6HKK6.js → chunk-5D27WZBW.js} +5 -5
- package/dist/{chunk-NIYD7MD2.js → chunk-7MKZP4TW.js} +89 -45
- package/dist/{chunk-IAMOUDHY.js → chunk-AUBB5DLY.js} +24 -15
- package/dist/{chunk-7PEXM2UI.js → chunk-BOD2IQ3P.js} +6 -6
- package/dist/{chunk-D6HU4VUZ.js → chunk-CMGRMPRQ.js} +1 -1
- package/dist/{chunk-MUWVC5R4.js → chunk-DZBXOF5Q.js} +11 -8
- package/dist/{chunk-BO6CY4V2.js → chunk-GEHV7JBS.js} +47 -4
- package/dist/{chunk-R5DC5PEF.js → chunk-GYDROM4W.js} +39 -10
- package/dist/{chunk-TAZZZKYO.js → chunk-HBQWOJRP.js} +1 -1
- package/dist/{chunk-WEZFTL4V.js → chunk-IVRTIKNZ.js} +183 -0
- package/dist/{chunk-P7RCYELG.js → chunk-J2NDOB7D.js} +1 -1
- package/dist/{chunk-T6DVUX4F.js → chunk-J4SYG2LC.js} +14 -3
- package/dist/{chunk-VAI5VOOI.js → chunk-JAKVPLHT.js} +1 -1
- package/dist/{chunk-NPSRGIHV.js → chunk-JWW5YAFL.js} +5 -4
- package/dist/{chunk-FCGJN5Q5.js → chunk-KYTTPWRP.js} +9 -9
- package/dist/{chunk-7YBWXEM6.js → chunk-LL7M7GL4.js} +4 -4
- package/dist/{chunk-SK4FFCFR.js → chunk-MZYD3LFP.js} +1 -1
- package/dist/{chunk-6GU6JSK6.js → chunk-QNQFS37A.js} +3 -3
- package/dist/{chunk-T46BQOLY.js → chunk-RHHCAWW3.js} +3 -3
- package/dist/{chunk-5UXHT6ED.js → chunk-SPR7N2EK.js} +113 -20
- package/dist/{chunk-AHJYP7DG.js → chunk-SYQ3FOLE.js} +74 -17
- package/dist/{chunk-3MP6ACKM.js → chunk-TPGBT5UR.js} +185 -78
- package/dist/{chunk-634DDFT5.js → chunk-TT7P5ZZ3.js} +8 -8
- package/dist/{chunk-D3OEMXYP.js → chunk-XQC6KYZD.js} +12 -7
- package/dist/{chunk-X53JXRS4.js → chunk-YGA52DHX.js} +3 -3
- package/dist/{chunk-5DJOB7IX.js → chunk-ZFA3MZ5N.js} +3 -3
- package/dist/{cloud-REV3DPJH.js → cloud-RFZSO6P5.js} +19 -19
- package/dist/{detect-BBFT5GEU.js → detect-NXD3PYBM.js} +4 -4
- package/dist/{docker-EG3QSE6I.js → docker-U5APUZBI.js} +10 -10
- package/dist/{docker-edge-executor-E5TOTLMR.js → docker-edge-executor-HUQOWFQU.js} +7 -7
- package/dist/{edge-import-YJVJUGYC.js → edge-import-UXD52WQR.js} +26 -26
- package/dist/{edge-preflight-QUW4BM7N.js → edge-preflight-3PMJ5BWM.js} +13 -13
- package/dist/{ensure-container-edge-FOEFQ3PI.js → ensure-container-edge-GDPY7UJD.js} +11 -11
- package/dist/{executor-NTWDJ3DB.js → executor-XOVSO6QZ.js} +6 -6
- package/dist/{host-channel-preflight-OI2TRHSG.js → host-channel-preflight-T2QUDQXU.js} +26 -26
- package/dist/index.js +71 -49
- package/dist/{local-executor-OQ2GRN7K.js → local-executor-KR7BFCJP.js} +3 -3
- package/dist/{nginx-4U4C2XUS.js → nginx-JMLAS7YS.js} +9 -9
- package/dist/{openresty-lua-LLWT5XQW.js → openresty-lua-FJH3KEC4.js} +7 -7
- package/dist/{privilege-MNDVMDST.js → privilege-H2QTJ5TE.js} +5 -5
- package/dist/server/index.js +9627 -4439
- package/dist/server/lua/site_logger.lua +18 -1
- package/dist/server/migrations/0117_github_installation_workspace_scope.sql +24 -0
- package/dist/server/migrations/0118_git_sources.sql +66 -0
- package/dist/server/migrations/0119_backup_run_batch.sql +8 -0
- package/dist/server/migrations/0120_domain_primary_unique.sql +24 -0
- package/dist/server/migrations/0121_host_port_claim_overlap.sql +14 -0
- package/dist/server/migrations/meta/_journal.json +35 -0
- package/dist/{setup-IFIMPQZJ.js → setup-ERGE5XNW.js} +12 -12
- package/dist/{ssh-client-2XWZCMGI.js → ssh-client-WVLLOAYK.js} +2 -2
- package/dist/up-EFCE6KA6.js +61 -0
- package/package.json +1 -1
- package/dist/bare-FA66N7GC.js +0 -29
- package/dist/up-RC5ZQIAD.js +0 -61
|
@@ -8621,6 +8621,156 @@ Two things worth knowing, both upstream behaviour: if the console shows a branch
|
|
|
8621
8621
|
defaultMode: "domain"
|
|
8622
8622
|
}
|
|
8623
8623
|
]
|
|
8624
|
+
},
|
|
8625
|
+
{
|
|
8626
|
+
$schema: "https://openship.io/app.schema.json",
|
|
8627
|
+
available: true,
|
|
8628
|
+
minEngine: "0.6.6",
|
|
8629
|
+
id: "pocketbase",
|
|
8630
|
+
name: "PocketBase",
|
|
8631
|
+
description: "Self-hosted PocketBase with auth, a realtime SQLite database, file storage, and an admin dashboard in one small service.",
|
|
8632
|
+
repository: "https://github.com/pocketbase/pocketbase",
|
|
8633
|
+
kind: "template",
|
|
8634
|
+
logo: "pocketbase",
|
|
8635
|
+
category: "backend",
|
|
8636
|
+
tags: [
|
|
8637
|
+
"auth",
|
|
8638
|
+
"database",
|
|
8639
|
+
"sqlite",
|
|
8640
|
+
"realtime"
|
|
8641
|
+
],
|
|
8642
|
+
framework: "docker-compose",
|
|
8643
|
+
services: [
|
|
8644
|
+
{
|
|
8645
|
+
name: "pocketbase",
|
|
8646
|
+
build: {
|
|
8647
|
+
dockerfile: 'FROM alpine:3.24.1 AS downloader\nARG PB_VERSION=0.40.1\nRUN apk add --no-cache ca-certificates unzip wget \\\n && ARCH=$(uname -m) \\\n && case "$ARCH" in x86_64) ARCH=amd64 ;; aarch64) ARCH=arm64 ;; *) echo "Unsupported architecture: $ARCH" >&2; exit 1 ;; esac \\\n && wget -q https://github.com/pocketbase/pocketbase/releases/download/v${PB_VERSION}/checksums.txt -O /tmp/checksums.txt \\\n && wget -q https://github.com/pocketbase/pocketbase/releases/download/v${PB_VERSION}/pocketbase_${PB_VERSION}_linux_${ARCH}.zip -O /tmp/pocketbase_${PB_VERSION}_linux_${ARCH}.zip \\\n && cd /tmp \\\n && grep " pocketbase_${PB_VERSION}_linux_${ARCH}.zip$" checksums.txt | sha256sum -c - \\\n && unzip pocketbase_${PB_VERSION}_linux_${ARCH}.zip -d /pb\nFROM alpine:3.24.1\nRUN apk add --no-cache ca-certificates su-exec \\\n && addgroup -S pocketbase \\\n && adduser -S -G pocketbase -h /pb pocketbase\nCOPY --chown=pocketbase:pocketbase --from=downloader /pb/pocketbase /pb/pocketbase\nCOPY --chown=pocketbase:pocketbase pocketbase/entrypoint.sh /pb/entrypoint.sh\nRUN chmod 755 /pb/entrypoint.sh\nWORKDIR /pb\nENTRYPOINT ["/pb/entrypoint.sh"]\nCMD ["/pb/pocketbase", "serve", "--http=0.0.0.0:8090", "--encryptionEnv=PB_ENCRYPTION_KEY"]\n',
|
|
8648
|
+
files: [
|
|
8649
|
+
{
|
|
8650
|
+
path: "entrypoint.sh",
|
|
8651
|
+
content: `#!/bin/sh
|
|
8652
|
+
set -eu
|
|
8653
|
+
mkdir -p /pb/pb_data
|
|
8654
|
+
chown pocketbase:pocketbase /pb/pb_data
|
|
8655
|
+
export PB_ENCRYPTION_KEY="$(printf '%.32s' "$PB_ENCRYPTION_SEED")"
|
|
8656
|
+
if [ ! -e /pb/pb_data/.openship-superuser ]; then
|
|
8657
|
+
su-exec pocketbase /pb/pocketbase superuser upsert "$POCKETBASE_SUPERUSER_EMAIL" "$POCKETBASE_SUPERUSER_PASSWORD" --dir=/pb/pb_data --encryptionEnv=PB_ENCRYPTION_KEY >/dev/null
|
|
8658
|
+
su-exec pocketbase touch /pb/pb_data/.openship-superuser
|
|
8659
|
+
fi
|
|
8660
|
+
exec su-exec pocketbase "$@"
|
|
8661
|
+
`
|
|
8662
|
+
}
|
|
8663
|
+
]
|
|
8664
|
+
},
|
|
8665
|
+
environment: {
|
|
8666
|
+
GOMEMLIMIT: "512MiB"
|
|
8667
|
+
},
|
|
8668
|
+
secretEnv: [
|
|
8669
|
+
"PB_ENCRYPTION_SEED",
|
|
8670
|
+
"POCKETBASE_SUPERUSER_PASSWORD"
|
|
8671
|
+
],
|
|
8672
|
+
ports: [
|
|
8673
|
+
"8090:8090"
|
|
8674
|
+
],
|
|
8675
|
+
exposedPort: 8090,
|
|
8676
|
+
exposed: true,
|
|
8677
|
+
volumes: [
|
|
8678
|
+
"pocketbase_data:/pb/pb_data"
|
|
8679
|
+
],
|
|
8680
|
+
healthcheck: {
|
|
8681
|
+
test: [
|
|
8682
|
+
"CMD",
|
|
8683
|
+
"wget",
|
|
8684
|
+
"-qO-",
|
|
8685
|
+
"http://127.0.0.1:8090/api/health"
|
|
8686
|
+
],
|
|
8687
|
+
interval: "5s",
|
|
8688
|
+
timeout: "3s",
|
|
8689
|
+
retries: 20,
|
|
8690
|
+
startPeriod: "10s"
|
|
8691
|
+
},
|
|
8692
|
+
stopGracePeriod: "30s",
|
|
8693
|
+
restart: "unless-stopped"
|
|
8694
|
+
}
|
|
8695
|
+
],
|
|
8696
|
+
configFields: [
|
|
8697
|
+
{
|
|
8698
|
+
key: "PB_ENCRYPTION_SEED",
|
|
8699
|
+
service: "pocketbase",
|
|
8700
|
+
label: "Settings encryption seed",
|
|
8701
|
+
help: "Derives the stable 32-character key that encrypts PocketBase settings in the data volume.",
|
|
8702
|
+
generate: "secret",
|
|
8703
|
+
secret: true
|
|
8704
|
+
},
|
|
8705
|
+
{
|
|
8706
|
+
key: "POCKETBASE_SUPERUSER_PASSWORD",
|
|
8707
|
+
service: "pocketbase",
|
|
8708
|
+
label: "Initial superuser password",
|
|
8709
|
+
help: "Auto-generated for the first deployment and shown in the connection card.",
|
|
8710
|
+
generate: "secret",
|
|
8711
|
+
secret: true
|
|
8712
|
+
},
|
|
8713
|
+
{
|
|
8714
|
+
key: "POCKETBASE_SUPERUSER_EMAIL",
|
|
8715
|
+
service: "pocketbase",
|
|
8716
|
+
label: "Superuser email",
|
|
8717
|
+
help: "Email for the superuser created during the first deployment.",
|
|
8718
|
+
type: "text",
|
|
8719
|
+
default: "admin@openship.local",
|
|
8720
|
+
required: true
|
|
8721
|
+
}
|
|
8722
|
+
],
|
|
8723
|
+
connection: {
|
|
8724
|
+
title: "Connect to PocketBase",
|
|
8725
|
+
description: "Use the public URL from browsers and other projects. The admin dashboard is available at /_/.",
|
|
8726
|
+
guide: {
|
|
8727
|
+
intro: "PocketBase stores auth, records, and files in one persistent SQLite-backed volume.",
|
|
8728
|
+
useHint: "Create scoped credentials for automation, configure off-host backups, and point each app at this URL.",
|
|
8729
|
+
defaultMode: "public"
|
|
8730
|
+
},
|
|
8731
|
+
outputs: [
|
|
8732
|
+
{
|
|
8733
|
+
id: "url",
|
|
8734
|
+
label: "PocketBase URL",
|
|
8735
|
+
source: "publicUrl:pocketbase",
|
|
8736
|
+
kind: "url",
|
|
8737
|
+
envKey: "POCKETBASE_URL",
|
|
8738
|
+
recommended: true
|
|
8739
|
+
},
|
|
8740
|
+
{
|
|
8741
|
+
id: "email",
|
|
8742
|
+
label: "Superuser email",
|
|
8743
|
+
source: "env:pocketbase:POCKETBASE_SUPERUSER_EMAIL",
|
|
8744
|
+
envKey: "POCKETBASE_SUPERUSER_EMAIL"
|
|
8745
|
+
},
|
|
8746
|
+
{
|
|
8747
|
+
id: "password",
|
|
8748
|
+
label: "Initial superuser password",
|
|
8749
|
+
help: "Use this installation credential until you change the password in PocketBase.",
|
|
8750
|
+
source: "env:pocketbase:POCKETBASE_SUPERUSER_PASSWORD",
|
|
8751
|
+
envKey: "POCKETBASE_SUPERUSER_PASSWORD",
|
|
8752
|
+
secret: true
|
|
8753
|
+
}
|
|
8754
|
+
]
|
|
8755
|
+
},
|
|
8756
|
+
provides: [
|
|
8757
|
+
{
|
|
8758
|
+
id: "pocketbase",
|
|
8759
|
+
outputRefs: [
|
|
8760
|
+
"url"
|
|
8761
|
+
],
|
|
8762
|
+
category: "database"
|
|
8763
|
+
}
|
|
8764
|
+
],
|
|
8765
|
+
endpoints: [
|
|
8766
|
+
{
|
|
8767
|
+
service: "pocketbase",
|
|
8768
|
+
port: 8090,
|
|
8769
|
+
label: "PocketBase API and dashboard",
|
|
8770
|
+
kind: "http",
|
|
8771
|
+
defaultMode: "domain"
|
|
8772
|
+
}
|
|
8773
|
+
]
|
|
8624
8774
|
}
|
|
8625
8775
|
]
|
|
8626
8776
|
};
|
|
@@ -25919,6 +26069,39 @@ var AUDIT_EVENTS = {
|
|
|
25919
26069
|
label: "GitHub app installed",
|
|
25920
26070
|
tone: "info"
|
|
25921
26071
|
},
|
|
26072
|
+
"github.source.created": {
|
|
26073
|
+
category: "system",
|
|
26074
|
+
action: "registered the GitHub App source",
|
|
26075
|
+
label: "GitHub App source registered",
|
|
26076
|
+
tone: "info",
|
|
26077
|
+
description: "An organization-owned GitHub App was verified and stored. Secret values are never recorded."
|
|
26078
|
+
},
|
|
26079
|
+
"github.source.updated": {
|
|
26080
|
+
category: "system",
|
|
26081
|
+
action: "updated the GitHub App source",
|
|
26082
|
+
label: "GitHub App source updated",
|
|
26083
|
+
tone: "info",
|
|
26084
|
+
description: "A GitHub App's identity, endpoint, or encrypted credentials changed."
|
|
26085
|
+
},
|
|
26086
|
+
"github.source.verified": {
|
|
26087
|
+
category: "system",
|
|
26088
|
+
action: "verified the GitHub App source",
|
|
26089
|
+
label: "GitHub App source verified",
|
|
26090
|
+
tone: "info"
|
|
26091
|
+
},
|
|
26092
|
+
"github.source.defaulted": {
|
|
26093
|
+
category: "system",
|
|
26094
|
+
action: "made the default GitHub App source",
|
|
26095
|
+
label: "Default GitHub App source changed",
|
|
26096
|
+
tone: "info"
|
|
26097
|
+
},
|
|
26098
|
+
"github.source.deleted": {
|
|
26099
|
+
category: "system",
|
|
26100
|
+
action: "deleted the GitHub App source",
|
|
26101
|
+
label: "GitHub App source deleted",
|
|
26102
|
+
tone: "warning",
|
|
26103
|
+
description: "The local App credentials and installation bindings were removed; the GitHub App itself was not uninstalled on GitHub."
|
|
26104
|
+
},
|
|
25922
26105
|
"github.disconnect": {
|
|
25923
26106
|
category: "system",
|
|
25924
26107
|
action: "disconnected GitHub from",
|
|
@@ -4,7 +4,7 @@ import { createRequire as __ospCreateRequire } from "node:module";
|
|
|
4
4
|
const require = __ospCreateRequire(import.meta.url);
|
|
5
5
|
import {
|
|
6
6
|
shellQuote
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-IVRTIKNZ.js";
|
|
8
8
|
|
|
9
9
|
// ../../packages/adapters/src/system/local-shell.ts
|
|
10
10
|
import { execFile } from "child_process";
|
|
@@ -8,13 +8,14 @@ import {
|
|
|
8
8
|
getLocalShellPath,
|
|
9
9
|
logEntry,
|
|
10
10
|
sq
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-J2NDOB7D.js";
|
|
12
12
|
|
|
13
13
|
// ../../packages/adapters/src/system/local-executor.ts
|
|
14
14
|
import { exec, spawn } from "child_process";
|
|
15
15
|
import {
|
|
16
16
|
access,
|
|
17
17
|
mkdir as fsMkdir,
|
|
18
|
+
open as fsOpen,
|
|
18
19
|
readFile as fsReadFile,
|
|
19
20
|
rename as fsRename,
|
|
20
21
|
rm as fsRm,
|
|
@@ -82,9 +83,19 @@ var LocalExecutor = class {
|
|
|
82
83
|
});
|
|
83
84
|
});
|
|
84
85
|
}
|
|
85
|
-
async writeFile(path, content) {
|
|
86
|
+
async writeFile(path, content, opts) {
|
|
86
87
|
await fsMkdir(dirname(path), { recursive: true });
|
|
87
|
-
|
|
88
|
+
if (opts?.mode === void 0) {
|
|
89
|
+
await fsWriteFile(path, content, "utf-8");
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const file = await fsOpen(path, "w", opts.mode);
|
|
93
|
+
try {
|
|
94
|
+
await file.chmod(opts.mode);
|
|
95
|
+
await file.writeFile(content, "utf-8");
|
|
96
|
+
} finally {
|
|
97
|
+
await file.close();
|
|
98
|
+
}
|
|
88
99
|
}
|
|
89
100
|
async rename(from, to) {
|
|
90
101
|
await fsRename(from, to);
|
|
@@ -4,7 +4,7 @@ import { createRequire as __ospCreateRequire } from "node:module";
|
|
|
4
4
|
const require = __ospCreateRequire(import.meta.url);
|
|
5
5
|
import {
|
|
6
6
|
PACKAGE_ROOT_ONLY_EXCLUDES
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-IVRTIKNZ.js";
|
|
8
8
|
|
|
9
9
|
// ../../packages/adapters/src/archive.ts
|
|
10
10
|
import { execFile } from "child_process";
|
|
@@ -4,7 +4,7 @@ import { createRequire as __ospCreateRequire } from "node:module";
|
|
|
4
4
|
const require = __ospCreateRequire(import.meta.url);
|
|
5
5
|
import {
|
|
6
6
|
sq
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-J2NDOB7D.js";
|
|
8
8
|
import {
|
|
9
9
|
formatDuration,
|
|
10
10
|
isRemoteConnectionError,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
parseSystemArch,
|
|
18
18
|
parseSystemOs,
|
|
19
19
|
safeErrorMessage
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-IVRTIKNZ.js";
|
|
21
21
|
|
|
22
22
|
// ../../packages/adapters/src/system/elevated-executor.ts
|
|
23
23
|
import { randomBytes } from "crypto";
|
|
@@ -47,12 +47,13 @@ function elevatedExecutor(inner) {
|
|
|
47
47
|
if (await inner.exists(path).catch(() => false)) return true;
|
|
48
48
|
return await inner.exec(elevateCommand(`test -e ${sq(path)}`)).then(() => true).catch(() => false);
|
|
49
49
|
};
|
|
50
|
-
const writeFileElevated = async (path, content) => {
|
|
50
|
+
const writeFileElevated = async (path, content, opts) => {
|
|
51
51
|
const stage = `/tmp/.openship-elev-${randomBytes(12).toString("hex")}`;
|
|
52
52
|
await inner.exec(`mkdir -m 700 ${sq(stage)}`);
|
|
53
53
|
try {
|
|
54
54
|
const staged = `${stage}/payload`;
|
|
55
|
-
await inner.writeFile(staged, content);
|
|
55
|
+
if (opts === void 0) await inner.writeFile(staged, content);
|
|
56
|
+
else await inner.writeFile(staged, content, opts);
|
|
56
57
|
await inner.exec(
|
|
57
58
|
elevateCommand(
|
|
58
59
|
`mkdir -p ${sq(dirOf(path))} && chown 0:0 ${sq(staged)} && mv -f ${sq(staged)} ${sq(path)}`
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
resolvePorts,
|
|
29
29
|
sourceBuildDir,
|
|
30
30
|
verifyHostChannel
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-TT7P5ZZ3.js";
|
|
32
32
|
import {
|
|
33
33
|
bootstrapAdmin,
|
|
34
34
|
importMigratedSites,
|
|
@@ -36,18 +36,18 @@ import {
|
|
|
36
36
|
internalPost,
|
|
37
37
|
mintBareInternalToken,
|
|
38
38
|
waitHealthy
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-LL7M7GL4.js";
|
|
40
40
|
import {
|
|
41
41
|
startUnitHint,
|
|
42
42
|
thisHost
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-SPR7N2EK.js";
|
|
44
44
|
import {
|
|
45
45
|
completeHostEdge,
|
|
46
46
|
markStoppedProxyImported,
|
|
47
47
|
planAndApplyHostEdge,
|
|
48
48
|
previewHostEdge,
|
|
49
49
|
rollbackHostEdge
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-5D27WZBW.js";
|
|
51
51
|
import {
|
|
52
52
|
AUTH_SECRET_FILE,
|
|
53
53
|
DATA_DIR,
|
|
@@ -58,17 +58,17 @@ import {
|
|
|
58
58
|
} from "./chunk-ELGRMZOW.js";
|
|
59
59
|
import {
|
|
60
60
|
LocalExecutor
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-J4SYG2LC.js";
|
|
62
62
|
import {
|
|
63
63
|
edgeCrashReason,
|
|
64
64
|
edgeIsBroken
|
|
65
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-YGA52DHX.js";
|
|
66
66
|
import {
|
|
67
67
|
EDGE_CONTAINER_NAME
|
|
68
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-CMGRMPRQ.js";
|
|
69
69
|
import {
|
|
70
70
|
isValidEmail
|
|
71
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-IVRTIKNZ.js";
|
|
72
72
|
|
|
73
73
|
// src/commands/up.ts
|
|
74
74
|
import { Command } from "commander";
|
|
@@ -1564,7 +1564,7 @@ async function runForeground(opts, source) {
|
|
|
1564
1564
|
const uiSpinner = ora("Preparing the dashboard\u2026").start();
|
|
1565
1565
|
try {
|
|
1566
1566
|
const bundle = await ensureDashboard({
|
|
1567
|
-
tag: source ? "local" : opts.uiVersion || `v${"0.
|
|
1567
|
+
tag: source ? "local" : opts.uiVersion || `v${"0.7.0"}`,
|
|
1568
1568
|
onProgress: (received, total) => {
|
|
1569
1569
|
if (total) {
|
|
1570
1570
|
uiSpinner.text = `Downloading dashboard\u2026 ${Math.round(received / total * 100)}%`;
|
|
@@ -7,20 +7,20 @@ import {
|
|
|
7
7
|
composeInstallExists,
|
|
8
8
|
readComposeEnvFile,
|
|
9
9
|
startUnitHint
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-SPR7N2EK.js";
|
|
11
11
|
import {
|
|
12
12
|
INTERNAL_TOKEN_FILE,
|
|
13
13
|
OS_DIR
|
|
14
14
|
} from "./chunk-ELGRMZOW.js";
|
|
15
15
|
import {
|
|
16
16
|
LocalExecutor
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-J4SYG2LC.js";
|
|
18
18
|
import {
|
|
19
19
|
edgeCrashReason
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-YGA52DHX.js";
|
|
21
21
|
import {
|
|
22
22
|
EDGE_CONTAINER_NAME
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-CMGRMPRQ.js";
|
|
24
24
|
|
|
25
25
|
// src/lib/edge-import.ts
|
|
26
26
|
import chalk from "chalk";
|
|
@@ -4,7 +4,7 @@ import { createRequire as __ospCreateRequire } from "node:module";
|
|
|
4
4
|
const require = __ospCreateRequire(import.meta.url);
|
|
5
5
|
import {
|
|
6
6
|
sq
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-J2NDOB7D.js";
|
|
8
8
|
|
|
9
9
|
// ../../packages/adapters/src/runtime/managed-artifact.ts
|
|
10
10
|
var MANAGED_ARTIFACT_BASE = "/opt/openship";
|
|
@@ -13,14 +13,14 @@ import {
|
|
|
13
13
|
resolveDockerRootDirectory,
|
|
14
14
|
resolveDockerfileCandidates,
|
|
15
15
|
resolveWithinDirectory
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-SYQ3FOLE.js";
|
|
17
17
|
import {
|
|
18
18
|
getTarCreateEnv,
|
|
19
19
|
prepareSourceTarArgs
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-JAKVPLHT.js";
|
|
21
21
|
import {
|
|
22
22
|
isValidEnvKey
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-IVRTIKNZ.js";
|
|
24
24
|
import {
|
|
25
25
|
__commonJS,
|
|
26
26
|
__toESM
|
|
@@ -4,15 +4,15 @@ import { createRequire as __ospCreateRequire } from "node:module";
|
|
|
4
4
|
const require = __ospCreateRequire(import.meta.url);
|
|
5
5
|
import {
|
|
6
6
|
hostRefusal
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-3LWGDMJU.js";
|
|
8
8
|
import {
|
|
9
9
|
elevatedExecutor,
|
|
10
10
|
resolveEnvironment
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-JWW5YAFL.js";
|
|
12
12
|
import {
|
|
13
13
|
answered,
|
|
14
14
|
refused
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-IVRTIKNZ.js";
|
|
16
16
|
|
|
17
17
|
// ../../packages/adapters/src/system/privilege.ts
|
|
18
18
|
function rootChecked(executor, why) {
|
|
@@ -134,10 +134,10 @@ import {
|
|
|
134
134
|
} from "./chunk-ZWLDLTJP.js";
|
|
135
135
|
import {
|
|
136
136
|
CloudRuntime
|
|
137
|
-
} from "./chunk-
|
|
137
|
+
} from "./chunk-DZBXOF5Q.js";
|
|
138
138
|
import {
|
|
139
139
|
OPENRESTY_DEFAULT_PATHS
|
|
140
|
-
} from "./chunk-
|
|
140
|
+
} from "./chunk-BOD2IQ3P.js";
|
|
141
141
|
import {
|
|
142
142
|
DockerRuntime,
|
|
143
143
|
daemonConnectionFrom,
|
|
@@ -146,26 +146,26 @@ import {
|
|
|
146
146
|
resolveExecExitCode,
|
|
147
147
|
startAttachStream,
|
|
148
148
|
startExecStream
|
|
149
|
-
} from "./chunk-
|
|
149
|
+
} from "./chunk-TPGBT5UR.js";
|
|
150
150
|
import {
|
|
151
151
|
BareRuntime
|
|
152
|
-
} from "./chunk-
|
|
152
|
+
} from "./chunk-5CFUYMPE.js";
|
|
153
153
|
import {
|
|
154
154
|
createExecutor
|
|
155
|
-
} from "./chunk-
|
|
155
|
+
} from "./chunk-3KUW2UC6.js";
|
|
156
156
|
import {
|
|
157
157
|
envOps
|
|
158
|
-
} from "./chunk-
|
|
158
|
+
} from "./chunk-3LWGDMJU.js";
|
|
159
159
|
import {
|
|
160
160
|
ENVIRONMENT_PROBE_SCRIPT,
|
|
161
161
|
ENVIRONMENT_PROBE_TIMEOUT_MS,
|
|
162
162
|
cacheEnvironment,
|
|
163
163
|
parseEnvironmentProbe,
|
|
164
164
|
profileIsFresh
|
|
165
|
-
} from "./chunk-
|
|
165
|
+
} from "./chunk-JWW5YAFL.js";
|
|
166
166
|
import {
|
|
167
167
|
MAIL_HOST_STATE_DIR
|
|
168
|
-
} from "./chunk-
|
|
168
|
+
} from "./chunk-CMGRMPRQ.js";
|
|
169
169
|
import {
|
|
170
170
|
FAMILY_BY_DISTRO,
|
|
171
171
|
isAwsS3Endpoint,
|
|
@@ -177,7 +177,7 @@ import {
|
|
|
177
177
|
validateBackupPath,
|
|
178
178
|
validateClearPath,
|
|
179
179
|
withTimeout
|
|
180
|
-
} from "./chunk-
|
|
180
|
+
} from "./chunk-IVRTIKNZ.js";
|
|
181
181
|
|
|
182
182
|
// ../../packages/adapters/src/runtime/image-transfer.ts
|
|
183
183
|
import { Transform } from "stream";
|
|
@@ -1141,6 +1141,8 @@ function demuxDockerStream(source, stdout, stderr, onError) {
|
|
|
1141
1141
|
|
|
1142
1142
|
// ../../packages/adapters/src/backup/executors/docker.ts
|
|
1143
1143
|
var HELPER_IMAGE = "alpine:3";
|
|
1144
|
+
var BIND_PROBE_TARGET = "/__openship_bind_source";
|
|
1145
|
+
var DOCKER_MODE_DIRECTORY = 2 ** 31;
|
|
1144
1146
|
var ARTIFACT_BUFFER_BYTES = 4 * 1024 * 1024;
|
|
1145
1147
|
var DEFAULT_HELPER_IDLE_MS = 10 * 60 * 1e3;
|
|
1146
1148
|
var DEFAULT_HELPER_TIMEOUT_MS = 6 * 60 * 60 * 1e3;
|
|
@@ -1216,6 +1218,29 @@ function parseVolumeSpec(spec) {
|
|
|
1216
1218
|
const type = isHostPathSource(source) ? "bind" : "volume";
|
|
1217
1219
|
return { source, target, type };
|
|
1218
1220
|
}
|
|
1221
|
+
function archivePathIsDirectory(response, path) {
|
|
1222
|
+
const rawHeader = response.headers?.["x-docker-container-path-stat"];
|
|
1223
|
+
const encoded = Array.isArray(rawHeader) ? rawHeader[0] : rawHeader;
|
|
1224
|
+
if (!encoded) {
|
|
1225
|
+
throw new Error(`Docker returned no path-stat header while inspecting ${path}`);
|
|
1226
|
+
}
|
|
1227
|
+
let stat;
|
|
1228
|
+
try {
|
|
1229
|
+
stat = JSON.parse(Buffer.from(encoded, "base64").toString("utf8"));
|
|
1230
|
+
} catch (err) {
|
|
1231
|
+
throw new Error(`Docker returned an invalid path-stat header while inspecting ${path}`, {
|
|
1232
|
+
cause: err
|
|
1233
|
+
});
|
|
1234
|
+
}
|
|
1235
|
+
const mode = stat?.mode;
|
|
1236
|
+
if (typeof mode !== "number" || !Number.isSafeInteger(mode)) {
|
|
1237
|
+
throw new Error(`Docker returned no valid path mode while inspecting ${path}`);
|
|
1238
|
+
}
|
|
1239
|
+
return mode >= DOCKER_MODE_DIRECTORY;
|
|
1240
|
+
}
|
|
1241
|
+
function isMissingBindSourceError(err) {
|
|
1242
|
+
return err?.statusCode === 400 && /bind source path does not exist/i.test(safeErrorMessage(err));
|
|
1243
|
+
}
|
|
1219
1244
|
var DockerBackupExecutor = class {
|
|
1220
1245
|
constructor(runtime) {
|
|
1221
1246
|
this.runtime = runtime;
|
|
@@ -1244,23 +1269,82 @@ var DockerBackupExecutor = class {
|
|
|
1244
1269
|
);
|
|
1245
1270
|
}
|
|
1246
1271
|
}
|
|
1272
|
+
/**
|
|
1273
|
+
* Ask the Docker daemon about a path in a container's mount namespace.
|
|
1274
|
+
*
|
|
1275
|
+
* The API may itself run in a container or connect to Docker over SSH/TLS, so
|
|
1276
|
+
* `node:fs` would inspect the wrong filesystem. Docker's archive-info endpoint
|
|
1277
|
+
* returns the daemon-side path's Go FileMode without copying any archive bytes.
|
|
1278
|
+
*/
|
|
1279
|
+
async containerPathIsDirectory(container, path) {
|
|
1280
|
+
let response;
|
|
1281
|
+
try {
|
|
1282
|
+
response = await container.infoArchive({ path });
|
|
1283
|
+
return archivePathIsDirectory(response, path);
|
|
1284
|
+
} finally {
|
|
1285
|
+
response?.resume?.();
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
/**
|
|
1289
|
+
* Classify a recorded bind source when there is no service container to inspect.
|
|
1290
|
+
* A never-started helper gives Docker a mount namespace, and archive-info reports
|
|
1291
|
+
* the source type from the daemon host. `Mounts` (rather than legacy `Binds`) is
|
|
1292
|
+
* deliberate: a missing source is rejected instead of being created as a directory.
|
|
1293
|
+
*/
|
|
1294
|
+
async declaredBindIsDirectory(sourcePath) {
|
|
1295
|
+
try {
|
|
1296
|
+
return await this.withHelper(
|
|
1297
|
+
{
|
|
1298
|
+
Image: HELPER_IMAGE,
|
|
1299
|
+
NetworkDisabled: true,
|
|
1300
|
+
HostConfig: {
|
|
1301
|
+
Mounts: [
|
|
1302
|
+
{
|
|
1303
|
+
Type: "bind",
|
|
1304
|
+
Source: sourcePath,
|
|
1305
|
+
Target: BIND_PROBE_TARGET,
|
|
1306
|
+
ReadOnly: true
|
|
1307
|
+
}
|
|
1308
|
+
]
|
|
1309
|
+
}
|
|
1310
|
+
},
|
|
1311
|
+
(helper) => this.containerPathIsDirectory(helper, BIND_PROBE_TARGET)
|
|
1312
|
+
);
|
|
1313
|
+
} catch (err) {
|
|
1314
|
+
if (isMissingBindSourceError(err)) return true;
|
|
1315
|
+
throw new Error(
|
|
1316
|
+
`Could not inspect bind mount source "${sourcePath}" on the Docker host: ` + safeErrorMessage(err),
|
|
1317
|
+
{ cause: err }
|
|
1318
|
+
);
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1247
1321
|
async listSources(service) {
|
|
1248
1322
|
if (service.containerId) {
|
|
1323
|
+
const container = this.dockerode.getContainer(service.containerId);
|
|
1324
|
+
let data = null;
|
|
1249
1325
|
try {
|
|
1250
|
-
|
|
1251
|
-
const mounts = data.Mounts ?? [];
|
|
1252
|
-
return mounts.filter((m2) => m2.Type === "volume" || m2.Type === "bind").map(
|
|
1253
|
-
(m2, i2) => ({
|
|
1254
|
-
id: m2.Name ?? m2.Source ?? `mount-${i2}`,
|
|
1255
|
-
target: m2.Destination ?? "",
|
|
1256
|
-
source: m2.Name ?? m2.Source ?? "",
|
|
1257
|
-
type: m2.Type ?? "volume"
|
|
1258
|
-
})
|
|
1259
|
-
);
|
|
1326
|
+
data = await container.inspect();
|
|
1260
1327
|
} catch {
|
|
1261
1328
|
}
|
|
1329
|
+
if (data) {
|
|
1330
|
+
const mounts = data.Mounts ?? [];
|
|
1331
|
+
const sources2 = [];
|
|
1332
|
+
for (const [i2, mount] of mounts.entries()) {
|
|
1333
|
+
if (mount.Type !== "volume" && mount.Type !== "bind") continue;
|
|
1334
|
+
if (mount.Type === "bind" && (!mount.Destination || !await this.containerPathIsDirectory(container, mount.Destination))) {
|
|
1335
|
+
continue;
|
|
1336
|
+
}
|
|
1337
|
+
sources2.push({
|
|
1338
|
+
id: mount.Name ?? mount.Source ?? `mount-${i2}`,
|
|
1339
|
+
target: mount.Destination ?? "",
|
|
1340
|
+
source: mount.Name ?? mount.Source ?? "",
|
|
1341
|
+
type: mount.Type
|
|
1342
|
+
});
|
|
1343
|
+
}
|
|
1344
|
+
return sources2;
|
|
1345
|
+
}
|
|
1262
1346
|
}
|
|
1263
|
-
|
|
1347
|
+
const sources = service.volumes.map((spec, i2) => {
|
|
1264
1348
|
const parsed = parseVolumeSpec(spec);
|
|
1265
1349
|
if (!parsed || !parsed.source) return null;
|
|
1266
1350
|
const source = parsed.type === "volume" && service.namespaceVolumes ? ensureScopedVolumeName(service.projectSlug, parsed.source) : parsed.source;
|
|
@@ -1271,6 +1355,15 @@ var DockerBackupExecutor = class {
|
|
|
1271
1355
|
type: parsed.type
|
|
1272
1356
|
};
|
|
1273
1357
|
}).filter((x2) => x2 !== null);
|
|
1358
|
+
if (!sources.some((source) => source.type === "bind")) return sources;
|
|
1359
|
+
await this.ensureImage(HELPER_IMAGE);
|
|
1360
|
+
const backupable = [];
|
|
1361
|
+
for (const source of sources) {
|
|
1362
|
+
if (source.type !== "bind" || await this.declaredBindIsDirectory(source.source)) {
|
|
1363
|
+
backupable.push(source);
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
return backupable;
|
|
1274
1367
|
}
|
|
1275
1368
|
/**
|
|
1276
1369
|
* The container's own `Config.Env`, as `KEY=value` pairs already split.
|