Pin Terra through repos.override.d so terra-release updates stop undoing it
This commit is contained in:
1 parent
042885f113
commit
c6fb2fa767
3 files changed
+94
-51
No files matched your search
@@ -159,8 +159,12 @@ installed. Its effective `terra` configuration reported `gpgcheck = 1`,
|
||||
`pkg_gpgcheck = 1`, and `repo_gpgcheck = 1`; no GPG-bypass option was used.
|
||||
The package's own `/etc/yum.repos.d/terra.repo` uses its Terra metalink and
|
||||
`RPM-GPG-KEY-terra44`. That differs from Panama's deliberately staged local
|
||||
key/base-URL file in `install-packages`, which replaces the release-generated
|
||||
file only after this verified bootstrap step.
|
||||
key and base URL. `install-packages` applies those after this verified
|
||||
bootstrap step as `/etc/dnf/repos.override.d/80-panama-terra.repo`, which dnf
|
||||
lays over the package's file. The pin does not edit `terra.repo` itself,
|
||||
because terra-release replaces that file on every update. Release 44-11 did
|
||||
so on 2026-10-28, shipping `repo_gpgcheck=0`, and every Panama machine
|
||||
stopped installing packages until the pin moved to the override directory.
|
||||
|
||||
Although the command runner returned after 30 seconds while DNF was still
|
||||
loading metadata, Podman's retained event log records the exact command's
|
||||
|
||||
@@ -729,7 +729,8 @@ _publish_repository_pair() {
|
||||
|
||||
# Reads the gpgkey of the single enabled Terra identity out of dnf's effective
|
||||
# configuration, applying the structural safety rules either way: one enabled
|
||||
# identity, named terra, with every signature check turned on.
|
||||
# identity, named terra, with package signature checks turned on (and, in the
|
||||
# pinned form, repository metadata checks too).
|
||||
#
|
||||
# With require_pinned set it additionally demands Panama's own reviewed baseurl
|
||||
# and key path. Without it, the answer is just "what trust root is this machine
|
||||
@@ -772,7 +773,11 @@ _effective_terra_key() {
|
||||
bad = 1
|
||||
}
|
||||
if (values["gpgcheck"] != "1" || values["pkg_gpgcheck"] != "1" \
|
||||
|| values["repo_gpgcheck"] != "1" || values["gpgkey"] == "") bad = 1
|
||||
|| values["gpgkey"] == "") bad = 1
|
||||
# Metadata signing is part of the pin, not of what adoption accepts:
|
||||
# terra-release ships repo_gpgcheck=0, and the override adoption
|
||||
# writes turns it back on.
|
||||
if (require_pinned != "" && values["repo_gpgcheck"] != "1") bad = 1
|
||||
trusted_key = values["gpgkey"]
|
||||
}
|
||||
BEGIN {
|
||||
@@ -864,10 +869,12 @@ _terra_effective_status() {
|
||||
#
|
||||
# The trust root is the signing key, not the URL it is served from. A machine
|
||||
# that installed Terra the way Terra documents has terra-release's own repo
|
||||
# file: a metalink instead of the reviewed baseurl, and the key at
|
||||
# RPM-GPG-KEY-terra44 rather than Panama's renamed copy. Every signature check
|
||||
# is already on, and that key is the same fingerprint this repository reviewed
|
||||
# and pinned. Cosmetics, in other words -- not a compromised trust root.
|
||||
# file: a metalink instead of the reviewed baseurl, the key at
|
||||
# RPM-GPG-KEY-terra44 rather than Panama's renamed copy, and (since
|
||||
# terra-release 44-11) repo_gpgcheck=0. Package signature checks are on, and
|
||||
# that key is the same fingerprint this repository reviewed and pinned. The pin
|
||||
# adoption writes restores metadata checking, so none of that is a compromised
|
||||
# trust root.
|
||||
#
|
||||
# Refusing it outright built a gate with no door. install_terra_repository
|
||||
# declined to touch a machine terra-release had already reached, so an ordinary
|
||||
@@ -1002,33 +1009,51 @@ install_rpmfusion_repositories() {
|
||||
# trust root rolls back. The effective state is re-read afterwards, because the
|
||||
# only acceptable proof that adoption worked is the check that judged it.
|
||||
#
|
||||
# terra-release owns /etc/yum.repos.d/terra.repo, so a later update to that
|
||||
# package restores the stock file. That is fine and deliberate: the next run
|
||||
# adopts it again, which is why adoption has to be repeatable rather than a
|
||||
# one-time migration.
|
||||
# Panama's Terra pin, as a dnf repos.override.d drop-in on top of whatever
|
||||
# /etc/yum.repos.d/terra.repo says. terra-release owns that file and replaces
|
||||
# it on every update (an edited copy is set aside as terra.repo.rpmsave), so a
|
||||
# pin written there lasted only until the next terra-release release. Nothing
|
||||
# owns the override directory, and its values win over the repo file's.
|
||||
TERRA_OVERRIDE=/etc/dnf/repos.override.d/80-panama-terra.repo
|
||||
|
||||
_write_terra_pin() {
|
||||
printf '%s\n' \
|
||||
'[terra]' \
|
||||
'name=Panama reviewed Terra 44' \
|
||||
"baseurl=${INSTALLER_PROVENANCE[TERRA_BASEURL]}" \
|
||||
'metalink=' \
|
||||
'mirrorlist=' \
|
||||
'enabled=1' \
|
||||
'gpgcheck=1' \
|
||||
'repo_gpgcheck=1' \
|
||||
'gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama' > "$1"
|
||||
chmod 0600 "$1"
|
||||
}
|
||||
|
||||
_ensure_override_dir() {
|
||||
[[ -d "$PANAMA_SYSTEM_ETC/dnf/repos.override.d" ]] && return 0
|
||||
sudo mkdir -p -- /etc/dnf/repos.override.d
|
||||
}
|
||||
|
||||
# A stock terra-release file (or one an older Panama rewrote) gets the pin laid
|
||||
# over it. Adoption stays repeatable: if the override is ever removed, the next
|
||||
# run puts it back.
|
||||
adopt_terra_repository() {
|
||||
local work staged_key staged_repo status=0 effective_status=0
|
||||
work="$(mktemp -d)" || return 1
|
||||
chmod 0700 "$work"
|
||||
staged_key="$work/terra44.asc"
|
||||
staged_repo="$work/terra.repo"
|
||||
staged_repo="$work/80-panama-terra.repo"
|
||||
if ! _stage_reviewed_key "$PANAMA_PATH/setup/provenance/keys/terra44.asc" "$staged_key" \
|
||||
TERRA_FINGERPRINT AE09157A4DE88B497EA1D5D300CDAB43DE226D6F; then
|
||||
rm -rf -- "$work"
|
||||
return 1
|
||||
fi
|
||||
printf '%s\n' \
|
||||
'[terra]' \
|
||||
'name=Panama reviewed Terra 44' \
|
||||
"baseurl=${INSTALLER_PROVENANCE[TERRA_BASEURL]}" \
|
||||
'enabled=1' \
|
||||
'gpgcheck=1' \
|
||||
'repo_gpgcheck=1' \
|
||||
'gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama' > "$staged_repo"
|
||||
chmod 0600 "$staged_repo"
|
||||
_publish_repository_pair \
|
||||
_write_terra_pin "$staged_repo"
|
||||
_ensure_override_dir || status=$?
|
||||
(( status == 0 )) && { _publish_repository_pair \
|
||||
"$staged_key" /etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama \
|
||||
"$staged_repo" /etc/yum.repos.d/terra.repo || status=$?
|
||||
"$staged_repo" "$TERRA_OVERRIDE" || status=$?; }
|
||||
if (( status == 0 )); then
|
||||
_terra_effective_status || effective_status=$?
|
||||
(( effective_status == 0 )) || status="$TERRA_TRUST_FAILURE_STATUS"
|
||||
@@ -1064,7 +1089,7 @@ install_terra_repository() {
|
||||
work="$(mktemp -d)" || return 1
|
||||
chmod 0700 "$work"
|
||||
staged_key="$work/terra44.asc"
|
||||
staged_repo="$work/terra.repo"
|
||||
staged_repo="$work/80-panama-terra.repo"
|
||||
if ! _stage_reviewed_key "$PANAMA_PATH/setup/provenance/keys/terra44.asc" "$staged_key" \
|
||||
TERRA_FINGERPRINT AE09157A4DE88B497EA1D5D300CDAB43DE226D6F; then
|
||||
rm -rf -- "$work"
|
||||
@@ -1074,15 +1099,7 @@ install_terra_repository() {
|
||||
rm -rf -- "$work"
|
||||
return 1
|
||||
}
|
||||
printf '%s\n' \
|
||||
'[terra]' \
|
||||
'name=Panama reviewed Terra 44' \
|
||||
"baseurl=${INSTALLER_PROVENANCE[TERRA_BASEURL]}" \
|
||||
'enabled=1' \
|
||||
'gpgcheck=1' \
|
||||
'repo_gpgcheck=1' \
|
||||
'gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama' > "$staged_repo"
|
||||
chmod 0600 "$staged_repo"
|
||||
_write_terra_pin "$staged_repo"
|
||||
status=0
|
||||
sudo dnf install -y \
|
||||
--repofrompath "terra,${INSTALLER_PROVENANCE[TERRA_BASEURL]}" \
|
||||
@@ -1091,7 +1108,10 @@ install_terra_repository() {
|
||||
--setopt=terra.gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama \
|
||||
terra-release || status=$?
|
||||
if (( status == 0 )); then
|
||||
sudo install -m 0644 "$staged_repo" /etc/yum.repos.d/terra.repo || status=$?
|
||||
_ensure_override_dir || status=$?
|
||||
fi
|
||||
if (( status == 0 )); then
|
||||
sudo install -m 0644 "$staged_repo" "$TERRA_OVERRIDE" || status=$?
|
||||
fi
|
||||
if (( status == 0 )); then
|
||||
effective_status=0
|
||||
|
||||
@@ -901,17 +901,26 @@ if [[ -n "$query" ]]; then
|
||||
wrong-url) mode=override-url ;;
|
||||
stock|stock-wrong-key) mode=stock ;;
|
||||
esac
|
||||
# Adoption rewrites the repository file. Once it is the pinned form the
|
||||
# dump has to say so, or the re-verification adoption performs on itself
|
||||
# could never pass.
|
||||
if [[ "$mode" == stock && -f "$STUB_ETC/yum.repos.d/terra.repo" ]] \
|
||||
&& grep -q '^gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama$' \
|
||||
"$STUB_ETC/yum.repos.d/terra.repo"; then
|
||||
# Adoption and a fresh install write the pin as a repos.override.d
|
||||
# drop-in, which dnf lays over the repository file. Once it is there
|
||||
# the dump has to say so, or the re-verification each performs on
|
||||
# itself could never pass.
|
||||
override="$STUB_ETC/dnf/repos.override.d/80-panama-terra.repo"
|
||||
pinned_override=0
|
||||
if [[ -f "$override" ]] \
|
||||
&& grep -q '^gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama$' "$override" \
|
||||
&& grep -q '^baseurl=https://repos.fyralabs.com/terra44$' "$override" \
|
||||
&& grep -qx 'metalink=' "$override"; then
|
||||
pinned_override=1
|
||||
fi
|
||||
if [[ "$mode" == stock && "$pinned_override" == 1 ]]; then
|
||||
mode=trusted
|
||||
fi
|
||||
if [[ "$mode" == auto && -f "$STUB_ETC/yum.repos.d/terra.repo" ]] \
|
||||
&& grep -q '^baseurl=https://repos.fyralabs.com/terra44$' "$STUB_ETC/yum.repos.d/terra.repo"; then
|
||||
mode=trusted
|
||||
elif [[ "$mode" == auto && "$pinned_override" == 1 ]]; then
|
||||
mode=trusted
|
||||
elif [[ "$mode" == auto ]]; then
|
||||
mode=absent
|
||||
fi
|
||||
@@ -945,7 +954,7 @@ if [[ -n "$query" ]]; then
|
||||
printf 'baseurl = \nenabled = 1\ngpgcheck = 1\n'
|
||||
printf 'gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44\n'
|
||||
printf 'metalink = https://tetsudou.fyralabs.com/metalink?repo=terra44&arch=x86_64\n'
|
||||
printf 'mirrorlist = \npkg_gpgcheck = 1\nrepo_gpgcheck = 1\n'
|
||||
printf 'mirrorlist = \npkg_gpgcheck = 1\nrepo_gpgcheck = 0\n'
|
||||
;;
|
||||
override-url)
|
||||
printf '======== "terra" repository configuration: ========\n'
|
||||
@@ -1150,7 +1159,7 @@ run_installer_function() {
|
||||
cp "$installer_fixture/setup/provenance/keys/flathub.asc" \
|
||||
"$case_root/etc/pki/rpm-gpg/RPM-GPG-KEY-terra44"
|
||||
fi
|
||||
printf '[terra]\nmetalink=https://tetsudou.fyralabs.com/metalink?repo=terra44&arch=$basearch\nenabled=1\ngpgcheck=1\nrepo_gpgcheck=1\ngpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44\n' \
|
||||
printf '[terra]\nmetalink=https://tetsudou.fyralabs.com/metalink?repo=terra44&arch=$basearch\nenabled=1\ngpgcheck=1\nrepo_gpgcheck=0\ngpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44\n' \
|
||||
> "$case_root/etc/yum.repos.d/terra.repo"
|
||||
;;
|
||||
wrong-key)
|
||||
@@ -1663,7 +1672,8 @@ rpm:query:terra-release
|
||||
gpg:fingerprint:AE09157A4DE88B497EA1D5D300CDAB43DE226D6F
|
||||
sudo:install:terra44.asc:/etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama
|
||||
sudo:dnf install -y --repofrompath terra,https://repos.fyralabs.com/terra44 --setopt=terra.pkg_gpgcheck=1 --setopt=terra.repo_gpgcheck=1 --setopt=terra.gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama terra-release
|
||||
sudo:install:terra.repo:/etc/yum.repos.d/terra.repo
|
||||
sudo:mkdir -p -- /etc/dnf/repos.override.d
|
||||
sudo:install:80-panama-terra.repo:/etc/dnf/repos.override.d/80-panama-terra.repo
|
||||
dnf:dump-all:locale=C
|
||||
gpg:fingerprint:AE09157A4DE88B497EA1D5D300CDAB43DE226D6F
|
||||
gpg:fingerprint:AE09157A4DE88B497EA1D5D300CDAB43DE226D6F
|
||||
@@ -1672,10 +1682,12 @@ EXPECTED
|
||||
cmp -s "$installer_fixture/setup/provenance/keys/terra44.asc" \
|
||||
"$test_tmp/cases/terra/etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama" \
|
||||
|| fail 'Terra privileged install did not preserve the fully staged reviewed key'
|
||||
assert_file_bytes "$test_tmp/cases/terra/etc/yum.repos.d/terra.repo" "$(cat <<'EXPECTED'
|
||||
assert_file_bytes "$test_tmp/cases/terra/etc/dnf/repos.override.d/80-panama-terra.repo" "$(cat <<'EXPECTED'
|
||||
[terra]
|
||||
name=Panama reviewed Terra 44
|
||||
baseurl=https://repos.fyralabs.com/terra44
|
||||
metalink=
|
||||
mirrorlist=
|
||||
enabled=1
|
||||
gpgcheck=1
|
||||
repo_gpgcheck=1
|
||||
@@ -1804,9 +1816,12 @@ for mode in nogpg wrong-url wrong-key absent; do
|
||||
done
|
||||
|
||||
# A machine that installed Terra the way Terra documents it. The repository file
|
||||
# is terra-release's own -- a metalink, and the key at its stock path -- so it is
|
||||
# not Panama's pinned form, but it IS the fingerprint this repository reviewed,
|
||||
# with every signature check on. That is an adoption, not a compromise.
|
||||
# is terra-release's own -- a metalink, the key at its stock path, and
|
||||
# repo_gpgcheck=0 as terra-release 44-11 ships it -- so it is not Panama's
|
||||
# pinned form, but it IS the fingerprint this repository reviewed, with package
|
||||
# signature checks on. That is an adoption, not a compromise. The pin goes in a
|
||||
# repos.override.d drop-in, because terra-release replaces its own repo file on
|
||||
# every update and a pin written there did not survive the next one.
|
||||
#
|
||||
# Refusing it was a gate with no door: the ordinary Fedora desktop could never
|
||||
# reach the pinned state, and status 78 then stopped every stage of every run,
|
||||
@@ -1818,13 +1833,17 @@ STUB_TERRA_INSTALLED=1 STUB_TERRA_REPO_MODE=stock \
|
||||
reset_installer_fixture
|
||||
STUB_TERRA_INSTALLED=1 STUB_TERRA_REPO_MODE=stock \
|
||||
expect_success run_installer_function terra-stock-adopt install_terra_repository
|
||||
terra_adopted="$test_tmp/cases/terra-stock-adopt/etc/yum.repos.d/terra.repo"
|
||||
terra_adopted="$test_tmp/cases/terra-stock-adopt/etc/dnf/repos.override.d/80-panama-terra.repo"
|
||||
grep -qx 'baseurl=https://repos.fyralabs.com/terra44' "$terra_adopted" \
|
||||
|| fail 'adoption left Terra off the reviewed baseurl'
|
||||
grep -qx 'gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama' "$terra_adopted" \
|
||||
|| fail 'adoption left Terra off the reviewed key path'
|
||||
grep -q 'metalink' "$terra_adopted" \
|
||||
&& fail 'adoption kept the metalink it was supposed to replace'
|
||||
grep -qx 'metalink=' "$terra_adopted" \
|
||||
|| fail 'adoption did not clear the metalink it was supposed to replace'
|
||||
grep -qx 'repo_gpgcheck=1' "$terra_adopted" \
|
||||
|| fail 'adoption did not turn repository metadata checks back on'
|
||||
grep -q 'RPM-GPG-KEY-terra44$' "$test_tmp/cases/terra-stock-adopt/etc/yum.repos.d/terra.repo" \
|
||||
|| fail "adoption rewrote terra-release's own repository file"
|
||||
[[ "$(<"$test_tmp/cases/terra-stock-adopt/commands.log")" != *'dnf:install'* ]] \
|
||||
|| fail 'adoption opened a DNF transaction it does not need'
|
||||
|
||||
|
||||
Reference in new issue
Block a user