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"