Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 105 additions & 24 deletions dom0-updates/qubes-dom0-update
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ if [ "$1" = "--help" ]; then
echo " --force-xen-upgrade force major Xen upgrade even if some qubes are running"
echo " --console does nothing; ignored for backward compatibility"
echo " --show-output does nothing; ignored for backward compatibility"
echo " --silent do not print anything to stdout"
echo " --preserve-terminal does nothing; ignored for backward compatibility"
echo " --skip-boot-check does not check if /boot & /boot/efi should be mounted"
echo " --switch-audio-server-to=(pulseaudio|pipewire) switch audio daemon to pipewire or pulseaudio"
Expand All @@ -46,6 +47,7 @@ YUM_OPTS=()
UPDATEVM_OPTS=()
QVMTEMPLATE_OPTS=()
GUI=
PROGRESS_REPORTING=
CHECK_ONLY=
CLEAN=
TEMPLATE=
Expand Down Expand Up @@ -79,6 +81,12 @@ while [ $# -gt 0 ]; do
--show-output)
# ignore
;;
--silent)
exec > /dev/null
;;
--just-print-progress)
PROGRESS_REPORTING=1
;;
--check-only)
CHECK_ONLY=1
UPDATEVM_OPTS+=( "$1" )
Expand Down Expand Up @@ -310,40 +318,111 @@ qvm-run --nogui -q -- "$UPDATEVM" "rm -rf -- '$dom0_updates_dir/etc' '$dom0_upda
exit "$status"
}

CMD="/usr/lib/qubes/qubes-download-dom0-updates.sh --doit --nogui"
QVMRUN_OPTS=(--quiet --filter-escape-chars --nogui --pass-io)

# We avoid using bash’s own facilities for this, as they produce $'\n'-style
# strings in certain cases. These are not portable, whereas the string produced
# by the following is.
for i in "${UPDATEVM_OPTS[@]}"; do CMD+=" '${i//\'/\'\\\'\'}'"; done
progress_agent_version="4.3"

QVMRUN_OPTS=(--quiet --filter-escape-chars --nogui --pass-io)
if [[ -t 1 ]] && [[ -t 2 ]]; then
# Use ‘script’ to emulate a TTY, so that we get status bars and other
# progress output. Since stdout and stderr are both terminals, qvm-run
# will automatically sanitize them, but we explicitly tell it to anyway
# as a precaution.
#
# We MUST NOT use ‘exec script’ here. That causes ‘script’ to
# inherit the child processes of the shell. ‘script’ mishandles
# this and enters an infinite loop.
CMD="script --quiet --return --command '${CMD//\'/\'\\\'\'}' /dev/null"
get_base_vm() {
# Resolve base VM (TemplateVM or StandaloneVM)
local vm="$1"
while true; do
# If it's a TemplateVM or StandaloneVM, stop
if qvm-check --template "$vm" &>/dev/null || qvm-check --standalone "$vm" &>/dev/null; then
echo "$vm"
return
fi
# Try to get its template
vm=$(qvm-prefs "$vm" template 2>/dev/null) || return 1
done
}
version_check() {
# Compare version numbers (e.g., 4.2 < 4.3)
awk 'BEGIN {exit !(ARGV[1] < ARGV[2])}' "$1" "$2"
}
base_vm=$(get_base_vm "$UPDATEVM")
OLD_VERSION=0
if [ -n "$base_vm" ]; then
agent_version=$(qvm-features "$base_vm" qubes-agent-version 2>/dev/null)

if [ -n "$agent_version" ] && version_check "$agent_version" "$progress_agent_version"; then
OLD_VERSION=1
fi
fi

qvm-run "${QVMRUN_OPTS[@]}" -- "$UPDATEVM" "$CMD" < /dev/null

RETCODE=$?
if [[ "$REMOTE_ONLY" = '1' ]] || [ "$RETCODE" -ne 0 ]; then
if [ "$PROGRESS_REPORTING" == "1" ] && [ "$OLD_VERSION" == "0" ]; then
CMD="/usr/lib/qubes/qubes-download-dom0-updates-init.sh"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to handle the case of old template too. It's okay to refuse this mode in such a case, but it needs a proper error message instead of a file not found error. Something like "Progress reporting requires updatevm based on a template with Qubes 4.3 packages", or something like this (maybe include template name and/or name of the updatevm?)
Whether it is new enough, you can check either by handling exit code 127 (file not found), or (better) by announcing some supported feature in the core-agent-linux PR and checking it here.

qvm-run "${QVMRUN_OPTS[@]}" -- "$UPDATEVM" "$CMD" || exit 1

update_agent_log="/var/log/qubes/qubes-update"
qvm-run --nogui -q -u root -- "$UPDATEVM" "user=\$(qubesdb-read /default-user) && chown -R -- \"\$user:qubes\" '$update_agent_log'" || exit 1

# "--no-cleanup" is needed since fakeroot cannot remove entrypoint
qubes-vm-update --force-update --targets "$UPDATEVM" --signal-no-updates --just-print-progress --display-name dom0 --download-only --no-cleanup --show-output --log=INFO ; RETCODE=$?
if [ "${RETCODE-0}" -eq 100 ]; then
echo "$(hostname):out: Nothing to do."
echo "$(hostname) done no_updates" >&2
exit 100
fi
if [ "${RETCODE-0}" -ne 0 ]; then
echo "$(hostname) done error" >&2
exit "$RETCODE"
fi

