From 552fd062ea2bb6c2d05faa1e64e172503cacbdbf Mon Sep 17 00:00:00 2001 From: Jean-Philippe Ouellet Date: Thu, 30 Nov 2017 08:52:13 -0500 Subject: [PATCH] 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). --- dom0-updates/qubes-dom0-update | 69 ++++++++++++++-------------------- 1 file changed, 28 insertions(+), 41 deletions(-) diff --git a/dom0-updates/qubes-dom0-update b/dom0-updates/qubes-dom0-update index 7329933..17b9126 100755 --- a/dom0-updates/qubes-dom0-update +++ b/dom0-updates/qubes-dom0-update @@ -30,6 +30,8 @@ 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 @@ -70,25 +72,29 @@ if [ "$YUM_ACTION" == "reinstall" ] || [ "$YUM_ACTION" == "upgrade" ] || [ "$YUM ONEPKG=`cut -f 1 -d ' ' <<<$PKGS` 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 TEMPLATE=${ONEPKG#qubes-template-} # Remove prefix + if qvm-shutdown --wait $TEMPLATE ; then echo "Template VM halted" fi - if ! TEMPLATE_NETVM=`qvm-prefs --force-root $TEMPLATE netvm` \ - || ! BAK_TEMPLATE_ROOT=`qvm-prefs --force-root $TEMPLATE root_img` \ - || ! BAK_TEMPLATE_PRIVATE=`qvm-prefs --force-root $TEMPLATE private_img` ; then - exit 1 - fi - if [[ "$TEMPLATE_NETVM" == *"(default)" ]] ; then - TEMPLATE_NETVM="default" + + # 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 @@ -184,44 +190,25 @@ if [ -z "$YUM_ACTION" ]; then YUM_ACTION=upgrade fi -if [ "x$PKGS" != "x" ]; then - if [[ -n "$BAK_TEMPLATE_ROOT" ]] ; then # Handle template details - # Backup root.img and private.img just in case - 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 +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 "$BAK_TEMPLATE_ROOT" ]] ; then # Handle template details - if [[ $RETCODE -eq 0 && -f "$BAK_TEMPLATE_ROOT" ]]; then - # Reinstall went OK, remove backup files. - rm -f "$BAK_TEMPLATE_ROOT-bak" - rm -f "$BAK_TEMPLATE_PRIVATE-bak" - else - echo "Yum exit: Restoring img files" - mv "$BAK_TEMPLATE_ROOT-bak" "$BAK_TEMPLATE_ROOT" - mv "$BAK_TEMPLATE_PRIVATE-bak" "$BAK_TEMPLATE_PRIVATE" - fi - 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!" + 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