Skip to content
Sirio is in private beta: sources and installer are sent to testers by email. Ask to join.

System packages

Sirio lists the updates available on the host and applies them: all at once, only the selected ones, or the two cleanup operations (autoremove and clearing the cache). It’s the same thing you’d do with apt from the command line, with the advantage of seeing in one table what’s behind and how much of that backlog is security-related.

Detection looks at which binary is present, not /etc/os-release, so it also works on derivatives. The search order is apt-get, dnf, yum, apk — dnf before yum because on RHEL 8+ yum is now a symlink to dnf.

Manager Distributions Notes
apt Debian, Ubuntu, Mint, Raspberry Pi OS, Devuan, Proxmox full support
dnf Fedora, RHEL 8+, Rocky, Alma, CentOS Stream full; the installed version comes from rpm -qa
yum CentOS 7, RHEL 7 like dnf, with update instead of upgrade
apk Alpine listing and upgrading only: see below

On everything else (pacman, zypper, portage) the section shows up empty and says so.

The list is always read without privileges, but they don’t all report the same things.

  • Installed version. apt and apk put it next to the available one. dnf check-update doesn’t, so it’s derived from a single call to rpm -qa; if rpm is missing, the column stays empty and the rest of the list still works.
  • Security updates. apt infers them from the source archive, dnf and yum from check-update --security (on very old yum a plugin is needed: without it, none get flagged). Alpine has no such concept: there’s no separate archive to infer it from, so the security counter stays at zero.
  • Available operations. apk has no autoremove and keeps the cache off by default, so it only declares refresh list and upgrade. The page doesn’t show buttons that would fail: it reads the possible actions from GET /api/packages (the status.actions field).

The trigger is a systemd .path unit, which doesn’t exist on Alpine. There, listing still works — it needs no privileges — but applying updates needs something to run the helper when a request shows up. The equivalent crontab line is:

* * * * * [ -f /var/lib/sirio/packages/richiesta ] && /usr/local/lib/sirio/sirio-pkg

The protocol is the same: the helper consumes the request and writes the log and result. This applies to any init system other than systemd, not just Alpine.

This is the part worth understanding, because it explains the three files install.sh puts on the machine.

sirio-sysadmin.service runs as the sirio user, not root, with NoNewPrivileges=true and ProtectSystem=strict. In that namespace /usr, /etc and /var/lib/dpkg are read-only: apt wouldn’t work even if Sirio were root, and sudo is blocked outright by NoNewPrivileges. The only writable directory is SIRIO_DATA_DIR.

Instead of loosening the hardening of the whole service, the privileged operation lives outside it:

panel → /var/lib/sirio/packages/richiesta (single channel, written by Sirio)
↓ sirio-pkg.path
sirio-pkg.service (root, oneshot, unsandboxed)
↓
/usr/local/lib/sirio/sirio-pkg → apt-get
↓
job/<id>.log + job/<id>.esito (Sirio reads and shows them)

Sirio never runs the helper itself: it writes one file and reads two files. The log is streamed line by line to the page over WebSocket while apt works.

It’s the same reasoning behind why the reverse proxy runs as a container instead of a host service: the hardening stays in place, and whatever needs more privileges moves outside it.

The set is closed and is checked twice: by Sirio before writing the request, and by the helper — which runs as root — before executing it. The request file is written by a process less trusted than the one reading it, so its contents are never taken at face value.

Action apt dnf / yum apk
Refresh list apt-get update makecache apk update
Update all apt-get upgrade upgrade (yum: update) apk upgrade
Update selected install --only-upgrade -- <names> upgrade <names> apk upgrade -- <names>
Remove unused apt-get autoremove autoremove —
Clear cache apt-get clean clean all —

None of the update selected variants installs a package that isn’t already present: --only-upgrade for apt, and for dnf/yum/apk the upgrade verb on a package that isn’t installed does nothing.

Everything else is rejected. In particular:

  • no dist-upgrade/full-upgrade: they remove packages, and that’s not what you’d expect from an “update” button;
  • no installing or removing arbitrary packages: --only-upgrade installs nothing new, and the only names accepted are the ones already present in the list of upgradable packages;
  • names must match ^[A-Za-z0-9][A-Za-z0-9+._-]*(:arch)?$ — the union of the Debian, RPM and Alpine naming policies. It’s not one specific manager’s rule, and that’s intentional: what must be impossible is passing something a shell or an option parser could interpret, while whether the name actually exists is established by the check against the upgradable list and by the manager itself;
  • for apt and apk a -- closes the options, so a name can never become a flag even if the validation failed; dnf5 (Fedora 41+) rejects -- after upgrade, so for dnf/yum it’s the name rule above — a letter or digit first, never - — that keeps names from being options. Nothing is ever concatenated into a shell string: the manager receives a list of arguments;
  • even the manager to use comes from the request, but the helper re-validates it against its own closed set and checks that the binary exists.

Operations run one at a time: apt takes the dpkg lock regardless, and two in parallel would just produce an unreadable error.

If the helper isn’t installed — install.sh skips it when apt-get isn’t present — the section still works, but read-only: the list of updates is obtained without privileges (apt-get -s upgrade), applying them is not. The page says so and disables the buttons.

To install the helper afterwards:

Terminal window
sudo install -d -m 0755 /usr/local/lib/sirio
sudo install -m 0755 deploy/sirio-pkg /usr/local/lib/sirio/sirio-pkg
sudo install -m 0644 deploy/sirio-pkg.service deploy/sirio-pkg.path /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now sirio-pkg.path

To remove it, just do the reverse: systemctl disable --now sirio-pkg.path and delete the three files. The section goes back to read-only with no other changes.

Some updates (kernel, libc) need a reboot to take effect. Sirio shows the warning by reading /var/run/reboot-required and the packages that created it. The panel doesn’t perform the reboot: it’s an operation that interrupts the hosted sites, and has to be decided by whoever knows when they can afford it.

Symptom Likely cause
“no response from sirio-pkg” the unit isn’t active: systemctl status sirio-pkg.path
“apt exited with code 100” the dpkg lock is held, often by unattended-upgrades. The full output is in the operation’s log
List stuck on an old date an apt-get update is missing: that’s the Refresh list button
The section is empty on Debian SIRIO_PACKAGES_ENABLED=false, or apt-get isn’t in the service’s PATH

The activity log records who requested what; the operations history keeps the log and result of the last SIRIO_PACKAGES_RETENTION runs.

They don’t conflict: unattended-upgrades keeps doing its job, and Sirio sees the result on the next list refresh. The only friction is the dpkg lock when the two happen at the same time — in that case the panel’s operation fails with an explicit error and can be retried.