openship 0.6.5 → 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-2ANV5ZQ5.js +88 -0
- package/dist/{chunk-LEYSL46B.js → chunk-2VSW6Q6C.js} +3911 -898
- package/dist/{chunk-5OUWIPOB.js → chunk-5T4UVOM3.js} +16 -86
- package/dist/{chunk-EZPPTWJQ.js → chunk-BLEXTYRK.js} +1 -1
- package/dist/{chunk-3ZAGC5NT.js → chunk-CIJV43LH.js} +83 -33
- package/dist/{chunk-7S4USQYF.js → chunk-DDFUESPJ.js} +67 -124
- package/dist/{chunk-6FH4AXVY.js → chunk-E2X26PXR.js} +1 -1
- package/dist/{chunk-XVOBL7BC.js → chunk-FYPFEDPZ.js} +1 -1
- package/dist/{chunk-WFRXYWK2.js → chunk-FZ6QCF6B.js} +8 -6
- package/dist/{chunk-VHMOQL5Y.js → chunk-GGIAIGUL.js} +125 -80
- package/dist/{chunk-WE7BXW6L.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-HPXP6LXZ.js → chunk-J2XM3QSP.js} +8 -5
- package/dist/{chunk-6JELW75A.js → chunk-J3K6XABC.js} +5 -5
- package/dist/{chunk-VDESJSG6.js → chunk-LHFXSC36.js} +558 -109
- package/dist/{chunk-MSZUCNPV.js → chunk-MEE6OZFP.js} +3 -3
- package/dist/chunk-N5YZMO33.js +111 -0
- package/dist/{chunk-VLQ3UIVO.js → chunk-NRTJRNAE.js} +105 -37
- package/dist/chunk-PPEBIY5F.js +2331 -0
- package/dist/{chunk-RFWJE7ZN.js → chunk-PVP4RGWT.js} +3 -3
- package/dist/{chunk-PZRRL5PC.js → chunk-QHMDCYZ3.js} +15 -4
- package/dist/chunk-R4VDPFLS.js +106 -0
- package/dist/chunk-RDXT4BQB.js +310 -0
- package/dist/{chunk-GRTXMUHA.js → chunk-S6B2Z3OO.js} +145 -60
- package/dist/chunk-UWEV6XTS.js +249 -0
- package/dist/{chunk-QLX7NBEA.js → chunk-VQM6JHJB.js} +1004 -2046
- package/dist/{chunk-A7EWM2KA.js → chunk-VSTFHUCV.js} +44 -50
- package/dist/chunk-WU54BXFE.js +70 -0
- package/dist/{chunk-LFCSC4IU.js → chunk-XWHWTHEL.js} +313 -469
- package/dist/{chunk-7334NSJL.js → chunk-ZPJ74LXE.js} +76 -38
- package/dist/cloud-KNNABE3O.js +40 -0
- package/dist/{detect-P4CIQBRH.js → detect-G4DR3U2N.js} +9 -6
- package/dist/{docker-3K2NEBD6.js → docker-YOVPCIB4.js} +11 -7
- package/dist/{docker-edge-executor-YZZ6P7IC.js → docker-edge-executor-QFXD3337.js} +8 -6
- package/dist/edge-import-CRFVSR6P.js +56 -0
- package/dist/{edge-preflight-ES6FH4JK.js → edge-preflight-MXERVAMG.js} +15 -12
- package/dist/{ensure-container-edge-YPITNH45.js → ensure-container-edge-F4JUNQIK.js} +13 -10
- package/dist/{executor-DZGX55K2.js → executor-CVPAYYHR.js} +10 -5
- package/dist/host-channel-preflight-QTDNGLCK.js +54 -0
- package/dist/index.js +139 -92
- package/dist/{local-executor-WOFZD72X.js → local-executor-ODC6RANU.js} +3 -2
- package/dist/{nginx-NSAHWGJV.js → nginx-KLFF43TC.js} +13 -8
- package/dist/{openresty-lua-DR4D3EZ6.js → openresty-lua-VKWUV4GB.js} +8 -5
- package/dist/{privilege-YTVI4SKF.js → privilege-7D3SSOL3.js} +6 -5
- package/dist/server/engine/samples/amavisd/amavisd.conf +25 -0
- package/dist/server/engine/samples/postfix/master.cf +14 -0
- package/dist/server/index.js +44526 -33476
- package/dist/server/migrations/0105_mail_inbound_rules.sql +80 -0
- package/dist/server/migrations/0106_mcp_call_tracking.sql +23 -0
- package/dist/server/migrations/0107_build_minute_metering_indexes.sql +20 -0
- package/dist/server/migrations/0108_credential.sql +68 -0
- package/dist/server/migrations/meta/_journal.json +28 -0
- package/dist/setup-I5AJC6NJ.js +25 -0
- package/dist/ssh-client-625VWGKP.js +29 -0
- package/dist/up-QXTOOVXC.js +61 -0
- package/package.json +1 -1
- package/dist/bare-XQIPDO4R.js +0 -24
- package/dist/chunk-6HOA5JT7.js +0 -124
- package/dist/chunk-TM2IQPYU.js +0 -434
- package/dist/chunk-XRNRT37W.js +0 -316
- package/dist/cloud-3DODOWTR.js +0 -36
- package/dist/edge-import-MCJNVTZ2.js +0 -51
- package/dist/host-channel-preflight-MUXE3KZU.js +0 -49
- package/dist/setup-WUUZURHS.js +0 -22
- package/dist/up-XEO3SR6Z.js +0 -58
- /package/dist/{dist-es-ZP5QDSJ3.js → dist-es-AXFRS7PS.js} +0 -0
|
@@ -3,102 +3,33 @@
|
|
|
3
3
|
import { createRequire as __ospCreateRequire } from "node:module";
|
|
4
4
|
const require = __ospCreateRequire(import.meta.url);
|
|
5
5
|
import {
|
|
6
|
-
PACKAGE_ROOT_ONLY_EXCLUDES,
|
|
7
|
-
hostFirewallRule,
|
|
8
6
|
isSshAuthError,
|
|
9
|
-
safeErrorMessage,
|
|
10
7
|
systemDebug
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
var execFileAsync = promisify(execFile);
|
|
20
|
-
var ROOT_ONLY_EXCLUDES = new Set(PACKAGE_ROOT_ONLY_EXCLUDES);
|
|
21
|
-
var NOOP_CLEANUP = async () => {
|
|
22
|
-
};
|
|
23
|
-
function getTarCreateEnv() {
|
|
24
|
-
return {
|
|
25
|
-
...process.env,
|
|
26
|
-
COPYFILE_DISABLE: "1",
|
|
27
|
-
COPY_EXTENDED_ATTRIBUTES_DISABLE: "1"
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
function tarCreateBaseArgs(localPath) {
|
|
31
|
-
const darwinFlags = process.platform === "darwin" ? ["--no-mac-metadata", "--no-xattrs", "--no-acls", "--no-fflags"] : [];
|
|
32
|
-
return [...darwinFlags, "-czf", "-", "-C", localPath];
|
|
33
|
-
}
|
|
34
|
-
async function gitTrackedFiles(localPath) {
|
|
35
|
-
try {
|
|
36
|
-
const { stdout } = await execFileAsync(
|
|
37
|
-
"git",
|
|
38
|
-
["-C", localPath, "ls-files", "-z", "--cached", "--others", "--exclude-standard"],
|
|
39
|
-
{ maxBuffer: 256 * 1024 * 1024 }
|
|
40
|
-
);
|
|
41
|
-
const files = stdout.split("\0").filter(Boolean);
|
|
42
|
-
return files.length > 0 ? files : null;
|
|
43
|
-
} catch {
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
async function existingRelativePaths(root, paths) {
|
|
48
|
-
if (!paths?.length) return [];
|
|
49
|
-
const found = [];
|
|
50
|
-
for (const p of paths) {
|
|
51
|
-
try {
|
|
52
|
-
await stat(join(root, p));
|
|
53
|
-
found.push(p);
|
|
54
|
-
} catch {
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return found;
|
|
58
|
-
}
|
|
59
|
-
async function prepareSourceTarArgs(localPath, options) {
|
|
60
|
-
if (options?.includes?.length) {
|
|
61
|
-
return { args: getTarCreateArgs(localPath, options), cleanup: NOOP_CLEANUP };
|
|
62
|
-
}
|
|
63
|
-
const files = await gitTrackedFiles(localPath);
|
|
64
|
-
if (files) {
|
|
65
|
-
const extra = await existingRelativePaths(localPath, options?.alsoInclude);
|
|
66
|
-
const entries = extra.length ? [...files, ...extra] : files;
|
|
67
|
-
const tmpDir = await mkdtemp(join(tmpdir(), "openship-tarlist-"));
|
|
68
|
-
const listFile = join(tmpDir, "files.null");
|
|
69
|
-
await writeFile(listFile, entries.join("\0"));
|
|
70
|
-
const args = [...tarCreateBaseArgs(localPath), "--null", "-T", listFile];
|
|
71
|
-
return { args, cleanup: () => rm(tmpDir, { recursive: true, force: true }) };
|
|
72
|
-
}
|
|
73
|
-
return { args: getTarCreateArgs(localPath, options), cleanup: NOOP_CLEANUP };
|
|
74
|
-
}
|
|
75
|
-
function getTarCreateArgs(localPath, options) {
|
|
76
|
-
const args = tarCreateBaseArgs(localPath);
|
|
77
|
-
if (options?.includes?.length) {
|
|
78
|
-
args.push(...options.includes);
|
|
79
|
-
return args;
|
|
80
|
-
}
|
|
81
|
-
for (const exclude of options?.excludes ?? []) {
|
|
82
|
-
const pattern = ROOT_ONLY_EXCLUDES.has(exclude) ? `./${exclude}` : exclude;
|
|
83
|
-
args.push(`--exclude=${pattern}`);
|
|
84
|
-
}
|
|
85
|
-
args.push(".");
|
|
86
|
-
return args;
|
|
87
|
-
}
|
|
8
|
+
} from "./chunk-N5YZMO33.js";
|
|
9
|
+
import {
|
|
10
|
+
HOST_CHANNEL_AUTH_REJECTED,
|
|
11
|
+
HOST_CHANNEL_NOT_PROVISIONED,
|
|
12
|
+
HOST_CHANNEL_ROW_CREDENTIALS_UNUSED,
|
|
13
|
+
hostFirewallRule,
|
|
14
|
+
safeErrorMessage
|
|
15
|
+
} from "./chunk-2VSW6Q6C.js";
|
|
88
16
|
|
|
89
17
|
// ../../packages/adapters/src/system/ssh-client.ts
|
|
90
18
|
import { Client } from "ssh2";
|
|
91
19
|
|
|
92
20
|
// ../../packages/adapters/src/system/ssh-support.ts
|
|
93
|
-
import { execFile
|
|
21
|
+
import { execFile } from "child_process";
|
|
94
22
|
import { access } from "fs/promises";
|
|
95
23
|
import { homedir } from "os";
|
|
96
|
-
import { join
|
|
24
|
+
import { join } from "path";
|
|
97
25
|
function formatSshTarget(config) {
|
|
98
26
|
return `${config.username ?? "root"}@${config.host}:${config.port ?? 22}`;
|
|
99
27
|
}
|
|
100
28
|
function describeSshAuthFailure(config, originalMessage) {
|
|
101
29
|
const target = formatSshTarget(config);
|
|
30
|
+
if (config.hostChannel) {
|
|
31
|
+
return `${HOST_CHANNEL_AUTH_REJECTED} Dialed ${target} from inside the Openship API container. ${HOST_CHANNEL_ROW_CREDENTIALS_UNUSED} ${HOST_CHANNEL_NOT_PROVISIONED} (${originalMessage})`;
|
|
32
|
+
}
|
|
102
33
|
if (config.password) {
|
|
103
34
|
return `SSH password authentication failed for ${target}. Check the username/password, or verify that the server allows password login. (${originalMessage})`;
|
|
104
35
|
}
|
|
@@ -119,7 +50,7 @@ Or re-run \`openship up\`, which probes this and offers the exact rule. (${origi
|
|
|
119
50
|
}
|
|
120
51
|
function execFileText(command, args, timeout = 5e3) {
|
|
121
52
|
return new Promise((resolve, reject) => {
|
|
122
|
-
|
|
53
|
+
execFile(command, args, { timeout }, (err, stdout, stderr) => {
|
|
123
54
|
if (err) {
|
|
124
55
|
reject(new Error(stderr.trim() || stdout.trim() || err.message));
|
|
125
56
|
return;
|
|
@@ -141,7 +72,7 @@ function parseKnownHostsEntries(text) {
|
|
|
141
72
|
return entries;
|
|
142
73
|
}
|
|
143
74
|
async function reconcileKnownHosts(config) {
|
|
144
|
-
const knownHostsPath =
|
|
75
|
+
const knownHostsPath = join(homedir(), ".ssh", "known_hosts");
|
|
145
76
|
try {
|
|
146
77
|
await access(knownHostsPath);
|
|
147
78
|
} catch {
|
|
@@ -378,13 +309,12 @@ async function execSshCommand(client, command, timeout = 1e4) {
|
|
|
378
309
|
}
|
|
379
310
|
|
|
380
311
|
export {
|
|
381
|
-
getTarCreateEnv,
|
|
382
|
-
prepareSourceTarArgs,
|
|
383
312
|
reconcileKnownHosts,
|
|
384
313
|
connectSshClient,
|
|
385
314
|
openSftp,
|
|
386
315
|
openSshUnixSocket,
|
|
387
316
|
DOCKER_DIAL_STDIO_COMMAND,
|
|
317
|
+
openSshExecChannel,
|
|
388
318
|
attachDialStdioDiagnostics,
|
|
389
319
|
dialStdioDiagnostics,
|
|
390
320
|
openDockerDialStdioChannel,
|
|
@@ -5,37 +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-LFCSC4IU.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";
|
|
28
32
|
import {
|
|
33
|
+
isRuntimeNotFoundError
|
|
34
|
+
} from "./chunk-N5YZMO33.js";
|
|
35
|
+
import {
|
|
36
|
+
PRICING,
|
|
29
37
|
STACKS,
|
|
30
38
|
SYSTEM,
|
|
31
39
|
TRANSFER_EXCLUDES,
|
|
32
40
|
buildOutputTransferExcludes,
|
|
33
|
-
isRuntimeNotFoundError,
|
|
34
41
|
missingOutputDirectoryMessage,
|
|
42
|
+
nodeBinPathExport,
|
|
35
43
|
packageManagerEnsureCommand,
|
|
36
44
|
safeErrorMessage,
|
|
37
45
|
shellSplitWords
|
|
38
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-2VSW6Q6C.js";
|
|
39
47
|
|
|
40
48
|
// ../../packages/adapters/src/runtime/cloud.ts
|
|
41
49
|
import { readFile } from "fs/promises";
|
|
@@ -47,6 +55,11 @@ var DEFAULT_RESOURCE_CONFIG = {
|
|
|
47
55
|
memoryMb: 512,
|
|
48
56
|
diskMb: 5120
|
|
49
57
|
};
|
|
58
|
+
var DEFAULT_BUILD_RESOURCE_CONFIG = {
|
|
59
|
+
cpuCores: PRICING.oblien.buildResources.cpuCores,
|
|
60
|
+
memoryMb: PRICING.oblien.buildResources.memoryMb,
|
|
61
|
+
diskMb: PRICING.oblien.buildResources.diskGb * 1024
|
|
62
|
+
};
|
|
50
63
|
function cloudCpus(cpuCores) {
|
|
51
64
|
return Math.max(0.25, cpuCores);
|
|
52
65
|
}
|
|
@@ -713,9 +726,11 @@ function restartPolicyForWorkload(policy) {
|
|
|
713
726
|
return "always";
|
|
714
727
|
}
|
|
715
728
|
function resolveCloudWorkloadCmd(opts) {
|
|
716
|
-
const { commandArgv, startCommand, workdir } = opts;
|
|
729
|
+
const { commandArgv, startCommand, workdir, binPathExport } = opts;
|
|
717
730
|
if (commandArgv != null) return commandArgv.length > 0 ? commandArgv : void 0;
|
|
718
|
-
|
|
731
|
+
if (!startCommand) return void 0;
|
|
732
|
+
const body = `cd ${sq(workdir)} && ${startCommand}`;
|
|
733
|
+
return ["sh", "-c", binPathExport ? `${binPathExport} && ${body}` : body];
|
|
719
734
|
}
|
|
720
735
|
function exposeTarget(port, serviceName, slug, domain = SYSTEM.DOMAINS.CLOUD_DOMAIN) {
|
|
721
736
|
const service = `service "${serviceName}" on port ${port}`;
|
|
@@ -1314,6 +1329,9 @@ function resolveCopyDestinationPath(copy, sourcePath, destination, destinationIs
|
|
|
1314
1329
|
const basename = posix.basename(sourcePath.replace(/\/+$/g, "")) || ".";
|
|
1315
1330
|
return posix.normalize(posix.join(destination, basename));
|
|
1316
1331
|
}
|
|
1332
|
+
function cloudBuildContextPath(config) {
|
|
1333
|
+
return dockerBuildContextDirectory(config) || normalizeDockerRelativePath(config.rootDirectory);
|
|
1334
|
+
}
|
|
1317
1335
|
var PAGE_CONTAINER_PREFIX = "page:";
|
|
1318
1336
|
async function provisionCloudWorkspace(client, config, logger) {
|
|
1319
1337
|
logger?.log(`Creating workspace from image "${config.image}"...
|
|
@@ -1414,7 +1432,12 @@ var CloudRuntime = class {
|
|
|
1414
1432
|
// per service and continues, rather than the workload coming up on its own
|
|
1415
1433
|
// network with nothing having said so (#533).
|
|
1416
1434
|
"networkMode",
|
|
1417
|
-
"pidMode"
|
|
1435
|
+
"pidMode",
|
|
1436
|
+
// A workspace is not a container whose ENTRYPOINT we compose: Oblien resolves its
|
|
1437
|
+
// own workload command, so an override (or a clearing `[]`) has nowhere to land
|
|
1438
|
+
// here. Declared so the deploy says so once per service and continues, rather
|
|
1439
|
+
// than the image's own launcher running with nothing having mentioned it (#575).
|
|
1440
|
+
"entrypoint"
|
|
1418
1441
|
]);
|
|
1419
1442
|
client;
|
|
1420
1443
|
// Optional admin-scoped proxy. Set when this runtime is constructed
|
|
@@ -1781,7 +1804,7 @@ var CloudRuntime = class {
|
|
|
1781
1804
|
logger.log("Using Dockerfile content from source metadata.\n");
|
|
1782
1805
|
return {
|
|
1783
1806
|
kind: "remote",
|
|
1784
|
-
contextRelativePath:
|
|
1807
|
+
contextRelativePath: cloudBuildContextPath(config),
|
|
1785
1808
|
dockerfile: config.dockerfileContent,
|
|
1786
1809
|
cleanup: async () => {
|
|
1787
1810
|
}
|
|
@@ -1796,9 +1819,12 @@ var CloudRuntime = class {
|
|
|
1796
1819
|
requireRepositoryDockerfile: true,
|
|
1797
1820
|
onLog: logger.callback
|
|
1798
1821
|
});
|
|
1799
|
-
const dockerfilePath = resolveWithinDirectory(
|
|
1822
|
+
const dockerfilePath = resolveWithinDirectory(
|
|
1823
|
+
context.buildContextDir,
|
|
1824
|
+
context.dockerfileName
|
|
1825
|
+
);
|
|
1800
1826
|
const dockerfile = await readFile(dockerfilePath, "utf-8");
|
|
1801
|
-
const contextRoot = resolveWithinDirectory(context.contextDir, context.rootDirectory);
|
|
1827
|
+
const contextRoot = context.contextSubdir ? context.buildContextDir : resolveWithinDirectory(context.contextDir, context.rootDirectory);
|
|
1802
1828
|
return {
|
|
1803
1829
|
kind: "local",
|
|
1804
1830
|
contextRoot,
|
|
@@ -1807,7 +1833,10 @@ var CloudRuntime = class {
|
|
|
1807
1833
|
};
|
|
1808
1834
|
}
|
|
1809
1835
|
async resolveRemoteDockerfileBuildSource(config, logger) {
|
|
1810
|
-
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);
|
|
1811
1840
|
const sourceLabel = config.commitSha ? `${config.branch}@${config.commitSha.slice(0, 7)}` : config.branch;
|
|
1812
1841
|
const checkoutRef = config.commitSha ?? "FETCH_HEAD";
|
|
1813
1842
|
const sourceDir = "/openship/dockerfile-source";
|
|
@@ -1870,7 +1899,7 @@ var CloudRuntime = class {
|
|
|
1870
1899
|
sourceWorkspaceId = void 0;
|
|
1871
1900
|
return {
|
|
1872
1901
|
kind: "remote",
|
|
1873
|
-
contextRelativePath:
|
|
1902
|
+
contextRelativePath: cloudBuildContextPath(config),
|
|
1874
1903
|
dockerfile,
|
|
1875
1904
|
cleanup: async () => {
|
|
1876
1905
|
await this.ws(workspaceId).delete().catch(() => {
|
|
@@ -2052,6 +2081,25 @@ var CloudRuntime = class {
|
|
|
2052
2081
|
const contextSource = contextRelativePath ? joinWorkspacePath(repoRoot, contextRelativePath) : contextRoot;
|
|
2053
2082
|
const prepareContextCommands = contextRelativePath ? [
|
|
2054
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`,
|
|
2055
2103
|
`mkdir -p ${sq(contextRoot)}`,
|
|
2056
2104
|
`cp -a ${sq(`${contextSource}/.`)} ${sq(contextRoot)}/`
|
|
2057
2105
|
] : ['echo "Using repository root as Dockerfile context."'];
|
|
@@ -2374,15 +2422,28 @@ fi`;
|
|
|
2374
2422
|
}
|
|
2375
2423
|
}
|
|
2376
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
|
+
}
|
|
2377
2433
|
const envArray = toEnvArray2({
|
|
2378
2434
|
...builtArtifact?.runtime.env ?? {},
|
|
2379
|
-
...
|
|
2435
|
+
...Object.fromEntries(projectEnv.entries)
|
|
2380
2436
|
});
|
|
2381
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
|
+
});
|
|
2382
2443
|
try {
|
|
2383
2444
|
await ws.workloads.create({
|
|
2384
2445
|
name: "app",
|
|
2385
|
-
cmd:
|
|
2446
|
+
cmd: workloadCmd,
|
|
2386
2447
|
working_dir: workDir,
|
|
2387
2448
|
env: [...envArray, `PORT=${config.port}`],
|
|
2388
2449
|
restart_policy: restartPolicy,
|
|
@@ -2684,15 +2745,7 @@ fi`;
|
|
|
2684
2745
|
}
|
|
2685
2746
|
async purge(deployment) {
|
|
2686
2747
|
if (deployment.containerId?.startsWith(PAGE_CONTAINER_PREFIX)) {
|
|
2687
|
-
|
|
2688
|
-
try {
|
|
2689
|
-
if (this.adminProxy?.deletePage) {
|
|
2690
|
-
await this.adminProxy.deletePage(slug);
|
|
2691
|
-
} else {
|
|
2692
|
-
await this.client.pages.delete(slug);
|
|
2693
|
-
}
|
|
2694
|
-
} catch {
|
|
2695
|
-
}
|
|
2748
|
+
await this.destroy(deployment.containerId);
|
|
2696
2749
|
return;
|
|
2697
2750
|
}
|
|
2698
2751
|
if (!deployment.containerId) return;
|
|
@@ -2706,10 +2759,7 @@ fi`;
|
|
|
2706
2759
|
err instanceof Error ? err.message : err
|
|
2707
2760
|
);
|
|
2708
2761
|
}
|
|
2709
|
-
|
|
2710
|
-
await this.destroy(deployment.containerId);
|
|
2711
|
-
} catch {
|
|
2712
|
-
}
|
|
2762
|
+
await this.destroy(deployment.containerId);
|
|
2713
2763
|
}
|
|
2714
2764
|
// ── Observability ──────────────────────────────────────────────────────
|
|
2715
2765
|
async getContainerInfo(containerId) {
|