@supacloud/admin 0.14.0 → 0.14.2

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 CHANGED
@@ -157,8 +157,9 @@ upload-drop paths for reconciliation. Inspect that evidence before retrying and
157
157
  do not retry blindly while the remote transaction may still be running.
158
158
 
159
159
  `--artifact_transport local` accepts only `--github_proxy direct` or `none` and
160
- clears proxy environment variables on both hosts. The legacy server-download
161
- path remains available as `--artifact_transport remote`.
160
+ clears proxy environment variables on both hosts. The server-download path
161
+ remains available as `--artifact_transport remote`; it verifies and executes
162
+ the target Management release as the runner even for Management-only upgrades.
162
163
 
163
164
  With `--artifact_transport remote` (the default), omitting
164
165
  `--edge_runtime_version` retains the Management and Web Console-only upgrade
@@ -175,14 +176,10 @@ command may finish later and then run its own cleanup. Reconcile the reported
175
176
  helper and trusted-root paths and read back deployed versions before deciding
176
177
  whether to retry.
177
178
 
178
- After a capable Management release is active, an exact rollback can use that
179
- active upgrader with explicit older targets, for example:
180
-
181
- ```bash
182
- npx @supacloud/admin ssh upgrade \
183
- --version 0.50.26 \
184
- --edge_runtime_version 0.16.6
185
- ```
179
+ Targets predating the target-bound systemd-unit helper identity command are
180
+ rejected before mutation. A failed transaction still restores its exact frozen
181
+ prior Management/helper/Web identities; an intentional downgrade to a legacy
182
+ release requires a separately reviewed compatibility procedure.
186
183
 
187
184
  Project commands owned by this CLI:
188
185
 
