Skip to content

fix: select APT Docker versions at literal component boundaries - #581

Open
soulteary wants to merge 1 commit into
docker:masterfrom
soulteary:codex/feat/version-selection-upstream
Open

soulteary wants to merge 1 commit into
docker:masterfrom
soulteary:codex/feat/version-selection-upstream

Conversation

@soulteary

@soulteary soulteary commented Oct 5, 2026 •

Copy link
Copy Markdown

- What I did

VERSION=24.0 can select Docker 28.4.0 on Ubuntu noble because the current lookup searches an entire apt-cache madison row. The requested 24.0 matches 24.04 in 5:28.4.0-1~ubuntu.24.04~noble, and the first row wins even though its Docker version is unrelated to the pin.

Anchoring the lookup to the version field alone does not resolve all false positives: VERSION=24.0.1 can still match 24.0.10, and VERSION=22.0 can match 22.02.1. The dots in the requested version are also treated as regular-expression wildcards.

This PR matches a literal Docker version prefix at a component boundary within the package version field. A missing version follows the existing error path before Docker package installation.

- How I did it

  • Use one selection helper for the APT Docker Engine and CLI lookups. Extract and trim the madison version field before matching, so distribution suffixes and repository metadata cannot satisfy the requested pin.
  • Escape regular-expression metacharacters and anchor the literal prefix after an optional numeric epoch. Accept both epoch-bearing and historical epoch-free package versions; require a component boundary so 24.0.1 cannot select 24.0.10.
  • Preserve partial version pins, the leading v shorthand, historical -ce releases, and pre-release forms. Docker's - separators are normalized to Debian's ~ spelling, including legacy -ce-rc1 and modern -rc.1 forms; direct ~rc.1 spelling also works.
  • Reject pins containing embedded newlines. Otherwise, grep interprets later fragments as additional expressions: a pin such as bogus\n24 could match the Ubuntu suffix and incorrectly select 29.4.0.
  • Run version matching outside the privileged shell command, passing the requested version as data.
  • Preserve the first matching repository row and existing test-channel ordering behavior. Add 24 offline installer regression scenarios, a dedicated CI job for sh and bash, and testing documentation.

- How to verify it

The candidate is commit 61e13c3267d663d323e9addeb4f1dd3eb921e875, based directly on upstream master at 2b32480025b223ebfddae9a3a8bef09027680f53.

  • All 24 scenarios pass under both sh and bash in an Ubuntu 24.04 container with networking disabled and a read-only repository mount. The tests execute the installer's APT installation flow against package-list fixtures, fix platform detection to Ubuntu noble, intercept repository/configuration operations, and record the final package installation arguments instead of executing them. Coverage includes independent Engine and CLI false positives, whitespace, optional epochs, partial pins, legacy releases, pre-releases through the test channel, unavailable versions, shell metacharacters, and embedded newlines.
  • The fork commit c57bd823 was used only as a regression-control baseline. With the same fixture, it records docker-ce=5:28.4.0-1~ubuntu.24.04~noble for VERSION=24.0; the fix records docker-ce=5:24.0.9-1~ubuntu.24.04~noble. This fork control is separate from the candidate's upstream base above.
  • The original Anchor VERSION match on the Docker epoch to avoid distro-version hits #571 matching expression was exercised through the installer with conventional single-space madison rows. It fixes the distribution-suffix example but still selects 24.0.10 for VERSION=24.0.1; this implementation selects 24.0.1.
  • sh -n and bash -n pass for the installer and regression script. ShellCheck 0.11.0 passes with the repository's existing exclusions, and git diff --check passes.
  • The candidate branch's GitHub Actions run passed in soulteary/docker-install, validating candidate commit 61e13c3 in the fork.

The fixture suite establishes offline package selection: it does not download or install Docker packages or start the daemon. It does not establish repository availability or successful installation for every requested pin. --dry-run still does not resolve version pins and is not used as selection evidence. RPM selection, supported distributions, and mirrors are unchanged; the existing fallback when a separate CLI package is unavailable is retained.

Source and provenance

Inspired by docker/docker-install#571, authored by fudianchn (付典), and its original signed-off commit. This is a fresh implementation extending the reported fix with literal matching, component boundaries, newline handling, and installer-flow regressions.

The candidate was cherry-picked with provenance from fork commit 149f5e5. It retains the Signed-off-by: Su Yang <soulteary@users.noreply.github.com> DCO trailer and the original fork commit reference in its commit message.

- Description for the changelog

Match APT Docker version pins literally within the package version field at component boundaries.

Match the madison version field for Engine and CLI, preserving optional epochs, partial pins and Debian prerelease spelling. Add offline installer-flow regression coverage and a dedicated CI job.

Inspired-by: docker#571
Signed-off-by: Su Yang <soulteary@users.noreply.github.com>
(cherry picked from commit 149f5e5)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant