Skip to content

apt::mark: make guards idempotent for auto, manual and unhold - #1292

Open
mbartmann wants to merge 1 commit into
puppetlabs:mainfrom
mbartmann:fix-mark-idempotency
Open

mbartmann wants to merge 1 commit into
puppetlabs:mainfrom
mbartmann:fix-mark-idempotency

Conversation

@mbartmann

Copy link
Copy Markdown

Summary

Three of the four apt::mark settings re-fire their exec on every agent run in common situations:

Changes

  • auto / manual: gate on the package being genuinely installed — dpkg-query --show --showformat '${db:Status-Status}' <pkg> | grep -qx installed (prints installed only for state ii; config-files for rc, not-installed for un).
  • unhold: only run when the package is actually held — apt-mark showhold <pkg> prints the name when held and nothing otherwise.
  • hold: deliberately unchanged. apt-mark hold on a not-yet-installed package is legitimate (pre-holding before install), sticks, and is already idempotent via the existing unless — the loose dpkg -l gate only filters names dpkg has never heard of.
  • Spec: new guard idempotency context asserting the exact onlyif/unless per setting (previously unasserted).

Validation

spec/defines/mark_spec.rb: 23 examples, 0 failures (Ubuntu 24.04, Ruby 3.4.7, Puppet 8.10, bundler 2.6.9). Full spec/defines + spec/classes run shows an identical failure set to pristine main in the same environment (369 pre-existing environmental failures, ±0 from this change).

Guard semantics verified live on Ubuntu 24.04: dpkg -l exit 0 for an un-state package, apt-mark manual exit 0 with "can not be marked as it is not installed", and the flap disappearing with the new gate.

Heads-up found while testing, not part of this PR: on Ruby 3.4 the spec harness fails to load with Cannot determine basic system flavour unless the gemified syslog stdlib gem is declared (Gemfile.local with gem "syslog" works) — Puppet's posix? feature requires it.

Fixes #1166
Fixes #1226

@mbartmann
mbartmann requested review from a team, bastelfreak and smortex as code owners August 28, 2026 21:20
@CLAassistant

CLAassistant commented Aug 28, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

apt-mark auto|manual on a package that dpkg merely knows about ('un' or
'rc' state) does nothing yet exits 0 - and dpkg -l also exits 0 for those
states, so the current onlyif passes, the unless can never become true,
and the exec re-fires on every agent run. unhold had no guard at all.

Gate auto/manual on the package being genuinely installed via
dpkg-query's db:Status-Status, and unhold on the package actually being
held. hold keeps the loose dpkg gate deliberately: pre-holding a
not-yet-installed package is legitimate and idempotent.

Fixes puppetlabs#1166
Fixes puppetlabs#1226
@jst-cyr

jst-cyr commented Aug 31, 2026

Copy link
Copy Markdown
Member

Running CI tests for this PR here: #1293

@jst-cyr

jst-cyr commented Aug 31, 2026

Copy link
Copy Markdown
Member

Acceptance Test results: https://github.com/puppetlabs/puppetlabs-apt/actions/runs/33428244807?pr=1293

All green! Queued up now for engineering review when the team has availability.

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.

apt::mark with setting auto is not idempotent apt::mark with setting => unhold is not idempotent

3 participants