qubes-dom0-update: Adapt template backup failsafe for R4

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).
This commit is contained in:
Jean-Philippe Ouellet 2017-11-30 08:52:13 -05:00
parent 7a644b6d61
commit 552fd062ea
No known key found for this signature in database
GPG Key ID: 4747332C27533622

View File

@ -30,6 +30,8 @@ ALL_OPTS="$*"
YUM_ACTION= YUM_ACTION=
QVMRUN_OPTS= QVMRUN_OPTS=
CLEAN= CLEAN=
TEMPLATE=
TEMPLATE_BACKUP=
# Filter out some yum options and collect packages list # Filter out some yum options and collect packages list
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
case "$1" in case "$1" in
@ -70,25 +72,29 @@ if [ "$YUM_ACTION" == "reinstall" ] || [ "$YUM_ACTION" == "upgrade" ] || [ "$YUM
ONEPKG=`cut -f 1 -d ' ' <<<$PKGS` ONEPKG=`cut -f 1 -d ' ' <<<$PKGS`
if [[ "$ONEPKG" == "qubes-template-"* ]] && [[ "$ONEPKG" == "${PKGS#\ }" ]]; then # test "$PKGS" minus space if [[ "$ONEPKG" == "qubes-template-"* ]] && [[ "$ONEPKG" == "${PKGS#\ }" ]]; then # test "$PKGS" minus space
# Prepare to backup template root.img in case reinstall doesn't complete.
ONEPKG=`sed -r 's/-[0-9]+(\.[0-9-]+)+(\.noarch)*$//' <<<$ONEPKG` # Remove version suffix ONEPKG=`sed -r 's/-[0-9]+(\.[0-9-]+)+(\.noarch)*$//' <<<$ONEPKG` # Remove version suffix
TEMPLATE=${ONEPKG#qubes-template-} # Remove prefix TEMPLATE=${ONEPKG#qubes-template-} # Remove prefix
if qvm-shutdown --wait $TEMPLATE ; then if qvm-shutdown --wait $TEMPLATE ; then
echo "Template VM halted" echo "Template VM halted"
fi fi
if ! TEMPLATE_NETVM=`qvm-prefs --force-root $TEMPLATE netvm` \
|| ! BAK_TEMPLATE_ROOT=`qvm-prefs --force-root $TEMPLATE root_img` \ # Try to avoid unrecoverable failures when operating on the template of
|| ! BAK_TEMPLATE_PRIVATE=`qvm-prefs --force-root $TEMPLATE private_img` ; then # the UpdateVM by making a backup first.
exit 1 UPDATEVM_TEMPLATE=$(qvm-prefs -- "$UPDATEVM" template 2>/dev/null)
fi if [ X"$UPDATEVM_TEMPLATE" = X"$TEMPLATE" ]; then
if [[ "$TEMPLATE_NETVM" == *"(default)" ]] ; then TEMPLATE_BACKUP="${TEMPLATE}-backup-$(date +%Y%m%d)-$(mktemp -u XXXX)"
TEMPLATE_NETVM="default" 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 fi
else else
echo "ERROR: Specify only one package to reinstall template" echo "ERROR: Specify only one package to reinstall template"
exit 1 exit 1
fi fi
else else
TEMPLATE_EXCLUDE_OPTS="--exclude=`rpm -qa --qf '%{NAME},' qubes-template-\*`" TEMPLATE_EXCLUDE_OPTS="--exclude=`rpm -qa --qf '%{NAME},' qubes-template-\*`"
fi fi
@ -184,44 +190,25 @@ if [ -z "$YUM_ACTION" ]; then
YUM_ACTION=upgrade YUM_ACTION=upgrade
fi fi
if [ "x$PKGS" != "x" ]; then if [ -n "$PKGS" ]; then
if [[ -n "$BAK_TEMPLATE_ROOT" ]] ; then # Handle template details if [ -n "$TEMPLATE" ]; then
# Backup root.img and private.img just in case TEMPLATE_NETVM=$(qvm-prefs --force-root $TEMPLATE netvm)
echo "Creating img backup files"
mv "$BAK_TEMPLATE_ROOT" "$BAK_TEMPLATE_ROOT-bak"
mv "$BAK_TEMPLATE_PRIVATE" "$BAK_TEMPLATE_PRIVATE-bak"
TDIR=`qvm-prefs --force-root $TEMPLATE dir`
if [ -f "$TDIR/firewall.xml" ]; then
mv "$TDIR/firewall.xml" "$TDIR/firewall.xml-bak"
fi
rm -f "$TDIR/volatile.img"
echo "--> Creating private.img..."
truncate -s 2G $BAK_TEMPLATE_PRIVATE
mkfs.ext4 -m 0 -q -F $BAK_TEMPLATE_PRIVATE
chown root:qubes $BAK_TEMPLATE_PRIVATE
chmod 0660 $BAK_TEMPLATE_PRIVATE
fi fi
dnf $YUM_OPTS $YUM_ACTION $PKGS ; RETCODE=$? dnf $YUM_OPTS $YUM_ACTION $PKGS ; RETCODE=$?
if [[ -n "$BAK_TEMPLATE_ROOT" ]] ; then # Handle template details if [ -n "$TEMPLATE_BACKUP" -a "$RETCODE" -eq 0 ]; then
if [[ $RETCODE -eq 0 && -f "$BAK_TEMPLATE_ROOT" ]]; then # Remove backup, if we made one. Better to do this only on success and
# Reinstall went OK, remove backup files. # potentially leave extra backups around than do it on an exit trap and
rm -f "$BAK_TEMPLATE_ROOT-bak" # clean up more reliably but potentially brick a system.
rm -f "$BAK_TEMPLATE_PRIVATE-bak" qvm-remove -- "$TEMPLATE_BACKUP"
else fi
echo "Yum exit: Restoring img files"
mv "$BAK_TEMPLATE_ROOT-bak" "$BAK_TEMPLATE_ROOT" if [ -n "$TEMPLATE" -a -n "$TEMPLATE_NETVM" -a x"$TEMPLATE_NETVM" != xNone ]; then
mv "$BAK_TEMPLATE_PRIVATE-bak" "$BAK_TEMPLATE_PRIVATE" if ! qvm-prefs --force-root -s $TEMPLATE netvm $TEMPLATE_NETVM; then
fi echo "ERROR: NetVM setting could not be restored!" >&2
if [ -f "$TDIR/firewall.xml-bak" ]; then
mv "$TDIR/firewall.xml-bak" "$TDIR/firewall.xml"
fi
if ! qvm-prefs --force-root -s $TEMPLATE netvm $TEMPLATE_NETVM ; then
echo "ERROR: NetVM setting could not be restored!"
exit 1 exit 1
fi fi
fi fi
elif [ -f /var/lib/qubes/updates/repodata/repomd.xml ]; then elif [ -f /var/lib/qubes/updates/repodata/repomd.xml ]; then
# Above file exists only when at least one package was downloaded # Above file exists only when at least one package was downloaded