From 5a156113d77c9842d97d2ce9fe16d4ff0575e2db Mon Sep 17 00:00:00 2001 From: batteryshark <1574871+batteryshark@users.noreply.github.com> Date: Mon, 26 Oct 2026 13:57:19 -0400 Subject: [PATCH] Keep installer pip cache out of the service checkout --- deploy/install.sh | 3 ++- tests/release/test_deployment.py | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/deploy/install.sh b/deploy/install.sh index f3138bb..3c16e7c 100755 --- a/deploy/install.sh +++ b/deploy/install.sh @@ -46,7 +46,8 @@ if [ ! -x "$VENV_PY" ]; then sudo -u "$SERVICE_USER" python3 -m venv "$REPO_ROOT/admin/.venv" fi echo "==> Installing the package + admin dependencies" -sudo -u "$SERVICE_USER" sh -c "cd '$REPO_ROOT' && '$VENV_PIP' install --quiet '.[admin,vault]' -r admin/requirements.txt -c admin/requirements-lock.txt" +# The service account's HOME is the checkout; do not create an untracked .cache there. +sudo -u "$SERVICE_USER" sh -c "cd '$REPO_ROOT' && '$VENV_PIP' install --no-cache-dir --quiet '.[admin,vault]' -r admin/requirements.txt -c admin/requirements-lock.txt" # 4. State + log dirs (the unit's StateDirectory/ReadWritePaths keep them; pre-create # so set-password + the SPS audit logger land right instead of crashing on first write) diff --git a/tests/release/test_deployment.py b/tests/release/test_deployment.py index 489bf5a..554aaf6 100644 --- a/tests/release/test_deployment.py +++ b/tests/release/test_deployment.py @@ -36,6 +36,30 @@ def test_all_installers_consume_same_export(self): self.assertIn('admin/requirements.txt', source) self.assertIn('admin/requirements-lock.txt', source) + def test_native_installer_disables_pip_cache_in_service_home(self): + # Execute only the dependency-install command with stand-ins, never the + # privileged installer or a real package download/service operation. + source = (ROOT / 'deploy/install.sh').read_text() + command, = [line for line in source.splitlines() + if line.startswith('sudo -u "$SERVICE_USER" sh -c ')] + with tempfile.TemporaryDirectory(prefix='toolstack-install-cache-') as tmp: + home = Path(tmp) + pip = home / 'fake-pip' + pip.write_text('#!/bin/sh\n' + 'printf "%s\\n" "$@" > "$HOME/pip-args"\n' + 'case " $* " in *" --no-cache-dir "*) ;; ' + '*) mkdir -p "$HOME/.cache/pip" ;; esac\n') + pip.chmod(0o700) + subprocess.run(['bash', '-c', 'sudo(){ shift 2; "$@"; }\n' + command], + env={'PATH': '/usr/bin:/bin', 'HOME': tmp, 'REPO_ROOT': tmp, + 'SERVICE_USER': 'fake', 'VENV_PIP': str(pip)}, + check=True, capture_output=True, text=True, timeout=10) + args = (home / 'pip-args').read_text().splitlines() + self.assertEqual(args[0], 'install') + self.assertIn('--no-cache-dir', args) + self.assertIn('admin/requirements-lock.txt', args) + self.assertFalse((home / '.cache').exists()) + def test_private_units_and_no_toml_environmentfile(self): for component in ('admin', 'sps'): source = (ROOT / f'deploy/toolstack-{component}.service').read_text()