From b61db9626cf9a1b3e50a855dd7e287dd79d54422 Mon Sep 17 00:00:00 2001 From: Michael Heller <21163552+mdheller@users.noreply.github.com> Date: Tue, 16 Jun 2026 16:32:21 -0400 Subject: [PATCH] =?UTF-8?q?enroll:=20R15=20=E2=80=94=20||=20die=20on=20mkt?= =?UTF-8?q?emp,=20sed=20-i,=20write=5Fenroll=5Fnix,=20katello-setup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seven LOW findings: - mktemp (x3 at lines 403, 407, 723): || die if /tmp or SOURCEOS_DIR is full. - sed -i (x2): || die on the sed command itself. The existing post-grep checks only catch "sed exited 0 but changed nothing"; a non-zero sed exit (e.g. disk full during in-place temp file write) would previously fire set -e silently. - write_enroll_nix: wrap heredoc in { } || die and add || die to mv. Call site already had no guard because the function had no internal die calls. - katello-sourceos-setup.sh: add existence check (|| die) before invoking it and || die on the bash call itself so API failures surface a clear message. - _KATELLO_RUNNING / _KATELLO_FINAL docker ps pipelines: append || echo 0 so that a Docker daemon crash between `up -d` and the count check does not fire set -e silently; the count falls to 0 and the existing die guard triggers. - printf > PLAINTEXT: || die on the write to the sops plaintext temp file. --- scripts/enroll.sh | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/scripts/enroll.sh b/scripts/enroll.sh index 38ef9e3..dfbb1cc 100755 --- a/scripts/enroll.sh +++ b/scripts/enroll.sh @@ -90,7 +90,8 @@ write_enroll_nix() { local signing_pub="$1" harmonia_pub_key="$2" # Write to a temp file then atomically rename so a partial write never leaves # a syntactically broken enroll.nix that silently poisons the next rebuild. - cat > "${ENROLL_NIX}.tmp" < "${ENROLL_NIX}.tmp" </dev/null | wc -l | tr -d ' ' || echo 0) [[ "${_KATELLO_RUNNING}" -ge 1 ]] || \ die "docker compose up -d returned 0 but no katello containers are running. Diagnose: docker-compose -f ${COMPOSE_FILE} logs @@ -370,9 +375,12 @@ ok "Foreman+Katello ready ($(elapsed))" step 5 "Katello content structure" +[[ -f "${REPO_ROOT}/scripts/katello-sourceos-setup.sh" ]] || \ + die "katello-sourceos-setup.sh not found at ${REPO_ROOT}/scripts/ — is the repo checkout complete?" FOREMAN_URL="${KATELLO_URL}" FOREMAN_USER="${KATELLO_USER}" \ FOREMAN_PASSWORD="${KATELLO_PASSWORD}" ORG="${ORG}" \ -bash "${REPO_ROOT}/scripts/katello-sourceos-setup.sh" +bash "${REPO_ROOT}/scripts/katello-sourceos-setup.sh" || \ + die "katello-sourceos-setup.sh failed — check Katello API at ${KATELLO_URL} and logs above" ok "Org, product, repos, content view ready ($(elapsed))" @@ -400,14 +408,17 @@ if [[ "${_needs_encrypt}" -eq 1 ]]; then # Create both temp files and set a single combined trap before writing anything. # Two separate traps (first PLAINTEXT, then adding _SECRETS_TMP) leave a window # between mktemp and the second trap where _SECRETS_TMP is not covered on exit. - PLAINTEXT=$(mktemp /tmp/sourceos-secrets-XXXXXX.yaml) + PLAINTEXT=$(mktemp /tmp/sourceos-secrets-XXXXXX.yaml) || \ + die "mktemp failed — is /tmp full or noexec? Check: df -h /tmp" # Write to a temp file on the same filesystem so the final mv is atomic. # A plain `> ${SECRETS_YAML}` would truncate the file before sops runs; # if sops then fails the file is empty and subsequent re-runs skip encryption. - _SECRETS_TMP=$(mktemp "${SOURCEOS_DIR}/secrets-XXXXXX.yaml.tmp") + _SECRETS_TMP=$(mktemp "${SOURCEOS_DIR}/secrets-XXXXXX.yaml.tmp") || \ + die "mktemp failed in ${SOURCEOS_DIR} — check disk space and permissions" chmod 600 "${_SECRETS_TMP}" trap "rm -f ${PLAINTEXT} ${_SECRETS_TMP}" EXIT - printf 'katello-password: "%s"\n' "${KATELLO_PASSWORD}" > "${PLAINTEXT}" + printf 'katello-password: "%s"\n' "${KATELLO_PASSWORD}" > "${PLAINTEXT}" || \ + die "Failed to write plaintext secrets to ${PLAINTEXT} — check /tmp disk space" SOPS_AGE_RECIPIENTS="${AGE_PUBKEY}" sops --encrypt "${PLAINTEXT}" > "${_SECRETS_TMP}" || \ die "sops --encrypt failed — check AGE_PUBKEY format and sops version. AGE_PUBKEY: ${AGE_PUBKEY}" @@ -691,7 +702,7 @@ fi # Verify Katello containers are still running after the long enrollment. # They can be OOM-killed during nix build (steps 10–11) without the script noticing. -_KATELLO_FINAL=$(docker ps --filter "name=katello" --format "{{.Names}}" 2>/dev/null | wc -l | tr -d ' ') +_KATELLO_FINAL=$(docker ps --filter "name=katello" --format "{{.Names}}" 2>/dev/null | wc -l | tr -d ' ' || echo 0) if [[ "${_KATELLO_FINAL}" -ge 1 ]]; then ok "Katello containers: ${_KATELLO_FINAL} running" else @@ -720,7 +731,8 @@ if systemctl is-active --quiet nginx 2>/dev/null; then fi # Cryptographically verify the minisig, not just that the endpoint responds. # A stale or wrong-key sig would pass an existence check but fail here. - _SIG_TMP=$(mktemp /tmp/nix-cache-info-XXXXX.minisig) + _SIG_TMP=$(mktemp /tmp/nix-cache-info-XXXXX.minisig) || \ + die "mktemp failed — is /tmp full or noexec? Check: df -h /tmp" # Trap ensures cleanup even if set -e fires inside this block. trap "rm -f ${_SIG_TMP}" EXIT if curl -fsSk http://127.0.0.1:8101/nix-cache-info.minisig -o "${_SIG_TMP}" 2>/dev/null && \