@supacloud/admin 0.7.9 → 0.7.11

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.
Files changed (2) hide show
  1. package/dist/index.js +33 -13
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -26399,6 +26399,8 @@ async function prepareLocalUpgradeBundle(request) {
26399
26399
  var REMOTE_STAGE_ROOT = "/var/lib/supacloud/upgrade-staging";
26400
26400
  var REMOTE_RUN_ROOT = "/var/lib/supacloud/upgrade-runs";
26401
26401
  var REMOTE_LOG_ROOT = "/var/log/supacloud";
26402
+ var REMOTE_UPLOAD_ROOT = "/var/tmp";
26403
+ var REMOTE_COMMAND_PATH = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
26402
26404
  var POLL_INTERVAL_MS = 2000;
26403
26405
  var STATE_READ_ATTEMPTS = 3;
26404
26406
  var REMOTE_STATE_READ_TIMEOUT_MS = 15000;
@@ -26433,9 +26435,9 @@ function trustedInstalledGithubFunction() {
26433
26435
  ].join(`
26434
26436
  `);
26435
26437
  }
26436
- function remotePaths(runId) {
26438
+ function buildRemoteUpgradePaths(runId) {
26437
26439
  return {
26438
- drop: `/tmp/.supacloud-upgrade-upload-${runId}`,
26440
+ drop: `${REMOTE_UPLOAD_ROOT}/.supacloud-upgrade-upload-${runId}`,
26439
26441
  stage: `${REMOTE_STAGE_ROOT}/${runId}`,
26440
26442
  status: `${REMOTE_RUN_ROOT}/${runId}.status`,
26441
26443
  log: `${REMOTE_LOG_ROOT}/upgrade-${runId}.log`,
@@ -26457,11 +26459,12 @@ function buildRemotePreflightScript() {
26457
26459
  const capabilityFlags = STRICT_GITHUB_CAPABILITY_FLAGS.join(" ");
26458
26460
  return [
26459
26461
  "set -euo pipefail",
26460
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
26462
+ `PATH=${REMOTE_COMMAND_PATH}`,
26461
26463
  "export PATH",
26462
26464
  trustedInstalledGithubFunction(),
26463
26465
  "test -d /run/systemd/system || { echo 'systemd is not the active init system' >&2; exit 1; }",
26464
- 'for tool in systemctl systemd-run sha256sum stat realpath tar file find sort awk grep timeout flock; do command -v "$tool" >/dev/null 2>&1 || { echo "Required local-upgrade tool is missing: $tool" >&2; exit 127; }; done',
26466
+ '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',
26467
+ "tail -n 0 -- /dev/null >/dev/null 2>&1 || { echo 'A tail implementation with -n and -- support is required' >&2; exit 1; }",
26465
26468
  "systemd-run --help | grep -Eq -- '(^|[[:space:]])--collect([=[:space:]]|$)' || { echo 'systemd-run --collect is required' >&2; exit 1; }",
26466
26469
  "test -d /run/lock || { echo '/run/lock is unavailable' >&2; exit 1; }",
26467
26470
  "test -d /var/lib/supacloud || { echo '/var/lib/supacloud is unavailable' >&2; exit 1; }",
@@ -26492,9 +26495,19 @@ function requiredRemoteBytes(bundle) {
26492
26495
  const transferBytes = [...bundle.files, ...bundle.verifierArchive ? [bundle.verifierArchive] : []].reduce((total, upload) => total + upload.size, 0);
26493
26496
  return transferBytes * 3 + 512 * 1024 * 1024;
26494
26497
  }
26498
+ function remoteUploadRootGate() {
26499
+ return [
26500
+ `UPLOAD_ROOT=${quoteShell2(REMOTE_UPLOAD_ROOT)}`,
26501
+ `test -d "$UPLOAD_ROOT" && test ! -L "$UPLOAD_ROOT" || { echo 'Remote upload root must be a directory, not a symlink' >&2; exit 1; }`,
26502
+ `test "$(stat -c '%u' "$UPLOAD_ROOT")" = 0 || { echo 'Remote upload root must be owned by root' >&2; exit 1; }`,
26503
+ `UPLOAD_ROOT_MODE=$(stat -c '%a' "$UPLOAD_ROOT")`,
26504
+ `case "$UPLOAD_ROOT_MODE" in [0-7]|[0-7][0-7]|[0-7][0-7][0-7]|[0-7][0-7][0-7][0-7]) ;; *) echo 'Remote upload root has invalid permission bits' >&2; exit 1 ;; esac`,
26505
+ "(( (8#$UPLOAD_ROOT_MODE & 01000) != 0 )) || { echo 'Remote upload root must set the sticky bit' >&2; exit 1; }",
26506
+ `test -w "$UPLOAD_ROOT" && test -x "$UPLOAD_ROOT" || { echo 'Remote upload root is not writable and searchable by the SSH user' >&2; exit 1; }`
26507
+ ];
26508
+ }
26495
26509
  function buildPrepareDropCommand(paths, bundle) {
26496
26510
  const directories = [
26497
- paths.drop,
26498
26511
  `${paths.drop}/bundle`,
26499
26512
  `${paths.drop}/bundle/management-api`,
26500
26513
  `${paths.drop}/bundle/edge-runtime`
@@ -26505,10 +26518,12 @@ function buildPrepareDropCommand(paths, bundle) {
26505
26518
  return [
26506
26519
  "set -euo pipefail",
26507
26520
  "umask 077",
26508
- `test ! -e ${quoteShell2(paths.drop)} && test ! -L ${quoteShell2(paths.drop)} || { echo 'Remote upload drop already exists' >&2; exit 1; }`,
26509
- "TMP_AVAILABLE_KB=$(df -Pk /tmp | awk 'NR == 2 { print $4 }')",
26521
+ ...remoteUploadRootGate(),
26522
+ `DROP=${quoteShell2(paths.drop)}`,
26523
+ `UPLOAD_AVAILABLE_KB=$(df -Pk "$UPLOAD_ROOT" | awk 'NR == 2 { print $4 }')`,
26510
26524
  "VAR_AVAILABLE_KB=$(df -Pk /var/lib/supacloud | awk 'NR == 2 { print $4 }')",
26511
- `test "${"$"}TMP_AVAILABLE_KB" -ge ${Math.ceil(requiredBytes / 1024)} && test "${"$"}VAR_AVAILABLE_KB" -ge ${Math.ceil(requiredBytes / 1024)} || { echo 'Insufficient remote disk space for verified upgrade staging' >&2; exit 1; }`,
26525
+ `test "${"$"}UPLOAD_AVAILABLE_KB" -ge ${Math.ceil(requiredBytes / 1024)} && test "${"$"}VAR_AVAILABLE_KB" -ge ${Math.ceil(requiredBytes / 1024)} || { echo 'Insufficient remote disk space for verified upgrade staging' >&2; exit 1; }`,
26526
+ `mkdir -m 700 -- "$DROP" || { echo 'Unable to create exclusive remote upload drop' >&2; exit 1; }`,
26512
26527
  `install -d -m 700 ${directories.map(quoteShell2).join(" ")}`
26513
26528
  ].join(`
26514
26529
  `);
@@ -26573,7 +26588,7 @@ function upgradeScriptSetup(paths) {
26573
26588
  "#!/usr/bin/env bash",
26574
26589
  "set -euo pipefail",
26575
26590
  "umask 077",
26576
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
26591
+ `PATH=${REMOTE_COMMAND_PATH}`,
26577
26592
  "export PATH",
26578
26593
  `STAGE=${quoteShell2(paths.stage)}`,
26579
26594
  `STATUS=${quoteShell2(paths.status)}`,
@@ -26876,9 +26891,11 @@ async function observeRemoteState(ssh, paths, observation) {
26876
26891
  }
26877
26892
  async function remoteLogTail(ssh, paths) {
26878
26893
  const script = [
26894
+ `PATH=${REMOTE_COMMAND_PATH}`,
26895
+ "export PATH",
26879
26896
  `LOG=${quoteShell2(paths.log)}`,
26880
26897
  `test -f "$LOG" && test ! -L "$LOG" || { echo 'Remote upgrade log is not a regular file' >&2; exit 1; }`,
26881
- 'tail -80 -- "$LOG"'
26898
+ 'tail -n 80 -- "$LOG"'
26882
26899
  ].join(`
26883
26900
  `);
26884
26901
  const output = await ssh.exec(rootCommand(script), 15000);
@@ -26924,6 +26941,9 @@ function remoteEvidence(paths) {
26924
26941
  function remoteReconciliationFailure(message, failures, paths) {
26925
26942
  return new RemoteUpgradeReconciliationError(failures.map((failure) => operationError(failure, message)), `${message}; reconcile remote evidence at ${remoteEvidence(paths)}; do not retry blindly`);
26926
26943
  }
26944
+ function buildUploadDropCleanupFailure(transferFailure, cleanupFailure, paths) {
26945
+ return remoteReconciliationFailure("Local upgrade failed and upload-drop cleanup did not complete", [transferFailure, cleanupFailure], paths);
26946
+ }
26927
26947
  function failureRequiresRemoteReconciliation(error) {
26928
26948
  return error instanceof RemoteUpgradeReconciliationError;
26929
26949
  }
@@ -27048,7 +27068,7 @@ async function awaitRemoteUpgrade(ssh, paths) {
27048
27068
  }
27049
27069
  async function executeLocalUpgradeTransfer(ssh, request) {
27050
27070
  const runId = randomUUID3();
27051
- const paths = remotePaths(runId);
27071
+ const paths = buildRemoteUpgradePaths(runId);
27052
27072
  const preflight = await remoteUpgradePreflight(ssh);
27053
27073
  const bundle = await prepareLocalUpgradeBundle({ ...preflight, ...request });
27054
27074
  let adopted = false;
@@ -27068,7 +27088,7 @@ async function executeLocalUpgradeTransfer(ssh, request) {
27068
27088
  try {
27069
27089
  await cleanupRemoteDrop(ssh, paths);
27070
27090
  } catch (cleanupError) {
27071
- transferError = new AggregateError([transferError, cleanupError], "Local upgrade failed and upload-drop cleanup did not complete");
27091
+ transferError = buildUploadDropCleanupFailure(transferError, cleanupError, paths);
27072
27092
  }
27073
27093
  }
27074
27094
  throw transferError;
@@ -28964,7 +28984,7 @@ Actions: routes, upsert_route, update_route, delete_route, config, get_certifica
28964
28984
  // package.json
28965
28985
  var package_default = {
28966
28986
  name: "@supacloud/admin",
28967
- version: "0.7.9",
28987
+ version: "0.7.11",
28968
28988
  description: "Platform administration CLI for SupaCloud operators",
28969
28989
  type: "module",
28970
28990
  main: "./dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supacloud/admin",
3
- "version": "0.7.9",
3
+ "version": "0.7.11",
4
4
  "description": "Platform administration CLI for SupaCloud operators",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",