openship 0.6.7 → 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-LHFXSC36.js → chunk-3MP6ACKM.js} +183 -87
- package/dist/{chunk-MEE6OZFP.js → chunk-5DJOB7IX.js} +3 -3
- package/dist/{chunk-PPEBIY5F.js → chunk-5I3COAFH.js} +35 -12
- package/dist/{chunk-VQM6JHJB.js → chunk-5UXHT6ED.js} +9 -9
- package/dist/{chunk-XWHWTHEL.js → chunk-6GU6JSK6.js} +21 -2
- package/dist/{chunk-QHMDCYZ3.js → chunk-7PEXM2UI.js} +213 -45
- package/dist/{chunk-RDXT4BQB.js → chunk-7YBWXEM6.js} +4 -4
- package/dist/{chunk-H4FS5BED.js → chunk-AHJYP7DG.js} +13 -11
- package/dist/{chunk-VSTFHUCV.js → chunk-BO6CY4V2.js} +109 -23
- package/dist/{chunk-J3K6XABC.js → chunk-D3OEMXYP.js} +3 -3
- package/dist/{chunk-UWEV6XTS.js → chunk-D6HU4VUZ.js} +1 -1
- package/dist/{chunk-S6B2Z3OO.js → chunk-ENKJ7XIF.js} +21 -11
- package/dist/{chunk-BLEXTYRK.js → chunk-GNOMEMNI.js} +1 -1
- package/dist/{chunk-NRTJRNAE.js → chunk-IAMOUDHY.js} +138 -54
- package/dist/{chunk-CIJV43LH.js → chunk-MUWVC5R4.js} +161 -39
- package/dist/{chunk-ZPJ74LXE.js → chunk-NIYD7MD2.js} +197 -45
- package/dist/{chunk-FZ6QCF6B.js → chunk-NPSRGIHV.js} +2 -2
- package/dist/{chunk-2GWYYHOR.js → chunk-NRU2EBYZ.js} +2 -2
- package/dist/{chunk-J2XM3QSP.js → chunk-NUT6HKK6.js} +5 -5
- package/dist/{chunk-H3WT3A6R.js → chunk-P7RCYELG.js} +1 -1
- package/dist/{chunk-FYPFEDPZ.js → chunk-R5DC5PEF.js} +1 -1
- package/dist/{chunk-DDFUESPJ.js → chunk-RCMERVBL.js} +9 -9
- package/dist/{chunk-RXQBD4ZY.js → chunk-RHLNVZMS.js} +2 -2
- package/dist/{chunk-WU54BXFE.js → chunk-SK4FFCFR.js} +1 -1
- package/dist/{chunk-PVP4RGWT.js → chunk-T46BQOLY.js} +3 -3
- package/dist/{chunk-E2X26PXR.js → chunk-T6DVUX4F.js} +1 -1
- package/dist/{chunk-5T4UVOM3.js → chunk-TAZZZKYO.js} +1 -1
- package/dist/{chunk-GGIAIGUL.js → chunk-UAWY6X7V.js} +34 -12
- package/dist/{chunk-2ANV5ZQ5.js → chunk-VAI5VOOI.js} +1 -1
- package/dist/{chunk-2VSW6Q6C.js → chunk-WEZFTL4V.js} +655 -62
- package/dist/{chunk-GIPJNNI5.js → chunk-X53JXRS4.js} +3 -3
- package/dist/{cloud-KRTZ2IL5.js → cloud-2CRDKOWQ.js} +1 -1
- package/dist/cloud-REV3DPJH.js +42 -0
- package/dist/{detect-G4DR3U2N.js → detect-BBFT5GEU.js} +4 -4
- package/dist/{docker-YOVPCIB4.js → docker-EG3QSE6I.js} +10 -10
- package/dist/{docker-edge-executor-QFXD3337.js → docker-edge-executor-E5TOTLMR.js} +7 -7
- package/dist/edge-import-YJVJUGYC.js +56 -0
- package/dist/{edge-preflight-MXERVAMG.js → edge-preflight-QUW4BM7N.js} +13 -13
- package/dist/{ensure-container-edge-F4JUNQIK.js → ensure-container-edge-FOEFQ3PI.js} +13 -11
- package/dist/{executor-CVPAYYHR.js → executor-NTWDJ3DB.js} +6 -6
- package/dist/host-channel-preflight-OMCZMMKR.js +54 -0
- package/dist/index.js +158 -72
- package/dist/{local-executor-ODC6RANU.js → local-executor-OQ2GRN7K.js} +3 -3
- package/dist/{nginx-KLFF43TC.js → nginx-4U4C2XUS.js} +9 -9
- package/dist/{noop-NJ72F46T.js → noop-CLLJHCPL.js} +1 -1
- package/dist/{openresty-lua-VKWUV4GB.js → openresty-lua-LLWT5XQW.js} +7 -5
- package/dist/{privilege-7D3SSOL3.js → privilege-MNDVMDST.js} +5 -5
- package/dist/server/index.js +31643 -25553
- 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-I5AJC6NJ.js → setup-IFIMPQZJ.js} +12 -12
- package/dist/{ssh-client-625VWGKP.js → ssh-client-2XWZCMGI.js} +2 -2
- package/dist/up-HQS7IR7H.js +61 -0
- package/package.json +1 -1
- package/dist/bare-7QD623QV.js +0 -29
- package/dist/cloud-KNNABE3O.js +0 -40
- package/dist/edge-import-CRFVSR6P.js +0 -56
- package/dist/host-channel-preflight-QTDNGLCK.js +0 -54
- package/dist/up-QXTOOVXC.js +0 -61
|
@@ -10,28 +10,28 @@ import {
|
|
|
10
10
|
readComposeEnvFile,
|
|
11
11
|
resolveLocalEnvironmentSync,
|
|
12
12
|
thisHost
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-5UXHT6ED.js";
|
|
14
14
|
import {
|
|
15
15
|
OS_DIR
|
|
16
16
|
} from "./chunk-ELGRMZOW.js";
|
|
17
17
|
import {
|
|
18
18
|
systemCatalog
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-NIYD7MD2.js";
|
|
20
20
|
import {
|
|
21
21
|
EDGE_CONTAINER_MOUNTS,
|
|
22
22
|
EDGE_HOST_STATE_DIR
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-7PEXM2UI.js";
|
|
24
24
|
import {
|
|
25
25
|
DEFAULT_DOCKER_SOCKET_PATH,
|
|
26
26
|
resolveLocalDockerSocketPath
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-3MP6ACKM.js";
|
|
28
28
|
import {
|
|
29
29
|
LocalExecutor
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-T6DVUX4F.js";
|
|
31
31
|
import {
|
|
32
32
|
invalidateEdgeContainer,
|
|
33
33
|
sanitizeEdgeVhosts
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-X53JXRS4.js";
|
|
35
35
|
import {
|
|
36
36
|
DEFAULT_IMAGE_REGISTRY,
|
|
37
37
|
HOST_CHANNEL_BLOCKED,
|
|
@@ -51,7 +51,7 @@ import {
|
|
|
51
51
|
hostFirewallRule,
|
|
52
52
|
hostFirewallRuleRemoval,
|
|
53
53
|
wrapText
|
|
54
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-WEZFTL4V.js";
|
|
55
55
|
|
|
56
56
|
// src/lib/host-channel-preflight.ts
|
|
57
57
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
@@ -66,13 +66,14 @@ import {
|
|
|
66
66
|
existsSync as existsSync4,
|
|
67
67
|
mkdirSync as mkdirSync3,
|
|
68
68
|
readFileSync as readFileSync3,
|
|
69
|
+
realpathSync,
|
|
69
70
|
renameSync,
|
|
70
71
|
rmSync,
|
|
71
72
|
statSync,
|
|
72
73
|
writeFileSync as writeFileSync2
|
|
73
74
|
} from "fs";
|
|
74
75
|
import { homedir, userInfo } from "os";
|
|
75
|
-
import { dirname, join as join4, resolve as resolve2 } from "path";
|
|
76
|
+
import { dirname, join as join4, relative, resolve as resolve2 } from "path";
|
|
76
77
|
|
|
77
78
|
// src/lib/ports.ts
|
|
78
79
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -400,8 +401,30 @@ async function rebuildFromSource(info) {
|
|
|
400
401
|
// src/lib/compose.ts
|
|
401
402
|
var EDGE_SITES_HOST_DIR = `${EDGE_HOST_STATE_DIR}/sites-enabled`;
|
|
402
403
|
var EDGE_ACME_HOST_DIR = `${EDGE_HOST_STATE_DIR}/acme`;
|
|
404
|
+
function canonicalComposeHostPath(target, platform = process.platform, resolvePath = realpathSync) {
|
|
405
|
+
if (platform !== "darwin") return target;
|
|
406
|
+
try {
|
|
407
|
+
return resolvePath(target);
|
|
408
|
+
} catch {
|
|
409
|
+
let parent = target;
|
|
410
|
+
while (parent !== dirname(parent)) {
|
|
411
|
+
parent = dirname(parent);
|
|
412
|
+
try {
|
|
413
|
+
return join4(resolvePath(parent), relative(parent, target));
|
|
414
|
+
} catch {
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
throw new Error(`Could not resolve edge bind-mount source ${target} on this Mac.`);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
function composeEdgeMounts() {
|
|
421
|
+
return EDGE_CONTAINER_MOUNTS.map((mount) => ({
|
|
422
|
+
...mount,
|
|
423
|
+
host: canonicalComposeHostPath(mount.host)
|
|
424
|
+
}));
|
|
425
|
+
}
|
|
403
426
|
function edgeVolumeYaml(indent) {
|
|
404
|
-
return
|
|
427
|
+
return composeEdgeMounts().map((m) => `${indent}- ${m.host}:${m.container}:z`).join("\n");
|
|
405
428
|
}
|
|
406
429
|
var DOCKER_CONFIG_MOUNT_MARKER = "__OPENSHIP_DOCKER_CONFIG_MOUNT__";
|
|
407
430
|
function dockerConfigMountYaml(indent) {
|
|
@@ -1604,7 +1627,7 @@ function operatorEnvPassthrough(managed, prev) {
|
|
|
1604
1627
|
}
|
|
1605
1628
|
var PRESERVED_ENV_HEADER = "# Preserved from your existing .env \u2014 set by you, not by `openship up` (#485).";
|
|
1606
1629
|
function resolveImageVersion(opts) {
|
|
1607
|
-
return opts.version?.trim() || process.env.OPENSHIP_VERSION?.trim() || (true ? "0.6.
|
|
1630
|
+
return opts.version?.trim() || process.env.OPENSHIP_VERSION?.trim() || (true ? "0.6.8" : "latest");
|
|
1608
1631
|
}
|
|
1609
1632
|
function managedEnvLines(opts, host, cfg, prev) {
|
|
1610
1633
|
const lines = [
|
|
@@ -1774,7 +1797,7 @@ function composePlan(opts) {
|
|
|
1774
1797
|
secretRotation: opts.resetSecrets ? null : secretRotationRisk(prev),
|
|
1775
1798
|
pgDataRisk: pgDataDetectionRisk(prev),
|
|
1776
1799
|
existing: Object.keys(prev).length > 0,
|
|
1777
|
-
mountDirs:
|
|
1800
|
+
mountDirs: composeEdgeMounts().map((m) => m.host),
|
|
1778
1801
|
buildDir,
|
|
1779
1802
|
hostChannel
|
|
1780
1803
|
};
|
|
@@ -1854,7 +1877,7 @@ function composePrefetch(opts) {
|
|
|
1854
1877
|
}
|
|
1855
1878
|
function ensureEdgeMountDirs() {
|
|
1856
1879
|
const failed = [];
|
|
1857
|
-
for (const { host } of
|
|
1880
|
+
for (const { host } of composeEdgeMounts()) {
|
|
1858
1881
|
try {
|
|
1859
1882
|
mkdirSync3(host, { recursive: true });
|
|
1860
1883
|
} catch (err) {
|
|
@@ -134,10 +134,10 @@ import {
|
|
|
134
134
|
} from "./chunk-ZWLDLTJP.js";
|
|
135
135
|
import {
|
|
136
136
|
CloudRuntime
|
|
137
|
-
} from "./chunk-
|
|
137
|
+
} from "./chunk-MUWVC5R4.js";
|
|
138
138
|
import {
|
|
139
139
|
OPENRESTY_DEFAULT_PATHS
|
|
140
|
-
} from "./chunk-
|
|
140
|
+
} from "./chunk-7PEXM2UI.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-3MP6ACKM.js";
|
|
150
150
|
import {
|
|
151
151
|
BareRuntime
|
|
152
|
-
} from "./chunk-
|
|
152
|
+
} from "./chunk-ENKJ7XIF.js";
|
|
153
153
|
import {
|
|
154
154
|
createExecutor
|
|
155
|
-
} from "./chunk-
|
|
155
|
+
} from "./chunk-UAWY6X7V.js";
|
|
156
156
|
import {
|
|
157
157
|
envOps
|
|
158
|
-
} from "./chunk-
|
|
158
|
+
} from "./chunk-GNOMEMNI.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-NPSRGIHV.js";
|
|
166
166
|
import {
|
|
167
167
|
MAIL_HOST_STATE_DIR
|
|
168
|
-
} from "./chunk-
|
|
168
|
+
} from "./chunk-D6HU4VUZ.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-WEZFTL4V.js";
|
|
181
181
|
|
|
182
182
|
// ../../packages/adapters/src/runtime/image-transfer.ts
|
|
183
183
|
import { Transform } from "stream";
|
|
@@ -13,11 +13,14 @@ import {
|
|
|
13
13
|
resolveDockerRootDirectory,
|
|
14
14
|
resolveDockerfileCandidates,
|
|
15
15
|
resolveWithinDirectory
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-AHJYP7DG.js";
|
|
17
17
|
import {
|
|
18
18
|
getTarCreateEnv,
|
|
19
19
|
prepareSourceTarArgs
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-VAI5VOOI.js";
|
|
21
|
+
import {
|
|
22
|
+
isValidEnvKey
|
|
23
|
+
} from "./chunk-WEZFTL4V.js";
|
|
21
24
|
import {
|
|
22
25
|
__commonJS,
|
|
23
26
|
__toESM
|
|
@@ -481,6 +484,21 @@ var require_ignore = __commonJS({
|
|
|
481
484
|
}
|
|
482
485
|
});
|
|
483
486
|
|
|
487
|
+
// ../../packages/adapters/src/runtime/docker-build-args.ts
|
|
488
|
+
function resolveDockerBuildArgs(config) {
|
|
489
|
+
const invalidExplicit = Object.keys(config.buildArgs ?? {}).filter((key) => !isValidEnvKey(key));
|
|
490
|
+
if (invalidExplicit.length > 0) {
|
|
491
|
+
throw new Error(`Invalid Docker build argument name(s): ${invalidExplicit.join(", ")}`);
|
|
492
|
+
}
|
|
493
|
+
const inherited = Object.fromEntries(
|
|
494
|
+
Object.entries({
|
|
495
|
+
...config.envVars,
|
|
496
|
+
NODE_ENV: "production"
|
|
497
|
+
}).filter(([key]) => isValidEnvKey(key))
|
|
498
|
+
);
|
|
499
|
+
return { ...inherited, ...config.buildArgs };
|
|
500
|
+
}
|
|
501
|
+
|
|
484
502
|
// ../../packages/adapters/src/runtime/docker-buildkit-trace.ts
|
|
485
503
|
var WIRE_VARINT = 0;
|
|
486
504
|
var WIRE_64BIT = 1;
|
|
@@ -1037,6 +1055,7 @@ async function createDockerBuildContext(config, opts) {
|
|
|
1037
1055
|
}
|
|
1038
1056
|
|
|
1039
1057
|
export {
|
|
1058
|
+
resolveDockerBuildArgs,
|
|
1040
1059
|
BuildKitTraceDecoder,
|
|
1041
1060
|
prepareSourceTree,
|
|
1042
1061
|
missingContextDockerfileMessage,
|
|
@@ -5,19 +5,23 @@ const require = __ospCreateRequire(import.meta.url);
|
|
|
5
5
|
import {
|
|
6
6
|
envOps,
|
|
7
7
|
opScript
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-GNOMEMNI.js";
|
|
9
9
|
import {
|
|
10
10
|
resolveEnvironment
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-NPSRGIHV.js";
|
|
12
12
|
import {
|
|
13
13
|
sq
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-P7RCYELG.js";
|
|
15
|
+
import {
|
|
16
|
+
describeProcess,
|
|
17
|
+
probeListeningPortOwners
|
|
18
|
+
} from "./chunk-BO6CY4V2.js";
|
|
15
19
|
import {
|
|
16
20
|
SYSTEM,
|
|
17
21
|
answered,
|
|
18
22
|
refused,
|
|
19
23
|
safeErrorMessage
|
|
20
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-WEZFTL4V.js";
|
|
21
25
|
|
|
22
26
|
// ../../packages/adapters/src/infra/openresty-lua.ts
|
|
23
27
|
import { createHash, randomBytes } from "crypto";
|
|
@@ -240,6 +244,184 @@ var EDGE_NOT_FOUND_LOCATION = ` server_tokens off;
|
|
|
240
244
|
return 404 '${EDGE_NOT_FOUND_HTML}';
|
|
241
245
|
}`;
|
|
242
246
|
|
|
247
|
+
// ../../packages/adapters/src/infra/openresty-reload.ts
|
|
248
|
+
var NGINX_MASTER_RE = /\b(?:nginx|openresty)\s*:\s*master process/i;
|
|
249
|
+
var NGINX_WORKER_RE = /\b(?:nginx|openresty)\s*:\s*worker process/i;
|
|
250
|
+
var NGINX_PROCESS_RE = /\b(?:nginx|openresty)\b/i;
|
|
251
|
+
async function canonicalRemotePath(executor, path) {
|
|
252
|
+
const resolved = await executor.exec(`readlink -f ${sq(path)} 2>/dev/null || true`, { timeout: 5e3 }).catch(() => "");
|
|
253
|
+
return resolved.trim() || null;
|
|
254
|
+
}
|
|
255
|
+
function explicitNginxConfig(rawCommand) {
|
|
256
|
+
const match = rawCommand.match(/(?:^|\s)-c(?:(?:\s+|=)(?:"([^"]+)"|'([^']+)'|(\S+))|(\S+))/);
|
|
257
|
+
if (!match) return void 0;
|
|
258
|
+
const value = match[1] ?? match[2] ?? match[3] ?? match[4] ?? "";
|
|
259
|
+
return value.startsWith("/") ? value : null;
|
|
260
|
+
}
|
|
261
|
+
function hasExplicitNginxPrefix(rawCommand) {
|
|
262
|
+
return /(?:^|\s)-p(?:\s+|=|\S)/.test(rawCommand);
|
|
263
|
+
}
|
|
264
|
+
async function processStartTime(executor, pid) {
|
|
265
|
+
const value = await executor.exec(
|
|
266
|
+
`awk '{ line=$0; sub(/^.*\\) /, "", line); split(line, fields, " "); print fields[20] }' /proc/${pid}/stat 2>/dev/null || true`,
|
|
267
|
+
{ timeout: 5e3 }
|
|
268
|
+
).catch(() => "");
|
|
269
|
+
return /^\d+$/.test(value.trim()) ? value.trim() : null;
|
|
270
|
+
}
|
|
271
|
+
async function verifyNginxProcessIdentity(executor, occupant, paths) {
|
|
272
|
+
if (!occupant.pid) return "unknown";
|
|
273
|
+
const rawCommand = occupant.rawCommand?.trim();
|
|
274
|
+
if (!rawCommand || !NGINX_MASTER_RE.test(rawCommand)) return "unknown";
|
|
275
|
+
const [actualExe, expectedExe] = await Promise.all([
|
|
276
|
+
canonicalRemotePath(executor, `/proc/${occupant.pid}/exe`),
|
|
277
|
+
canonicalRemotePath(executor, paths.bin)
|
|
278
|
+
]);
|
|
279
|
+
if (!actualExe || !expectedExe) return "unknown";
|
|
280
|
+
if (actualExe !== expectedExe) return "foreign";
|
|
281
|
+
if (hasExplicitNginxPrefix(rawCommand)) return "unknown";
|
|
282
|
+
const explicitConfig = explicitNginxConfig(rawCommand);
|
|
283
|
+
if (explicitConfig === null) return "unknown";
|
|
284
|
+
const effectiveConfig = explicitConfig ?? paths.compiledConfPath;
|
|
285
|
+
const [actualConfig, expectedConfig] = await Promise.all([
|
|
286
|
+
canonicalRemotePath(executor, effectiveConfig),
|
|
287
|
+
canonicalRemotePath(executor, paths.confPath)
|
|
288
|
+
]);
|
|
289
|
+
if (!actualConfig || !expectedConfig || actualConfig !== expectedConfig) return "unknown";
|
|
290
|
+
return "match";
|
|
291
|
+
}
|
|
292
|
+
async function resolveListeningNginxMaster(executor, occupant) {
|
|
293
|
+
const description = `${occupant.rawCommand ?? ""} ${occupant.command}`;
|
|
294
|
+
if (!occupant.pid || !NGINX_WORKER_RE.test(description)) return occupant;
|
|
295
|
+
const rawParent = await executor.exec(`awk '/^PPid:/{print $2}' /proc/${occupant.pid}/status 2>/dev/null || true`).catch(() => "");
|
|
296
|
+
const parentPid = Number.parseInt(rawParent.trim(), 10);
|
|
297
|
+
if (!Number.isInteger(parentPid) || parentPid <= 1) return occupant;
|
|
298
|
+
const parent = await describeProcess(executor, parentPid).catch(() => null);
|
|
299
|
+
if (!parent) return occupant;
|
|
300
|
+
const parentDescription = `${parent.rawCommand ?? ""} ${parent.command}`;
|
|
301
|
+
return NGINX_MASTER_RE.test(parentDescription) ? parent : occupant;
|
|
302
|
+
}
|
|
303
|
+
async function reloadBareOpenResty(executor, paths, opts = {}) {
|
|
304
|
+
await executor.exec(`${sq(paths.bin)} -t -c ${sq(paths.confPath)} 2>&1`, {
|
|
305
|
+
timeout: 15e3
|
|
306
|
+
});
|
|
307
|
+
const listenerStates = await Promise.all([
|
|
308
|
+
probeListeningPortOwners(executor, 80),
|
|
309
|
+
probeListeningPortOwners(executor, 443)
|
|
310
|
+
]);
|
|
311
|
+
if (listenerStates.some((state) => !state.checked)) {
|
|
312
|
+
throw new Error(
|
|
313
|
+
"OpenResty config is valid, but the port 80/443 listener probe was inconclusive; refusing to assume the managed daemon is stopped."
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
if (listenerStates.some((state) => !state.ownershipComplete)) {
|
|
317
|
+
throw new Error(
|
|
318
|
+
"OpenResty config is valid, but every listener on port 80/443 could not be identified; refusing to signal an unknown or mixed owner."
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
const occupants = listenerStates.flatMap((state) => state.occupants);
|
|
322
|
+
const verifiedMasters = /* @__PURE__ */ new Map();
|
|
323
|
+
let foreignListenerOwner = false;
|
|
324
|
+
let ambiguousNginxOwner = false;
|
|
325
|
+
let containerBackedNginxOwner = false;
|
|
326
|
+
for (const occupant of occupants) {
|
|
327
|
+
if (!occupant.rawCommand?.trim()) {
|
|
328
|
+
ambiguousNginxOwner = true;
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
const description = [
|
|
332
|
+
occupant.rawCommand,
|
|
333
|
+
occupant.command,
|
|
334
|
+
occupant.systemdUnit,
|
|
335
|
+
occupant.systemdDescription
|
|
336
|
+
].filter(Boolean).join(" ");
|
|
337
|
+
if (!NGINX_PROCESS_RE.test(description)) {
|
|
338
|
+
foreignListenerOwner = true;
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
if (occupant.containerId) {
|
|
342
|
+
containerBackedNginxOwner = true;
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
const master = await resolveListeningNginxMaster(executor, occupant);
|
|
346
|
+
if (master.containerId) {
|
|
347
|
+
containerBackedNginxOwner = true;
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
const initialIdentity = await verifyNginxProcessIdentity(executor, master, paths);
|
|
351
|
+
if (initialIdentity === "foreign") {
|
|
352
|
+
foreignListenerOwner = true;
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
if (initialIdentity === "unknown" || !master.pid) {
|
|
356
|
+
ambiguousNginxOwner = true;
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
if (master.cgroupVerified !== true || !master.processCgroup) {
|
|
360
|
+
ambiguousNginxOwner = true;
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
const startTime = await processStartTime(executor, master.pid);
|
|
364
|
+
if (!startTime) {
|
|
365
|
+
ambiguousNginxOwner = true;
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
const refreshedMaster = await describeProcess(executor, master.pid).catch(() => null);
|
|
369
|
+
const confirmedStartTime = await processStartTime(executor, master.pid);
|
|
370
|
+
if (!refreshedMaster || confirmedStartTime !== startTime || refreshedMaster.cgroupVerified !== true || !refreshedMaster.processCgroup) {
|
|
371
|
+
ambiguousNginxOwner = true;
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
if (refreshedMaster.containerId) {
|
|
375
|
+
containerBackedNginxOwner = true;
|
|
376
|
+
continue;
|
|
377
|
+
}
|
|
378
|
+
const identity = await verifyNginxProcessIdentity(executor, refreshedMaster, paths);
|
|
379
|
+
if (identity !== "match") {
|
|
380
|
+
ambiguousNginxOwner = true;
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
verifiedMasters.set(master.pid, {
|
|
384
|
+
pid: master.pid,
|
|
385
|
+
startTime,
|
|
386
|
+
processCgroup: refreshedMaster.processCgroup
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
if (containerBackedNginxOwner) {
|
|
390
|
+
throw new Error(
|
|
391
|
+
"A container-backed nginx/OpenResty listener owns port 80/443; refusing to signal it from bare-host reload."
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
if (ambiguousNginxOwner) {
|
|
395
|
+
throw new Error(
|
|
396
|
+
"A live nginx/OpenResty listener was found, but its executable and configuration could not be verified, or its host ownership could not be proven; refusing to signal an ambiguous process."
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
if (foreignListenerOwner) {
|
|
400
|
+
throw new Error(
|
|
401
|
+
verifiedMasters.size > 0 ? "The managed OpenResty master shares ports 80/443 with a foreign listener; refusing a reload that cannot apply the validated configuration safely." : "A foreign listener owns port 80/443; refusing to treat a live daemon as stopped or report the managed route reload as complete."
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
if (verifiedMasters.size === 0) {
|
|
405
|
+
if (opts.allowStopped && occupants.length === 0) return;
|
|
406
|
+
const owners = occupants.map((occupant) => occupant.command).filter(Boolean);
|
|
407
|
+
throw new Error(
|
|
408
|
+
"OpenResty config is valid, but no verified bare-host master is listening on port 80/443" + (owners.length > 0 ? ` (found: ${owners.join(", ")})` : "") + "; refusing to start a second daemon."
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
if (verifiedMasters.size !== 1) {
|
|
412
|
+
throw new Error(
|
|
413
|
+
`Found ${verifiedMasters.size} verified nginx/OpenResty masters on ports 80/443; refusing an ambiguous reload.`
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
const target = [...verifiedMasters.values()][0];
|
|
417
|
+
await executor.exec(
|
|
418
|
+
`current_exe=$(readlink -f /proc/${target.pid}/exe 2>/dev/null || true); expected_exe=$(readlink -f ${sq(paths.bin)} 2>/dev/null || true); current_start=$(awk '{ line=$0; sub(/^.*\\) /, "", line); split(line, fields, " "); print fields[20] }' /proc/${target.pid}/stat 2>/dev/null || true); current_cgroup=$(cat /proc/${target.pid}/cgroup 2>/dev/null) || { echo "nginx master cgroup became unreadable; refusing reload" >&2; exit 1; }; [ -n "$current_exe" ] && [ "$current_exe" = "$expected_exe" ] && [ "$current_start" = ${sq(target.startTime)} ] && [ -n "$current_cgroup" ] && [ "$current_cgroup" = ${sq(target.processCgroup)} ] || { echo "nginx master identity changed; refusing reload" >&2; exit 1; }; kill -HUP ${target.pid}`,
|
|
419
|
+
{ timeout: 5e3 }
|
|
420
|
+
).catch((err) => {
|
|
421
|
+
throw new Error(`Safe bare-host OpenResty reload failed: ${safeErrorMessage(err)}`);
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
|
|
243
425
|
// ../../packages/adapters/src/infra/openresty-lua.ts
|
|
244
426
|
var OPENRESTY_LUA_DIR = "/usr/local/openresty/site/lualib/openship";
|
|
245
427
|
var LUA_LOGGER_PATH = `${OPENRESTY_LUA_DIR}/site_logger.lua`;
|
|
@@ -293,6 +475,7 @@ function parseNginxVersion(raw) {
|
|
|
293
475
|
}
|
|
294
476
|
var OPENRESTY_DEFAULT_PATHS = {
|
|
295
477
|
bin: "/usr/local/openresty/bin/openresty",
|
|
478
|
+
compiledConfPath: "/usr/local/openresty/nginx/conf/nginx.conf",
|
|
296
479
|
confPath: "/usr/local/openresty/nginx/conf/nginx.conf",
|
|
297
480
|
confDir: "/usr/local/openresty/nginx/conf",
|
|
298
481
|
sitesDir: "/usr/local/openresty/nginx/conf/sites-enabled",
|
|
@@ -316,6 +499,7 @@ var EDGE_SAME_PATH_MOUNTS = EDGE_CONTAINER_MOUNTS.filter(
|
|
|
316
499
|
).map((m) => m.host.replace(/\/+$/, ""));
|
|
317
500
|
var EDGE_HOST_PATHS = {
|
|
318
501
|
bin: OPENRESTY_DEFAULT_PATHS.bin,
|
|
502
|
+
compiledConfPath: OPENRESTY_DEFAULT_PATHS.compiledConfPath,
|
|
319
503
|
confPath: OPENRESTY_DEFAULT_PATHS.confPath,
|
|
320
504
|
confDir: OPENRESTY_DEFAULT_PATHS.confDir,
|
|
321
505
|
sitesDir: `${EDGE_HOST_STATE_DIR}/sites-enabled`,
|
|
@@ -333,7 +517,8 @@ async function detectOpenRestyPaths(executor) {
|
|
|
333
517
|
return m ? m[1] : null;
|
|
334
518
|
};
|
|
335
519
|
const bin = parseFlag("sbin-path") ?? OPENRESTY_DEFAULT_PATHS.bin;
|
|
336
|
-
|
|
520
|
+
const compiledConfPath = parseFlag("conf-path") ?? OPENRESTY_DEFAULT_PATHS.compiledConfPath;
|
|
521
|
+
let confPath = compiledConfPath;
|
|
337
522
|
const pidPath = parseFlag("pid-path") ?? OPENRESTY_DEFAULT_PATHS.pidPath;
|
|
338
523
|
if (!await executor.exists(confPath)) {
|
|
339
524
|
let found = false;
|
|
@@ -351,6 +536,7 @@ async function detectOpenRestyPaths(executor) {
|
|
|
351
536
|
const nginxVersion = parseNginxVersion(raw);
|
|
352
537
|
return {
|
|
353
538
|
bin,
|
|
539
|
+
compiledConfPath,
|
|
354
540
|
confPath,
|
|
355
541
|
confDir,
|
|
356
542
|
sitesDir: `${confDir}/sites-enabled`,
|
|
@@ -358,28 +544,11 @@ async function detectOpenRestyPaths(executor) {
|
|
|
358
544
|
...nginxVersion ? { nginxVersion } : {}
|
|
359
545
|
};
|
|
360
546
|
}
|
|
361
|
-
function buildReloadCommand(paths
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
return `${paths.bin} -t 2>&1 || exit 1
|
|
367
|
-
|
|
368
|
-
reload_err=$(${paths.bin} -s reload 2>&1) && exit 0
|
|
369
|
-
|
|
370
|
-
if [ "$(cat /proc/1/comm 2>/dev/null)" = "openresty" ] || [ "$(cat /proc/1/comm 2>/dev/null)" = "nginx" ]; then
|
|
371
|
-
echo "openresty reload failed and openresty is PID 1 (containerized edge) \u2014 not killing it; the container supervisor owns restarts." >&2
|
|
372
|
-
echo "$reload_err" >&2
|
|
373
|
-
exit 1
|
|
374
|
-
fi
|
|
375
|
-
|
|
376
|
-
if [ -f ${paths.pidPath} ] && kill -0 "$(cat ${paths.pidPath} 2>/dev/null)" 2>/dev/null; then
|
|
377
|
-
echo "openresty (pid $(cat ${paths.pidPath})) is running but refused -s reload" >&2
|
|
378
|
-
exit 1
|
|
379
|
-
fi
|
|
380
|
-
|
|
381
|
-
rm -f ${paths.pidPath}
|
|
382
|
-
${paths.bin}`;
|
|
547
|
+
function buildReloadCommand(paths) {
|
|
548
|
+
const bin = sq(paths?.bin || "openresty");
|
|
549
|
+
const config = sq(paths?.confPath || "/etc/openresty/nginx.conf");
|
|
550
|
+
return `${bin} -t -c ${config} 2>&1 || exit 1
|
|
551
|
+
${bin} -s reload -c ${config} 2>&1 || exit 1`;
|
|
383
552
|
}
|
|
384
553
|
async function ensureEdgeDefaultCert(executor, confDir) {
|
|
385
554
|
const { dir, certPath, keyPath } = edgeDefaultCertPaths(confDir);
|
|
@@ -422,10 +591,7 @@ async function ensureOpenRestyConfig(executor, paths) {
|
|
|
422
591
|
await executor.writeFile(`${paths.sitesDir}/_default.conf`, edgeDefaultCatchAllConf(defaultCert));
|
|
423
592
|
if (!await executor.exists(paths.confPath)) {
|
|
424
593
|
await executor.mkdir(paths.confDir);
|
|
425
|
-
await executor.writeFile(
|
|
426
|
-
paths.confPath,
|
|
427
|
-
MINIMAL_NGINX_CONF(paths.confDir, paths.sitesDir)
|
|
428
|
-
);
|
|
594
|
+
await executor.writeFile(paths.confPath, MINIMAL_NGINX_CONF(paths.confDir, paths.sitesDir));
|
|
429
595
|
return;
|
|
430
596
|
}
|
|
431
597
|
const hasCorrectInclude = await executor.exec(`grep -qF 'include ${paths.sitesDir}/' ${paths.confPath}`).then(() => true).catch(() => false);
|
|
@@ -518,11 +684,11 @@ var ACME_CHALLENGE_LOCATION = ` location ^~ /.well-known/acme-challenge/ {
|
|
|
518
684
|
}`;
|
|
519
685
|
var EDGE_CHALLENGE_URL_PREFIX = "/.well-known/oblien-proxy-challenge/";
|
|
520
686
|
var EDGE_CHALLENGE_ROOT = "/var/www/acme/oblien";
|
|
521
|
-
var EDGE_CHALLENGE_DIR = `${EDGE_CHALLENGE_ROOT}${EDGE_CHALLENGE_URL_PREFIX}`.replace(
|
|
522
|
-
var EDGE_CHALLENGE_HOST_DIR = `${EDGE_HOST_STATE_DIR}/acme/oblien${EDGE_CHALLENGE_URL_PREFIX}`.replace(
|
|
687
|
+
var EDGE_CHALLENGE_DIR = `${EDGE_CHALLENGE_ROOT}${EDGE_CHALLENGE_URL_PREFIX}`.replace(
|
|
523
688
|
/\/$/,
|
|
524
689
|
""
|
|
525
690
|
);
|
|
691
|
+
var EDGE_CHALLENGE_HOST_DIR = `${EDGE_HOST_STATE_DIR}/acme/oblien${EDGE_CHALLENGE_URL_PREFIX}`.replace(/\/$/, "");
|
|
526
692
|
var EDGE_CHALLENGE_LOCATION = ` location ^~ ${EDGE_CHALLENGE_URL_PREFIX} {
|
|
527
693
|
root ${EDGE_CHALLENGE_ROOT};
|
|
528
694
|
default_type text/plain;
|
|
@@ -635,7 +801,9 @@ async function ensureLuaScripts(executor, paths) {
|
|
|
635
801
|
const expected = luaBundleHash();
|
|
636
802
|
await executor.mkdir(OPENRESTY_LUA_DIR);
|
|
637
803
|
const listing = await executor.exec(`ls -1 '${OPENRESTY_LUA_DIR}' 2>/dev/null || true`).catch(() => "");
|
|
638
|
-
const present = new Set(
|
|
804
|
+
const present = new Set(
|
|
805
|
+
listing.split("\n").map((s) => s.trim()).filter(Boolean)
|
|
806
|
+
);
|
|
639
807
|
const missing = LUA_SCRIPTS.filter((name) => !present.has(name));
|
|
640
808
|
const onBoxVersion = (await executor.readFile(LUA_VERSION_MARKER).catch(() => "")).trim();
|
|
641
809
|
if (missing.length === 0 && onBoxVersion === expected) {
|
|
@@ -647,12 +815,14 @@ async function ensureLuaScripts(executor, paths) {
|
|
|
647
815
|
await executor.writeFile(LUA_VERSION_MARKER, expected);
|
|
648
816
|
const reason = missing.length ? `missing: ${missing.join(", ")}` : "version changed";
|
|
649
817
|
console.warn(`[openresty] (re)installed Lua (${reason}) \u2014 reloading edge.`);
|
|
650
|
-
await executor
|
|
818
|
+
await reloadBareOpenResty(executor, paths).catch((err) => {
|
|
651
819
|
console.error(`[openresty] reload after Lua (re)install failed: ${safeErrorMessage(err)}`);
|
|
652
820
|
});
|
|
653
821
|
return { repaired: missing.length ? missing : [...LUA_SCRIPTS], available: true };
|
|
654
822
|
} catch (err) {
|
|
655
|
-
console.error(
|
|
823
|
+
console.error(
|
|
824
|
+
`[openresty] ensureLuaScripts failed (deploy continues): ${safeErrorMessage(err)}`
|
|
825
|
+
);
|
|
656
826
|
return { repaired: [], available: false };
|
|
657
827
|
}
|
|
658
828
|
}
|
|
@@ -672,15 +842,15 @@ async function installGeoDeps(executor) {
|
|
|
672
842
|
);
|
|
673
843
|
});
|
|
674
844
|
} else {
|
|
675
|
-
console.warn(
|
|
845
|
+
console.warn(
|
|
846
|
+
`[openresty] libmaxminddb not installed \u2014 geo lookups return nil: ${install.reason}`
|
|
847
|
+
);
|
|
676
848
|
}
|
|
677
849
|
try {
|
|
678
850
|
const exists = await executor.exists(GEOIP_DB_PATH);
|
|
679
851
|
if (!exists) {
|
|
680
852
|
await executor.mkdir(GEOIP_DIR);
|
|
681
|
-
await executor.exec(
|
|
682
|
-
`curl -fsSL -o ${GEOIP_DB_PATH} "${GEOIP_DB_URL}"`
|
|
683
|
-
);
|
|
853
|
+
await executor.exec(`curl -fsSL -o ${GEOIP_DB_PATH} "${GEOIP_DB_URL}"`);
|
|
684
854
|
}
|
|
685
855
|
} catch {
|
|
686
856
|
}
|
|
@@ -694,10 +864,7 @@ async function deployLuaScripts(executor, paths) {
|
|
|
694
864
|
}
|
|
695
865
|
await executor.mkdir(OPENRESTY_LUA_DIR);
|
|
696
866
|
for (const name of LUA_SCRIPTS) {
|
|
697
|
-
await executor.writeFile(
|
|
698
|
-
`${OPENRESTY_LUA_DIR}/${name}`,
|
|
699
|
-
readLua(name)
|
|
700
|
-
);
|
|
867
|
+
await executor.writeFile(`${OPENRESTY_LUA_DIR}/${name}`, readLua(name));
|
|
701
868
|
}
|
|
702
869
|
await ensureOpenRestyConfig(executor, paths);
|
|
703
870
|
for (const dict of EDGE_SHARED_DICTS) {
|
|
@@ -713,12 +880,13 @@ async function deployLuaScripts(executor, paths) {
|
|
|
713
880
|
await executor.exec(
|
|
714
881
|
`grep -q '${EDGE_REAL_IP_CONF_NAME}' '${paths.confPath}' || sed -i '/http *{/a \\ include ${realIpPath};' '${paths.confPath}'`
|
|
715
882
|
);
|
|
716
|
-
await executor
|
|
883
|
+
await reloadBareOpenResty(executor, paths);
|
|
717
884
|
}
|
|
718
885
|
|
|
719
886
|
export {
|
|
720
887
|
isCloudFrontedHost,
|
|
721
888
|
cloudEdgeRealIpConf,
|
|
889
|
+
reloadBareOpenResty,
|
|
722
890
|
OPENRESTY_LUA_DIR,
|
|
723
891
|
LUA_LOGGER_PATH,
|
|
724
892
|
RULES_GUARD_PATH,
|
|
@@ -7,20 +7,20 @@ import {
|
|
|
7
7
|
composeInstallExists,
|
|
8
8
|
readComposeEnvFile,
|
|
9
9
|
startUnitHint
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-5UXHT6ED.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-T6DVUX4F.js";
|
|
18
18
|
import {
|
|
19
19
|
edgeCrashReason
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-X53JXRS4.js";
|
|
21
21
|
import {
|
|
22
22
|
EDGE_CONTAINER_NAME
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-D6HU4VUZ.js";
|
|
24
24
|
|
|
25
25
|
// src/lib/edge-import.ts
|
|
26
26
|
import chalk from "chalk";
|
|
@@ -5,7 +5,7 @@ const require = __ospCreateRequire(import.meta.url);
|
|
|
5
5
|
import {
|
|
6
6
|
getTarCreateEnv,
|
|
7
7
|
prepareSourceTarArgs
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-VAI5VOOI.js";
|
|
9
9
|
import {
|
|
10
10
|
TRANSFER_EXCLUDES,
|
|
11
11
|
nodeBinDirs,
|
|
@@ -13,23 +13,25 @@ import {
|
|
|
13
13
|
packageManagerEnsureCommand,
|
|
14
14
|
safeErrorMessage,
|
|
15
15
|
shellQuote
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-WEZFTL4V.js";
|
|
17
17
|
|
|
18
18
|
// ../../packages/adapters/src/runtime/git-clone.ts
|
|
19
19
|
var sq = shellQuote;
|
|
20
|
+
function gitCredentialPair(hostname, token) {
|
|
21
|
+
if (hostname === "github.com" && !token.startsWith("ghs_")) {
|
|
22
|
+
return { username: token, password: "x-oauth-basic" };
|
|
23
|
+
}
|
|
24
|
+
return { username: "x-access-token", password: token };
|
|
25
|
+
}
|
|
20
26
|
function injectGitToken(repoUrl, token) {
|
|
21
|
-
|
|
27
|
+
const secret = token?.trim();
|
|
28
|
+
if (!secret) return repoUrl;
|
|
22
29
|
try {
|
|
23
30
|
const url = new URL(repoUrl);
|
|
24
31
|
if (url.protocol !== "https:") return repoUrl;
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
url.password = "";
|
|
29
|
-
} else {
|
|
30
|
-
url.username = "x-access-token";
|
|
31
|
-
url.password = token;
|
|
32
|
-
}
|
|
32
|
+
const { username, password } = gitCredentialPair(url.hostname, secret);
|
|
33
|
+
url.username = username;
|
|
34
|
+
url.password = password;
|
|
33
35
|
return url.toString();
|
|
34
36
|
} catch {
|
|
35
37
|
return repoUrl;
|