← Back to issue list

Package installer fails if `/etc/apt/sources.list` is absent

View original Github issue

Metadata

Project
craft-parts
Number
#976
Type
issue
State
closed
Author
lengau
Labels
Status: Triaged Type: Bug
Created
Updated
Closed

Current evaluation

Fixed by merged PR #1485 (commit a98be83a), replacing python-apt installed-package checks with dpkg-query so a missing /etc/apt/sources.list no longer breaks package installation.

Resolution: closed resolved

Reason: PR #1485 was merged as commit a98be83a and closes #976. It changed host installed-package checks to use dpkg-query with apt-get simulation, avoiding AptCache's attempt to create the absent sources.list.

Evaluated by: mr-cal-bot

No scores available.

Issue body

### Bug Description On a fresh Ubuntu Plucky install, `/etc/apt/sources.list` is not included, as Ubuntu has migrated to fully utilising deb822. However, craft-parts ### To Reproduce Clone the repository on a fresh plucky machine and run the cmake integration tests. It does not matter whether cmake is installed - it just needs any plugin that has a build dependency. ### part yaml ```shell n/a ``` ### Relevant log output ```shell (craft-parts) lengau@ratel:~/Work/Code/craft-parts$ pytest tests/integration/plugins/test_cmake.py::test_cmake_plugin[-bin] ========================================================================================= test session starts ========================================================================================= platform linux -- Python 3.11.10, pytest-8.3.4, pluggy-1.5.0 rootdir: /home/lengau/Work/Code/craft-parts configfile: pyproject.toml plugins: subprocess-1.5.3, cov-5.0.0, requests-mock-1.12.1, check-2.4.1, hypothesis-6.123.7, mock-3.14.0 collected 1 item tests/integration/plugins/test_cmake.py F [100%] ============================================================================================== FAILURES =============================================================================================== _______________________________________________________________________________________ test_cmake_plugin[-bin] _______________________________________________________________________________________ new_dir = local('/tmp/pytest-of-lengau/pytest-15/test_cmake_plugin__bin_0'), partitions = None, prefix = '', install_path = 'bin' @pytest.mark.parametrize( ("prefix", "install_path"), [ (None, "usr/local/bin"), ("", "bin"), ("/usr/local", "usr/local/bin"), ("/something/else", "something/else/bin"), ], ) def test_cmake_plugin(new_dir, partitions, prefix, install_path): parts_yaml = textwrap.dedent( """\ parts: foo: plugin: cmake source: . """ ) if prefix is not None: parts_yaml += f" cmake-parameters: [-DCMAKE_INSTALL_PREFIX={prefix}]" parts = yaml.safe_load(parts_yaml) Path("cmake.build").write_text( textwrap.dedent( """\ project('cmake-hello', 'c') executable('hello', 'hello.c', install : true) """ ) ) Path("hello.c").write_text( textwrap.dedent( """\ #include <stdio.h> int main() { printf(\"hello world\\n\"); return 0; } """ ) ) Path("CMakeLists.txt").write_text( textwrap.dedent( """\ cmake_minimum_required(VERSION 2.6) project(cmake-hello C) add_executable(cmake-hello hello.c) install(TARGETS cmake-hello RUNTIME DESTINATION bin) """ ) ) lf = LifecycleManager( parts, application_name="test_cmake", cache_dir=new_dir, partitions=partitions ) actions = lf.plan(Step.PRIME) > with lf.action_executor() as ctx: /home/lengau/Work/Code/craft-parts/tests/integration/plugins/test_cmake.py:88: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ /home/lengau/Work/Code/craft-parts/craft_parts/executor/executor.py:304: in __enter__ self._executor.prologue() /home/lengau/Work/Code/craft-parts/craft_parts/executor/executor.py:88: in prologue self._install_build_packages() /home/lengau/Work/Code/craft-parts/craft_parts/executor/executor.py:246: in _install_build_packages packages.Repository.install_packages(sorted(build_packages)) /home/lengau/Work/Code/craft-parts/craft_parts/packages/deb.py:562: in install_packages if not cls._check_if_all_packages_installed(package_names): /home/lengau/Work/Code/craft-parts/craft_parts/packages/deb.py:293: in wrapped return method(*args, **kwargs) /home/lengau/Work/Code/craft-parts/craft_parts/packages/deb.py:466: in _check_if_all_packages_installed with AptCache() as apt_cache: # pyright: ignore[reportPossiblyUnboundVariable] /home/lengau/Work/Code/craft-parts/craft_parts/packages/apt_cache.py:103: in __enter__ self.cache = apt.cache.Cache(rootdir="/") /home/lengau/Work/Code/craft-parts/.venv/lib/python3.11/site-packages/apt/cache.py:148: in __init__ self._check_and_create_required_dirs(rootdir) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <apt.cache.Cache object at 0x7a99f22c1fd0>, rootdir = '/' def _check_and_create_required_dirs(self, rootdir: str) -> None: """ check if the required apt directories/files are there and if not create them """ files = [ "/var/lib/dpkg/status", "/etc/apt/sources.list", ] dirs = [ "/var/lib/dpkg", "/etc/apt/", "/var/cache/apt/archives/partial", "/var/lib/apt/lists/partial", ] for d in dirs: if not os.path.exists(rootdir + d): # print "creating: ", rootdir + d os.makedirs(rootdir + d) for f in files: if not os.path.exists(rootdir + f): > open(rootdir + f, "w").close() E PermissionError: [Errno 13] Permission denied: '//etc/apt/sources.list' /home/lengau/Work/Code/craft-parts/.venv/lib/python3.11/site-packages/apt/cache.py:188: PermissionError ======================================================================================= short test summary info ======================================================================================= FAILED tests/integration/plugins/test_cmake.py::test_cmake_plugin[-bin] - PermissionError: [Errno 13] Permission denied: '//etc/apt/sources.list' ========================================================================================== 1 failed in 0.11s ========================================================================================== ```

