← Back to issue list

Marking deb packages fails with versioned interdependencies

View original Github issue

Metadata

Project
craft-parts
Number
#1444
Type
issue
State
closed
Author
EddyPronk
Labels
—
Created
Updated
Closed

Current evaluation

Fixed by PR #1446 in commit cf118b5f: mark_packages now sets all candidate versions before marking packages for installation, preventing order-dependent failures.

Resolution: closed resolved

Reason: PR #1446 was merged as commit cf118b5f and changed mark_packages to resolve and pin every requested version before marking any package, with regression coverage for versioned interdependencies.

Evaluated by: mr-cal-bot

No scores available.

Issue body

### Bug Description `AptCache.mark_packages` in `craft_parts/packages/apt_cache.py` resolves package names, sets candidate versions, and calls `mark_install` all within a single loop iteration per package. When two or more packages in the same set have exact-version dependencies on each other, the order in which they are processed determines whether `mark_install` succeeds. Because the input is a `set[str]`, iteration order is non-deterministic. ### Example Given these packages to mark: ``` libnvinfer-dev=10.14.1.48-1+cuda12.9 libnvinfer10=10.14.1.48-1+cuda12.9 ``` `libnvinfer-dev` has an exact dependency: `Depends: libnvinfer10 (= 10.14.1.48-1+cuda12.9)`. If `libnvinfer-dev` is processed first: 1. Its candidate is set to `10.14.1.48`. 2. `mark_install` runs and evaluates the dependency on `libnvinfer10`. 3. `libnvinfer10` has **not been processed yet**, so its candidate is still the repository default (e.g. `10.15.1.29`). 4. The resolver sees a version mismatch and the mark fails silently (with `auto_fix=False`). 5. `_verify_marked_install` raises `PackageNotFound` because the candidate was invalidated. The user sees: ``` Cannot find package listed in 'build-packages': libnvinfer-dev ``` This is misleading -- the package exists, but its dependency's candidate version had not been pinned yet. ### Real-world trigger This shows up when using snapcraft with NVIDIA's CUDA repository and pinning TensorRT packages to a specific version while a newer version also exists in the repo: ### To Reproduce Add the deb repository. Stage packages with specific version numbers - ibnvinfer10=10.14.1.48-1+cuda12.9 - libnvinfer-headers-dev=10.14.1.48-1+cuda12.9 - libnvinfer-dev=10.14.1.48-1+cuda12.9 - cuda-cudart-12-9 In the `part yaml` section I included the snapcraft.yaml to reproduce it. The proposed fix has a failing test (before applying the fix) : ``` tests/unit/packages/test_apt_cache.py:191: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ craft_parts/packages/apt_cache.py:328: in mark_packages _verify_marked_install(package) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ package = <MagicMock id='136220264840544'> def _verify_marked_install(package: apt.package.Package) -> None: if package.installed or package.marked_install: return if package.candidate is None: > raise errors.PackageNotFound(package.name) E craft_parts.packages.errors.PackageNotFound: Package not found: libnvinfer-dev. ``` ### part yaml ```shell name: tensorrt-test base: core22 version: '0.1' summary: Test snap for TensorRT library installation description: | This snap demonstrates installing TensorRT libraries from NVIDIA CUDA developer repository on Ubuntu 22.04. grade: devel confinement: devmode # Add NVIDIA CUDA developer repository using path for flat repository package-repositories: - type: apt formats: [deb] path: / key-id: EB693B3035CD5710E231E123A4B469963BF863CC key-server: keyserver.ubuntu.com url: https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64 parts: tensorrt: plugin: nil build-packages: - cuda-toolkit-12-9 stage-packages: - libnvinfer10=10.14.1.48-1+cuda12.9 - libnvinfer-headers-dev=10.14.1.48-1+cuda12.9 - libnvinfer-dev=10.14.1.48-1+cuda12.9 - cuda-cudart-12-9 - bash apps: test: command: bin/bash ``` ### Relevant log output ```shell 2026-01-31 11:18:06.748 Installed package repositories 2026-01-31 11:18:06.750 part build packages: ['cuda-toolkit-12-9', 'libnvinfer-dev=10.14.1.48-1+cuda12.9', 'libnvinfer-headers-dev=10.14.1.48-1+cuda12.9', 'libnvinfer10=10.14.1.48-1+cuda12.9'] 2026-01-31 11:18:06.750 Installing build-packages 2026-01-31 11:18:06.750 Requested build-packages: ['cuda-toolkit-12-9', 'libnvinfer-dev=10.14.1.48-1+cuda12.9', 'libnvinfer-headers-dev=10.14.1.48-1+cuda12.9', 'libnvinfer10=10.14.1.48-1+cuda12.9'] 2026-01-31 11:18:10.222 Marking libnvinfer10=10.14.1.48-1+cuda12.9 (and its dependencies) to be fetched 2026-01-31 11:18:10.237 package: libnvinfer10 2026-01-31 11:18:10.305 Marking libnvinfer-dev=10.14.1.48-1+cuda12.9 (and its dependencies) to be fetched 2026-01-31 11:18:10.325 package: libnvinfer-dev 2026-01-31 11:18:10.347 Cannot find package listed in 'build-packages': libnvinfer-dev 2026-01-31 11:18:10.349 Traceback (most recent call last): 2026-01-31 11:18:10.349 File "/lib/python3.10/site-packages/snapcraft/application.py", line 473, in main 2026-01-31 11:18:10.349 return app.run() 2026-01-31 11:18:10.349 File "/lib/python3.10/site-packages/craft_application/application.py", line 623, in run 2026-01-31 11:18:10.349 return_code = self._run_inner() 2026-01-31 11:18:10.349 File "/lib/python3.10/site-packages/snapcraft/application.py", line 184, in _run_inner 2026-01-31 11:18:10.349 return_code = super()._run_inner() 2026-01-31 11:18:10.349 File "/lib/python3.10/site-packages/craft_application/application.py", line 569, in _run_inner 2026-01-31 11:18:10.349 dispatcher = self._get_dispatcher() 2026-01-31 11:18:10.350 File "/lib/python3.10/site-packages/snapcraft/application.py", line 411, in _get_dispatcher 2026-01-31 11:18:10.350 self._check_for_classic_fallback() 2026-01-31 11:18:10.350 File "/lib/python3.10/site-packages/snapcraft/application.py", line 323, in _check_for_classic_fallback 2026-01-31 11:18:10.350 raise errors.ClassicFallback() 2026-01-31 11:18:10.350 snapcraft.errors.ClassicFallback 2026-01-31 11:18:10.350 2026-01-31 11:18:10.350 During handling of the above exception, another exception occurred: 2026-01-31 11:18:10.350 Traceback (most recent call last): 2026-01-31 11:18:10.350 File "/lib/python3.10/site-packages/craft_parts/packages/deb.py", line 509, in _get_packages_marked_for_installation 2026-01-31 11:18:10.350 apt_cache.mark_packages(set(package_names)) 2026-01-31 11:18:10.350 File "/lib/python3.10/site-packages/craft_parts/packages/apt_cache.py", line 328, in mark_packages 2026-01-31 11:18:10.350 _verify_marked_install(package) 2026-01-31 11:18:10.350 File "/lib/python3.10/site-packages/craft_parts/packages/apt_cache.py", line 375, in _verify_marked_install 2026-01-31 11:18:10.350 raise errors.PackageNotFound(package.name) 2026-01-31 11:18:10.350 craft_parts.packages.errors.PackageNotFound: Package not found: libnvinfer-dev. 2026-01-31 11:18:10.351 2026-01-31 11:18:10.351 The above exception was the direct cause of the following exception: 2026-01-31 11:18:10.351 Traceback (most recent call last): 2026-01-31 11:18:10.351 File "/lib/python3.10/site-packages/snapcraft/parts/parts.py", line 204, in run 2026-01-31 11:18:10.351 with self._lcm.action_executor() as aex: 2026-01-31 11:18:10.351 File "/lib/python3.10/site-packages/craft_parts/executor/executor.py", line 319, in __enter__ 2026-01-31 11:18:10.351 self._executor.prologue() 2026-01-31 11:18:10.351 File "/lib/python3.10/site-packages/craft_parts/executor/executor.py", line 88, in prologue 2026-01-31 11:18:10.351 self._install_build_packages() 2026-01-31 11:18:10.351 File "/lib/python3.10/site-packages/craft_parts/executor/executor.py", line 261, in _install_build_packages 2026-01-31 11:18:10.351 packages.Repository.install_packages(sorted(build_packages)) 2026-01-31 11:18:10.351 File "/lib/python3.10/site-packages/craft_parts/packages/deb.py", line 566, in install_packages 2026-01-31 11:18:10.351 marked_packages = cls._get_packages_marked_for_installation(package_names) 2026-01-31 11:18:10.351 File "/lib/python3.10/site-packages/craft_parts/packages/deb.py", line 293, in wrapped 2026-01-31 11:18:10.351 return method(*args, **kwargs) 2026-01-31 11:18:10.351 File "/lib/python3.10/site-packages/craft_parts/packages/deb.py", line 511, in _get_packages_marked_for_installation 2026-01-31 11:18:10.351 raise errors.BuildPackageNotFound(error.package_name) from error 2026-01-31 11:18:10.351 craft_parts.packages.errors.BuildPackageNotFound: Cannot find package listed in 'build-packages': libnvinfer-dev ```

