@marcusrbrown/infra 0.25.0 → 0.25.1
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/cli.js +51 -11
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -6950,7 +6950,7 @@ import { goke } from "goke";
|
|
|
6950
6950
|
// package.json
|
|
6951
6951
|
var package_default = {
|
|
6952
6952
|
name: "@marcusrbrown/infra",
|
|
6953
|
-
version: "0.25.
|
|
6953
|
+
version: "0.25.1",
|
|
6954
6954
|
description: "Infrastructure management CLI \u2014 deploy automation, health checks, and MCP bridge",
|
|
6955
6955
|
keywords: [
|
|
6956
6956
|
"infra",
|
|
@@ -8406,7 +8406,7 @@ var CONTENT_EVENTS = new Set([
|
|
|
8406
8406
|
"discussion_comment"
|
|
8407
8407
|
]);
|
|
8408
8408
|
var VERIFIED_ACTION_SHA_BY_LAYOUT = {
|
|
8409
|
-
"fro-bot/agent@v0.
|
|
8409
|
+
"fro-bot/agent@v0.119.2": "83ed683da24111bd1474eb4bda39715ed5799bc2"
|
|
8410
8410
|
};
|
|
8411
8411
|
var REQUIRED_S3_INPUTS = {
|
|
8412
8412
|
"s3-backup": undefined,
|
|
@@ -8917,7 +8917,7 @@ function formatStorageWorkflowSnippet() {
|
|
|
8917
8917
|
with:
|
|
8918
8918
|
role-to-assume: \${{ vars.FRO_BOT_S3_ROLE_TO_ASSUME }}
|
|
8919
8919
|
aws-region: \${{ vars.FRO_BOT_S3_REGION }}
|
|
8920
|
-
- uses: fro-bot/agent@
|
|
8920
|
+
- uses: fro-bot/agent@83ed683da24111bd1474eb4bda39715ed5799bc2
|
|
8921
8921
|
with:
|
|
8922
8922
|
s3-backup: true
|
|
8923
8923
|
s3-bucket: \${{ vars.FRO_BOT_S3_BUCKET }}
|
|
@@ -9138,7 +9138,7 @@ var STORAGE_VARIABLE_NAMES = {
|
|
|
9138
9138
|
prefix: "FRO_BOT_S3_PREFIX",
|
|
9139
9139
|
expectedBucketOwner: "FRO_BOT_S3_EXPECTED_BUCKET_OWNER"
|
|
9140
9140
|
};
|
|
9141
|
-
var KNOWN_KEY_LAYOUT_VERSION = "fro-bot/agent@v0.
|
|
9141
|
+
var KNOWN_KEY_LAYOUT_VERSION = "fro-bot/agent@v0.119.2";
|
|
9142
9142
|
var manifestSchema = z6.object({
|
|
9143
9143
|
owner: z6.string().min(1),
|
|
9144
9144
|
repo: z6.string().min(1),
|
|
@@ -11934,8 +11934,29 @@ function validateGatewayHost(host) {
|
|
|
11934
11934
|
return host;
|
|
11935
11935
|
}
|
|
11936
11936
|
|
|
11937
|
+
// src/commands/gateway/volume.ts
|
|
11938
|
+
var GATEWAY_COMPOSE_PROJECT_NAME = "fro-bot";
|
|
11939
|
+
var MITMPROXY_CERTS_VOLUME = `${GATEWAY_COMPOSE_PROJECT_NAME}_mitmproxy-certs`;
|
|
11940
|
+
var VOLUME_EXISTS_SENTINEL = "EXISTS";
|
|
11941
|
+
var VOLUME_MISSING_SENTINEL = "MISSING";
|
|
11942
|
+
function volumeProbeCommand(volume) {
|
|
11943
|
+
return `docker volume inspect ${volume} >/dev/null 2>&1 && echo ${VOLUME_EXISTS_SENTINEL} || echo ${VOLUME_MISSING_SENTINEL}`;
|
|
11944
|
+
}
|
|
11945
|
+
function checkVolumeProbeResult(volume, result) {
|
|
11946
|
+
if (result.exitCode !== 0) {
|
|
11947
|
+
return `Could not verify Docker volume ${volume} on the gateway host (exit ${result.exitCode}): ${result.stderr.trim() || "unknown error"}`;
|
|
11948
|
+
}
|
|
11949
|
+
const sentinel = result.stdout.trim();
|
|
11950
|
+
if (sentinel === VOLUME_EXISTS_SENTINEL) {
|
|
11951
|
+
return;
|
|
11952
|
+
}
|
|
11953
|
+
if (sentinel === VOLUME_MISSING_SENTINEL) {
|
|
11954
|
+
return `Docker volume ${volume} does not exist on the gateway host; refusing to continue (it would be created empty as a side effect).`;
|
|
11955
|
+
}
|
|
11956
|
+
return `Could not verify Docker volume ${volume} on the gateway host: unrecognized probe output`;
|
|
11957
|
+
}
|
|
11958
|
+
|
|
11937
11959
|
// src/commands/gateway/backup.ts
|
|
11938
|
-
var MITMPROXY_CERTS_VOLUME = "mitmproxy-certs";
|
|
11939
11960
|
var CA_CERT_FILE = "mitmproxy-ca-cert.pem";
|
|
11940
11961
|
var CA_KEY_FILE = "mitmproxy-ca.pem";
|
|
11941
11962
|
var DEFAULT_OUTPUT = "apps/gateway/.local/mitmproxy-ca.tar";
|
|
@@ -11948,7 +11969,7 @@ async function backupGatewayCa(opts, spawn = defaultSpawn3, printErr) {
|
|
|
11948
11969
|
return { ok: false, error: "Only CA backup is currently supported; --no-include-ca is not accepted" };
|
|
11949
11970
|
}
|
|
11950
11971
|
validateGatewayHost(opts.host);
|
|
11951
|
-
const
|
|
11972
|
+
const sshCommand = (remote) => [
|
|
11952
11973
|
"ssh",
|
|
11953
11974
|
"-o",
|
|
11954
11975
|
"BatchMode=yes",
|
|
@@ -11956,13 +11977,28 @@ async function backupGatewayCa(opts, spawn = defaultSpawn3, printErr) {
|
|
|
11956
11977
|
"StrictHostKeyChecking=yes",
|
|
11957
11978
|
...buildKnownHostsArgs(),
|
|
11958
11979
|
`root@${opts.host}`,
|
|
11959
|
-
|
|
11980
|
+
remote
|
|
11960
11981
|
];
|
|
11961
11982
|
const env = {
|
|
11962
11983
|
PATH: process.env.PATH ?? "/usr/bin:/bin",
|
|
11963
11984
|
HOME: process.env.HOME ?? "/tmp",
|
|
11964
11985
|
...process.env.SSH_AUTH_SOCK ? { SSH_AUTH_SOCK: process.env.SSH_AUTH_SOCK } : {}
|
|
11965
11986
|
};
|
|
11987
|
+
const probe = spawn(sshCommand(volumeProbeCommand(MITMPROXY_CERTS_VOLUME)), { env, stdout: "pipe", stderr: "pipe" });
|
|
11988
|
+
const [probeStdout, probeStderr, probeExit] = await Promise.all([
|
|
11989
|
+
new Response(probe.stdout).text(),
|
|
11990
|
+
new Response(probe.stderr).text(),
|
|
11991
|
+
probe.exited
|
|
11992
|
+
]);
|
|
11993
|
+
const probeError = checkVolumeProbeResult(MITMPROXY_CERTS_VOLUME, {
|
|
11994
|
+
stdout: probeStdout,
|
|
11995
|
+
stderr: probeStderr,
|
|
11996
|
+
exitCode: probeExit
|
|
11997
|
+
});
|
|
11998
|
+
if (probeError !== undefined) {
|
|
11999
|
+
return { ok: false, error: probeError };
|
|
12000
|
+
}
|
|
12001
|
+
const sshCmd = sshCommand(`docker run --rm -v ${MITMPROXY_CERTS_VOLUME}:/src:ro alpine tar -cf - -C /src ${CA_CERT_FILE} ${CA_KEY_FILE}`);
|
|
11966
12002
|
const child = spawn(sshCmd, { env, stdout: "pipe", stderr: "pipe" });
|
|
11967
12003
|
const [tarBytes, stderrText, exitCode] = await Promise.all([
|
|
11968
12004
|
new Response(child.stdout).arrayBuffer(),
|
|
@@ -12231,7 +12267,6 @@ function registerGatewayLogs(cli) {
|
|
|
12231
12267
|
|
|
12232
12268
|
// src/commands/gateway/restore.ts
|
|
12233
12269
|
import { z as z25 } from "zod";
|
|
12234
|
-
var MITMPROXY_CERTS_VOLUME2 = "mitmproxy-certs";
|
|
12235
12270
|
var CA_CERT_FILE2 = "mitmproxy-ca-cert.pem";
|
|
12236
12271
|
var CA_KEY_FILE2 = "mitmproxy-ca.pem";
|
|
12237
12272
|
var COMPOSE_PROJECT_DIR4 = "/opt/gateway/deploy";
|
|
@@ -12300,6 +12335,11 @@ async function restoreGatewayCa(opts, spawn = defaultSpawn4) {
|
|
|
12300
12335
|
if (archiveError !== undefined) {
|
|
12301
12336
|
return { ok: false, error: archiveError };
|
|
12302
12337
|
}
|
|
12338
|
+
const probeResult = await spawnText(spawn, sshCommand(opts.host, volumeProbeCommand(MITMPROXY_CERTS_VOLUME)), env);
|
|
12339
|
+
const probeError = checkVolumeProbeResult(MITMPROXY_CERTS_VOLUME, probeResult);
|
|
12340
|
+
if (probeError !== undefined) {
|
|
12341
|
+
return { ok: false, error: probeError };
|
|
12342
|
+
}
|
|
12303
12343
|
const mktempResult = await spawnText(spawn, sshCommand(opts.host, "mktemp -t gateway-ca-restore-XXXXXX.tar"), env);
|
|
12304
12344
|
if (mktempResult.exitCode !== 0) {
|
|
12305
12345
|
return {
|
|
@@ -12336,7 +12376,7 @@ async function restoreGatewayCa(opts, spawn = defaultSpawn4) {
|
|
|
12336
12376
|
};
|
|
12337
12377
|
return primaryError;
|
|
12338
12378
|
}
|
|
12339
|
-
const extractResult = await spawnText(spawn, sshCommand(opts.host, `docker run --rm -v ${
|
|
12379
|
+
const extractResult = await spawnText(spawn, sshCommand(opts.host, `docker run --rm -v ${MITMPROXY_CERTS_VOLUME}:/dst -v ${tmpRemote}:/src.tar:ro alpine sh -c 'tar -xf /src.tar -C /dst'`), env);
|
|
12340
12380
|
if (extractResult.exitCode !== 0) {
|
|
12341
12381
|
primaryError = {
|
|
12342
12382
|
ok: false,
|
|
@@ -12353,8 +12393,8 @@ async function restoreGatewayCa(opts, spawn = defaultSpawn4) {
|
|
|
12353
12393
|
return primaryError;
|
|
12354
12394
|
}
|
|
12355
12395
|
const [certResult, keyResult] = await Promise.all([
|
|
12356
|
-
spawnText(spawn, sshCommand(opts.host, `docker run --rm -v ${
|
|
12357
|
-
spawnText(spawn, sshCommand(opts.host, `docker run --rm -v ${
|
|
12396
|
+
spawnText(spawn, sshCommand(opts.host, `docker run --rm -v ${MITMPROXY_CERTS_VOLUME}:/src:ro alpine cat /src/${CA_CERT_FILE2}`), env),
|
|
12397
|
+
spawnText(spawn, sshCommand(opts.host, `docker run --rm -v ${MITMPROXY_CERTS_VOLUME}:/src:ro alpine cat /src/${CA_KEY_FILE2}`), env)
|
|
12358
12398
|
]);
|
|
12359
12399
|
if (certResult.exitCode !== 0 || keyResult.exitCode !== 0) {
|
|
12360
12400
|
primaryError = {
|