Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package transactional-update for openSUSE:Factory checked in at 2023-05-10 16:16:44 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/transactional-update (Old) and /work/SRC/openSUSE:Factory/.transactional-update.new.1533 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "transactional-update" Wed May 10 16:16:44 2023 rev:99 rq:1085717 version:4.2.1 Changes: -------- --- /work/SRC/openSUSE:Factory/transactional-update/transactional-update.changes 2023-03-27 18:15:18.046796493 +0200 +++ /work/SRC/openSUSE:Factory/.transactional-update.new.1533/transactional-update.changes 2023-05-10 16:16:46.150351701 +0200 @@ -1,0 +2,24 @@ +Mon May 8 17:38:24 UTC 2023 - Ignaz Forster <ifors...@suse.com> + +- Version 4.2.1 + - Implement "apply" command to switch into new snapshot directly + [jsc#PED-3912] + - Use new snapper functionality to set default snapshot - this + makes it possible to execute hooks as requested in + [poo#127160], [gh#openSUSE/transactional-update#85] and + [gh#openSUSE/transactional-update#105]. + - Don't hardcode GRUB2 [gh#openSUSE/transactional-update#100] / + [poo#127154] + - Fix cleanup handler + - Fix unmounting temporary mounts + - Prevent loosing track of snapshots in certain rollback + scenarios - these would not be marked for deletion otherwise + - Document "notify" reboot method +- Minimal required snapper version is 0.8.10 now, for the new + snapper functionality there is a backwards compatibility layer. +- Conflict with health-checker < 1.8 - the "good" snapshot + detection of GRUB cannot rely on transactional-update any more + due to the new apply command +- Depend on usrmerge for apply command + +------------------------------------------------------------------- Old: ---- transactional-update-4.1.5.tar.gz New: ---- transactional-update-4.2.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ transactional-update.spec ++++++ --- /var/tmp/diff_new_pack.JNZwXM/_old 2023-05-10 16:16:46.730355131 +0200 +++ /var/tmp/diff_new_pack.JNZwXM/_new 2023-05-10 16:16:46.734355155 +0200 @@ -26,7 +26,7 @@ %{!?_distconfdir: %global _distconfdir %{_prefix}%{_sysconfdir}} Name: transactional-update -Version: 4.1.5 +Version: 4.2.1 Release: 0 Summary: Transactional Updates with btrfs and snapshots License: GPL-2.0-or-later AND LGPL-2.1-or-later @@ -64,6 +64,8 @@ BuildRequires: python3-lxml BuildRequires: w3m BuildRequires: xsltproc +# XXX libsolv never sees the rpmlib provides fulfilled +Requires: (compat-usrmerge-tools or rpmlib(X-CheckUnifiedSystemdir)) Requires: /usr/bin/bc Requires: dracut-transactional-update = %{version}-%{release} Requires: logrotate @@ -76,6 +78,7 @@ Recommends: inotify-tools Recommends: rebootmgr Suggests: tukitd = %{version}-%{release} +Conflicts: health-checker < 1.8 %description transactional-update is a tool to update a system in an atomic @@ -111,7 +114,7 @@ Group: System/Libraries Requires: btrfsprogs Requires: rsync -Requires: snapper +Requires: snapper >= 0.8.10 %description -n %{libname} This package contains the libraries required for programs to do ++++++ transactional-update-4.1.5.tar.gz -> transactional-update-4.2.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/transactional-update-4.1.5/NEWS new/transactional-update-4.2.1/NEWS --- old/transactional-update-4.1.5/NEWS 2023-03-23 11:48:29.000000000 +0100 +++ new/transactional-update-4.2.1/NEWS 2023-05-09 14:44:34.000000000 +0200 @@ -2,6 +2,25 @@ Copyright (C) 2016-2022 Thorsten Kukuk, Ignaz Forster et al. +Version 4.2.1 +* Add backwards compatibility with older snapper releases, otherwise + the selfupdate may break if the installed snapper version is too old; + requires snapper 0.8.10 as a minimal base (for rollbacks) now + +Version 4.2.0 +* Implement "apply" command to switch into new snapshot directly +* Use new snapper functionality to set default snapshot - this makes it + possible to execute hooks as requested in [poo#127160], + [gh#openSUSE/transactional-update#85] and + [gh#openSUSE/transactional-update#105]. +* Don't hardcode GRUB2 [gh#openSUSE/transactional-update#85] / + [poo#127154] +* Fix cleanup handler +* Fix unmounting temporary mounts +* Prevent loosing track of snapshots in certain rollback scenarios - these + would not be marked for deletion otherwise +* Document "notify" reboot method + Version 4.1.5 * Add support for configuration file snippets diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/transactional-update-4.1.5/configure.ac new/transactional-update-4.2.1/configure.ac --- old/transactional-update-4.1.5/configure.ac 2023-03-23 11:48:29.000000000 +0100 +++ new/transactional-update-4.2.1/configure.ac 2023-05-09 14:44:34.000000000 +0200 @@ -1,11 +1,11 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT(transactional-update, 4.1.5) +AC_INIT(transactional-update, 4.2.1) # Increase on any interface change and reset revision LIBTOOL_CURRENT=4 # On interface change increase if backwards compatible, reset otherwise LIBTOOL_AGE=0 # Increase on *any* C/C++ library code change, reset at interface change -LIBTOOL_REVISION=3 +LIBTOOL_REVISION=5 AC_CANONICAL_SYSTEM AM_INIT_AUTOMAKE([foreign]) AC_CONFIG_FILES([tukit.pc]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/transactional-update-4.1.5/lib/Overlay.cpp new/transactional-update-4.2.1/lib/Overlay.cpp --- old/transactional-update-4.1.5/lib/Overlay.cpp 2023-03-23 11:48:29.000000000 +0100 +++ new/transactional-update-4.2.1/lib/Overlay.cpp 2023-05-09 14:44:34.000000000 +0200 @@ -104,7 +104,7 @@ tulog.info("Parent snapshot ", previousSnapId, " does not exist any more - skipping rsync"); return; } - unique_ptr<Mount> previousEtc{new Mount("/etc")}; + unique_ptr<Mount> previousEtc{new Mount("/etc", 0, true)}; previousEtc->setTabSource(previousSnapshot->getRoot() / "etc" / "fstab"); // Mount read-only, so mount everything as lowerdir diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/transactional-update-4.1.5/lib/Snapshot/Snapper.cpp new/transactional-update-4.2.1/lib/Snapshot/Snapper.cpp --- old/transactional-update-4.1.5/lib/Snapshot/Snapper.cpp 2023-03-23 11:48:29.000000000 +0100 +++ new/transactional-update-4.2.1/lib/Snapshot/Snapper.cpp 2023-05-09 14:44:34.000000000 +0200 @@ -141,14 +141,22 @@ } void Snapper::setDefault() { - Util::exec("btrfs subvolume set-default " + std::string(getRoot())); + try { + callSnapper("modify --default " + snapshotId); + } catch (const ExecutionException &e) { + Util::exec("btrfs subvolume set-default " + std::string(getRoot())); + } } void Snapper::setReadOnly(bool readonly) { - std::string boolstr = "true"; - if (readonly == false) - boolstr = "false"; - Util::exec("btrfs property set " + std::string(getRoot()) + " ro " + boolstr); + try { + if (readonly == true) + callSnapper("modify --read-only " + snapshotId); + else + callSnapper("modify --read-write " + snapshotId); + } catch (const ExecutionException &e) { + Util::exec("btrfs property set " + std::string(getRoot()) + " ro " + (readonly ? "true" : "false")); + } } /* Helper methods */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/transactional-update-4.1.5/lib/Transaction.cpp new/transactional-update-4.2.1/lib/Transaction.cpp --- old/transactional-update-4.1.5/lib/Transaction.cpp 2023-03-23 11:48:29.000000000 +0100 +++ new/transactional-update-4.2.1/lib/Transaction.cpp 2023-05-09 14:44:34.000000000 +0200 @@ -185,10 +185,12 @@ dirsToMount.push_back(std::move(mntVarTmp)); // Mount platform specific GRUB directories for GRUB updates - for (auto& path: fs::directory_iterator("/boot/grub2")) { - if (fs::is_directory(path)) { - if (BindMount{path.path()}.isMount()) - dirsToMount.push_back(std::make_unique<BindMount>(path.path())); + if (fs::exists("/boot/grub2")) { + for (auto& path: fs::directory_iterator("/boot/grub2")) { + if (fs::is_directory(path)) { + if (BindMount{path.path()}.isMount()) + dirsToMount.push_back(std::make_unique<BindMount>(path.path())); + } } } if (BindMount{"/boot/efi"}.isMount()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/transactional-update-4.1.5/man/transactional-update.8.xml new/transactional-update-4.2.1/man/transactional-update.8.xml --- old/transactional-update-4.1.5/man/transactional-update.8.xml 2023-03-23 11:48:29.000000000 +0100 +++ new/transactional-update-4.2.1/man/transactional-update.8.xml 2023-05-09 14:44:34.000000000 +0200 @@ -155,6 +155,29 @@ </para> <variablelist remap='TP'> <varlistentry> + <term><option>apply</option></term> + <listitem> + <para> + Mounts <filename class='directory'>/usr</filename>, + <filename class='directory'>/etc</filename> and + <filename class='directory'>/boot</filename> of the (new) default + snapshot into the currently running system. This is mostly useful for + using newly installed packages directly without a reboot. When using + apply on a system where existing files will be replaced (e.g. when doing + a system update) this behaves similarly to a regular zypper update where + files of currently running applications will also be replaced, but with + the additional advantage that the update itself was finished successfully + as a whole, avoiding inconsistent states on update failures. + </para> + <para> + Note that - in contrast to regular zypper updates - services will not be + restarted automatically. Additionally mounting the three directories is + not one atomic operation, so there will be a short timespan where the + directories visible to the system will not be in sync. + </para> + </listitem> + </varlistentry> + <varlistentry> <term><option>cleanup</option></term> <listitem> <para>Identical to calling both <option>cleanup-snapshots</option> and @@ -477,6 +500,10 @@ <option>last</option>. <option>last</option> will try to reset to the latest working snapshot. </para> + <para> + This command can be combind with the <option>apply</option> command + to make the snapshot effective immediately. + </para> </listitem> </varlistentry> <varlistentry> @@ -608,6 +635,33 @@ </variablelist> </refsect1> +<refsect1 id='exitstatus'><title>EXIT STATUS</title> +<variablelist> + <varlistentry> + <term><option>0</option></term> + <listitem> + <para>All commands were executed successfully.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><option>1</option></term> + <listitem> + <para>One of the commands returned with an error. Due to that a + potential new snapshot has been deleted again.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><option>2</option></term> + <listitem> + <para>The <option>apply</option> command was not successfull. + If called together with another commands, these commands were completed + successfully, but the new default snapshot will not be set in the + live system.</para> + </listitem> + </varlistentry> +</variablelist> +</refsect1> + <refsect1 id='important'><title>IMPORTANT</title> <para> Only RPMs which are fully part of the root filesystem and @@ -630,7 +684,9 @@ system</emphasis>. Calling <command>transactional-update</command> multiple times without rebooting will <emphasis>not</emphasis> include the changes of the previous - snapshot, thus effectively discarding all previous changes. + snapshot, thus effectively discarding all previous changes (except when + using <option>--continue</option> to explicitly continue a previous snapshot + or when <option>apply</option> was called previously). </para> </refsect1> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/transactional-update-4.1.5/man/transactional-update.conf.5.xml new/transactional-update-4.2.1/man/transactional-update.conf.5.xml --- old/transactional-update-4.1.5/man/transactional-update.conf.5.xml 2023-03-23 11:48:29.000000000 +0100 +++ new/transactional-update-4.2.1/man/transactional-update.conf.5.xml 2023-05-09 14:44:34.000000000 +0200 @@ -138,6 +138,16 @@ </listitem> </varlistentry> <varlistentry> + <term><literal>notify</literal></term> + <listitem> + <para> + Trigger the <application>Transactional Update + Notifier</application> to inform the user about the + necessary reboot. + </para> + </listitem> + </varlistentry> + <varlistentry> <term><literal>none</literal></term> <listitem> <para> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/transactional-update-4.1.5/sbin/transactional-update.in new/transactional-update-4.2.1/sbin/transactional-update.in --- old/transactional-update-4.1.5/sbin/transactional-update.in 2023-03-23 11:48:29.000000000 +0100 +++ new/transactional-update-4.2.1/sbin/transactional-update.in 2023-05-09 14:44:34.000000000 +0200 @@ -30,6 +30,7 @@ REWRITE_GRUB_CFG=0 REWRITE_INITRD=0 REBUILD_KDUMP_INITRD=0 +DO_APPLY=0 DO_CLEANUP_OVERLAYS=0 DO_CLEANUP_SNAPSHOTS=0 DO_MIGRATION=0 @@ -91,6 +92,7 @@ SNAPSHOT_DIR="" BASE_SNAPSHOT_ID="" TMPFILE="" +APPLYWORKDIR="" DO_CALLEXT=0 declare -A ROLES=() @@ -137,6 +139,7 @@ echo "system." echo "" echo "General Commands:" + echo "apply Switch into default snapshot without reboot" echo "cleanup Run both cleanup-snapshots and cleanup-overlays" echo "cleanup-snapshots Mark unused snapshots for snapper removal" echo "cleanup-overlays Remove unused overlay layers" @@ -292,6 +295,14 @@ # Cleanup temporary files rm -f ${TMPFILE} + if [ -d "${APPLYWORKDIR}" ]; then + if mountpoint --quiet "${APPLYWORKDIR}/mount"; then + umount --recursive "${APPLYWORKDIR}/mount" + fi + rmdir "${APPLYWORKDIR}/mount" + rmdir "${APPLYWORKDIR}" + fi + # The following commands only make sense if snapshot dir is set already if [ "${SNAPSHOT_DIR}" = "" ]; then return @@ -301,6 +312,97 @@ rm -rf ${SNAPSHOT_DIR}/run/* } +do_apply() { + if [ -n "${SNAPSHOT_ID}" -o -n "${ROLLBACK_SNAPSHOT}" -o "${DEFAULT_SNAPSHOT_ID}" != "${CURRENT_SNAPSHOT_ID}" ]; then + NEW_DEFAULT_SNAPSHOT_ID=`btrfs subvolume get-default / | sed -e 's|.*.snapshots/\(.*\)/snapshot|\1|g'` + if ! APPLYWORKDIR="$(mktemp -d /tmp/transactional-update.apply.XXXXXXXX)"; then + log_error "ERROR during apply: Temporary directory template failed." + fi + if ! mkdir "${APPLYWORKDIR}/mount"; then + log_error "ERROR during apply: Couldn't create mount directory." + fi + + sourcedevice="$(findmnt --target /usr --raw --noheadings --output SOURCE --nofsroot | tail -n 1)" + # Mount new snapshot as base + if ! mount "${sourcedevice}" "${APPLYWORKDIR}/mount"; then + log_error "ERROR during apply: Mounting ${sourcedevice} to ${APPLYWORKDIR}/mount failed." + quit 2 + fi + # Mount /etc overlay + if [ "$(findmnt --noheadings --nofsroot --output FSTYPE /etc | tail -n 1)" == "overlay" ]; then + if ! mount overlay -t overlay -o "$(findmnt --tab-file "${APPLYWORKDIR}/mount/etc/fstab" --noheadings --nofsroot --output OPTIONS /etc | sed 's/\/sysroot//g' | sed 's/:\/etc,/:\/.snapshots\/'${NEW_DEFAULT_SNAPSHOT_ID}'\/snapshot\/etc,/g')" "${APPLYWORKDIR}/mount/etc"; then + log_error "ERROR during apply: Mounting /etc overlay failed." + quit 2 + fi + fi + # Find and mount potential submounts + VISIBLEMOUNTS=(/usr /etc /boot) + for line in $(findmnt --raw --noheadings --nofsroot --output TARGET -d forward | grep -E "^/(usr|etc|boot)"); do + for i in ${!VISIBLEMOUNTS[@]}; do + if [[ $line == ${VISIBLEMOUNTS[$i]} ]]; then + while [ $i -lt ${#VISIBLEMOUNTS[@]} ]; do + if [[ ${VISIBLEMOUNTS[$i]} == ${line}* ]]; then + unset -v VISIBLEMOUNTS[$i] + VISIBLEMOUNTS=("${VISIBLEMOUNTS[@]}") + else + ((i++)) + fi + done + break + fi + done + VISIBLEMOUNTS+=(${line}) + done + for dir in ${VISIBLEMOUNTS[@]}; do + if [[ $dir =~ ^/(usr|etc|boot)$ ]]; then + continue; + fi + dir="$(echo -e ${dir})" + if ! mount --bind "${dir}" "${APPLYWORKDIR}/mount/${dir}"; then + log_error "ERROR during apply: Bind-mounting ${dir} failed." + quit 2 + fi + done + if ! mount --make-rprivate "${APPLYWORKDIR}/mount"; then + log_error "ERROR during apply: make-rprivate failed." + quit 2 + fi + + log_info "" + log_info "Using default snapshot ${NEW_DEFAULT_SNAPSHOT_ID} to replace running system..." + + # Mount new snapshot into running system + for rbinddir in usr etc boot; do + log_info "Applying /${rbinddir}..." + if ! mount --rbind "${APPLYWORKDIR}/mount/${rbinddir}" "/${rbinddir}"; then + log_error "ERROR during apply: Mounting /${rbinddir} failed!" + for dir in ${rbinddir_done}; do + umount "/${dir}" + done + quit 2 + fi + rbinddir_done="${rbinddir_done} ${rbinddir}" + done + + umount --lazy "${APPLYWORKDIR}/mount" + rmdir "${APPLYWORKDIR}/mount" + rmdir "${APPLYWORKDIR}" + + log_info "Executing systemctl daemon-reexec..." + systemctl daemon-reexec + log_info "Executing create_dirs_from_rpmdb..." + create_dirs_from_rpmdb + log_info "Executing systemd-tmpfiles --create..." + systemd-tmpfiles --create + + log_info "=> Applied default snapshot as new base for running system!" + log_info " Running processes will not be restarted automatically." + else + log_info "" + log_info "The default snapshot is active already." + fi +} + reboot_via_rebootmgr() { TELEM_PAYLOAD="${TELEM_PAYLOAD}\nreboot=rebootmgr" tukit reboot rebootmgr |& tee -a ${LOGFILE} @@ -892,6 +994,10 @@ shift fi ;; + apply) + DO_APPLY=1 + shift + ;; run) test -z "$TELEM_CLASS" && TELEM_CLASS="shell" DO_RUN=1 @@ -1011,7 +1117,7 @@ exec {origstderr}>&2 # Log stderr to log file in case anything goes wrong within transactional-update -exec 2> >(exec tee -a "${LOGFILE}" >&2) +exec 2> >(exec tee -i -a "${LOGFILE}" >&2) if [ "${VERBOSITY}" -eq 1 ]; then exec 1>/dev/null if [ -n "${ZYPPER_ARG}" ]; then @@ -1065,7 +1171,7 @@ # If no commands were given, assume "up" if [ -z "${ZYPPER_ARG}" -a -z "${TELEM_CLASS}" -a "${REBOOT_AFTERWARDS}" -eq 0 \ -a "${DO_REGISTRATION}" -eq 0 -a "${DO_CLEANUP_OVERLAYS}" -eq 0 \ - -a "${DO_CLEANUP_SNAPSHOTS}" -eq 0 ]; then + -a "${DO_CLEANUP_SNAPSHOTS}" -eq 0 -a "${DO_APPLY}" -eq 0 ]; then ZYPPER_ARG="up" TELEM_CLASS="update" fi @@ -1155,7 +1261,8 @@ ZYPPER_ARG="--gpg-auto-import-keys ${ZYPPER_ARG}" fi -CURRENT_SNAPSHOT_ID=`grep subvol=/@/.snapshots/ /proc/mounts | grep "/ btrfs" | sed -e 's|.*.snapshots/\(.*\)/snapshot.*|\1|g'` +BOOTED_SNAPSHOT_ID=`grep subvol=/@/.snapshots/ /proc/mounts | grep "/ btrfs" | sed -e 's|.*.snapshots/\(.*\)/snapshot.*|\1|g'` +CURRENT_SNAPSHOT_ID=`findmnt --target /usr --raw --noheadings --output FSROOT | tail -n 1 | sed -e 's|.*.snapshots/\(.*\)/snapshot.*|\1|g'` DEFAULT_SNAPSHOT_ID=`btrfs subvolume get-default / | sed -e 's|.*.snapshots/\(.*\)/snapshot|\1|g'` RO_ROOT=`btrfs property get / ro | sed -e 's|ro=||'` @@ -1181,34 +1288,35 @@ log_info "Rollback to snapshot ${ROLLBACK_SNAPSHOT}..." + snapper rollback "${ROLLBACK_SNAPSHOT}" + if [ $? -ne 0 ]; then + log_error "ERROR: Rollback to snapshot $ROLLBACK_SNAPSHOT failed!" + quit 1 + fi if [ ${RO_ROOT} == "true" ]; then - BTRFS_ID=`btrfs subvolume list -o /.snapshots | grep /.snapshots/${ROLLBACK_SNAPSHOT}/snapshot | awk '{print $2}'` - if [ -z $BTRFS_ID ]; then - log_error "ERROR: couldn't determine btrfs subvolume ID" - quit 1 - else - btrfs subvolume set-default $BTRFS_ID /.snapshots - if [ $? -ne 0 ]; then - log_error "ERROR: btrfs set-default $BTRFS_ID failed!" - quit 1 - fi - # Create the trigger to re-register the system as new version after next - # reboot. - check_registration_on_next_reboot + # Create the trigger to re-register the system as new version after next + # reboot. + check_registration_on_next_reboot + # Remove possible cleanup algo and re-add to list + if ! ( echo "${LAST_WORKING_SNAPSHOTS} ${UNUSED_SNAPSHOTS}" | grep --word-regexp --quiet "${ROLLBACK_SNAPSHOT}" ); then + UNUSED_SNAPSHOTS="${UNUSED_SNAPSHOTS} ${ROLLBACK_SNAPSHOT}" + save_state_file 0 fi - # Remove possible cleanup algo - snapper modify -c '' ${ROLLBACK_SNAPSHOT} if [ ${NEED_REBOOT_WARNING} -eq 0 ]; then rm -f "${NEEDS_RESTARTING_FILE}" fi else - snapper rollback ${ROLLBACK_SNAPSHOT} NEED_REBOOT_WARNING=1 fi if [ ${NEED_REBOOT_WARNING} -eq 1 ]; then - log_error "Please reboot to finish rollback!" + if [ ${DO_APPLY} -eq 1 ]; then + do_apply + else + log_error "Please reboot to finish rollback!" + fi fi + log_info "transactional-update finished" telem_finish 0 exit 0 fi @@ -1230,10 +1338,11 @@ # if [ ${DO_CLEANUP_SNAPSHOTS} -eq 1 ]; then # If there is a list of working snapshots, go through it and mark any snapshot for deletion, if it is - # not the currently used one or the active one. + # not the currently used one, the booted one (still required for health-checker rollbacks) or the + # active one. if [ -n "${LAST_WORKING_SNAPSHOTS}" ]; then for snap in ${LAST_WORKING_SNAPSHOTS}; do - if [ ${CURRENT_SNAPSHOT_ID} -ne ${snap} ]; then + if [ ${CURRENT_SNAPSHOT_ID} -ne ${snap} -a ${BOOTED_SNAPSHOT_ID} -ne ${snap} ]; then log_info "Adding cleanup algorithm to snapshot #${snap}" snapper modify -c number ${snap} |& tee -a ${LOGFILE} if [ ${PIPESTATUS[0]} -ne 0 ]; then @@ -1266,13 +1375,15 @@ UNUSED_SNAPSHOTS="${UNUSED_SNAPSHOTS} ${snap}" done - # Always try to cleanup all snapshots; only the current snapshot and an - # eventual new default one needs to be kept. + # Always try to cleanup all snapshots; only the current snapshot, the + # one which the system was booted from and some parts of the system + # may still use, and an eventual new default one needs to be kept. if [ -n "${UNUSED_SNAPSHOTS}" ]; then _new_unused="" for snap in ${UNUSED_SNAPSHOTS}; do # Don't mark our current in use snapshot for deletion if [ ${snap} -ne ${CURRENT_SNAPSHOT_ID} ] && \ + [ ${snap} -ne ${BOOTED_SNAPSHOT_ID} ] && \ [ ${snap} -ne ${DEFAULT_SNAPSHOT_ID} ]; then log_info "Mark unused snapshot #${snap} for deletion" snapper modify -c number ${snap} |& tee -a ${LOGFILE} @@ -1284,7 +1395,7 @@ _new_unused="${snap} ${_new_unused}" fi fi - elif [ ${snap} -ne ${CURRENT_SNAPSHOT_ID} ]; then + elif [ ${snap} -ne ${CURRENT_SNAPSHOT_ID} -a ${snap} -ne ${BOOTED_SNAPSHOT_ID} ]; then # This is the snapshot which is currently in use, so keep it in # the list. We would probably never clean it up later otherwise. _new_unused="${snap} ${_new_unused}" @@ -1409,7 +1520,7 @@ # Rebuild grub.cfg if /etc/os-release changes, could change grub # menu output, too. cmp -s /etc/os-release ${SNAPSHOT_DIR}/etc/os-release - if [ $? -ne 0 ]; then + if [ $? -ne 0 -a -x /usr/sbin/grub2-mkconfig ]; then REWRITE_GRUB_CFG=1 fi source <(grep VERSION_ID ${SNAPSHOT_DIR}/etc/os-release) @@ -1569,7 +1680,7 @@ if [ ${EXITCODE} -ne 0 ]; then quit ${EXITCODE} - elif [ $REBOOT_AFTERWARDS -eq 0 ]; then + elif [ $REBOOT_AFTERWARDS -eq 0 -a $DO_APPLY -ne 1 ]; then log_info "" log_info "Please reboot your machine to activate the changes and avoid data loss." touch "${NEEDS_RESTARTING_FILE}" @@ -1586,6 +1697,10 @@ log_info "New default snapshot is #${SNAPSHOT_ID} (${SNAPSHOT_DIR})." fi +if [ ${DO_APPLY} -eq 1 -a ${EXITCODE} -eq 0 ]; then + do_apply +fi + log_info "transactional-update finished" if [ ${EXITCODE} -eq 0 ]; then