Can somebody clarifies how qubes-update-check service works and how dom0 gets update notifications for TemplateVMs that are never powered on?

The AppVm checks for the available updates.

In the AppVM, five minutes after the boot, qubes-update-check.timer launches qubes-update-check.service which checks for available updates and then notifies dom0 that update are (not) available for the TemplateVM.

Example with the test-f35 App-VM based on the fedora-35 TemplateVM
[user@test-f35 ~]$ sudo systemctl list-units| grep update
  systemd-update-utmp.service                       loaded active exited    Record System Boot/Shutdown in UTMP
  qubes-update-check.timer                          loaded active waiting   Periodically check for updates
  unbound-anchor.timer                              loaded active waiting   daily update of the root trust anchor for DNSSEC

[user@test-f35 ~]$ systemctl cat qubes-update-check.timer
# /usr/lib/systemd/system/qubes-update-check.timer
[Unit]
Description=Periodically check for updates
ConditionPathExists=/var/run/qubes-service/qubes-update-check

[Timer]
OnBootSec=5min
OnUnitActiveSec=2d

[Install]
WantedBy=multi-user.target

[user@test-f35 ~]$ systemctl cat qubes-update-check.service
# /usr/lib/systemd/system/qubes-update-check.service
[Unit]
Description=Qubes check for VM updates and notify dom0
ConditionPathExists=/var/run/qubes-service/qubes-update-check
After=qubes-qrexec-agent.service

[Service]
Type=oneshot
ExecStart=-/usr/lib/qubes/upgrades-status-notify

[user@test-f35 ~]$ cat /usr/lib/qubes/upgrades-status-notify
#!/usr/bin/bash

set -e

upgrades_installed="$(/usr/lib/qubes/upgrades-installed-check)"

if [ "$upgrades_installed" = "true" ]; then
    /usr/lib/qubes/qrexec-client-vm dom0 qubes.NotifyUpdates /bin/sh -c 'echo 0'
elif [ "$upgrades_installed" = "false" ]; then
    /usr/lib/qubes/qrexec-client-vm dom0 qubes.NotifyUpdates /bin/sh -c 'echo 1'
fi

[user@test-f35 ~]$ cat /usr/lib/qubes/upgrades-installed-check
#!/usr/bin/bash

## `echo`s:
## * 'true' - if all upgrades have been installed
## * 'false' - if there are pending upgrades
## * nothing - if apt-get is currently locked
##
## Forwards the exit code of the package manager.

if [ -e /etc/system-release ]; then
    ## Fedora
    if command -v dnf >/dev/null; then
        yum=dnf
    else
        yum=yum
    fi
    # shellcheck disable=SC2034
    yum_output="$($yum -yq check-update)"
    exit_code="$?"
    [ "$exit_code" -eq 100 ] && echo "false" && exit 0
    [ "$exit_code" -eq 0 ] && echo "true"
elif [ -e /etc/debian_version ]; then

[...]

fi

exit "$exit_code"

2 Likes