From 85106cb50601a3c833bd65e7db9134cb0dddd545 Mon Sep 17 00:00:00 2001 From: Andre Brait Date: Mon, 31 Aug 2026 01:58:27 +0200 Subject: [PATCH] install: stabilize candidate activation --- scripts/install.sh | 4 ++++ tests/test_channel_install.py | 26 +++++++++++++++++++++++--- tests/test_gen_landing.py | 15 ++++++++++----- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/scripts/install.sh b/scripts/install.sh index c73534d..aeb64dd 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -480,7 +480,9 @@ pfb_channel_install() { # probe fetch a truncated/foreign URL, and a commented or extra url line could # satisfy a grep-anywhere check while the real value points elsewhere. _url_keys="$(grep -c '^[[:space:]]*url[[:space:]]*:' "${_candidate}" 2>/dev/null || true)" + case "${_url_keys}" in '' | *[!0-9]*) _url_keys=0 ;; esac _url_wellformed="$(sed -n 's/^[[:space:]]*url:[[:space:]]*"\([^"]*\)",[[:space:]]*$/\1/p' "${_candidate}" 2>/dev/null | grep -c . || true)" + case "${_url_wellformed}" in '' | *[!0-9]*) _url_wellformed=0 ;; esac _catalog_url="$(sed -n 's/^[[:space:]]*url:[[:space:]]*"\([^"]*\)",[[:space:]]*$/\1/p' "${_candidate}" 2>/dev/null | head -n 1)" [ "${_url_keys}" -eq 1 ] && [ "${_url_wellformed}" -eq 1 ] || { die 4 "$(printf 'the candidate conf does not carry exactly one canonical quoted url key (found %s url key line(s), %s well-formed) — refusing to probe or activate; inspect: sh %s onestart' \ @@ -542,6 +544,8 @@ pfb_channel_install() { die 1 "${CONF_PATH} exists and is not a regular file — refusing to activate over it" fi [ -f "${CONF_PATH}" ] || CONF_CREATED=1 + chmod 644 "${_candidate}" || + die 1 "could not set the mode on the validated candidate conf" mv "${_candidate}" "${CONF_PATH}" || die 1 "could not activate ${CONF_PATH} from the validated candidate" # _candidate stays armed for the EXIT trap until the destination is VERIFIED as diff --git a/tests/test_channel_install.py b/tests/test_channel_install.py index 3d16908..2f42d8e 100644 --- a/tests/test_channel_install.py +++ b/tests/test_channel_install.py @@ -224,7 +224,7 @@ # The fake fetch(1): one line per call in fetch-invocations.log — -# ``pkg-log-bytes= `` — so a +# ``pkg-log-bytes= `` — so a # test can assert the EXACT probed URL and prove the probe ran before the first pkg # call (size 0). Succeeds unless ``PFB_STUB_FETCH_FAIL=1``. _FETCH_STUB = r"""#!/bin/sh @@ -239,8 +239,7 @@ _url="" for _arg in "$@"; do case "${_arg}" in - -*) ;; - *) _url="${_arg}" ;; + *://*) _url="${_arg}" ;; esac done printf '%s\n' "$*" >> "${ARGV_LOG}" @@ -1948,6 +1947,27 @@ def test_probe_requests_the_exact_generated_catalog_url_before_any_pkg_call() -> ) +def test_activated_conf_mode_is_stable_under_restrictive_umask() -> None: + """Candidate activation sets the repository conf mode independently of caller umask.""" + with tempfile.TemporaryDirectory() as root: + argv, env = _prepare_install(root, "stable") + + def restrictive_umask() -> None: + os.umask(0o077) + + proc = subprocess.run( + argv, + env=env, + capture_output=True, + text=True, + check=False, + preexec_fn=restrictive_umask, + ) + + assert proc.returncode == 0, proc.stdout + proc.stderr + assert stat.S_IMODE(_conf_path(root, "stable").stat().st_mode) == 0o644 + + @pytest.mark.parametrize( "hostile_id, hostile_tail", [ diff --git a/tests/test_gen_landing.py b/tests/test_gen_landing.py index caeb674..38f1552 100644 --- a/tests/test_gen_landing.py +++ b/tests/test_gen_landing.py @@ -2363,7 +2363,7 @@ def test_published_installer_runs_piped_with_embedded_hook(tmp_path: Path, monke """ import subprocess - from tests.test_channel_install import _PKG_STUB, _seed_box, _write_fetch_stub + from tests.test_channel_install import _PKG_STUB, _seed_box, _write_fetch_stub, _write_timeout_stub site = tmp_path / "site" site.mkdir() @@ -2395,6 +2395,7 @@ def test_published_installer_runs_piped_with_embedded_hook(tmp_path: Path, monke "PFBLOCKERNG_ROOT": str(root), "PKG_BIN": str(fake_pkg), "FETCH_BIN": str(_write_fetch_stub(str(root))), + "TIMEOUT_BIN": str(_write_timeout_stub(str(root))), "PFB_TEST_ROOT": str(root), "PFB_BASE_URL": base, } @@ -2440,7 +2441,7 @@ def test_published_installer_never_treats_the_on_box_hook_as_its_checkout_source """ import subprocess - from tests.test_channel_install import _PKG_STUB, _seed_box, _write_fetch_stub + from tests.test_channel_install import _PKG_STUB, _seed_box, _write_fetch_stub, _write_timeout_stub site = tmp_path / "site" site.mkdir() @@ -2482,6 +2483,7 @@ def test_published_installer_never_treats_the_on_box_hook_as_its_checkout_source "PFBLOCKERNG_ROOT": str(root), "PKG_BIN": str(fake_pkg), "FETCH_BIN": str(_write_fetch_stub(str(root))), + "TIMEOUT_BIN": str(_write_timeout_stub(str(root))), "PFB_TEST_ROOT": str(root), "PFB_BASE_URL": base, } @@ -2516,7 +2518,7 @@ def test_published_installer_saved_to_disk_still_replaces_a_stale_on_box_hook(tm """ import subprocess - from tests.test_channel_install import _PKG_STUB, _seed_box, _write_fetch_stub + from tests.test_channel_install import _PKG_STUB, _seed_box, _write_fetch_stub, _write_timeout_stub site = tmp_path / "site" site.mkdir() @@ -2556,6 +2558,7 @@ def test_published_installer_saved_to_disk_still_replaces_a_stale_on_box_hook(tm "PFBLOCKERNG_ROOT": str(root), "PKG_BIN": str(fake_pkg), "FETCH_BIN": str(_write_fetch_stub(str(root))), + "TIMEOUT_BIN": str(_write_timeout_stub(str(root))), "PFB_TEST_ROOT": str(root), "PFB_BASE_URL": base, } @@ -2586,7 +2589,7 @@ def test_write_site_bakes_the_sites_base_url_into_the_published_installer(tmp_pa """ import subprocess - from tests.test_channel_install import _PKG_STUB, _seed_box, _write_fetch_stub + from tests.test_channel_install import _PKG_STUB, _seed_box, _write_fetch_stub, _write_timeout_stub site = tmp_path / "site" site.mkdir() @@ -2627,6 +2630,7 @@ def test_write_site_bakes_the_sites_base_url_into_the_published_installer(tmp_pa "PFBLOCKERNG_ROOT": str(root), "PKG_BIN": str(fake_pkg), "FETCH_BIN": str(_write_fetch_stub(str(root))), + "TIMEOUT_BIN": str(_write_timeout_stub(str(root))), "PFB_TEST_ROOT": str(root), } result = subprocess.run( @@ -2676,7 +2680,7 @@ def test_write_site_bakes_a_base_url_containing_shell_metacharacters_as_inert_da """ import subprocess - from tests.test_channel_install import _PKG_STUB, _seed_box, _write_fetch_stub + from tests.test_channel_install import _PKG_STUB, _seed_box, _write_fetch_stub, _write_timeout_stub site = tmp_path / "site" site.mkdir() @@ -2715,6 +2719,7 @@ def test_write_site_bakes_a_base_url_containing_shell_metacharacters_as_inert_da "PFBLOCKERNG_ROOT": str(root), "PKG_BIN": str(fake_pkg), "FETCH_BIN": str(_write_fetch_stub(str(root))), + "TIMEOUT_BIN": str(_write_timeout_stub(str(root))), "PFB_TEST_ROOT": str(root), } result = subprocess.run(