Evaluation history

Date Model Scores Action Summary
stealth/space-bunny-alpha — closed resolved Fixed by merged PR #1485 (commit a98be83a), replacing python-apt installed-package checks with dpkg-query so a missing /etc/apt/sources.list no longer breaks package installation.
stealth/space-bunny-alpha — closed resolved Fixed by canonical/craft-parts#1485 (a98be83a), which replaced python-apt installed-package checks with dpkg-query, avoiding creation of the missing sources.list.
qwen3.6-35b-a3b-mtp-q6 — — Closed without a fix. The issue seems abandoned or resolved by environment changes, as reproduction now requires manually removing the placeholder file in LXD, indicating standard Ubuntu images include it.
qwen/qwen3.8-27b
Impact: 60
Quick Win: 27
Staleness: 30
Complexity: 55
Confidence: 75
Support Request: 5
keep open Package installation crashes with PermissionError when /etc/apt/sources.list is absent (Ubuntu Plucky deb822 migration). Triaged, but a maintainer recently (173 days ago) could only reproduce it in LXD after manually removing the placeholder file, so the fix is still pending.
qwen/qwen3.6-35b-a3b
Staleness: 65
Complexity: 20
Confidence: 75
Support Request: 0
keep open Package installer crashes when /etc/apt/sources.list is missing due to a permission error during file creation. Triaged, awaiting clarification on environment-specific reproducibility.
qwen3.6-35b-a3b-mtp-q6
Staleness: 45
Complexity: 40
Confidence: 85
Support Request: 5
keep open craft-parts fails to install packages when /etc/apt/sources.list is missing, causing a PermissionError during apt cache initialization. Triaged and under maintainer investigation.

Update history

Date Change
closed

Related work

  • Likely Fixed By: canonical/craft-parts#1485 (confidence 100%)

    Merged fix commit a98be83a removes python-apt from the failing installed-package check path.

Related issues

Issue Project State Summary Similarity
#1485 fix(deb): avoid python-apt for installed package checks craft-parts merged PR #1485 merged as commit a98be83a: host install_packages() now uses dpkg-query (plus apt-get --simulate) instead of python-apt for installed-package checks, fixing PermissionError when /etc/apt/sources.list is absent. Closes #976.
76%