package¶
package makes sure a system package is installed, or not installed. Sadame
reads /etc/os-release to pick the package manager, so the same recipe works
on Debian and Ubuntu (apt), Rocky, AlmaLinux and Fedora (dnf), Alpine (apk),
and Arch and Arch-based systems such as Omarchy (pacman). Before acting it
asks the package manager whether the package is installed, and only installs
or removes when the answer differs from the recipe.
Minimal example¶
package "htop"
Options¶
| Option | Type | Default | Description |
|---|---|---|---|
state |
:installed or :absent |
:installed |
Whether the package must be installed. |
options |
String or Array of Strings | none | Extra flags for the install or remove command, placed before the package name. A String is used as is; Array elements are each shell-quoted. |
notifies |
[:action, "type[name]"], optionally with :immediately, or a list of them |
none | Actions to run on other resources when this one changes. See Notifications. |
subscribes |
[:action, "type[name]"], optionally with :immediately, or a list of them |
none | Actions to run on this resource when another one changes. |
tags |
Symbol, String, or an Array of them | none | Tags for running part of a recipe with --tags and --skip-tags. See Tags. |
Commands per package manager¶
NAME is the package name, OPTIONS the options: value.
| Manager | Detected on | Installed when | Install | Remove |
|---|---|---|---|---|
| apt | ID or ID_LIKE is debian, ubuntu |
dpkg-query -W -f='${Status}' NAME ends in installed |
DEBIAN_FRONTEND=noninteractive apt-get install -y OPTIONS NAME |
DEBIAN_FRONTEND=noninteractive apt-get remove -y OPTIONS NAME |
| dnf | rhel, centos, fedora, rocky, almalinux, ol | rpm -q NAME exits 0 |
dnf install -y OPTIONS NAME |
dnf remove -y OPTIONS NAME |
| apk | alpine | apk info -e NAME exits 0 |
apk add OPTIONS NAME |
apk del OPTIONS NAME |
| pacman | arch, archarm, manjaro, endeavouros | pacman -Q NAME exits 0 |
pacman -S --needed --noconfirm OPTIONS NAME |
pacman -Rns --noconfirm OPTIONS NAME |
Index refreshes:
- apt:
DEBIAN_FRONTEND=noninteractive apt-get updateruns once perapply, right before the first install. Runs that install nothing never touch the network. - dnf and apk refresh their metadata themselves.
- pacman: sadame never runs
pacman -Sy. Refreshing the sync database without upgrading (-Sywithout-u) is a partial upgrade, which Arch does not support. Keep the system upgraded withpacman -Syuas usual.
Scenarios¶
The recipe used below:
# Package names are the distribution's own; these exist on Debian, Ubuntu,
# Rocky (with EPEL for htop), Alpine and Arch.
package "tree"
package "htop"
# Make sure a package is not installed.
package "nano", state: :absent
Debian 12¶
$ sudo sadame plan examples/resources/package
sadame 0.5.1 plan on local (Debian GNU/Linux 12 (bookworm))
+ package[tree]
state: absent -> installed
+ package[htop]
state: absent -> installed
Plan: 2 to create, 0 to update, 0 to remove, 0 to run, 1 unchanged.
$ sudo sadame apply examples/resources/package
sadame 0.5.1 apply on local (Debian GNU/Linux 12 (bookworm))
changed package[tree]
state: absent -> installed
changed package[htop]
state: absent -> installed
unchanged package[nano]
Summary
changed 2 package[tree]
package[htop]
unchanged 1
failed 0
skipped 0
notified 0
Finished in 7.04s.
$ sudo sadame plan examples/resources/package
sadame 0.5.1 plan on local (Debian GNU/Linux 12 (bookworm))
Plan: 0 to create, 0 to update, 0 to remove, 0 to run, 3 unchanged.
Arch Linux¶
The same recipe, unchanged, on Arch:
$ sudo sadame plan examples/resources/package
sadame 0.5.1 plan on local (Arch Linux)
+ package[tree]
state: absent -> installed
+ package[htop]
state: absent -> installed
Plan: 2 to create, 0 to update, 0 to remove, 0 to run, 1 unchanged.
$ sudo sadame apply examples/resources/package
sadame 0.5.1 apply on local (Arch Linux)
changed package[tree]
state: absent -> installed
changed package[htop]
state: absent -> installed
unchanged package[nano]
Summary
changed 2 package[tree]
package[htop]
unchanged 1
failed 0
skipped 0
notified 0
Finished in 2.64s.
$ pacman -Q tree htop
tree 2.3.2-1
htop 3.5.3-1
Different names on different distributions¶
Package names are the distribution's own. Choose with plain Ruby:
# Package names are the distribution's own; pick one with plain Ruby.
web_server = platform.family == "debian" ? "apache2" : "httpd"
package web_server
$ sudo sadame plan examples/resources/package/by_family.rb
sadame 0.5.1 plan on local (Debian GNU/Linux 12 (bookworm))
+ package[apache2]
state: absent -> installed
Plan: 1 to create, 0 to update, 0 to remove, 0 to run, 0 unchanged.
AUR packages¶
The package resource does not install from the AUR in this release. Until
it does, use an AUR helper such as yay or paru through
exec, guarded so it only runs when the package is missing:
# AUR packages are not handled by the package resource in sadame 0.1. Use an
# AUR helper through exec, guarded so it only runs when the package is
# missing and the helper is installed. yay and paru refuse to run as root,
# so the command runs as the user named in vars[:aur_user].
exec "runuser -u #{vars[:aur_user]} -- yay -S --needed --noconfirm visual-studio-code-bin",
only_if: "command -v yay",
not_if: "pacman -Q visual-studio-code-bin"
# The AUR helper must run as a normal user. When sadame runs through sudo,
# SUDO_USER is the user who called it.
{
aur_user: ENV["SUDO_USER"] || ENV["USER"]
}
AUR helpers refuse to run as root, which is why the command goes through
runuser. The helper then calls sudo pacman itself, so that user needs to
be able to run pacman with sudo without a password prompt: sadame runs
commands with standard input closed and cannot answer one. Without yay
installed, only_if skips the resource:
$ sudo sadame plan examples/resources/package/aur.rb
sadame 0.5.1 plan on local (Arch Linux)
Plan: 0 to create, 0 to update, 0 to remove, 0 to run, 1 unchanged.
Common mistakes¶
- Fresh Arch containers have no sync database. In the
archlinuxDocker image,pacman -Swarns "database file for 'core' does not exist" and fails with "target not found" untilpacman -Syuhas run once. Installed systems do not have this problem. - Package groups and virtual packages. The installed check asks for the
exact name. A group such as
base-develon Arch, or a name that is only provided by another package, never reports as installed, so it shows up in every plan. Declare the member packages instead. - Expecting upgrades.
state: :installedmeans "some version is installed". Sadame does not upgrade packages in this release. - Mixing families without a condition.
package "apache2"on Rocky fails at apply time with the package manager's own error.
See also¶
- exec for guarded commands, including the AUR workaround.
- service to enable and start what a package installs.
- Recipe basics for
platformandvars.