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.
- package/dist/bare-7QD623QV.js +29 -0
- package/dist/{chunk-Q7WGTQQ5.js → chunk-2ANV5ZQ5.js} +1 -1
- package/dist/{chunk-UJ6JZM65.js → chunk-2VSW6Q6C.js} +601 -382
- package/dist/{chunk-PCPVTH6M.js → chunk-5T4UVOM3.js} +6 -4
- package/dist/{chunk-YMMQRE5J.js → chunk-BLEXTYRK.js} +1 -1
- package/dist/{chunk-OBPKYXQL.js → chunk-CIJV43LH.js} +71 -32
- package/dist/{chunk-NK5N5LXN.js → chunk-DDFUESPJ.js} +24 -9
- package/dist/{chunk-6FH4AXVY.js → chunk-E2X26PXR.js} +1 -1
- package/dist/{chunk-HKRQXPTI.js → chunk-FYPFEDPZ.js} +1 -1
- package/dist/{chunk-UVNMQM7W.js → chunk-FZ6QCF6B.js} +8 -6
- package/dist/{chunk-MLYSEZQB.js → chunk-GGIAIGUL.js} +15 -66
- package/dist/{chunk-2YM3NI2E.js → chunk-GIPJNNI5.js} +38 -44
- package/dist/{chunk-ZFJXPCQP.js → chunk-H3WT3A6R.js} +4 -3
- package/dist/chunk-H4FS5BED.js +936 -0
- package/dist/{chunk-CBLD2HS5.js → chunk-J2XM3QSP.js} +8 -5
- package/dist/{chunk-FE7ZZQSE.js → chunk-J3K6XABC.js} +3 -3
- package/dist/{chunk-77QDF6UD.js → chunk-LHFXSC36.js} +428 -93
- package/dist/{chunk-YIMOCZBZ.js → chunk-MEE6OZFP.js} +3 -3
- package/dist/chunk-N5YZMO33.js +111 -0
- package/dist/{chunk-QVW76WDL.js → chunk-NRTJRNAE.js} +58 -16
- package/dist/{chunk-WVAML4H6.js → chunk-PPEBIY5F.js} +247 -61
- package/dist/{chunk-4I2BM2DT.js → chunk-PVP4RGWT.js} +3 -3
- package/dist/{chunk-RSR7PFIQ.js → chunk-QHMDCYZ3.js} +4 -4
- package/dist/chunk-R4VDPFLS.js +106 -0
- package/dist/{chunk-VTGPEC6B.js → chunk-RDXT4BQB.js} +6 -4
- package/dist/{chunk-LFE5KQ7Y.js → chunk-S6B2Z3OO.js} +142 -57
- package/dist/chunk-UWEV6XTS.js +249 -0
- package/dist/{chunk-5DMWSTOM.js → chunk-VQM6JHJB.js} +940 -224
- package/dist/{chunk-SM26HDS2.js → chunk-VSTFHUCV.js} +44 -50
- package/dist/chunk-WU54BXFE.js +70 -0
- package/dist/{chunk-LUKYPVJ4.js → chunk-XWHWTHEL.js} +313 -469
- package/dist/{chunk-A4GXYE4L.js → chunk-ZPJ74LXE.js} +22 -20
- package/dist/cloud-KNNABE3O.js +40 -0
- package/dist/{detect-OIE5V3VZ.js → detect-G4DR3U2N.js} +9 -6
- package/dist/{docker-VTR2GK5Y.js → docker-YOVPCIB4.js} +11 -8
- package/dist/{docker-edge-executor-22IBXNYJ.js → docker-edge-executor-QFXD3337.js} +8 -6
- package/dist/edge-import-CRFVSR6P.js +56 -0
- package/dist/{edge-preflight-GBNCPNVU.js → edge-preflight-MXERVAMG.js} +15 -12
- package/dist/{ensure-container-edge-KPI2CVXJ.js → ensure-container-edge-F4JUNQIK.js} +13 -10
- package/dist/{executor-7LXXZPBR.js → executor-CVPAYYHR.js} +8 -6
- package/dist/host-channel-preflight-QTDNGLCK.js +54 -0
- package/dist/index.js +84 -48
- package/dist/{local-executor-WOFZD72X.js → local-executor-ODC6RANU.js} +3 -2
- package/dist/{nginx-KUFMLMAC.js → nginx-KLFF43TC.js} +11 -8
- package/dist/{openresty-lua-ATTH35BE.js → openresty-lua-VKWUV4GB.js} +6 -5
- package/dist/{privilege-I4W3ZNZK.js → privilege-7D3SSOL3.js} +6 -5
- package/dist/server/index.js +8813 -5232
- package/dist/setup-I5AJC6NJ.js +25 -0
- package/dist/{ssh-client-JBMA7SN4.js → ssh-client-625VWGKP.js} +3 -2
- package/dist/up-QXTOOVXC.js +61 -0
- package/package.json +1 -1
- package/dist/bare-OXJVW3AK.js +0 -25
- package/dist/chunk-LH2PLRQO.js +0 -434
- package/dist/cloud-75VIT4KV.js +0 -37
- package/dist/edge-import-WJUB4M7F.js +0 -52
- package/dist/host-channel-preflight-KE6OONYK.js +0 -50
- package/dist/setup-XGLGUUFW.js +0 -22
- package/dist/up-K4BV7466.js +0 -57
|
@@ -2,15 +2,17 @@
|
|
|
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
|
+
isSshAuthError,
|
|
7
|
+
systemDebug
|
|
8
|
+
} from "./chunk-N5YZMO33.js";
|
|
5
9
|
import {
|
|
6
10
|
HOST_CHANNEL_AUTH_REJECTED,
|
|
7
11
|
HOST_CHANNEL_NOT_PROVISIONED,
|
|
8
12
|
HOST_CHANNEL_ROW_CREDENTIALS_UNUSED,
|
|
9
13
|
hostFirewallRule,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
systemDebug
|
|
13
|
-
} from "./chunk-UJ6JZM65.js";
|
|
14
|
+
safeErrorMessage
|
|
15
|
+
} from "./chunk-2VSW6Q6C.js";
|
|
14
16
|
|
|
15
17
|
// ../../packages/adapters/src/system/ssh-client.ts
|
|
16
18
|
import { Client } from "ssh2";
|
|
@@ -5,38 +5,45 @@ const require = __ospCreateRequire(import.meta.url);
|
|
|
5
5
|
import {
|
|
6
6
|
checkGit,
|
|
7
7
|
installGit
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-ZPJ74LXE.js";
|
|
9
9
|
import {
|
|
10
|
-
createDockerBuildContext
|
|
11
|
-
|
|
12
|
-
resolveDockerfileCandidates,
|
|
13
|
-
resolveWithinDirectory
|
|
14
|
-
} from "./chunk-LUKYPVJ4.js";
|
|
10
|
+
createDockerBuildContext
|
|
11
|
+
} from "./chunk-XWHWTHEL.js";
|
|
15
12
|
import {
|
|
16
13
|
prepareStackOutput,
|
|
17
14
|
resolveProjectDir,
|
|
18
15
|
resolveStaticOutputPath,
|
|
19
16
|
runLocalBuild
|
|
20
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-MEE6OZFP.js";
|
|
21
18
|
import {
|
|
22
19
|
BuildLogger,
|
|
20
|
+
dockerBuildContextDirectory,
|
|
21
|
+
droppedRuntimeEnvMessage,
|
|
23
22
|
injectGitToken,
|
|
23
|
+
normalizeDockerRelativePath,
|
|
24
|
+
resolveContextDockerfileCandidates,
|
|
25
|
+
resolveDockerfileCandidates,
|
|
26
|
+
resolveWithinDirectory,
|
|
24
27
|
runBuildPipeline,
|
|
28
|
+
splitRuntimeEnv,
|
|
25
29
|
sq,
|
|
26
30
|
transferLocalDirectory
|
|
27
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-H4FS5BED.js";
|
|
32
|
+
import {
|
|
33
|
+
isRuntimeNotFoundError
|
|
34
|
+
} from "./chunk-N5YZMO33.js";
|
|
28
35
|
import {
|
|
29
36
|
PRICING,
|
|
30
37
|
STACKS,
|
|
31
38
|
SYSTEM,
|
|
32
39
|
TRANSFER_EXCLUDES,
|
|
33
40
|
buildOutputTransferExcludes,
|
|
34
|
-
isRuntimeNotFoundError,
|
|
35
41
|
missingOutputDirectoryMessage,
|
|
42
|
+
nodeBinPathExport,
|
|
36
43
|
packageManagerEnsureCommand,
|
|
37
44
|
safeErrorMessage,
|
|
38
45
|
shellSplitWords
|
|
39
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-2VSW6Q6C.js";
|
|
40
47
|
|
|
41
48
|
// ../../packages/adapters/src/runtime/cloud.ts
|
|
42
49
|
import { readFile } from "fs/promises";
|
|
@@ -719,9 +726,11 @@ function restartPolicyForWorkload(policy) {
|
|
|
719
726
|
return "always";
|
|
720
727
|
}
|
|
721
728
|
function resolveCloudWorkloadCmd(opts) {
|
|
722
|
-
const { commandArgv, startCommand, workdir } = opts;
|
|
729
|
+
const { commandArgv, startCommand, workdir, binPathExport } = opts;
|
|
723
730
|
if (commandArgv != null) return commandArgv.length > 0 ? commandArgv : void 0;
|
|
724
|
-
|
|
731
|
+
if (!startCommand) return void 0;
|
|
732
|
+
const body = `cd ${sq(workdir)} && ${startCommand}`;
|
|
733
|
+
return ["sh", "-c", binPathExport ? `${binPathExport} && ${body}` : body];
|
|
725
734
|
}
|
|
726
735
|
function exposeTarget(port, serviceName, slug, domain = SYSTEM.DOMAINS.CLOUD_DOMAIN) {
|
|
727
736
|
const service = `service "${serviceName}" on port ${port}`;
|
|
@@ -1320,6 +1329,9 @@ function resolveCopyDestinationPath(copy, sourcePath, destination, destinationIs
|
|
|
1320
1329
|
const basename = posix.basename(sourcePath.replace(/\/+$/g, "")) || ".";
|
|
1321
1330
|
return posix.normalize(posix.join(destination, basename));
|
|
1322
1331
|
}
|
|
1332
|
+
function cloudBuildContextPath(config) {
|
|
1333
|
+
return dockerBuildContextDirectory(config) || normalizeDockerRelativePath(config.rootDirectory);
|
|
1334
|
+
}
|
|
1323
1335
|
var PAGE_CONTAINER_PREFIX = "page:";
|
|
1324
1336
|
async function provisionCloudWorkspace(client, config, logger) {
|
|
1325
1337
|
logger?.log(`Creating workspace from image "${config.image}"...
|
|
@@ -1792,7 +1804,7 @@ var CloudRuntime = class {
|
|
|
1792
1804
|
logger.log("Using Dockerfile content from source metadata.\n");
|
|
1793
1805
|
return {
|
|
1794
1806
|
kind: "remote",
|
|
1795
|
-
contextRelativePath:
|
|
1807
|
+
contextRelativePath: cloudBuildContextPath(config),
|
|
1796
1808
|
dockerfile: config.dockerfileContent,
|
|
1797
1809
|
cleanup: async () => {
|
|
1798
1810
|
}
|
|
@@ -1807,9 +1819,12 @@ var CloudRuntime = class {
|
|
|
1807
1819
|
requireRepositoryDockerfile: true,
|
|
1808
1820
|
onLog: logger.callback
|
|
1809
1821
|
});
|
|
1810
|
-
const dockerfilePath = resolveWithinDirectory(
|
|
1822
|
+
const dockerfilePath = resolveWithinDirectory(
|
|
1823
|
+
context.buildContextDir,
|
|
1824
|
+
context.dockerfileName
|
|
1825
|
+
);
|
|
1811
1826
|
const dockerfile = await readFile(dockerfilePath, "utf-8");
|
|
1812
|
-
const contextRoot = resolveWithinDirectory(context.contextDir, context.rootDirectory);
|
|
1827
|
+
const contextRoot = context.contextSubdir ? context.buildContextDir : resolveWithinDirectory(context.contextDir, context.rootDirectory);
|
|
1813
1828
|
return {
|
|
1814
1829
|
kind: "local",
|
|
1815
1830
|
contextRoot,
|
|
@@ -1818,7 +1833,10 @@ var CloudRuntime = class {
|
|
|
1818
1833
|
};
|
|
1819
1834
|
}
|
|
1820
1835
|
async resolveRemoteDockerfileBuildSource(config, logger) {
|
|
1821
|
-
const
|
|
1836
|
+
const contextSubdir = dockerBuildContextDirectory(config);
|
|
1837
|
+
const candidates = contextSubdir ? resolveContextDockerfileCandidates(contextSubdir, config.dockerfilePath).map(
|
|
1838
|
+
(candidate) => `${contextSubdir}/${candidate}`
|
|
1839
|
+
) : resolveDockerfileCandidates(config.rootDirectory, config.dockerfilePath);
|
|
1822
1840
|
const sourceLabel = config.commitSha ? `${config.branch}@${config.commitSha.slice(0, 7)}` : config.branch;
|
|
1823
1841
|
const checkoutRef = config.commitSha ?? "FETCH_HEAD";
|
|
1824
1842
|
const sourceDir = "/openship/dockerfile-source";
|
|
@@ -1881,7 +1899,7 @@ var CloudRuntime = class {
|
|
|
1881
1899
|
sourceWorkspaceId = void 0;
|
|
1882
1900
|
return {
|
|
1883
1901
|
kind: "remote",
|
|
1884
|
-
contextRelativePath:
|
|
1902
|
+
contextRelativePath: cloudBuildContextPath(config),
|
|
1885
1903
|
dockerfile,
|
|
1886
1904
|
cleanup: async () => {
|
|
1887
1905
|
await this.ws(workspaceId).delete().catch(() => {
|
|
@@ -2063,6 +2081,25 @@ var CloudRuntime = class {
|
|
|
2063
2081
|
const contextSource = contextRelativePath ? joinWorkspacePath(repoRoot, contextRelativePath) : contextRoot;
|
|
2064
2082
|
const prepareContextCommands = contextRelativePath ? [
|
|
2065
2083
|
`echo "Copying Dockerfile context ${contextRelativePath}..."`,
|
|
2084
|
+
// `cp -a` FOLLOWS a symlinked source directory, so a repo that tracks
|
|
2085
|
+
// `svc -> /` and declares `build: ./svc` would copy the workspace's root
|
|
2086
|
+
// filesystem into its own build context. The lexical `..` refusal above
|
|
2087
|
+
// cannot see that; only a resolved path can. Same class as
|
|
2088
|
+
// GHSA-443m-7g52-94w8, reachable through the build context rather than
|
|
2089
|
+
// rootDirectory, and asserted here for the same reason the docker paths
|
|
2090
|
+
// assert it: at the sink.
|
|
2091
|
+
// `pwd -P` rather than `readlink -f`: it is a POSIX shell builtin, so it
|
|
2092
|
+
// exists in every workspace image, and it answers both questions at once —
|
|
2093
|
+
// the `cd` fails when the context is not a directory, and the resolved path
|
|
2094
|
+
// reveals a symlink that left the checkout.
|
|
2095
|
+
// BOTH sides resolved, and an unresolvable either side is fatal: an empty
|
|
2096
|
+
// `__root` would turn the prefix test into `"/"*`, which every absolute path
|
|
2097
|
+
// matches — a containment check that passes vacuously is worse than none.
|
|
2098
|
+
// `|| __x=""` keeps `set -e` from killing the script before the message.
|
|
2099
|
+
`__root="$(cd ${sq(repoRoot)} && pwd -P)" || __root=""`,
|
|
2100
|
+
`__ctx="$(cd ${sq(contextSource)} 2>/dev/null && pwd -P)" || __ctx=""`,
|
|
2101
|
+
`if [ -z "$__root" ] || [ -z "$__ctx" ]; then echo "Build context ${contextRelativePath} is not a directory in this repository." >&2; exit 1; fi`,
|
|
2102
|
+
`case "$__ctx/" in "$__root/"*) ;; *) echo "Build context ${contextRelativePath} resolves outside this repository." >&2; exit 1 ;; esac`,
|
|
2066
2103
|
`mkdir -p ${sq(contextRoot)}`,
|
|
2067
2104
|
`cp -a ${sq(`${contextSource}/.`)} ${sq(contextRoot)}/`
|
|
2068
2105
|
] : ['echo "Using repository root as Dockerfile context."'];
|
|
@@ -2385,15 +2422,28 @@ fi`;
|
|
|
2385
2422
|
}
|
|
2386
2423
|
}
|
|
2387
2424
|
const startCommand = builtArtifact?.runtime.startCommand || config.startCommand || "npm start";
|
|
2425
|
+
const projectEnv = splitRuntimeEnv(config.envVars);
|
|
2426
|
+
if (projectEnv.dropped.length > 0) {
|
|
2427
|
+
onLog?.({
|
|
2428
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2429
|
+
level: "warn",
|
|
2430
|
+
message: droppedRuntimeEnvMessage(projectEnv.dropped)
|
|
2431
|
+
});
|
|
2432
|
+
}
|
|
2388
2433
|
const envArray = toEnvArray2({
|
|
2389
2434
|
...builtArtifact?.runtime.env ?? {},
|
|
2390
|
-
...
|
|
2435
|
+
...Object.fromEntries(projectEnv.entries)
|
|
2391
2436
|
});
|
|
2392
2437
|
const restartPolicy = config.restartPolicy === "no" ? "never" : config.restartPolicy ?? "always";
|
|
2438
|
+
const workloadCmd = resolveCloudWorkloadCmd({
|
|
2439
|
+
startCommand,
|
|
2440
|
+
workdir: workDir,
|
|
2441
|
+
binPathExport: builtArtifact ? "" : nodeBinPathExport(config.packageManager, [workDir, "/app"])
|
|
2442
|
+
});
|
|
2393
2443
|
try {
|
|
2394
2444
|
await ws.workloads.create({
|
|
2395
2445
|
name: "app",
|
|
2396
|
-
cmd:
|
|
2446
|
+
cmd: workloadCmd,
|
|
2397
2447
|
working_dir: workDir,
|
|
2398
2448
|
env: [...envArray, `PORT=${config.port}`],
|
|
2399
2449
|
restart_policy: restartPolicy,
|
|
@@ -2695,15 +2745,7 @@ fi`;
|
|
|
2695
2745
|
}
|
|
2696
2746
|
async purge(deployment) {
|
|
2697
2747
|
if (deployment.containerId?.startsWith(PAGE_CONTAINER_PREFIX)) {
|
|
2698
|
-
|
|
2699
|
-
try {
|
|
2700
|
-
if (this.adminProxy?.deletePage) {
|
|
2701
|
-
await this.adminProxy.deletePage(slug);
|
|
2702
|
-
} else {
|
|
2703
|
-
await this.client.pages.delete(slug);
|
|
2704
|
-
}
|
|
2705
|
-
} catch {
|
|
2706
|
-
}
|
|
2748
|
+
await this.destroy(deployment.containerId);
|
|
2707
2749
|
return;
|
|
2708
2750
|
}
|
|
2709
2751
|
if (!deployment.containerId) return;
|
|
@@ -2717,10 +2759,7 @@ fi`;
|
|
|
2717
2759
|
err instanceof Error ? err.message : err
|
|
2718
2760
|
);
|
|
2719
2761
|
}
|
|
2720
|
-
|
|
2721
|
-
await this.destroy(deployment.containerId);
|
|
2722
|
-
} catch {
|
|
2723
|
-
}
|
|
2762
|
+
await this.destroy(deployment.containerId);
|
|
2724
2763
|
}
|
|
2725
2764
|
// ── Observability ──────────────────────────────────────────────────────
|
|
2726
2765
|
async getContainerInfo(containerId) {
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
resolvePorts,
|
|
29
29
|
sourceBuildDir,
|
|
30
30
|
verifyHostChannel
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-PPEBIY5F.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-RDXT4BQB.js";
|
|
40
40
|
import {
|
|
41
41
|
startUnitHint,
|
|
42
42
|
thisHost
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-VQM6JHJB.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-J2XM3QSP.js";
|
|
51
51
|
import {
|
|
52
52
|
AUTH_SECRET_FILE,
|
|
53
53
|
DATA_DIR,
|
|
@@ -58,15 +58,17 @@ import {
|
|
|
58
58
|
} from "./chunk-ELGRMZOW.js";
|
|
59
59
|
import {
|
|
60
60
|
LocalExecutor
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-E2X26PXR.js";
|
|
62
62
|
import {
|
|
63
|
-
EDGE_CONTAINER_NAME,
|
|
64
63
|
edgeCrashReason,
|
|
65
64
|
edgeIsBroken
|
|
66
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-GIPJNNI5.js";
|
|
66
|
+
import {
|
|
67
|
+
EDGE_CONTAINER_NAME
|
|
68
|
+
} from "./chunk-UWEV6XTS.js";
|
|
67
69
|
import {
|
|
68
70
|
isValidEmail
|
|
69
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-2VSW6Q6C.js";
|
|
70
72
|
|
|
71
73
|
// src/commands/up.ts
|
|
72
74
|
import { Command } from "commander";
|
|
@@ -609,6 +611,7 @@ async function planUp(opts) {
|
|
|
609
611
|
...opts.hostControl === false ? { noHostControl: true } : {},
|
|
610
612
|
...opts.hostSshHost ? { hostSshHost: opts.hostSshHost } : {},
|
|
611
613
|
...opts.hostSshPort ? { hostSshPort: opts.hostSshPort } : {},
|
|
614
|
+
...opts.hostSshUser ? { hostSshUser: opts.hostSshUser } : {},
|
|
612
615
|
...opts.resetSecrets ? { resetSecrets: true } : {},
|
|
613
616
|
...opts.mail ? { mail: true } : {}
|
|
614
617
|
});
|
|
@@ -630,6 +633,13 @@ async function planUp(opts) {
|
|
|
630
633
|
] : [],
|
|
631
634
|
...stack.hostChannel.rootUnavailable ? [
|
|
632
635
|
"\u26A0 host control needs root \u2014 this user isn't root and passwordless sudo isn't available, so mail/edge host ops will fail (re-run as root, or enable passwordless sudo, to fix)"
|
|
636
|
+
] : [],
|
|
637
|
+
// A plan that named one account and then settled on another would read as the
|
|
638
|
+
// plan being wrong, and this run genuinely cannot know which: only a dial can
|
|
639
|
+
// establish whether sshd accepts the first account, and dialing means writing
|
|
640
|
+
// the key a dry run exists not to write (#527, previewHostChannel).
|
|
641
|
+
...stack.hostChannel.fallbacks?.length ? [
|
|
642
|
+
`if this host's sshd refuses that account, falls back to ${stack.hostChannel.fallbacks.join(", ")} (pin one with --host-ssh-user)`
|
|
633
643
|
] : []
|
|
634
644
|
] : [],
|
|
635
645
|
...stack.mountDirs.map((d) => `${d}/ (edge routing state + certs)`),
|
|
@@ -1071,6 +1081,9 @@ var upCommand = new Command("up").description("Start Openship as a persistent se
|
|
|
1071
1081
|
).option(
|
|
1072
1082
|
"--host-ssh-port <port>",
|
|
1073
1083
|
"Compose mode: port the host's sshd listens on for host operations (default 22). Preserved across re-runs."
|
|
1084
|
+
).option(
|
|
1085
|
+
"--host-ssh-user <name>",
|
|
1086
|
+
"Compose mode: the host account the api container logs in as for host operations. Normally left unset \u2014 provisioning authorizes a key and DIALS to find an account this host's sshd actually accepts (root when invoked as root, otherwise the invoking user, falling back to $SUDO_USER when a root login is refused). Set this when neither is the account you want, or when sshd's rules mean neither works: the named account is used as-is and never falls back, so it must be able to log in over SSH and should have passwordless sudo (host operations elevate per command). Preserved across re-runs."
|
|
1074
1087
|
).option(
|
|
1075
1088
|
"--open-host-firewall",
|
|
1076
1089
|
"Compose mode: if the api container can't reach this machine's SSH port, add the host firewall rule that allows it (scoped to the container subnet, ufw/firewalld only). Without this the blocked channel is reported and left alone. Not implied by --yes."
|
|
@@ -1213,6 +1226,7 @@ async function runCompose(opts) {
|
|
|
1213
1226
|
// so the containers would keep an environment the file no longer shows.
|
|
1214
1227
|
hostSshHost: opts.hostSshHost,
|
|
1215
1228
|
hostSshPort: opts.hostSshPort,
|
|
1229
|
+
hostSshUser: opts.hostSshUser,
|
|
1216
1230
|
resetSecrets: opts.resetSecrets,
|
|
1217
1231
|
mail: opts.mail
|
|
1218
1232
|
});
|
|
@@ -1267,6 +1281,7 @@ async function runCompose(opts) {
|
|
|
1267
1281
|
// configured with rather than resetting it to host.docker.internal:22.
|
|
1268
1282
|
hostSshHost: opts.hostSshHost,
|
|
1269
1283
|
hostSshPort: opts.hostSshPort,
|
|
1284
|
+
hostSshUser: opts.hostSshUser,
|
|
1270
1285
|
resetSecrets: opts.resetSecrets,
|
|
1271
1286
|
// Absent on a re-run keeps the install's mode (resolveEnvConfig), so this
|
|
1272
1287
|
// never flips a mail box back to the platform shell.
|
|
@@ -1549,7 +1564,7 @@ async function runForeground(opts, source) {
|
|
|
1549
1564
|
const uiSpinner = ora("Preparing the dashboard\u2026").start();
|
|
1550
1565
|
try {
|
|
1551
1566
|
const bundle = await ensureDashboard({
|
|
1552
|
-
tag: source ? "local" : opts.uiVersion || `v${"0.6.
|
|
1567
|
+
tag: source ? "local" : opts.uiVersion || `v${"0.6.7"}`,
|
|
1553
1568
|
onProgress: (received, total) => {
|
|
1554
1569
|
if (total) {
|
|
1555
1570
|
uiSpinner.text = `Downloading dashboard\u2026 ${Math.round(received / total * 100)}%`;
|
|
@@ -4,18 +4,20 @@ 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-H3WT3A6R.js";
|
|
8
8
|
import {
|
|
9
|
-
assessHostSupport,
|
|
10
|
-
classifyDistro,
|
|
11
9
|
formatDuration,
|
|
12
10
|
isRemoteConnectionError,
|
|
11
|
+
systemDebug
|
|
12
|
+
} from "./chunk-N5YZMO33.js";
|
|
13
|
+
import {
|
|
14
|
+
assessHostSupport,
|
|
15
|
+
classifyDistro,
|
|
13
16
|
parseOsRelease,
|
|
14
17
|
parseSystemArch,
|
|
15
18
|
parseSystemOs,
|
|
16
|
-
safeErrorMessage
|
|
17
|
-
|
|
18
|
-
} from "./chunk-UJ6JZM65.js";
|
|
19
|
+
safeErrorMessage
|
|
20
|
+
} from "./chunk-2VSW6Q6C.js";
|
|
19
21
|
|
|
20
22
|
// ../../packages/adapters/src/system/elevated-executor.ts
|
|
21
23
|
import { randomBytes } from "crypto";
|
|
@@ -2,103 +2,52 @@
|
|
|
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
|
+
probeTcpDetailed
|
|
7
|
+
} from "./chunk-R4VDPFLS.js";
|
|
5
8
|
import {
|
|
6
9
|
getTarCreateEnv,
|
|
7
10
|
prepareSourceTarArgs
|
|
8
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-2ANV5ZQ5.js";
|
|
9
12
|
import {
|
|
10
13
|
connectSshClient,
|
|
11
14
|
openDockerDialStdioChannel,
|
|
12
15
|
openSftp,
|
|
13
16
|
openSshUnixSocket,
|
|
14
17
|
reconcileKnownHosts
|
|
15
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-5T4UVOM3.js";
|
|
16
19
|
import {
|
|
17
20
|
LocalExecutor
|
|
18
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-E2X26PXR.js";
|
|
19
22
|
import {
|
|
20
23
|
emitBufferedLines,
|
|
21
24
|
flushBufferedLines,
|
|
22
25
|
hasLocalCommand,
|
|
23
26
|
logEntry,
|
|
24
27
|
sq
|
|
25
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-H3WT3A6R.js";
|
|
29
|
+
import {
|
|
30
|
+
HostChannelUnavailableError,
|
|
31
|
+
SshDisconnectedError,
|
|
32
|
+
commandForError,
|
|
33
|
+
isSshAuthError
|
|
34
|
+
} from "./chunk-N5YZMO33.js";
|
|
26
35
|
import {
|
|
27
36
|
HOST_CHANNEL_AUTH_REJECTED,
|
|
28
37
|
HOST_CHANNEL_NOT_PROVISIONED,
|
|
29
38
|
HOST_CHANNEL_UNPROVISIONED,
|
|
30
|
-
HostChannelUnavailableError,
|
|
31
|
-
SshDisconnectedError,
|
|
32
39
|
TRANSFER_EXCLUDES,
|
|
33
|
-
commandForError,
|
|
34
40
|
explainHostChannelCause,
|
|
35
41
|
formatBytes,
|
|
36
42
|
hostChannelAccount,
|
|
37
43
|
hostFirewallRule,
|
|
38
|
-
isSshAuthError,
|
|
39
44
|
safeErrorMessage
|
|
40
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-2VSW6Q6C.js";
|
|
41
46
|
|
|
42
47
|
// ../../packages/adapters/src/system/executor.ts
|
|
43
48
|
import { existsSync, readFileSync } from "fs";
|
|
44
49
|
import { networkInterfaces } from "os";
|
|
45
50
|
|
|
46
|
-
// ../../packages/adapters/src/system/reachability.ts
|
|
47
|
-
import { connect } from "net";
|
|
48
|
-
import { request } from "http";
|
|
49
|
-
function classifyDialError(code) {
|
|
50
|
-
switch (code) {
|
|
51
|
-
case "ECONNREFUSED":
|
|
52
|
-
case "ECONNRESET":
|
|
53
|
-
return "refused";
|
|
54
|
-
case "ENOTFOUND":
|
|
55
|
-
case "EAI_AGAIN":
|
|
56
|
-
return "unresolved";
|
|
57
|
-
case "EHOSTUNREACH":
|
|
58
|
-
case "ENETUNREACH":
|
|
59
|
-
case "ENETDOWN":
|
|
60
|
-
return "no_route";
|
|
61
|
-
// The kernel's own connect timeout, i.e. our `timeout` reported for us.
|
|
62
|
-
case "ETIMEDOUT":
|
|
63
|
-
return "timeout";
|
|
64
|
-
default:
|
|
65
|
-
return "error";
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
function probeTcpDetailed(host, port, timeoutMs = 2500) {
|
|
69
|
-
return new Promise((resolve) => {
|
|
70
|
-
let settled = false;
|
|
71
|
-
const done = (result, socket2) => {
|
|
72
|
-
if (settled) return;
|
|
73
|
-
settled = true;
|
|
74
|
-
try {
|
|
75
|
-
socket2?.destroy();
|
|
76
|
-
} catch {
|
|
77
|
-
}
|
|
78
|
-
resolve(result);
|
|
79
|
-
};
|
|
80
|
-
const socket = connect({ host, port });
|
|
81
|
-
socket.setTimeout(timeoutMs);
|
|
82
|
-
socket.once("connect", () => done({ ok: true }, socket));
|
|
83
|
-
socket.once(
|
|
84
|
-
"timeout",
|
|
85
|
-
() => done({ ok: false, reason: "timeout", message: `no response within ${timeoutMs}ms` }, socket)
|
|
86
|
-
);
|
|
87
|
-
socket.once("error", (err) => {
|
|
88
|
-
const errno = err;
|
|
89
|
-
done(
|
|
90
|
-
{
|
|
91
|
-
ok: false,
|
|
92
|
-
reason: classifyDialError(errno.code),
|
|
93
|
-
...errno.code ? { code: errno.code } : {},
|
|
94
|
-
...errno.message ? { message: errno.message } : {}
|
|
95
|
-
},
|
|
96
|
-
socket
|
|
97
|
-
);
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
|
|
102
51
|
// ../../packages/adapters/src/system/ssh-executor.ts
|
|
103
52
|
import { createReadStream } from "fs";
|
|
104
53
|
import { mkdtemp as mkdtemp2, rm as fsRm2, stat } from "fs/promises";
|
|
@@ -1720,7 +1669,7 @@ async function verifyHostChannelAuth(config) {
|
|
|
1720
1669
|
let hint = null;
|
|
1721
1670
|
let forwarding = "unknown";
|
|
1722
1671
|
try {
|
|
1723
|
-
const { connectSshClient: connectSshClient2 } = await import("./ssh-client-
|
|
1672
|
+
const { connectSshClient: connectSshClient2 } = await import("./ssh-client-625VWGKP.js");
|
|
1724
1673
|
const client = await connectSshClient2({
|
|
1725
1674
|
host: config.host,
|
|
1726
1675
|
port: config.port,
|