fix: a release job uses only the key it is given, never the runner's own
Measured on a throwaway Gitea: with the key secret unset, Preview's publish job would have fallen back to the runner machine's own ssh configuration — on the development VM, the production publish key — and published a throwaway 9.9.9 to the real server. It was cancelled before it ran. And with the key set, the job wrote over the runner account's own ~/.ssh/config and known_hosts. Now, under Actions, a job without RELEASE_SSH_KEY stops; with it, the key, its known_hosts and an ssh configuration live in the job's own directory and every ssh and rsync goes through `ssh -F` (RELEASE_SSH_CONFIG in release-lib), which reads nothing else. The key is deleted when the job ends. By hand, nothing changes. Also records the end-to-end measurements of Release 1 and of Preview's gate job in docs/releasing.md. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
22f25854aa
commit
14291fde37
+28
-11
@@ -30,7 +30,8 @@
|
||||
# release. preview and stable also need the update server, through
|
||||
# RELEASE_SSH_KEY (the private key's text), RELEASE_SSH_KNOWN_HOSTS,
|
||||
# RELEASE_SSH_ADDRESS and RELEASE_SSH_USER, which only the release runner's
|
||||
# jobs are given. Run by hand, ~/.ssh/config is used as it always was.
|
||||
# jobs are given, and without which a job refuses to publish. Run by hand
|
||||
# (no GITHUB_ACTIONS), ~/.ssh/config is used as it always was.
|
||||
set -euo pipefail
|
||||
shopt -s inherit_errexit
|
||||
|
||||
@@ -109,30 +110,46 @@ fetch() {
|
||||
printf '%s\n' "$WORK/$name"
|
||||
}
|
||||
|
||||
# The update server, for the release runner. The key is written to a file
|
||||
# only this job can read, and is gone when the job's container is.
|
||||
# The update server, for the release runner: the key it was given, in a
|
||||
# configuration of its own (RELEASE_SSH_CONFIG, used with ssh -F), so
|
||||
# nothing on the runner's own disk is read or overwritten, and the key is
|
||||
# deleted when this ends. Under Actions there is no other way: a job
|
||||
# without the key stops, rather than reach for whatever credentials the
|
||||
# machine it runs on happens to hold. Measured: on the development VM,
|
||||
# which holds the production publish key, the fallback would have
|
||||
# published a throwaway build to the real server.
|
||||
ssh_setup() {
|
||||
local dir="$WORK/ssh"
|
||||
|
||||
if [[ -z "${RELEASE_SSH_KEY:-}" ]]; then
|
||||
echo "release-ci: no RELEASE_SSH_KEY; using this machine's own ssh configuration" >&2
|
||||
if [[ -n "${GITHUB_ACTIONS:-}${GITEA_ACTIONS:-}" ]]; then
|
||||
fail "no RELEASE_SSH_KEY: set the CLASSROOM_UPDATES_SSH_KEY secret. A job never uses the runner's own ssh keys"
|
||||
fi
|
||||
|
||||
echo "release-ci: no RELEASE_SSH_KEY; by hand, so this machine's own ssh configuration" >&2
|
||||
return
|
||||
fi
|
||||
|
||||
[[ -n "${RELEASE_SSH_KNOWN_HOSTS:-}" ]] || fail "RELEASE_SSH_KNOWN_HOSTS is required with RELEASE_SSH_KEY"
|
||||
|
||||
mkdir -p "$HOME/.ssh"
|
||||
chmod 700 "$HOME/.ssh"
|
||||
(umask 077; printf '%s\n' "$RELEASE_SSH_KEY" > "$HOME/.ssh/release-key")
|
||||
printf '%s\n' "$RELEASE_SSH_KNOWN_HOSTS" > "$HOME/.ssh/known_hosts"
|
||||
cat > "$HOME/.ssh/config" <<EOF
|
||||
mkdir -p "$dir"
|
||||
chmod 700 "$dir"
|
||||
(umask 077; printf '%s\n' "$RELEASE_SSH_KEY" > "$dir/key")
|
||||
trap 'rm -f "$WORK/ssh/key"' EXIT
|
||||
printf '%s\n' "$RELEASE_SSH_KNOWN_HOSTS" > "$dir/known_hosts"
|
||||
cat > "$dir/config" <<EOF
|
||||
Host $RELEASE_HOST
|
||||
HostName ${RELEASE_SSH_ADDRESS:?RELEASE_SSH_ADDRESS is required}
|
||||
User ${RELEASE_SSH_USER:?RELEASE_SSH_USER is required}
|
||||
IdentityFile $HOME/.ssh/release-key
|
||||
IdentityFile $dir/key
|
||||
IdentitiesOnly yes
|
||||
UserKnownHostsFile $dir/known_hosts
|
||||
GlobalKnownHostsFile /dev/null
|
||||
StrictHostKeyChecking yes
|
||||
BatchMode yes
|
||||
EOF
|
||||
chmod 600 "$HOME/.ssh/config"
|
||||
chmod 600 "$dir/config"
|
||||
export RELEASE_SSH_CONFIG="$dir/config"
|
||||
}
|
||||
|
||||
# Every package on the server and its checksum, to prove afterwards that
|
||||
|
||||
Reference in New Issue
Block a user