@forgezero/agent 0.1.88 → 0.1.89
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/README.md +23 -9
- package/dist/agent-heartbeat.js +1 -1
- package/dist/bootstrap.d.ts +8 -1
- package/dist/bootstrap.js +228 -54
- package/dist/capacity-calibration.d.ts +35 -5
- package/dist/capacity-calibration.js +66 -22
- package/dist/cli/agent-install.d.ts +3 -0
- package/dist/community-rehearsal-host.js +7 -2
- package/dist/control.d.ts +3 -1
- package/dist/definition.js +83 -28
- package/dist/deploy-file.js +83 -28
- package/dist/deployment.d.ts +5 -0
- package/dist/egress-policy.d.ts +4 -0
- package/dist/fz-agent.js +416 -150
- package/dist/fz.js +413 -129
- package/dist/host-maintenance.js +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/metal-bootstrap.js +1 -1
- package/dist/metal-helper-socket.js +7 -2
- package/dist/metal-provision.js +7 -2
- package/dist/operator-bootstrap.d.ts +12 -0
- package/dist/operator-bootstrap.js +372 -64
- package/dist/platform-bootstrap-runtime.d.ts +1 -0
- package/dist/platform-bootstrap-runtime.js +47 -8
- package/dist/platform-fleet-verification.js +262 -87
- package/dist/platform-genesis.js +7 -2
- package/dist/provision.d.ts +5 -1
- package/dist/provision.js +185 -71
- package/dist/recovery-host.js +1 -1
- package/dist/software-helper.js +144 -48
- package/dist/software.js +7 -2
- package/dist/ubuntu.js +7 -2
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/schema/deploy-v3.json +5 -2
|
@@ -175,6 +175,7 @@ export interface PlatformActivationCommandResult {
|
|
|
175
175
|
output: string;
|
|
176
176
|
}
|
|
177
177
|
export type PlatformActivationExec = (argv: readonly string[]) => Promise<PlatformActivationCommandResult>;
|
|
178
|
+
export declare const assertReleaseLinksContained: (path: string) => void;
|
|
178
179
|
/** Agent-native blue/green activation with health and nginx rollback. */
|
|
179
180
|
export declare function activatePlatformRelease(config: PlatformActivationConfig, requestedRelease: string, options?: {
|
|
180
181
|
exec?: PlatformActivationExec;
|
|
@@ -355,7 +355,12 @@ async function executeSoftwareOperation(operation) {
|
|
|
355
355
|
}
|
|
356
356
|
if (software === "nginx") {
|
|
357
357
|
const binary = await run(["/usr/sbin/nginx", "-v"]);
|
|
358
|
-
|
|
358
|
+
if (binary.exitCode !== 0)
|
|
359
|
+
return binary;
|
|
360
|
+
if (!existsSync("/usr/lib/nginx/modules/ngx_http_headers_more_filter_module.so")) {
|
|
361
|
+
return { exitCode: 1, output: "Nginx response-header suppression module is unavailable" };
|
|
362
|
+
}
|
|
363
|
+
return run(["/usr/bin/systemctl", "is-active", "--quiet", "nginx.service"]);
|
|
359
364
|
}
|
|
360
365
|
if (software === "arangodb") {
|
|
361
366
|
const binary = await run(["/usr/sbin/arangod", "--version"]);
|
|
@@ -387,7 +392,7 @@ async function executeSoftwareOperation(operation) {
|
|
|
387
392
|
}
|
|
388
393
|
if (software === "docker" || software === "nginx" || software === "ufw" || software === "openssh-client" || software === "git") {
|
|
389
394
|
const packageName = software === "openssh-client" ? "openssh-client" : software === "docker" ? "docker.io" : software;
|
|
390
|
-
const installed = await aptInstall(packageName);
|
|
395
|
+
const installed = software === "nginx" ? await aptInstallMany(["nginx", "libnginx-mod-http-headers-more-filter"]) : await aptInstall(packageName);
|
|
391
396
|
if (installed.exitCode !== 0 || software !== "nginx" && software !== "docker")
|
|
392
397
|
return installed;
|
|
393
398
|
if (software === "docker") {
|
|
@@ -1050,12 +1055,26 @@ map $limit_conn_status $forgezero_retry_after { default ''; REJECTED 1; REJECTED
|
|
|
1050
1055
|
server {
|
|
1051
1056
|
listen 127.0.0.1:${input.publicPort};
|
|
1052
1057
|
server_name _;
|
|
1058
|
+
server_tokens off;
|
|
1059
|
+
more_clear_headers Server X-Powered-By;
|
|
1053
1060
|
limit_conn forgezero_admission ${concurrencyLimit};
|
|
1054
1061
|
limit_conn_status 503;
|
|
1055
1062
|
add_header Retry-After $forgezero_retry_after always;
|
|
1056
|
-
|
|
1057
|
-
location
|
|
1058
|
-
location / {
|
|
1063
|
+
error_page 400 403 404 405 408 413 414 429 500 502 503 504 = @transport_failure;
|
|
1064
|
+
location @transport_failure { internal; return 444; }
|
|
1065
|
+
location / {
|
|
1066
|
+
proxy_pass http://forgezero;
|
|
1067
|
+
proxy_http_version 1.1;
|
|
1068
|
+
proxy_intercept_errors off;
|
|
1069
|
+
proxy_hide_header Server;
|
|
1070
|
+
proxy_hide_header X-Powered-By;
|
|
1071
|
+
proxy_set_header Host $host;
|
|
1072
|
+
proxy_set_header X-Forwarded-Proto https;
|
|
1073
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
1074
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
1075
|
+
proxy_set_header Connection $forgezero_connection;
|
|
1076
|
+
proxy_read_timeout 3600s;
|
|
1077
|
+
}
|
|
1059
1078
|
}
|
|
1060
1079
|
`
|
|
1061
1080
|
};
|
|
@@ -1128,11 +1147,29 @@ var replaceLink = (path2, target) => {
|
|
|
1128
1147
|
symlinkSync2(target, pending);
|
|
1129
1148
|
renameSync2(pending, path2);
|
|
1130
1149
|
};
|
|
1150
|
+
var assertReleaseLinksContained = (path2) => {
|
|
1151
|
+
const root = realpathSync(path2);
|
|
1152
|
+
const visit = (current2) => {
|
|
1153
|
+
const metadata = lstatSync(current2);
|
|
1154
|
+
if (metadata.isSymbolicLink()) {
|
|
1155
|
+
const target = realpathSync(current2);
|
|
1156
|
+
if (target !== root && !target.startsWith(`${root}/`)) {
|
|
1157
|
+
throw new Error("release contains a symbolic link outside its immutable root");
|
|
1158
|
+
}
|
|
1159
|
+
return;
|
|
1160
|
+
}
|
|
1161
|
+
if (metadata.isDirectory())
|
|
1162
|
+
for (const name of readdirSync(current2))
|
|
1163
|
+
visit(join2(current2, name));
|
|
1164
|
+
};
|
|
1165
|
+
visit(root);
|
|
1166
|
+
};
|
|
1131
1167
|
var secureRelease = (path2, uid, gid) => {
|
|
1168
|
+
assertReleaseLinksContained(path2);
|
|
1132
1169
|
const visit = (current2) => {
|
|
1133
1170
|
const metadata = lstatSync(current2);
|
|
1134
1171
|
if (metadata.isSymbolicLink())
|
|
1135
|
-
|
|
1172
|
+
return;
|
|
1136
1173
|
chownSync(current2, uid, gid);
|
|
1137
1174
|
chmodSync2(current2, metadata.isDirectory() ? 365 : 292);
|
|
1138
1175
|
if (metadata.isDirectory())
|
|
@@ -1158,7 +1195,7 @@ async function activatePlatformRelease(config, requestedRelease, options = {}) {
|
|
|
1158
1195
|
const sleep = options.sleep ?? Bun.sleep;
|
|
1159
1196
|
const slots = join2(normalized.root, "slots");
|
|
1160
1197
|
mkdirSync2(slots, { recursive: true, mode: 493 });
|
|
1161
|
-
const slotFile = join2(
|
|
1198
|
+
const slotFile = join2(slots, ".active");
|
|
1162
1199
|
const previousSlot = existsSync2(slotFile) ? readFileSync2(slotFile, "utf8").trim() : undefined;
|
|
1163
1200
|
const target = previousSlot === "blue" ? "green" : "blue";
|
|
1164
1201
|
const port = target === "blue" ? normalized.bluePort : normalized.greenPort;
|
|
@@ -1208,6 +1245,7 @@ async function activatePlatformRelease(config, requestedRelease, options = {}) {
|
|
|
1208
1245
|
const test = await exec(["/usr/sbin/nginx", "-t"]);
|
|
1209
1246
|
const reload = test.exitCode === 0 ? await exec(["/usr/sbin/nginx", "-s", "reload"]) : test;
|
|
1210
1247
|
if (reload.exitCode !== 0) {
|
|
1248
|
+
const refusal = (reload.output || test.output).trim().slice(0, 2000);
|
|
1211
1249
|
if (existsSync2(backup))
|
|
1212
1250
|
renameSync2(backup, upstream);
|
|
1213
1251
|
else
|
|
@@ -1215,7 +1253,7 @@ async function activatePlatformRelease(config, requestedRelease, options = {}) {
|
|
|
1215
1253
|
await exec(["/usr/sbin/nginx", "-t"]);
|
|
1216
1254
|
await exec(["/usr/sbin/nginx", "-s", "reload"]);
|
|
1217
1255
|
await stopTarget();
|
|
1218
|
-
throw new Error(
|
|
1256
|
+
throw new Error(`nginx refused the promoted upstream${refusal ? `: ${refusal}` : ""}`);
|
|
1219
1257
|
}
|
|
1220
1258
|
rmSync2(backup, { force: true });
|
|
1221
1259
|
writeFileSync2(slotFile, `${target}
|
|
@@ -1276,5 +1314,6 @@ export {
|
|
|
1276
1314
|
platformApiCredentialSpecs,
|
|
1277
1315
|
planPlatformActivation,
|
|
1278
1316
|
planLocalOtlpProof,
|
|
1317
|
+
assertReleaseLinksContained,
|
|
1279
1318
|
activatePlatformRelease
|
|
1280
1319
|
};
|