qubes-core-admin-linux/dom0-updates/qubes-dom0-update
Marek Marczykowski-Górecki 03959b670c
dom0-updates: display GUI notification about no updates
If no updates are available, display some notification about that (when
GUI mode requested). Otherwise user has no idea what happened (update
failed? still doing something?).

Fixes QubesOS/qubes-issues#3751
2018-04-21 02:58:30 +02:00

236 lines
7.7 KiB
Bash
Executable File

#!/bin/bash
UPDATEVM=`qubes-prefs --force-root updatevm`
UPDATES_STAT_FILE=/var/lib/qubes/updates/dom0-updates-available
if [ -z "$UPDATEVM" ]; then
echo "UpdateVM not set, exiting"
exit 1
fi
if [ "$1" = "--help" ]; then
echo "This tool is used to download packages for dom0. Without package list"
echo "it checks for updates for installed packages"
echo ""
echo "Usage: $0 [--clean] [--check-only] [--gui] [<pkg list>]"
echo " --clean clean yum cache before doing anything"
echo " --check-only only check for updates (no install)"
echo " --gui use gpk-update-viewer for update selection"
echo " --action=... use specific yum action, instead of automatic install/update"
echo " <pkg list> download (and install if run by root) new packages"
echo " in dom0 instead of updating"
exit
fi
PKGS=
YUM_OPTS=
GUI=
CHECK_ONLY=
ALL_OPTS="$*"
YUM_ACTION=
QVMRUN_OPTS=
CLEAN=
TEMPLATE=
TEMPLATE_BACKUP=
# Filter out some yum options and collect packages list
while [ $# -gt 0 ]; do
case "$1" in
--enablerepo=*|\
--disablerepo=*)
;;
--clean)
CLEAN=1
;;
--gui)
GUI=1
;;
--check-only)
CHECK_ONLY=1
;;
--action=*)
YUM_ACTION=${1#--action=}
;;
-*)
YUM_OPTS="$YUM_OPTS $1"
;;
*)
PKGS="$PKGS $1"
if [ -z "$YUM_ACTION" ]; then
YUM_ACTION=install
fi
;;
esac
shift
done
# Prevent implicit update of template - this would override user changes -
# but do allow explicit template upgrade, downgrade, reinstall
if [ "$YUM_ACTION" == "reinstall" ] || [ "$YUM_ACTION" == "upgrade" ] || [ "$YUM_ACTION" == "upgrade-to" ] \
|| [ "$YUM_ACTION" == "downgrade" ] && [[ "$PKGS" == *"qubes-template-"* ]]; then
TEMPLATE_EXCLUDE_OPTS=""
echo "WARNING: Replacing a template will erase all files in template's /home and /rw !"
ONEPKG=`cut -f 1 -d ' ' <<<$PKGS`
if [[ "$ONEPKG" == "qubes-template-"* ]] && [[ "$ONEPKG" == "${PKGS#\ }" ]]; then # test "$PKGS" minus space
ONEPKG=`sed -r 's/-[0-9]+(\.[0-9-]+)+(\.noarch)*$//' <<<$ONEPKG` # Remove version suffix
TEMPLATE=${ONEPKG#qubes-template-} # Remove prefix
if qvm-shutdown --wait $TEMPLATE ; then
echo "Template VM halted"
fi
# Try to avoid unrecoverable failures when operating on the template of
# the UpdateVM by making a backup first.
UPDATEVM_TEMPLATE=$(qvm-prefs -- "$UPDATEVM" template 2>/dev/null)
if [ X"$UPDATEVM_TEMPLATE" = X"$TEMPLATE" ]; then
TEMPLATE_BACKUP="${TEMPLATE}-backup-$(date +%Y%m%d)-$(mktemp -u XXXX)"
TEMPLATE_BACKUP=${TEMPLATE_BACKUP:0:32}
echo "Attempting to operate on template of UpdateVM... backing up $TEMPLATE to $TEMPLATE_BACKUP"
if ! qvm-clone -- "$TEMPLATE" "$TEMPLATE_BACKUP"; then
echo "ERROR: Unable to make backup of UpdateVM template!" >&2
exit 1
fi
fi
else
echo "ERROR: Specify only one package to reinstall template"
exit 1
fi
else
TEMPLATE_EXCLUDE_OPTS="--exclude=`rpm -qa --qf '%{NAME},' qubes-template-\*`"
fi
YUM_OPTS="$TEMPLATE_EXCLUDE_OPTS $YUM_OPTS"
ALL_OPTS="$TEMPLATE_EXCLUDE_OPTS $ALL_OPTS"
ID=$(id -ur)
if [ $ID != 0 -a -z "$GUI" -a -z "$CHECK_ONLY" ] ; then
echo "This script should be run as root (when used in console mode), use sudo." >&2
exit 1
fi
if [ "$GUI" == "1" -a -n "$PKGS" ]; then
echo "ERROR: GUI mode can be used only for updates" >&2
exit 1
fi
if [ "$GUI" == "1" ]; then
apps="xterm konsole yumex apper gpk-update-viewer"
if [ -n "$KDE_FULL_SESSION" ]; then
apps="konsole xterm apper yumex gpk-update-viewer"
fi
guiapp=
for app in $apps; do
if type $app &>/dev/null; then
guiapp=$app
case $guiapp in
apper) guiapp="apper --updates --nofork" ;;
xterm) guiapp="xterm -e sudo dnf update" ;;
konsole) guiapp="konsole --hold -e sudo dnf update" ;;
*) guiapp=$app ;;
esac
break;
fi
done
if [ -z "$guiapp" ]; then
message1="You don't have any supported yum frontend installed."
message2="Install (using qubes-dom0-update) one of: $apps"
if [ "$KDE_FULL_SESSION" ]; then
kdialog --sorry "$message1<br/>$message2"
else
zenity --error --text "$message1\n$message2"
fi
exit 1
fi
fi
if [ "$GUI" != "1" ]; then
QVMRUN_OPTS=--nogui
fi
# Do not start VM automatically when running from cron (only checking for updates)
if [ "$CHECK_ONLY" == "1" ] && ! qvm-check -q --running $UPDATEVM > /dev/null 2>&1; then
echo "ERROR: UpdateVM not running, not starting it in non-interactive mode" >&2
exit 1
fi
if [ -n "$CLEAN" ]; then
rm -f /var/lib/qubes/updates/rpm/*
rm -f /var/lib/qubes/updates/repodata/*
fi
rm -f /var/lib/qubes/updates/errors
echo "Using $UPDATEVM as UpdateVM to download updates for Dom0; this may take some time..." >&2
# qvm-run by default auto-starts the VM if not running
qvm-run --nogui -q -u root $UPDATEVM 'mkdir -m 775 -p /var/lib/qubes/dom0-updates/' || exit 1
qvm-run --nogui -q -u root $UPDATEVM 'chown user:user /var/lib/qubes/dom0-updates/' || exit 1
qvm-run --nogui -q $UPDATEVM 'rm -rf /var/lib/qubes/dom0-updates/etc' || exit 1
tar c /var/lib/rpm /etc/yum.repos.d /etc/yum.conf 2>/dev/null | \
qvm-run --nogui --pass-io "$UPDATEVM" 'LC_MESSAGES=C tar x -C /var/lib/qubes/dom0-updates 2>&1 | grep -v -E "s in the future"'
qvm-run $QVMRUN_OPTS --pass-io $UPDATEVM "script --quiet --return --command '/usr/lib/qubes/qubes-download-dom0-updates.sh --doit --nogui $ALL_OPTS' /dev/null"
RETCODE=$?
if [ "$CHECK_ONLY" == "1" ]; then
exit $RETCODE
elif [ "$RETCODE" -ne 0 ]; then
exit $RETCODE
fi
# Wait for download completed
while pidof -x qubes-receive-updates >/dev/null; do sleep 0.5; done
if [ -r /var/lib/qubes/updates/errors ]; then
echo "*** ERROR while receiving updates:" >&2
cat /var/lib/qubes/updates/errors >&2
echo "--> if you want to use packages that were downloaded correctly, use yum directly now" >&2
exit 1
fi
if [ -z "$YUM_ACTION" ]; then
YUM_ACTION=upgrade
fi
if [ -n "$PKGS" ]; then
if [ -n "$TEMPLATE" ]; then
TEMPLATE_NETVM=$(qvm-prefs --force-root $TEMPLATE netvm)
fi
dnf $YUM_OPTS $YUM_ACTION $PKGS ; RETCODE=$?
if [ -n "$TEMPLATE_BACKUP" -a "$RETCODE" -eq 0 ]; then
# Remove backup, if we made one. Better to do this only on success and
# potentially leave extra backups around than do it on an exit trap and
# clean up more reliably but potentially brick a system.
qvm-remove -- "$TEMPLATE_BACKUP"
fi
if [ -n "$TEMPLATE" -a -n "$TEMPLATE_NETVM" -a x"$TEMPLATE_NETVM" != xNone ]; then
if ! qvm-prefs --force-root -s $TEMPLATE netvm $TEMPLATE_NETVM; then
echo "ERROR: NetVM setting could not be restored!" >&2
exit 1
fi
fi
elif [ -f /var/lib/qubes/updates/repodata/repomd.xml ]; then
# Above file exists only when at least one package was downloaded
if [ "$GUI" == "1" ]; then
# refresh packagekit metadata, GUI utilities use it
pkcon refresh force
$guiapp
else
dnf check-update
if [ $? -eq 100 ]; then # Run yum with options
dnf $YUM_OPTS $YUM_ACTION
fi
fi
dnf -q check-update && rm -f $UPDATES_STAT_FILE
else
rm -f $UPDATES_STAT_FILE
echo "No updates available" >&2
if [ "$GUI" == "1" ]; then
zenity --title='Dom0 updates' --text='No updates available'
fi
fi