Skip to content

feature(bootstrap): add -e/-PipRequirements to install PyPI packagesbefore Salt starts - #2146

Merged
twangboy merged 1 commit into
saltstack:developfrom
twangboy:fix/1975/develop
Oct 8, 2026
Merged

twangboy merged 1 commit into
saltstack:developfrom
twangboy:fix/1975/develop

Conversation

@twangboy

@twangboy twangboy commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Add a requirements-file option to bootstrap-salt.sh (-e FILE) and bootstrap-salt.ps1 (-PipRequirements FILE) that installs PyPI packages, such as Salt Extensions, into the Salt onedir with salt-pip after Salt is installed and before its services are first started. Pinning and custom or authenticated indexes use normal pip syntax in the file (==, --index-url, --extra-index-url, PIP_INDEX_URL), so no credentials are needed on the command line. The file's contents are never printed.

Linux:

  • Onedir installs only. -e is rejected up front for git installs, -C, macOS, and a missing or package-less file.
  • Debian and Ubuntu packages start the service as soon as they are installed, even with -X. When -e is used, a temporary policy-rc.d holds back service starts until the packages are installed. Any existing policy-rc.d is restored afterward, including on failure and signals, via the existing exit trap.
  • RPM based and other onedir installs only enable the services, so they need no guard.

Windows:

  • salt-pip.exe runs between the installer finishing (already run with /start-service=0) and the service start. The path is resolved before the elevation relaunch so a relative path still works. Hardening, since the file is installed as root/administrator:
  • salt-pip runs from / (Linux) or %SystemRoot% (Windows), not from the requirements file's directory. "python -m pip" puts the working directory first on sys.path, so running from a directory others can write to would let them run code as root. Local package paths in the file must therefore be absolute; nested -r files still resolve against the file.
  • salt-pip is only used from its fixed locations (/usr/bin/salt-pip, /opt/saltstack/salt/salt-pip), never found through PATH.
  • The policy-rc.d path is a fixed default, not read from the environment.
  • A world-writable requirements file is refused, and a group-writable one produces a warning.

macOS is not supported: the pkg postinstall starts the minion itself during installer -pkg, leaving no window to install packages first. Tests: ShellSpec specs for validation, the pip step, the working directory and PATH hardening, and the start guard; Pester tests for the new functions; CI steps on Linux, Windows and macOS.

What issues does this PR fix or reference?

Closes #1975

…before Salt starts

Add a requirements-file option to bootstrap-salt.sh (-e FILE) and
bootstrap-salt.ps1 (-PipRequirements FILE) that installs PyPI packages,
such as Salt Extensions, into the Salt onedir with salt-pip after Salt is
installed and before its services are first started. Pinning and custom or
authenticated indexes use normal pip syntax in the file (==, --index-url,
--extra-index-url, PIP_INDEX_URL), so no credentials are needed on the
command line. The file's contents are never printed.

Linux:
- Onedir installs only. -e is rejected up front for git installs, -C,
  macOS, and a missing or package-less file.
- Debian and Ubuntu packages start the service as soon as they are
  installed, even with -X. When -e is used, a temporary policy-rc.d holds
  back service starts until the packages are installed. Any existing
  policy-rc.d is restored afterward, including on failure and signals, via
  the existing exit trap.
- RPM based and other onedir installs only enable the services, so they
  need no guard.

Windows:
- salt-pip.exe runs between the installer finishing (already run with
  /start-service=0) and the service start. The path is resolved before the
  elevation relaunch so a relative path still works.
Hardening, since the file is installed as root/administrator:
- salt-pip runs from / (Linux) or %SystemRoot% (Windows), not from the
  requirements file's directory. "python -m pip" puts the working
  directory first on sys.path, so running from a directory others can
  write to would let them run code as root. Local package paths in the
  file must therefore be absolute; nested -r files still resolve against
  the file.
- salt-pip is only used from its fixed locations (/usr/bin/salt-pip,
  /opt/saltstack/salt/salt-pip), never found through PATH.
- The policy-rc.d path is a fixed default, not read from the environment.
- A world-writable requirements file is refused, and a group-writable one
  produces a warning.

macOS is not supported: the pkg postinstall starts the minion itself during
installer -pkg, leaving no window to install packages first.
Tests: ShellSpec specs for validation, the pip step, the working
directory and PATH hardening, and the start guard; Pester tests for the
new functions; CI steps on Linux, Windows and macOS.

Closes saltstack#1975
@twangboy twangboy self-assigned this Oct 8, 2026
@twangboy
twangboy merged commit 4f0fc61 into saltstack:develop Oct 8, 2026
165 checks passed
@twangboy
twangboy deleted the fix/1975/develop branch October 8, 2026 22:10
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.

[FEATURE REQUEST] A flag to install Salt Extensions and other PyPI packages

1 participant