Evaluation history

Date Model Scores Action Summary
stealth/space-bunny-alpha — closed resolved Fixed by PR #1446 in commit cf118b5f: mark_packages now sets all candidate versions before marking packages for installation, preventing order-dependent failures.
stealth/space-bunny-alpha — closed stale Closed without a documented fix, replacement, or maintainer explanation; versioned interdependency handling remains unverified.
qwen/qwen3.6-35b-a3b — — Closed and fixed. Resolved by replacing the non-deterministic set iteration in mark_packages with a sorted list, ensuring versioned interdependencies are processed consistently before marking installation.
qwen/qwen3.6-35b-a3b — — Closed. Fixed by enforcing deterministic iteration order in mark_packages, resolving silent failures when marking deb packages with exact-version interdependencies.
qwen/qwen3.6-35b-a3b — — Closed after a fix was implemented to resolve the non-deterministic iteration order in mark_packages, ensuring versioned interdependencies are processed correctly and preventing misleading PackageNotFound errors.
qwen3.6-35b-a3b-mtp-q6 — — Fixed by ensuring mark_packages processes versioned interdependencies deterministically, resolving silent apt cache failures and misleading PackageNotFound errors.

Update history

No update history recorded yet.

Related work

  • Likely Fixed By: canonical/craft-parts#1446 (confidence 99%)

    Commit cf118b5f implements the two-pass candidate-pinning fix described in issue #1444.

Related issues

No related issues found above the similarity threshold.