Skip to content

Fixed simulate mode reporting both removal and install of the same package - #25

Open
djbclark wants to merge 2 commits into
masterfrom
fix/simulate-pkg-mapremove
Open

Fixed simulate mode reporting both removal and install of the same package#25
djbclark wants to merge 2 commits into
masterfrom
fix/simulate-pkg-mapremove

Conversation

@djbclark

Copy link
Copy Markdown
Owner

Fixes #24.

In DiffPkgOperations() and ManifestPkgOperations(), inserting an install message into the installed/present map set name_arch to NULL because the map took ownership of it as a key. The MapRemove() call that cancels a previous removal message ran after that, so it looked up a NULL key and matched nothing: a package recorded as removed and then installed was reported as both removed and installed. Moved the cancellation above the code that hands name_arch to the map.

Includes a regression test (tests/unit/simulate_mode_test.c) feeding r,foo,, + i,foo,1.2.3, records to both functions; it fails on master and passes with the fix.

Testing:

  • macOS (arm64): test passes with fix, fails on master (rebuilt libcf-agent between runs).
  • Ubuntu 24.04 (arm64 container, /bin/sh = dash): same pass/fail discrimination.
  • x86_64: this PR's CI run.

AI-assisted, reviewed and verified by me before submitting.

🤖 Generated with Claude Code

@djbclark

Copy link
Copy Markdown
Owner Author

Upstream submission package (human-in-the-loop)

Everything below is ready to paste. Per upstream's restart protocol the submission itself is djbclark's act: 1 bug ticket + 1 PR, smallest possible, with reproduce and before/after output.

Preconditions before submitting:

  • The relevant decisions on Consolidated judgment calls from the 2026-08 submissions #23 are answered.
  • CI green on head commit 9ee0d1bfc (run 32603359614; the prior identical change already passed run 32602383710).
  • Branch state check: git log --oneline -2 fix/simulate-pkg-mapremove shows 9ee0d1bfc on top of upstream master b14a380d0 (rebased and verified 2026-08-22; if upstream master moves substantially before submission, re-verify the cherry-pick).

Step 1 — File the Jira ticket (northerntech.atlassian.net, project CFE, type Bug)

Summary:

simulate mode reports both removal and install of the same package

Description:

Recording a package removal and then an installation of the same package makes --simulate=diff / --simulate=manifest report both operations instead of the net install.

In DiffPkgOperations() and ManifestPkgOperations() (cf-agent/simulate_mode.c), the MapRemove() that cancels the earlier removal message runs after MapInsert() has taken ownership of the key and the local name_arch was set to NULL, so it looks up a NULL key and matches nothing. Debug builds instead fail assert(str != NULL) in StringHash() once the map outgrows its array stage.

Reproduce: feed pkgs_ops records r,foo,, then i,foo,1.2.3, (the format RecordPkgOperationInChroot() writes).
Before: output contains both Package 'foo [1.2.3]' would be installed and Package 'foo' would be removed.
After: only the install line.

Found while prototyping a JSON output for simulate mode; the defect is pre-existing on master and independent of that work.


Step 2 — Stamp the ticket number into the commit

cd ~/src/cfengine-core
git checkout fix/simulate-pkg-mapremove
git commit --amend -m "$(git log -1 --format=%B | sed 's/Ticket: None/Ticket: CFE-XXXX/')"
git push --force-with-lease origin fix/simulate-pkg-mapremove

(Replace CFE-XXXX. Everything else in the message already follows CONTRIBUTING: past-tense title under 80 chars, full-sentence body, Changelog: Title.)


Step 3 — Open the upstream PR

From https://github.com/djbclark/core/tree/fix/simulate-pkg-mapremove → "Contribute" → PR against cfengine:master.

Title:

CFE-XXXX: Fixed simulate mode reporting both removal and install of the same package

Body:

Ticket: https://northerntech.atlassian.net/browse/CFE-XXXX

In DiffPkgOperations() and ManifestPkgOperations(), inserting an install message into the installed/present map set name_arch to NULL because the map took ownership of it as a key. The MapRemove() call that cancels a previous removal message ran after that, so it looked up a NULL key and matched nothing: a package recorded as removed and then installed was reported as both removed and installed. Moved the cancellation above the code that hands name_arch to the map.

The regression test feeds r,foo,, + i,foo,1.2.3, records to both functions: it fails before the fix and passes after, verified on x86_64 Linux (CI), Ubuntu 24.04 arm64, and macOS arm64.

AI-assisted; reviewed and verified by me before submitting, and I take authorship responsibility.


Notes for the submitter

…ckage

In DiffPkgOperations() and ManifestPkgOperations(), inserting an install
message into the installed/present map set name_arch to NULL because the
map took ownership of it as a key. The MapRemove() call that cancels a
previous removal message ran after that, so it looked up a NULL key and
matched nothing. The cancellation was silently skipped exactly when an
install message had been inserted: a package recorded as removed and
then installed was reported as both removed and installed. In debug
builds a NULL key also fails an assertion in StringHash() once the map
outgrows the array-map stage.

Moved the cancellation above the code that hands name_arch to the map.

Changelog: Title
Ticket: CFE-4742

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@djbclark
djbclark force-pushed the fix/simulate-pkg-mapremove branch from 9ee0d1b to 5ddb6d9 Compare August 22, 2026 23:47
@djbclark

Copy link
Copy Markdown
Owner Author

Submitted upstream 2026-08-22: ticket CFE-4742, PR cfengine/core#6332 (same commit, 5ddb6d97b = green 9ee0d1bfc + the Ticket: trailer). This fork PR stays open as the CI-evidence anchor until upstream resolves.

Co-authored-by: Lars Erik Wik <53906608+larsewi@users.noreply.github.com>
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.

simulate mode reports both removal and install of the same package

2 participants