Skip to content

Fix salt-master package upgrade resetting non-root user ownership (#68577)#69360

Open
dwoz wants to merge 2 commits into
saltstack:3006.xfrom
dwoz:fix/issue-68577
Open

Fix salt-master package upgrade resetting non-root user ownership (#68577)#69360
dwoz wants to merge 2 commits into
saltstack:3006.xfrom
dwoz:fix/issue-68577

Conversation

@dwoz

@dwoz dwoz commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Make the salt-master .deb preinst and the rpm %pre master scriptlet
honor the user: directive in /etc/salt/master (or a drop-in under
/etc/salt/master.d/) when deciding which user owns the master state
directories during an upgrade. Also remove dead %global _MS_CUR_USER ...
macro lines from %pre master (rpm expands %global at build time and
the referenced macros were undefined at that point).

What issues does this PR fix or reference?

Fixes #68577

Previous Behavior

The Debian preinst never read /etc/salt/master; it inferred the
target user from filesystem ownership of /run/salt-master.pid and
fell back to the package default salt otherwise. The rpm %pre master
similarly only looked at ls -dl /run/salt/master. On systemd-managed
installs those paths can be root-owned (or the pid file absent) between
restarts, so the upgrade would db_set salt-master/user salt and the
subsequent chown -R salt:salt reset state directory ownership even
when /etc/salt/master clearly specified a non-root user. The postinst
then re-chowned to whatever debconf reported, so the misconfigured
state persisted.

New Behavior

Both scriptlets read user: from /etc/salt/master and
/etc/salt/master.d/*.conf as the authoritative source and use
filesystem ownership only as a fallback. The dead %global lines are
removed from the spec.

A new regression test at
tests/pytests/unit/pkg/test_master_scriptlets.py runs the actual
scriptlet shell code in a sandbox and asserts that a user: bob
config produces CUR_USER=bob for both deb and rpm.

This mirrors the salt-minion-side fix in #69351 / #68793. The
salt-syndic and salt-api preinst scripts have the same shape but are
out of scope here — the reporter's title is salt-master + salt-minion.

Merge requirements satisfied?

  • Docs
  • Changelog
  • Tests written/updated

Commits signed with GPG?

No

@dwoz dwoz requested a review from a team as a code owner June 7, 2026 04:56
@dwoz dwoz added this to the Sulphur v3006.26 milestone Jun 7, 2026
@dwoz dwoz added the test:full Run the full test suite label Jun 7, 2026
@dwoz dwoz force-pushed the fix/issue-68577 branch from 133ce1d to 92377b9 Compare June 12, 2026 23:29
@dwoz dwoz force-pushed the fix/issue-68577 branch from 92377b9 to dad71af Compare June 15, 2026 05:51
Daniel A. Wozniak added 2 commits June 17, 2026 03:43
The Debian preinst and the rpm `%pre master` scriptlet decided which
user owns the salt-master state directories on upgrade by inspecting
filesystem ownership only: deb looked at `/run/salt-master.pid`, rpm
looked at `/run/salt/master`. Neither read `user:` from
`/etc/salt/master` or a drop-in under `/etc/salt/master.d/`. On
systemd-managed installs those paths can be root-owned (or the pid file
absent) between restarts, so the preinst's `db_set salt-master/user`
wrote the package default (`salt`) back into debconf and the subsequent
chowns clobbered the configured non-root user. The postinst then
re-chowned to whatever debconf reported.

Make both scriptlets read `user:` from `/etc/salt/master` and
`/etc/salt/master.d/*.conf` as the authoritative source and fall back
to filesystem ownership only when no user is configured. Drop the dead
`%global _MS_CUR_USER ...` lines from `%pre master` — `%global` is an
rpm parse-time directive and the macros referenced (`%{_MS_LCUR_USER}`)
were never defined as rpm macros, so the lines were inert.

Add a regression test at `tests/pytests/unit/pkg/test_master_scriptlets.py`
that runs the actual scriptlet shell code in a sandbox and asserts that
a `user: bob` config produces `CUR_USER=bob` for both deb and rpm.

Fixes saltstack#68577
rpmbuild parses macros even inside shell comments within scriptlet
sections. The literal `%global _MS_CUR_USER ...` in the explanatory
comment caused rpmbuild to try to define a macro at parse time, failing
with 'Macro % has illegal name (%global)'. Escape with %% so the comment
reads as a literal.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test:full Run the full test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant