openship 0.6.6 → 0.6.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bare-FA66N7GC.js +29 -0
- package/dist/{chunk-77QDF6UD.js → chunk-3MP6ACKM.js} +587 -156
- package/dist/{chunk-YIMOCZBZ.js → chunk-5DJOB7IX.js} +3 -3
- package/dist/{chunk-WVAML4H6.js → chunk-5I3COAFH.js} +274 -65
- package/dist/{chunk-5DMWSTOM.js → chunk-5UXHT6ED.js} +940 -224
- package/dist/{chunk-LUKYPVJ4.js → chunk-6GU6JSK6.js} +329 -466
- package/dist/{chunk-RSR7PFIQ.js → chunk-7PEXM2UI.js} +213 -45
- package/dist/{chunk-VTGPEC6B.js → chunk-7YBWXEM6.js} +6 -4
- package/dist/chunk-AHJYP7DG.js +938 -0
- package/dist/chunk-BO6CY4V2.js +265 -0
- package/dist/{chunk-FE7ZZQSE.js → chunk-D3OEMXYP.js} +3 -3
- package/dist/chunk-D6HU4VUZ.js +249 -0
- package/dist/{chunk-LFE5KQ7Y.js → chunk-ENKJ7XIF.js} +152 -57
- package/dist/{chunk-YMMQRE5J.js → chunk-GNOMEMNI.js} +1 -1
- package/dist/{chunk-QVW76WDL.js → chunk-IAMOUDHY.js} +190 -64
- package/dist/{chunk-OBPKYXQL.js → chunk-MUWVC5R4.js} +219 -58
- package/dist/chunk-N5YZMO33.js +111 -0
- package/dist/{chunk-A4GXYE4L.js → chunk-NIYD7MD2.js} +206 -52
- package/dist/{chunk-UVNMQM7W.js → chunk-NPSRGIHV.js} +8 -6
- package/dist/{chunk-2GWYYHOR.js → chunk-NRU2EBYZ.js} +2 -2
- package/dist/{chunk-CBLD2HS5.js → chunk-NUT6HKK6.js} +8 -5
- package/dist/{chunk-ZFJXPCQP.js → chunk-P7RCYELG.js} +4 -3
- package/dist/chunk-R4VDPFLS.js +106 -0
- package/dist/{chunk-HKRQXPTI.js → chunk-R5DC5PEF.js} +1 -1
- package/dist/{chunk-NK5N5LXN.js → chunk-RCMERVBL.js} +24 -9
- package/dist/{chunk-RXQBD4ZY.js → chunk-RHLNVZMS.js} +2 -2
- package/dist/chunk-SK4FFCFR.js +70 -0
- package/dist/{chunk-4I2BM2DT.js → chunk-T46BQOLY.js} +3 -3
- package/dist/{chunk-6FH4AXVY.js → chunk-T6DVUX4F.js} +1 -1
- package/dist/{chunk-PCPVTH6M.js → chunk-TAZZZKYO.js} +6 -4
- package/dist/{chunk-MLYSEZQB.js → chunk-UAWY6X7V.js} +43 -72
- package/dist/{chunk-Q7WGTQQ5.js → chunk-VAI5VOOI.js} +1 -1
- package/dist/{chunk-UJ6JZM65.js → chunk-WEZFTL4V.js} +1325 -513
- package/dist/{chunk-2YM3NI2E.js → chunk-X53JXRS4.js} +38 -44
- package/dist/{cloud-KRTZ2IL5.js → cloud-2CRDKOWQ.js} +1 -1
- package/dist/cloud-REV3DPJH.js +42 -0
- package/dist/{detect-OIE5V3VZ.js → detect-BBFT5GEU.js} +9 -6
- package/dist/{docker-VTR2GK5Y.js → docker-EG3QSE6I.js} +11 -8
- package/dist/{docker-edge-executor-22IBXNYJ.js → docker-edge-executor-E5TOTLMR.js} +8 -6
- package/dist/edge-import-YJVJUGYC.js +56 -0
- package/dist/{edge-preflight-GBNCPNVU.js → edge-preflight-QUW4BM7N.js} +15 -12
- package/dist/{ensure-container-edge-KPI2CVXJ.js → ensure-container-edge-FOEFQ3PI.js} +15 -10
- package/dist/{executor-7LXXZPBR.js → executor-NTWDJ3DB.js} +8 -6
- package/dist/host-channel-preflight-OMCZMMKR.js +54 -0
- package/dist/index.js +198 -76
- package/dist/{local-executor-WOFZD72X.js → local-executor-OQ2GRN7K.js} +3 -2
- package/dist/{nginx-KUFMLMAC.js → nginx-4U4C2XUS.js} +11 -8
- package/dist/{noop-NJ72F46T.js → noop-CLLJHCPL.js} +1 -1
- package/dist/{openresty-lua-ATTH35BE.js → openresty-lua-LLWT5XQW.js} +8 -5
- package/dist/{privilege-I4W3ZNZK.js → privilege-MNDVMDST.js} +6 -5
- package/dist/server/index.js +40049 -30378
- package/dist/server/migrations/0109_service_build_args.sql +9 -0
- package/dist/server/migrations/0110_service_deployment_host_ports.sql +18 -0
- package/dist/server/migrations/0111_host_port_claim.sql +381 -0
- package/dist/server/migrations/0112_backup_run_execution_lease.sql +12 -0
- package/dist/server/migrations/0113_docker_migration_execution_lease.sql +11 -0
- package/dist/server/migrations/0114_build_session_execution_lease_index.sql +6 -0
- package/dist/server/migrations/0115_orphan_target_key.sql +3 -0
- package/dist/server/migrations/0116_domain_ssl_challenge.sql +2 -0
- package/dist/server/migrations/meta/_journal.json +56 -0
- package/dist/setup-IFIMPQZJ.js +25 -0
- package/dist/{ssh-client-JBMA7SN4.js → ssh-client-2XWZCMGI.js} +3 -2
- package/dist/up-HQS7IR7H.js +61 -0
- package/package.json +1 -1
- package/dist/bare-OXJVW3AK.js +0 -25
- package/dist/chunk-LH2PLRQO.js +0 -434
- package/dist/chunk-SM26HDS2.js +0 -185
- 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
|
@@ -7,42 +7,59 @@ import {
|
|
|
7
7
|
resolveProjectDir,
|
|
8
8
|
resolveStaticOutputPath,
|
|
9
9
|
runLocalBuild
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-5DJOB7IX.js";
|
|
11
|
+
import {
|
|
12
|
+
isArtifactPathRef,
|
|
13
|
+
removeManagedArtifact
|
|
14
|
+
} from "./chunk-SK4FFCFR.js";
|
|
11
15
|
import {
|
|
12
16
|
BuildCancelledError,
|
|
13
17
|
BuildLogger,
|
|
14
18
|
detectBuildKillHint,
|
|
19
|
+
droppedRuntimeEnvMessage,
|
|
20
|
+
isExcludedDocRootEntry,
|
|
15
21
|
killProcessesUnderDir,
|
|
16
22
|
parseLogLevel,
|
|
17
23
|
runBuildPipeline,
|
|
24
|
+
splitRuntimeEnv,
|
|
18
25
|
sq,
|
|
19
26
|
transferLocalDirectory
|
|
20
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-AHJYP7DG.js";
|
|
21
28
|
import {
|
|
22
29
|
LocalExecutor
|
|
23
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-T6DVUX4F.js";
|
|
24
31
|
import {
|
|
25
32
|
privilegedExecutor
|
|
26
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-T46BQOLY.js";
|
|
27
34
|
import {
|
|
28
35
|
HOST_STATE_DIR,
|
|
29
36
|
envOps,
|
|
30
37
|
hostRefusal,
|
|
31
38
|
opScript
|
|
32
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-GNOMEMNI.js";
|
|
33
40
|
import {
|
|
34
41
|
ensureOwnedDir,
|
|
35
42
|
resolveEnvironment
|
|
36
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-NPSRGIHV.js";
|
|
37
44
|
import {
|
|
38
45
|
sq as sq2,
|
|
39
46
|
wrapLocalBuildCommand
|
|
40
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-P7RCYELG.js";
|
|
48
|
+
import {
|
|
49
|
+
portOccupantDetails,
|
|
50
|
+
probeListeningPort
|
|
51
|
+
} from "./chunk-BO6CY4V2.js";
|
|
41
52
|
import {
|
|
53
|
+
managedDeploymentUnitName,
|
|
42
54
|
probeExec,
|
|
43
|
-
probeListeningPort,
|
|
44
55
|
withReason
|
|
45
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-D6HU4VUZ.js";
|
|
57
|
+
import {
|
|
58
|
+
formatDuration,
|
|
59
|
+
isRemoteConnectionError,
|
|
60
|
+
isRetryableRemoteConnectionError,
|
|
61
|
+
systemDebug
|
|
62
|
+
} from "./chunk-N5YZMO33.js";
|
|
46
63
|
import {
|
|
47
64
|
DeployError,
|
|
48
65
|
LANGUAGES,
|
|
@@ -50,16 +67,13 @@ import {
|
|
|
50
67
|
answered,
|
|
51
68
|
appVolumeTargets,
|
|
52
69
|
buildOutputTransferExcludes,
|
|
53
|
-
formatDuration,
|
|
54
|
-
isRemoteConnectionError,
|
|
55
|
-
isRetryableRemoteConnectionError,
|
|
56
70
|
missingOutputDirectoryMessage,
|
|
71
|
+
nodeBinPathExport,
|
|
57
72
|
packageManagerEnsureCommand,
|
|
58
73
|
refused,
|
|
59
74
|
safeErrorMessage,
|
|
60
|
-
shellQuote
|
|
61
|
-
|
|
62
|
-
} from "./chunk-UJ6JZM65.js";
|
|
75
|
+
shellQuote
|
|
76
|
+
} from "./chunk-WEZFTL4V.js";
|
|
63
77
|
|
|
64
78
|
// ../../packages/adapters/src/system/remote-journal.ts
|
|
65
79
|
var OPSH_RUN_VERSION = 1;
|
|
@@ -1114,7 +1128,6 @@ async function sampleBareUsage(executor, pid, cgroupCandidates = []) {
|
|
|
1114
1128
|
}
|
|
1115
1129
|
|
|
1116
1130
|
// ../../packages/adapters/src/runtime/supervisor/systemd.ts
|
|
1117
|
-
var UNIT_PREFIX = "openship";
|
|
1118
1131
|
function escapeSystemdEnvValue(value) {
|
|
1119
1132
|
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/%/g, "%%").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
|
|
1120
1133
|
}
|
|
@@ -1126,7 +1139,7 @@ var SystemdSupervisor = class {
|
|
|
1126
1139
|
name = "systemd";
|
|
1127
1140
|
// ── Helpers ──────────────────────────────────────────────────────────
|
|
1128
1141
|
unitName(deploymentId) {
|
|
1129
|
-
return
|
|
1142
|
+
return managedDeploymentUnitName(deploymentId);
|
|
1130
1143
|
}
|
|
1131
1144
|
unitPath(deploymentId) {
|
|
1132
1145
|
return `/etc/systemd/system/${this.unitName(deploymentId)}`;
|
|
@@ -1172,7 +1185,7 @@ Restart=on-failure
|
|
|
1172
1185
|
RestartSec=3
|
|
1173
1186
|
StandardOutput=journal
|
|
1174
1187
|
StandardError=journal
|
|
1175
|
-
SyslogIdentifier=${
|
|
1188
|
+
SyslogIdentifier=${this.unitName(opts.deploymentId).replace(/\.service$/, "")}
|
|
1176
1189
|
|
|
1177
1190
|
[Install]
|
|
1178
1191
|
WantedBy=multi-user.target
|
|
@@ -1206,16 +1219,7 @@ WantedBy=multi-user.target
|
|
|
1206
1219
|
throw new DeployError(
|
|
1207
1220
|
`Port ${opts.port} is already in use` + (occupant ? ` by ${occupant.command}` : "") + ". Stop the existing process before deploying.",
|
|
1208
1221
|
"PORT_IN_USE",
|
|
1209
|
-
|
|
1210
|
-
port: opts.port,
|
|
1211
|
-
pid: occupant?.pid,
|
|
1212
|
-
command: occupant?.command,
|
|
1213
|
-
rawCommand: occupant?.rawCommand,
|
|
1214
|
-
systemdUnit: occupant?.systemdUnit,
|
|
1215
|
-
systemdDescription: occupant?.systemdDescription,
|
|
1216
|
-
deploymentId: occupant?.deploymentId,
|
|
1217
|
-
isManagedDeployment: occupant?.isManagedDeployment
|
|
1218
|
-
}
|
|
1222
|
+
portOccupantDetails(opts.port, occupant)
|
|
1219
1223
|
);
|
|
1220
1224
|
}
|
|
1221
1225
|
const msg = hint ? `Process exited immediately after start. Last output:
|
|
@@ -1424,7 +1428,7 @@ var NohupSupervisor = class {
|
|
|
1424
1428
|
throw new DeployError(
|
|
1425
1429
|
`Port ${opts.port} is already in use` + (occupant ? ` by ${occupant.command}` : "") + ". Stop the existing process before deploying.",
|
|
1426
1430
|
"PORT_IN_USE",
|
|
1427
|
-
|
|
1431
|
+
portOccupantDetails(opts.port, occupant)
|
|
1428
1432
|
);
|
|
1429
1433
|
}
|
|
1430
1434
|
const msg = hint ? `Process exited immediately after spawn. Last output:
|
|
@@ -1604,6 +1608,16 @@ var BareRuntime = class {
|
|
|
1604
1608
|
async inContainerExecutor() {
|
|
1605
1609
|
return this.executor;
|
|
1606
1610
|
}
|
|
1611
|
+
/**
|
|
1612
|
+
* Resolve a retained application release for an env-only refresh.
|
|
1613
|
+
* Deployment ids originate in our database, but reject path-shaped input at
|
|
1614
|
+
* this boundary so an imported/corrupt row cannot escape releases/.
|
|
1615
|
+
*/
|
|
1616
|
+
async retainedReleaseArtifact(deploymentId) {
|
|
1617
|
+
if (!deploymentId || deploymentId.includes("/") || deploymentId.includes("\\")) return null;
|
|
1618
|
+
const path = this.releaseDir(deploymentId);
|
|
1619
|
+
return await this.executor.exists(path).catch(() => false) ? path : null;
|
|
1620
|
+
}
|
|
1607
1621
|
/** Get or lazily initialise the process supervisor. */
|
|
1608
1622
|
async supervisor() {
|
|
1609
1623
|
if (this._supervisor) return this._supervisor;
|
|
@@ -1690,6 +1704,7 @@ var BareRuntime = class {
|
|
|
1690
1704
|
async promoteBuildArtifact(artifactPath, deploymentId, previousDeploymentId) {
|
|
1691
1705
|
const releaseDir = this.releaseDir(deploymentId);
|
|
1692
1706
|
if (artifactPath === releaseDir) return releaseDir;
|
|
1707
|
+
const consumeSource = !artifactPath.startsWith(`${this.workDir}/releases/`);
|
|
1693
1708
|
await ensureOwnedDir(this.executor, `${this.workDir}/releases`);
|
|
1694
1709
|
await this.executor.rm(releaseDir);
|
|
1695
1710
|
const previousReleaseDir = previousDeploymentId ? this.releaseDir(previousDeploymentId) : void 0;
|
|
@@ -1700,7 +1715,7 @@ var BareRuntime = class {
|
|
|
1700
1715
|
`deploy:${deploymentId}:promote-rsync`,
|
|
1701
1716
|
`rsync -a --delete --link-dest=${sq(previousReleaseDir)} ${sq(artifactPath)}/ ${sq(releaseDir)}/`
|
|
1702
1717
|
);
|
|
1703
|
-
await this.executor.rm(artifactPath).catch(() => {
|
|
1718
|
+
if (consumeSource) await this.executor.rm(artifactPath).catch(() => {
|
|
1704
1719
|
});
|
|
1705
1720
|
return releaseDir;
|
|
1706
1721
|
} catch {
|
|
@@ -1708,6 +1723,14 @@ var BareRuntime = class {
|
|
|
1708
1723
|
});
|
|
1709
1724
|
}
|
|
1710
1725
|
}
|
|
1726
|
+
if (!consumeSource) {
|
|
1727
|
+
await execReliable(
|
|
1728
|
+
this.executor,
|
|
1729
|
+
`deploy:${deploymentId}:promote-copy`,
|
|
1730
|
+
`mkdir -p ${sq(releaseDir)} && cp -a ${sq(artifactPath)}/. ${sq(releaseDir)}/`
|
|
1731
|
+
);
|
|
1732
|
+
return releaseDir;
|
|
1733
|
+
}
|
|
1711
1734
|
await execReliable(
|
|
1712
1735
|
this.executor,
|
|
1713
1736
|
`deploy:${deploymentId}:promote-mv`,
|
|
@@ -1947,19 +1970,29 @@ var BareRuntime = class {
|
|
|
1947
1970
|
) : stagedDir;
|
|
1948
1971
|
await this.linkPersistentPaths(workDir, config.projectId, config.volumes, _onLog);
|
|
1949
1972
|
const sv = await this.supervisor();
|
|
1973
|
+
const projectEnv = splitRuntimeEnv(
|
|
1974
|
+
Object.fromEntries(Object.entries(config.envVars ?? {}).map(([k, v]) => [k, String(v)]))
|
|
1975
|
+
);
|
|
1976
|
+
if (projectEnv.dropped.length > 0) {
|
|
1977
|
+
_onLog?.({
|
|
1978
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1979
|
+
level: "warn",
|
|
1980
|
+
message: droppedRuntimeEnvMessage(projectEnv.dropped)
|
|
1981
|
+
});
|
|
1982
|
+
}
|
|
1950
1983
|
const env = {
|
|
1951
|
-
...Object.fromEntries(
|
|
1952
|
-
Object.entries(config.envVars ?? {}).map(([k, v]) => [k, String(v)])
|
|
1953
|
-
),
|
|
1984
|
+
...Object.fromEntries(projectEnv.entries),
|
|
1954
1985
|
PORT: String(config.port),
|
|
1955
1986
|
NODE_ENV: config.environment === "production" ? "production" : "development"
|
|
1956
1987
|
};
|
|
1988
|
+
const startBinPath = nodeBinPathExport(config.packageManager, [workDir]);
|
|
1989
|
+
const resolvedStart = config.startCommand || "npm start";
|
|
1957
1990
|
try {
|
|
1958
1991
|
await sv.deploy({
|
|
1959
1992
|
deploymentId: config.deploymentId,
|
|
1960
1993
|
projectId: config.projectId,
|
|
1961
1994
|
workDir,
|
|
1962
|
-
startCommand:
|
|
1995
|
+
startCommand: startBinPath ? `${startBinPath} && ${resolvedStart}` : resolvedStart,
|
|
1963
1996
|
port: config.port,
|
|
1964
1997
|
env
|
|
1965
1998
|
});
|
|
@@ -1979,13 +2012,40 @@ var BareRuntime = class {
|
|
|
1979
2012
|
};
|
|
1980
2013
|
}
|
|
1981
2014
|
async deployStatic(config) {
|
|
1982
|
-
const
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
config.
|
|
1986
|
-
config.
|
|
1987
|
-
|
|
1988
|
-
|
|
2015
|
+
const workDir = await this.promoteStaticRelease({
|
|
2016
|
+
artifactPath: config.imageRef ?? this.projectDir(config.projectId),
|
|
2017
|
+
releaseId: config.deploymentId,
|
|
2018
|
+
previousReleaseId: config.previousDeploymentId,
|
|
2019
|
+
outputDirectory: config.outputDirectory,
|
|
2020
|
+
promote: Boolean(config.imageRef)
|
|
2021
|
+
});
|
|
2022
|
+
return {
|
|
2023
|
+
deploymentId: config.deploymentId,
|
|
2024
|
+
containerId: workDir,
|
|
2025
|
+
status: "running"
|
|
2026
|
+
};
|
|
2027
|
+
}
|
|
2028
|
+
/**
|
|
2029
|
+
* Promote an extracted static build into a stable release directory and PROVE it
|
|
2030
|
+
* can serve, returning the release dir.
|
|
2031
|
+
*
|
|
2032
|
+
* Split out of `deployStatic` so the compose/monorepo static path reuses the
|
|
2033
|
+
* identical promote + validation instead of registering a vhost straight at the
|
|
2034
|
+
* `.builds/<session>` staging dir. Two things came from that shortcut: the
|
|
2035
|
+
* public doc-root of a compose static sub-app was a per-build-session scratch
|
|
2036
|
+
* directory (nothing owned its lifetime, so superseded copies accumulated and
|
|
2037
|
+
* any sweep of `.builds` would take the live site down), and it skipped the only
|
|
2038
|
+
* HARD deploy-time output gate we have — so an extract that produced nothing
|
|
2039
|
+
* deployed green and 404'd.
|
|
2040
|
+
*
|
|
2041
|
+
* `releaseId` is the release's identity, not necessarily a deployment id: the
|
|
2042
|
+
* compose path passes `<deploymentId>-<serviceId>` so each static sub-app owns
|
|
2043
|
+
* its own release dir under one deployment.
|
|
2044
|
+
*/
|
|
2045
|
+
async promoteStaticRelease(opts) {
|
|
2046
|
+
const stagedDir = opts.artifactPath;
|
|
2047
|
+
const workDir = opts.promote === false ? stagedDir : await this.promoteBuildArtifact(stagedDir, opts.releaseId, opts.previousReleaseId);
|
|
2048
|
+
const staticRoot = resolveStaticOutputPath(workDir, opts.outputDirectory);
|
|
1989
2049
|
const abort = async (message) => {
|
|
1990
2050
|
if (workDir !== stagedDir) {
|
|
1991
2051
|
await this.executor.rm(workDir).catch(() => {
|
|
@@ -1994,18 +2054,47 @@ var BareRuntime = class {
|
|
|
1994
2054
|
throw new Error(message);
|
|
1995
2055
|
};
|
|
1996
2056
|
if (!await this.executor.exists(staticRoot)) {
|
|
1997
|
-
return abort(missingOutputDirectoryMessage(
|
|
2057
|
+
return abort(missingOutputDirectoryMessage(opts.outputDirectory));
|
|
2058
|
+
}
|
|
2059
|
+
if (staticRoot === workDir) {
|
|
2060
|
+
const undeleted = await this.pruneBuildFilesFromDocRoot(staticRoot);
|
|
2061
|
+
if (undeleted.length > 0) {
|
|
2062
|
+
return abort(
|
|
2063
|
+
`Refusing to publish ${staticRoot}: could not remove ${undeleted.join(", ")} from the document root. Serving them would expose the repository (and, for a private repo, the access token in .git/config) at the site's public URL.`
|
|
2064
|
+
);
|
|
2065
|
+
}
|
|
1998
2066
|
}
|
|
1999
2067
|
if (await this.isEmptyDir(staticRoot)) {
|
|
2000
2068
|
return abort(
|
|
2001
|
-
`The output directory "${
|
|
2069
|
+
`The output directory "${opts.outputDirectory || "."}" is empty \u2014 the build produced no files to serve, so every request would 404. Check the build command and the Output Directory setting.`
|
|
2002
2070
|
);
|
|
2003
2071
|
}
|
|
2004
|
-
return
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2072
|
+
return workDir;
|
|
2073
|
+
}
|
|
2074
|
+
/**
|
|
2075
|
+
* Remove top-level build inputs from a doc root, returning the names it could NOT
|
|
2076
|
+
* remove (empty on success, and on "there was nothing to remove").
|
|
2077
|
+
*
|
|
2078
|
+
* Reuses `isExcludedDocRootEntry` rather than re-listing the names, because the
|
|
2079
|
+
* Docker sandbox already owns that list and two copies of "what must not be
|
|
2080
|
+
* served" is precisely how the bare path came to serve `.git`.
|
|
2081
|
+
*
|
|
2082
|
+
* An unreadable listing returns empty — a probe that cannot read must not fail a
|
|
2083
|
+
* deploy — but a listed entry that survives its `rm` is reported, because the
|
|
2084
|
+
* caller must refuse to publish rather than expose a token.
|
|
2085
|
+
*/
|
|
2086
|
+
async pruneBuildFilesFromDocRoot(root) {
|
|
2087
|
+
const listed = await this.executor.exec(`ls -A ${sq(root)} 2>/dev/null; true`).catch(() => null);
|
|
2088
|
+
if (listed === null) return [];
|
|
2089
|
+
const doomed = listed.split("\n").map((l) => l.trim()).filter(Boolean).filter(isExcludedDocRootEntry);
|
|
2090
|
+
if (doomed.length === 0) return [];
|
|
2091
|
+
await this.executor.exec(`rm -rf ${doomed.map((n) => sq(`${root}/${n}`)).join(" ")}`).catch(() => {
|
|
2092
|
+
});
|
|
2093
|
+
const survivors = [];
|
|
2094
|
+
for (const name of doomed) {
|
|
2095
|
+
if (await this.executor.exists(`${root}/${name}`)) survivors.push(name);
|
|
2096
|
+
}
|
|
2097
|
+
return survivors;
|
|
2009
2098
|
}
|
|
2010
2099
|
/**
|
|
2011
2100
|
* Is this an existing directory with no entries? Any inconclusive answer (not a
|
|
@@ -2033,8 +2122,8 @@ var BareRuntime = class {
|
|
|
2033
2122
|
await sv.restart(containerId);
|
|
2034
2123
|
}
|
|
2035
2124
|
async destroy(containerId) {
|
|
2036
|
-
if (containerId
|
|
2037
|
-
await this.executor
|
|
2125
|
+
if (isArtifactPathRef(containerId)) {
|
|
2126
|
+
await removeManagedArtifact(this.executor, containerId);
|
|
2038
2127
|
return;
|
|
2039
2128
|
}
|
|
2040
2129
|
const sv = await this.supervisor();
|
|
@@ -2078,15 +2167,21 @@ var BareRuntime = class {
|
|
|
2078
2167
|
}
|
|
2079
2168
|
}
|
|
2080
2169
|
async purge(deployment) {
|
|
2170
|
+
const failures = [];
|
|
2081
2171
|
if (deployment.containerId) {
|
|
2082
|
-
|
|
2083
|
-
await this.destroy(deployment.containerId);
|
|
2084
|
-
} catch {
|
|
2085
|
-
}
|
|
2172
|
+
await this.destroy(deployment.containerId).catch((err) => failures.push(err));
|
|
2086
2173
|
}
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2174
|
+
const releaseDir = this.releaseDir(deployment.id);
|
|
2175
|
+
if (releaseDir !== deployment.containerId) {
|
|
2176
|
+
await removeManagedArtifact(this.executor, releaseDir).catch(
|
|
2177
|
+
(err) => failures.push(err)
|
|
2178
|
+
);
|
|
2179
|
+
}
|
|
2180
|
+
if (failures.length === 1) throw failures[0];
|
|
2181
|
+
if (failures.length > 1) {
|
|
2182
|
+
throw new Error(
|
|
2183
|
+
failures.map((err) => err instanceof Error ? err.message : String(err)).join("; ")
|
|
2184
|
+
);
|
|
2090
2185
|
}
|
|
2091
2186
|
}
|
|
2092
2187
|
// ── Observability ──────────────────────────────────────────────────────
|