package/dist/index.js CHANGED
@@ -4759,7 +4759,7 @@ var require_utils = __commonJS((exports, module) => {
4759
4759
 
4760
4760
  // node_modules/ssh2/lib/protocol/crypto/build/Release/sshcrypto.node
4761
4761
  var require_sshcrypto = __commonJS((exports, module) => {
4762
- module.exports = __require("./sshcrypto-8m50vnmb.node");
4762
+ module.exports = __require("./sshcrypto-vd2k5hq9.node");
4763
4763
  });
4764
4764
 
4765
4765
  // node_modules/ssh2/lib/protocol/crypto/poly1305.js
@@ -27252,7 +27252,7 @@ function buildRemotePreflightScript() {
27252
27252
  "export PATH",
27253
27253
  trustedInstalledGithubFunction(),
27254
27254
  "test -d /run/systemd/system || { echo 'systemd is not the active init system' >&2; exit 1; }",
27255
- 'for tool in systemctl systemd-run sha256sum stat realpath tar file find sort awk grep tail timeout flock; do command -v "$tool" >/dev/null 2>&1 || { echo "Required local-upgrade tool is missing: $tool" >&2; exit 127; }; done',
27255
+ 'for tool in systemctl systemd-run sha256sum stat realpath tar file find sort awk grep tail timeout flock install mktemp; do command -v "$tool" >/dev/null 2>&1 || { echo "Required local-upgrade tool is missing: $tool" >&2; exit 127; }; done',
27256
27256
  "tail -n 0 -- /dev/null >/dev/null 2>&1 || { echo 'A tail implementation with -n and -- support is required' >&2; exit 1; }",
27257
27257
  "systemd-run --help | grep -Eq -- '(^|[[:space:]])--collect([=[:space:]]|$)' || { echo 'systemd-run --collect is required' >&2; exit 1; }",
27258
27258
  "test -d /run/lock || { echo '/run/lock is unavailable' >&2; exit 1; }",
@@ -27328,6 +27328,54 @@ async function uploadBundleFiles(ssh, paths, bundle) {
27328
27328
  await ssh.upload(upload.localPath, `${paths.drop}/${upload.relativePath}`, { mode: 384, timeoutMs: 10 * 60000 });
27329
27329
  }
27330
27330
  }
27331
+ function managementRunnerFile(bundle) {
27332
+ const relativePath = `bundle/management-api/${bundle.managementBinaryName}`;
27333
+ const runner = bundle.files.find((file) => file.relativePath === relativePath);
27334
+ if (!runner)
27335
+ throw new Error(`Local upgrade bundle is missing ${relativePath}`);
27336
+ return runner;
27337
+ }
27338
+ function targetRunnerCapabilityCommands() {
27339
+ return [
27340
+ 'RUNNER=$(mktemp "$DROP/.runner-capability.XXXXXX")',
27341
+ `trap 'rm -f -- "$RUNNER"' EXIT`,
27342
+ `trap 'trap - EXIT HUP INT TERM; rm -f -- "$RUNNER"; exit 1' HUP INT TERM`,
27343
+ 'install -m 0700 "$RUNNER_ASSET" "$RUNNER"',
27344
+ `test "$(sha256sum "$RUNNER" | awk '{print $1}')" = "$EXPECTED_SHA256"`,
27345
+ 'VERSION_OUTPUT=$(timeout 5s "$RUNNER" --version 2>&1)',
27346
+ `[[ "$VERSION_OUTPUT" =~ ^SupaCloud[[:space:]]Version:[[:space:]]\${EXPECTED_VERSION//./\\.}$ ]] || { echo 'Target Management runner version mismatch' >&2; exit 1; }`,
27347
+ 'SYSTEMD_HELPER_OUTPUT=$(timeout 5s "$RUNNER" --systemd-unit-helper-sha256 2>&1)',
27348
+ `[[ "$SYSTEMD_HELPER_OUTPUT" =~ ^SupaCloud[[:space:]]systemd-unit[[:space:]]helper[[:space:]]SHA-256:[[:space:]][0-9a-f]{64}$ ]] || { echo 'Target Management runner lacks systemd-unit helper delivery' >&2; exit 1; }`,
27349
+ 'POSTGREST_LAUNCHER_OUTPUT=$(timeout 5s "$RUNNER" --postgrest-launcher-sha256 2>&1)',
27350
+ `[[ "$POSTGREST_LAUNCHER_OUTPUT" =~ ^SupaCloud[[:space:]]PostgREST[[:space:]]launcher[[:space:]]SHA-256:[[:space:]][0-9a-f]{64}$ ]] || { echo 'Target Management runner lacks PostgREST launcher delivery' >&2; exit 1; }`,
27351
+ 'rm -f -- "$RUNNER"',
27352
+ "trap - EXIT HUP INT TERM"
27353
+ ];
27354
+ }
27355
+ function buildTargetRunnerCapabilityScript(paths, bundle, request) {
27356
+ const runnerFile = managementRunnerFile(bundle);
27357
+ const runnerAsset = `${paths.drop}/${runnerFile.relativePath}`;
27358
+ return [
27359
+ "set -euo pipefail",
27360
+ "umask 077",
27361
+ `DROP=${quoteShell2(paths.drop)}`,
27362
+ `RUNNER_ASSET=${quoteShell2(runnerAsset)}`,
27363
+ `EXPECTED_SIZE=${runnerFile.size}`,
27364
+ `EXPECTED_SHA256=${quoteShell2(runnerFile.sha256)}`,
27365
+ `EXPECTED_VERSION=${quoteShell2(request.managementVersion)}`,
27366
+ `test -f "$RUNNER_ASSET" && test ! -L "$RUNNER_ASSET" && test "$(stat -c '%h' "$RUNNER_ASSET")" = 1 || { echo 'Target Management runner is not a direct single-link file' >&2; exit 1; }`,
27367
+ `test "$(stat -c '%s' "$RUNNER_ASSET")" = "$EXPECTED_SIZE"`,
27368
+ `test "$(sha256sum "$RUNNER_ASSET" | awk '{print $1}')" = "$EXPECTED_SHA256"`,
27369
+ ...targetRunnerCapabilityCommands()
27370
+ ].join(`
27371
+ `);
27372
+ }
27373
+ async function verifyTargetRunnerCapability(ssh, paths, bundle, request) {
27374
+ const verified = await ssh.exec(buildTargetRunnerCapabilityScript(paths, bundle, request), 30000);
27375
+ if (!verified.success) {
27376
+ throw remoteFailure("Target Management runner lacks required transactional helper delivery", verified);
27377
+ }
27378
+ }
27331
27379
  function expectedComponentFiles(bundle) {
27332
27380
  return {
27333
27381
  management: [
@@ -27474,6 +27522,8 @@ function upgradeScriptExecution(paths, bundle, request) {
27474
27522
  'install -m 0755 "$RUNNER_ASSET" "$RUNNER"',
27475
27523
  `test "$(sha256sum "$RUNNER"|awk '{print $1}')" = "$(sha256sum "$RUNNER_ASSET"|awk '{print $1}')"`,
27476
27524
  '"$RUNNER" --version | grep -Eq "(^|[^0-9])${MANAGEMENT_VERSION//./\\.}([^0-9]|$)"',
27525
+ `timeout 5s "$RUNNER" --systemd-unit-helper-sha256 | grep -Eq 'SupaCloud systemd-unit helper SHA-256: [0-9a-f]{64}'`,
27526
+ `timeout 5s "$RUNNER" --postgrest-launcher-sha256 | grep -Eq 'SupaCloud PostgREST launcher SHA-256: [0-9a-f]{64}'`,
27477
27527
  `env PATH="$VERIFIER_PATH:$PATH" "$RUNNER" upgrade --yes --target-version ${quoteShell2(request.managementVersion)} --edge-runtime-version ${quoteShell2(request.edgeRuntimeVersion)} --asset-bundle-dir "$BUNDLE"`
27478
27528
  ];
27479
27529
  }
@@ -27866,6 +27916,7 @@ async function executeLocalUpgradeTransfer(ssh, request) {
27866
27916
  try {
27867
27917
  await prepareRemoteDrop(ssh, paths, bundle);
27868
27918
  await uploadBundleFiles(ssh, paths, bundle);
27919
+ await verifyTargetRunnerCapability(ssh, paths, bundle, request);
27869
27920
  await uploadRunScript(ssh, paths, bundle, request, preflight.architecture);
27870
27921
  await adoptRemoteDrop(ssh, paths);
27871
27922
  adopted = true;
@@ -28060,30 +28111,30 @@ function assertExactStableVersion2(value, fieldName) {
28060
28111
  }
28061
28112
  return value;
28062
28113
  }
28063
- function upgradeEnvAssignments(request) {
28114
+ function upgradeTransactionEnvAssignments(request) {
28064
28115
  return [
28065
- request.version ? `SUPACLOUD_UPGRADE_TAG=${quoteEnvValue(request.version)}` : "",
28116
+ 'SUPACLOUD_UPGRADE_TAG="$TARGET_MANAGEMENT_VERSION"',
28066
28117
  request.edgeRuntimeVersion ? `SUPACLOUD_EDGE_RUNTIME_UPGRADE_TAG=${quoteEnvValue(request.edgeRuntimeVersion)}` : "",
28067
28118
  request.githubProxy ? `SUPACLOUD_GITHUB_PROXY=${quoteEnvValue(request.githubProxy)}` : ""
28068
28119
  ].filter(Boolean).join(" ");
28069
28120
  }
28070
28121
  function componentBootstrapCommands(request) {
28071
- if (!request.edgeRuntimeVersion)
28072
- return [`UPGRADE_RUNNER=${quoteEnvValue("/usr/local/bin/supacloud")}`];
28073
28122
  const managementVersion = request.version || "latest";
28074
28123
  return [
28075
- `ACTIVE_VERSION=$(/usr/local/bin/supacloud --version 2>&1 | grep -Eo '[0-9]+\\.[0-9]+\\.[0-9]+' | head -1 || true)`,
28076
- `UPGRADE_RUNNER=${quoteEnvValue("/usr/local/bin/supacloud")}`,
28077
- `if ! supacloud_version_at_least "$ACTIVE_VERSION" ${quoteEnvValue(MINIMUM_COMPONENT_UPGRADE_VERSION)}; then`,
28078
- ` case "$(uname -m)" in x86_64|amd64) MANAGEMENT_ASSET=supacloud-linux-amd64 ;; aarch64|arm64) MANAGEMENT_ASSET=supacloud-linux-arm64 ;; *) echo 'Unsupported Management architecture' >&2; exit 1 ;; esac`,
28079
- ` STAGED_MANAGEMENT=$(mktemp /tmp/supacloud-management-upgrade.XXXXXX)`,
28080
- ` MANAGEMENT_RELEASE=$(supacloud_fetch_component_release management-api ${quoteEnvValue(managementVersion)} "$MANAGEMENT_ASSET" web-console-build.tar.gz)`,
28081
- ` supacloud_download_release_asset "$MANAGEMENT_RELEASE" "$MANAGEMENT_ASSET" "$STAGED_MANAGEMENT" binary`,
28082
- ` chmod 0755 "$STAGED_MANAGEMENT"`,
28083
- ` STAGED_VERSION=$("$STAGED_MANAGEMENT" --version 2>&1 | grep -Eo '[0-9]+\\.[0-9]+\\.[0-9]+' | head -1 || true)`,
28084
- ` supacloud_version_at_least "$STAGED_VERSION" ${quoteEnvValue(MINIMUM_COMPONENT_UPGRADE_VERSION)} || { echo 'Target Management release lacks Edge Runtime transaction capability' >&2; exit 1; }`,
28085
- ` UPGRADE_RUNNER="$STAGED_MANAGEMENT"`,
28086
- "fi"
28124
+ `case "$(uname -m)" in x86_64|amd64) MANAGEMENT_ASSET=supacloud-linux-amd64 ;; aarch64|arm64) MANAGEMENT_ASSET=supacloud-linux-arm64 ;; *) echo 'Unsupported Management architecture' >&2; exit 1 ;; esac`,
28125
+ `STAGED_MANAGEMENT=$(mktemp /tmp/supacloud-management-upgrade.XXXXXX)`,
28126
+ `MANAGEMENT_RELEASE=$(supacloud_fetch_component_release management-api ${quoteEnvValue(managementVersion)} "$MANAGEMENT_ASSET" web-console-build.tar.gz)`,
28127
+ `supacloud_download_release_asset "$MANAGEMENT_RELEASE" "$MANAGEMENT_ASSET" "$STAGED_MANAGEMENT" binary`,
28128
+ `chmod 0755 "$STAGED_MANAGEMENT"`,
28129
+ `TARGET_MANAGEMENT_VERSION=$(jq -er '.tag_name | capture("^management-api-v(?<version>(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*))$").version' <<< "$MANAGEMENT_RELEASE")`,
28130
+ `STAGED_VERSION=$(timeout 5s "$STAGED_MANAGEMENT" --version 2>&1 | grep -Eo '[0-9]+\\.[0-9]+\\.[0-9]+' | head -1 || true)`,
28131
+ `test "$STAGED_VERSION" = "$TARGET_MANAGEMENT_VERSION" || { echo 'Target Management binary version does not match its verified release' >&2; exit 1; }`,
28132
+ `supacloud_version_at_least "$STAGED_VERSION" ${quoteEnvValue(MINIMUM_COMPONENT_UPGRADE_VERSION)} || { echo 'Target Management release lacks component transaction capability' >&2; exit 1; }`,
28133
+ `SYSTEMD_HELPER_OUTPUT=$(timeout 5s "$STAGED_MANAGEMENT" --systemd-unit-helper-sha256 2>&1)`,
28134
+ `[[ "$SYSTEMD_HELPER_OUTPUT" =~ ^SupaCloud[[:space:]]systemd-unit[[:space:]]helper[[:space:]]SHA-256:[[:space:]][0-9a-f]{64}$ ]] || { echo 'Target Management release lacks target-bound systemd-unit helper delivery' >&2; exit 1; }`,
28135
+ `POSTGREST_LAUNCHER_OUTPUT=$(timeout 5s "$STAGED_MANAGEMENT" --postgrest-launcher-sha256 2>&1)`,
28136
+ `[[ "$POSTGREST_LAUNCHER_OUTPUT" =~ ^SupaCloud[[:space:]]PostgREST[[:space:]]launcher[[:space:]]SHA-256:[[:space:]][0-9a-f]{64}$ ]] || { echo 'Target Management release lacks target-bound PostgREST launcher delivery' >&2; exit 1; }`,
28137
+ `UPGRADE_RUNNER="$STAGED_MANAGEMENT"`
28087
28138
  ];
28088
28139
  }
28089
28140
  function componentPreflightCommands(request) {
@@ -28121,7 +28172,7 @@ function trustedRootPreflightCommands(helperPath) {
28121
28172
  ];
28122
28173
  }
28123
28174
  function buildRootUpgradeScript(request) {
28124
- const envAssignments = upgradeEnvAssignments(request);
28175
+ const envAssignments = upgradeTransactionEnvAssignments(request);
28125
28176
  return [
28126
28177
  "set -euo pipefail",
28127
28178
  "umask 077",
@@ -28129,7 +28180,7 @@ function buildRootUpgradeScript(request) {
28129
28180
  "export PATH",
28130
28181
  "unset SUPACLOUD_ALLOW_UNVERIFIED_RELEASE SUPACLOUD_GITHUB_REPOSITORY SUPACLOUD_RELEASES_API SUPACLOUD_ATTESTATION_SIGNER_WORKFLOW SUPACLOUD_ATTESTATION_TRUSTED_ROOT SUPACLOUD_GH_VERSION SUPACLOUD_GH_MIN_VERSION SUPACLOUD_GH_AMD64_SHA256 SUPACLOUD_GH_ARM64_SHA256 GH_PROXY",
28131
28182
  request.githubProxy ? `export SUPACLOUD_GITHUB_PROXY=${quoteEnvValue(request.githubProxy)}` : "unset SUPACLOUD_GITHUB_PROXY SUPACLOUD_GITHUB_PROXIES",
28132
- 'for tool in curl jq file sha256sum stat tar flock find sort chown; do command -v "$tool" >/dev/null 2>&1 || { echo "Required upgrade tool is missing: $tool" >&2; exit 127; }; done',
28183
+ 'for tool in curl jq file sha256sum stat tar flock find sort chown timeout; do command -v "$tool" >/dev/null 2>&1 || { echo "Required upgrade tool is missing: $tool" >&2; exit 127; }; done',
28133
28184
  "test -d /run/lock || { echo '/run/lock is unavailable' >&2; exit 1; }",
28134
28185
  "test -x /usr/local/bin/supacloud || { echo 'SupaCloud binary not found at /usr/local/bin/supacloud; run ssh install first.' >&2; exit 127; }",
28135
28186
  ...trustedRootPreflightCommands(request.helperPath),
@@ -28142,7 +28193,7 @@ function buildRootUpgradeScript(request) {
28142
28193
  "if ! supacloud_attestation_verifier_available; then supacloud_install_pinned_gh /usr/local/bin/gh; fi",
28143
28194
  "supacloud_attestation_verifier_available || { echo 'Pinned GitHub attestation verifier is unavailable' >&2; exit 1; }",
28144
28195
  ...componentBootstrapCommands(request),
28145
- `${envAssignments ? `env ${envAssignments} ` : ""}"$UPGRADE_RUNNER" upgrade --yes`
28196
+ `env ${envAssignments} "$UPGRADE_RUNNER" upgrade --yes`
28146
28197
  ].join(`
28147
28198
  `);
28148
28199
  }
@@ -31845,7 +31896,7 @@ Actions: list_releases, get_release, upload_release, activate_release`, {
31845
31896
  // package.json
31846
31897
  var package_default = {
31847
31898
  name: "@supacloud/admin",
31848
- version: "0.14.0",
31899
+ version: "0.14.2",
31849
31900
  description: "Platform administration CLI for SupaCloud operators",
31850
31901
  type: "module",
31851
31902
  main: "./dist/index.js",
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supacloud/admin",
3
- "version": "0.14.0",
3
+ "version": "0.14.2",
4
4
  "description": "Platform administration CLI for SupaCloud operators",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
Binary file