552fd062ea
Perhaps the UpdateVM template should be temporarily switched to the backup too. That would make it really failsafe. Currently it requires manual recovery (by setting template of UpdateVM to the backup).
228 lines
7.2 KiB
Bash
Executable File
228 lines
7.2 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="yumex apper gpk-update-viewer"
|
|
|
|
if [ -n "$KDE_FULL_SESSION" ]; then
|
|
apps="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" ;;
|
|
*) guiapp=$app ;;
|
|
esac
|
|
break;
|
|
fi
|
|
done
|
|
|
|
if [ -z "$guiapp" ]; then
|
|
message1="You don't have installed any supported yum frontend."
|
|
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 automaticaly when running from cron (only checking for updates)
|
|
if [ "$CHECK_ONLY" == "1" ] && ! xl domid $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
|
|
|
|
# Start VM if not running already
|
|
qvm-start --skip-if-running $UPDATEVM
|
|
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
|
|
$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 avaliable" >&2
|
|
fi
|