@supacloud/admin 0.7.4 → 0.7.6
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/index.js +59 -10
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25622,7 +25622,7 @@ SUPACLOUD_GITHUB_REPOSITORY="\${SUPACLOUD_GITHUB_REPOSITORY:-zuohuadong/supaclou
|
|
|
25622
25622
|
SUPACLOUD_RELEASES_API="\${SUPACLOUD_RELEASES_API:-https://api.github.com/repos/\${SUPACLOUD_GITHUB_REPOSITORY}/releases}"
|
|
25623
25623
|
SUPACLOUD_ATTESTATION_SIGNER_WORKFLOW="\${SUPACLOUD_ATTESTATION_SIGNER_WORKFLOW:-\${SUPACLOUD_GITHUB_REPOSITORY}/.github/workflows/release-please.yml}"
|
|
25624
25624
|
SUPACLOUD_GH_VERSION="\${SUPACLOUD_GH_VERSION:-2.96.0}"
|
|
25625
|
-
SUPACLOUD_GH_MIN_VERSION="\${SUPACLOUD_GH_MIN_VERSION:-2.
|
|
25625
|
+
SUPACLOUD_GH_MIN_VERSION="\${SUPACLOUD_GH_MIN_VERSION:-2.68.0}"
|
|
25626
25626
|
SUPACLOUD_GH_AMD64_SHA256="\${SUPACLOUD_GH_AMD64_SHA256:-83d5c2ccad5498f58bf6368acb1ab32588cf43ab3a4b1c301bf36328b1c8bd60}"
|
|
25627
25627
|
SUPACLOUD_GH_ARM64_SHA256="\${SUPACLOUD_GH_ARM64_SHA256:-06f86ec7103d41993b76cd78072f43595c34aaa56506d971d9860e67140bf909}"
|
|
25628
25628
|
|
|
@@ -25951,13 +25951,49 @@ supacloud_record_integrity_mode() {
|
|
|
25951
25951
|
chmod 600 "$record_file" 2>/dev/null || true
|
|
25952
25952
|
}
|
|
25953
25953
|
|
|
25954
|
-
|
|
25954
|
+
supacloud_fetch_attestation_bundle() {
|
|
25955
|
+
local artifact_file="$1"
|
|
25956
|
+
local bundle_file="$2"
|
|
25957
|
+
local digest response
|
|
25958
|
+
digest=$(sha256sum "$artifact_file" | awk '{print $1}') || return 1
|
|
25959
|
+
[[ "$digest" =~ ^[0-9a-fA-F]{64}$ ]] || {
|
|
25960
|
+
echo "Unable to calculate the artifact digest for attestation lookup" >&2
|
|
25961
|
+
return 1
|
|
25962
|
+
}
|
|
25963
|
+
digest=$(printf '%s' "$digest" | tr '[:upper:]' '[:lower:]')
|
|
25964
|
+
response=$(supacloud_fetch_release_json \\
|
|
25965
|
+
"https://api.github.com/repos/\${SUPACLOUD_GITHUB_REPOSITORY}/attestations/sha256:\${digest}") || {
|
|
25966
|
+
echo "Unable to download the public GitHub artifact attestation bundle" >&2
|
|
25967
|
+
return 1
|
|
25968
|
+
}
|
|
25969
|
+
if ! jq -ce '
|
|
25970
|
+
.attestations
|
|
25971
|
+
| if type != "array" or length == 0 or any(.[]; (.bundle | type) != "object")
|
|
25972
|
+
then error("no valid attestation bundles returned")
|
|
25973
|
+
else .[].bundle
|
|
25974
|
+
end
|
|
25975
|
+
' <<< "$response" > "$bundle_file"; then
|
|
25976
|
+
echo "GitHub artifact attestation response did not contain a valid bundle" >&2
|
|
25977
|
+
return 1
|
|
25978
|
+
fi
|
|
25979
|
+
}
|
|
25980
|
+
|
|
25981
|
+
supacloud_verify_attestation() (
|
|
25955
25982
|
local artifact_file="$1"
|
|
25956
25983
|
if supacloud_attestation_verifier_available; then
|
|
25957
|
-
local verification_output
|
|
25984
|
+
local verification_output bundle_dir bundle_file
|
|
25985
|
+
bundle_dir=$(mktemp -d "\${TMPDIR:-/tmp}/supacloud-attestation.XXXXXX") || return 1
|
|
25986
|
+
trap 'rm -rf -- "$bundle_dir"' EXIT
|
|
25987
|
+
trap 'trap - EXIT HUP INT TERM; rm -rf -- "$bundle_dir"; exit 1' HUP INT TERM
|
|
25988
|
+
bundle_file="\${bundle_dir}/bundle.jsonl"
|
|
25989
|
+
if ! supacloud_fetch_attestation_bundle "$artifact_file" "$bundle_file"; then
|
|
25990
|
+
return 1
|
|
25991
|
+
fi
|
|
25958
25992
|
if ! verification_output=$(gh attestation verify "$artifact_file" \\
|
|
25993
|
+
--bundle "$bundle_file" \\
|
|
25959
25994
|
--repo "$SUPACLOUD_GITHUB_REPOSITORY" \\
|
|
25960
|
-
--signer-workflow "$SUPACLOUD_ATTESTATION_SIGNER_WORKFLOW"
|
|
25995
|
+
--signer-workflow "$SUPACLOUD_ATTESTATION_SIGNER_WORKFLOW" \\
|
|
25996
|
+
--source-ref "refs/heads/main" 2>&1); then
|
|
25961
25997
|
echo "GitHub artifact attestation verification failed: \${verification_output}" >&2
|
|
25962
25998
|
return 1
|
|
25963
25999
|
fi
|
|
@@ -25973,15 +26009,18 @@ supacloud_verify_attestation() {
|
|
|
25973
26009
|
|
|
25974
26010
|
echo "Artifact attestation verification is required, but gh attestation verify is unavailable. Install GitHub CLI or explicitly set SUPACLOUD_ALLOW_UNVERIFIED_RELEASE=true for emergency break-glass use." >&2
|
|
25975
26011
|
return 1
|
|
25976
|
-
|
|
26012
|
+
)
|
|
25977
26013
|
|
|
25978
26014
|
supacloud_attestation_verifier_available() {
|
|
25979
|
-
local version
|
|
26015
|
+
local version help
|
|
25980
26016
|
command -v gh >/dev/null 2>&1 || return 1
|
|
25981
26017
|
version=$(supacloud_gh_version)
|
|
25982
26018
|
[[ -n "$version" ]] || return 1
|
|
25983
26019
|
supacloud_version_at_least "$version" "$SUPACLOUD_GH_MIN_VERSION" || return 1
|
|
25984
|
-
gh attestation verify --help 2>&1
|
|
26020
|
+
help=$(gh attestation verify --help 2>&1) || return 1
|
|
26021
|
+
grep -Eq -- '(^|[[:space:]])--bundle([=[:space:]]|$)' <<< "$help" || return 1
|
|
26022
|
+
grep -Eq -- '(^|[[:space:]])--signer-workflow([=[:space:]]|$)' <<< "$help" || return 1
|
|
26023
|
+
grep -Eq -- '(^|[[:space:]])--source-ref([=[:space:]]|$)' <<< "$help"
|
|
25985
26024
|
}
|
|
25986
26025
|
|
|
25987
26026
|
supacloud_download_release_asset() (
|
|
@@ -26136,6 +26175,12 @@ function componentPreflightCommands(request) {
|
|
|
26136
26175
|
`test "$EDGE_RUNTIME_MODE_VALUE" = external || { echo 'Edge Runtime component upgrade supports persisted external mode only' >&2; exit 1; }`
|
|
26137
26176
|
] : [];
|
|
26138
26177
|
}
|
|
26178
|
+
function signalSafeCleanupTraps(cleanupCommand) {
|
|
26179
|
+
return [
|
|
26180
|
+
`trap '${cleanupCommand}' EXIT`,
|
|
26181
|
+
`trap 'trap - EXIT HUP INT TERM; ${cleanupCommand}; exit 1' HUP INT TERM`
|
|
26182
|
+
];
|
|
26183
|
+
}
|
|
26139
26184
|
function buildRootUpgradeScript(request) {
|
|
26140
26185
|
const envAssignments = upgradeEnvAssignments(request);
|
|
26141
26186
|
return [
|
|
@@ -26144,12 +26189,12 @@ function buildRootUpgradeScript(request) {
|
|
|
26144
26189
|
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
|
26145
26190
|
"export PATH",
|
|
26146
26191
|
"unset SUPACLOUD_ALLOW_UNVERIFIED_RELEASE SUPACLOUD_GITHUB_REPOSITORY SUPACLOUD_RELEASES_API SUPACLOUD_ATTESTATION_SIGNER_WORKFLOW SUPACLOUD_GH_VERSION SUPACLOUD_GH_MIN_VERSION SUPACLOUD_GH_AMD64_SHA256 SUPACLOUD_GH_ARM64_SHA256 GH_PROXY",
|
|
26147
|
-
request.githubProxy ? `export SUPACLOUD_GITHUB_PROXY=${quoteEnvValue(request.githubProxy)}` : "unset SUPACLOUD_GITHUB_PROXY",
|
|
26192
|
+
request.githubProxy ? `export SUPACLOUD_GITHUB_PROXY=${quoteEnvValue(request.githubProxy)}` : "unset SUPACLOUD_GITHUB_PROXY SUPACLOUD_GITHUB_PROXIES",
|
|
26148
26193
|
'for tool in curl jq file sha256sum tar; do command -v "$tool" >/dev/null 2>&1 || { echo "Required upgrade tool is missing: $tool" >&2; exit 127; }; done',
|
|
26149
26194
|
"test -x /usr/local/bin/supacloud || { echo 'SupaCloud binary not found at /usr/local/bin/supacloud; run ssh install first.' >&2; exit 127; }",
|
|
26150
26195
|
...componentPreflightCommands(request),
|
|
26151
26196
|
"STAGED_MANAGEMENT=''",
|
|
26152
|
-
|
|
26197
|
+
...signalSafeCleanupTraps('test -z "$STAGED_MANAGEMENT" || rm -f "$STAGED_MANAGEMENT"'),
|
|
26153
26198
|
`source ${quoteEnvValue(request.helperPath)}`,
|
|
26154
26199
|
"if ! supacloud_attestation_verifier_available; then supacloud_install_pinned_gh /usr/local/bin/gh; fi",
|
|
26155
26200
|
"supacloud_attestation_verifier_available || { echo 'Pinned GitHub attestation verifier is unavailable' >&2; exit 1; }",
|
|
@@ -26160,7 +26205,11 @@ function buildRootUpgradeScript(request) {
|
|
|
26160
26205
|
}
|
|
26161
26206
|
function buildOfficialUpgradeCommand(request) {
|
|
26162
26207
|
const rootScript = buildRootUpgradeScript(request);
|
|
26163
|
-
return
|
|
26208
|
+
return [
|
|
26209
|
+
"set -e",
|
|
26210
|
+
...signalSafeCleanupTraps(`rm -f ${request.helperPath}`),
|
|
26211
|
+
'if [ "$(id -u)" -eq 0 ]; then ' + `bash -c ${quoteEnvValue(rootScript)}; ` + "else sudo -n true; " + `sudo -n bash -c ${quoteEnvValue(rootScript)}; fi`
|
|
26212
|
+
].join("; ");
|
|
26164
26213
|
}
|
|
26165
26214
|
async function removeRemoteUpgradeHelper(ssh, helperPath) {
|
|
26166
26215
|
const cleanup = await ssh.exec(`rm -f ${quoteEnvValue(helperPath)}`);
|