# qubes-vm-update leaves the downloaded packages with root ownership
qvm-run --nogui -q -u root -- "$UPDATEVM" "user=\$(qubesdb-read /default-user) && chown -R -- \"\$user:qubes\" '$dom0_updates_dir'" || exit 1

CMD="/usr/lib/qubes/qubes-download-dom0-updates-finish.sh"
qvm-run "${QVMRUN_OPTS[@]}" -- "$UPDATEVM" "$CMD" || exit 1
else
if [ "$PROGRESS_REPORTING" == "1" ] && [ "$OLD_VERSION" == "1" ]; then
echo "$(hostname):out: Progress reporting requires updateVM based on a template with Qubes 4.3 packages."
fi
CMD="/usr/lib/qubes/qubes-download-dom0-updates.sh --doit --nogui"

# We avoid using bash’s own facilities for this, as they produce $'\n'-style
# strings in certain cases. These are not portable, whereas the string produced
# by the following is.
for i in "${UPDATEVM_OPTS[@]}"; do CMD+=" '${i//\'/\'\\\'\'}'"; done

if [[ -t 1 ]] && [[ -t 2 ]]; then
# Use ‘script’ to emulate a TTY, so that we get status bars and other
# progress output. Since stdout and stderr are both terminals, qvm-run
# will automatically sanitize them, but we explicitly tell it to anyway
# as a precaution.
#
# We MUST NOT use ‘exec script’ here. That causes ‘script’ to
# inherit the child processes of the shell. ‘script’ mishandles
# this and enters an infinite loop.
CMD="script --quiet --return --command '${CMD//\'/\'\\\'\'}' /dev/null"
fi
if [ "$PROGRESS_REPORTING" == "1" ]; then
qvm-run "${QVMRUN_OPTS[@]}" -- "$UPDATEVM" "$CMD" < /dev/null | sed "s/^/$(hostname):out: /" ; RETCODE=$?
# "consume" the last empty line
echo ""
else
qvm-run "${QVMRUN_OPTS[@]}" -- "$UPDATEVM" "$CMD" < /dev/null ; RETCODE=$?
fi
fi

if [ "$PROGRESS_REPORTING" == "1" ] && [ "$OLD_VERSION" == "1" ]; then
echo "$(hostname) updating 50.0" >&2
if [ "${RETCODE-0}" -ne 0 ]; then
echo "$(hostname) done error" >&2
exit "$RETCODE"
fi
fi
if [[ "$REMOTE_ONLY" = '1' ]] || [ "${RETCODE-0}" -ne 0 ]; then
if [ "$CHECK_ONLY" = '1' ]; then
if [ "$RETCODE" -eq 100 ]; then
if [ "${RETCODE-0}" -eq 100 ]; then
echo "There are dom0 updates available" >&2
elif [ "$RETCODE" -eq 0 ]; then
elif [ "${RETCODE-0}" -eq 0 ]; then
echo "No dom0 updates available" >&2
else
echo "Failed to check for dom0 updates" >&2
fi
fi
exit $RETCODE
exit "${RETCODE-0}"
fi
# Wait for download completed
while pidof -x qubes-receive-updates >/dev/null; do sleep 0.5; done
Expand Down Expand Up @@ -401,6 +480,9 @@ elif [ -f /var/lib/qubes/updates/repodata/repomd.xml ]; then
# refresh packagekit metadata, GUI utilities use it
pkcon refresh force
$guiapp
elif [ "$PROGRESS_REPORTING" == 1 ]; then
# report progress to the user
qubes-vm-update --no-refresh --targets dom0 --force-update --log=DEBUG --just-print-progress --show-output ; RETCODE=$?
else
dnf check-update ||
if [ $? -eq 100 ]; then # Run dnf with options
Expand All @@ -416,9 +498,8 @@ elif [ -f /var/lib/qubes/updates/repodata/repomd.xml ]; then
fi
fi
else
if ! qvm-features dom0 updates-available '' 2>/dev/null; then
qvm-features dom0 updates-available '' >/dev/null 2>&1 ||
echo "*** WARNING: cannot set feature 'updates-available'" >&2
fi
echo "No updates available" >&2
if [ "$GUI" == "1" ]; then
if [ "$KDE_FULL_SESSION" ]; then
Expand Down
1 change: 1 addition & 0 deletions rpm_spec/core-dom0-linux.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Requires: qubes-core-admin-client
Requires: qubes-utils >= 3.1.3
Requires: qubes-utils-libs >= 4.0.16
Requires: qubes-rpm-oxide
Requires: python-libdnf5
Conflicts: qubes-core-dom0 < 4.0.23
Requires: %{name}-kernel-install
Requires: xdotool
Expand Down
2 changes: 1 addition & 1 deletion vmupdate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
# USA.
# USA.
2 changes: 1 addition & 1 deletion vmupdate/agent/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
# USA.
# USA.
Loading