Noninteractive System Upgrades

Vendor configuration defaults of zypper are very conservative.

  1. Astute users may want to tweak solver default settings and some more options:
3400g:~ # grep ^solver /etc/zypp/zypp.conf
solver.onlyRequires = true
solver.allowVendorChange = true
solver.dupAllowVendorChange = true
solver.cleandepsOnRemove = true
3400g:~ # 

  1. Use of priorities allows for safe non-interactive operation: https://www.youtube.com/watch?v=x8kEaJU6hlw
3400g:~ # zypper repos --alias --uri --refresh --show-enabled-only --priority
#  | Alias                               | Enabled | GPG Check | Refresh | Priority | URI
---+-------------------------------------+---------+-----------+---------+----------+--------------------------------------------------------------------------------------------------
 5 | Packman                             | Yes     | (r ) Yes  | Yes     |   90     | https://ftp.fau.de/packman/suse/openSUSE_Tumbleweed/
28 | repo-non-oss                        | Yes     | (r ) Yes  | Yes     |   99     | https://cdn.opensuse.org/tumbleweed/repo/non-oss/
29 | repo-oss                            | Yes     | (r ) Yes  | Yes     |   99     | https://cdn.opensuse.org/tumbleweed/repo/oss/
31 | repo-update                         | Yes     | (r ) Yes  | Yes     |   99     | https://cdn.opensuse.org/update/tumbleweed/
 1 | Application_Geo                     | Yes     | (r ) Yes  | Yes     |  100     | https://cdn.opensuse.org/repositories/Application:/Geo/openSUSE_Tumbleweed/
 8 | brave-browser                       | Yes     | (r ) Yes  | Yes     |  100     | https://brave-browser-rpm-release.s3.brave.com/x86_64/
12 | home_Herbster0815_HTPC              | Yes     | (r ) Yes  | Yes     |  100     | https://cdn.opensuse.org/repositories/home:/Herbster0815:/HTPC/openSUSE_Tumbleweed/
15 | home_SquarePeg79                    | Yes     | (r ) Yes  | Yes     |  100     | https://cdn.opensuse.org/repositories/home:/SquarePeg79/openSUSE_Tumbleweed/
18 | home_eyecreate_branches_filesystems | Yes     | (r ) Yes  | Yes     |  100     | https://cdn.opensuse.org/repositories/home:/eyecreate:/branches:/filesystems/openSUSE_Tumbleweed/
19 | home_kukuk_qmapshack                | Yes     | (r ) Yes  | Yes     |  100     | https://cdn.opensuse.org/repositories/home:/kukuk:/qmapshack/openSUSE_Tumbleweed/
22 | jalbum                              | Yes     | ( p) Yes  | Yes     |  100     | https://jalbum.net/download/software/yumrepo/
35 | utilities                           | Yes     | (r ) Yes  | Yes     |  100     | https://cdn.opensuse.org/repositories/utilities/openSUSE_Factory/
3400g:~ # 

  1. Use of transactional upgrade options will not impair running processes and allows for simple rollback:
    a. GitHub - openSUSE/transactional-update: Atomic updates for Linux operating systems
    b. GitHub - pavinjosdev/atomic-update: Atomic (transactional) update for openSUSE systems with read-write root filesystems

  2. Running the upgrade as a systemd service ensures robustness:

3400g:~ # systemctl cat dup.service 
# /etc/systemd/system/dup.service
[Unit] 
Description=Dist Upgrade

[Service] 
ExecStartPre=/usr/bin/nm-online
ExecStart=/usr/bin/zypper --non-interactive dist-upgrade

# /etc/systemd/system/service.d/failure-notification.conf
[Unit]
OnFailure=failure-notification@%n
3400g:~ # 
1 Like

Thanks for creating this post. :white_check_mark:

This was both a blessing and curse IME, as in during the recent Packman Mesa updates which were rolled out gradually over the course of 2-3 days, the nightly dup failed without changing vendor. Allowing vendor change resulted in a successful dup, but mixing Mesa packages from both openSUSE and Packman resulted in issues for some users including myself, losing the ability to use Wayland session in Gnome.

Cleaning dependencies have sometimes resulted in a lot of packages (useful) being removed by default. I now check the output with and without clean deps in dry run mode before choosing an appropriate course of action.

1 Like

Infamous host erlangen was upgraded noninteractively from 20240319-0 → 20240403-0:

erlangen:~ # grep ^solver /etc/zypp/zypp.conf
solver.onlyRequires = true
solver.allowVendorChange = true
solver.dupAllowVendorChange = true
solver.cleandepsOnRemove = true
erlangen:~ # 
erlangen:~ # zypper repos --alias --uri --refresh --show-enabled-only --priority
#  | Alias                               | Enabled | GPG Check | Refresh | Priority | URI
---+-------------------------------------+---------+-----------+---------+----------+--------------------------------------------------------------------------------------------------
 7 | Packman                             | Yes     | (r ) Yes  | Yes     |   90     | https://ftp.fau.de/packman/suse/openSUSE_Tumbleweed/
28 | non-oss                             | Yes     | (r ) Yes  | Yes     |   99     | https://cdn.opensuse.org/tumbleweed/repo/non-oss/
30 | oss                                 | Yes     | (r ) Yes  | Yes     |   99     | https://cdn.opensuse.org/tumbleweed/repo/oss/
37 | update                              | Yes     | (r ) Yes  | Yes     |   99     | https://cdn.opensuse.org/update/tumbleweed/
 9 | brave-browser                       | Yes     | (r ) Yes  | Yes     |  100     | https://brave-browser-rpm-release.s3.brave.com/x86_64
16 | home_Herbster0815_HTPC              | Yes     | (r ) Yes  | Yes     |  100     | https://cdn.opensuse.org/repositories/home:/Herbster0815:/HTPC/openSUSE_Tumbleweed/
18 | home_SquarePeg79                    | Yes     | (r ) Yes  | Yes     |  100     | https://cdn.opensuse.org/repositories/home:/SquarePeg79/openSUSE_Tumbleweed/
19 | home_Stan8                          | Yes     | (r ) Yes  | Yes     |  100     | https://cdn.opensuse.org/repositories/home:/Stan8/openSUSE_Tumbleweed/
22 | home_eyecreate_branches_filesystems | Yes     | (r ) Yes  | Yes     |  100     | https://cdn.opensuse.org/repositories/home:/eyecreate:/branches:/filesystems/openSUSE_Tumbleweed/
23 | home_k-hb                           | Yes     | (r ) Yes  | Yes     |  100     | https://cdn.opensuse.org/repositories/home:/k-hb/openSUSE_Tumbleweed/
24 | home_kukuk_qmapshack                | Yes     | (r ) Yes  | Yes     |  100     | https://cdn.opensuse.org/repositories/home:/kukuk:/qmapshack/openSUSE_Tumbleweed/
25 | jalbum                              | Yes     | ( p) Yes  | Yes     |  100     | https://jalbum.net/download/software/yumrepo/
38 | utilities                           | Yes     | (r ) Yes  | Yes     |  100     | https://cdn.opensuse.org/repositories/utilities/openSUSE_Factory/
erlangen:~ # 
erlangen:~ # journalctl -b -1 -u dup -g 'following|Consumed'
Apr 04 18:46:45 erlangen zypper[6996]: The following 3864 packages are going to be upgraded:
Apr 04 18:46:45 erlangen zypper[6996]: The following 35 patterns are going to be upgraded:
Apr 04 18:46:45 erlangen zypper[6996]: The following product is going to be upgraded:
Apr 04 18:46:45 erlangen zypper[6996]: The following 20 NEW packages are going to be installed:
Apr 04 18:46:45 erlangen zypper[6996]: The following package requires a system reboot:
Apr 04 19:02:48 erlangen systemd[1]: dup.service: Consumed 11min 32.408s CPU time.
erlangen:~ # 
1 Like

Host erlangen is your main machine right? Aren’t you afraid of browser 0-days and such to go 2 weeks without updating? :thinking:

Repos of infamous host erlangen provide three versions:

erlangen:~ # zypper search --details --match-exact Mesa.x86_64
Loading repository data...
Reading installed packages...

S  | Name | Type    | Version                                    | Arch   | Repository
---+------+---------+--------------------------------------------+--------+-----------------------
i+ | Mesa | package | 24.0.3-1699.373.pm.1                       | x86_64 | Packman
v  | Mesa | package | 24.0.3-371.2                               | x86_64 | Haupt-Repository (OSS)
v  | Mesa | package | 24.1.0+git.20240405T002541~c891a384e-600.1 | x86_64 | home:Herbster0815:HTPC
erlangen:~ # 

Priorities ensure consistent upgrades:

erlangen:~ # zypper search --details --installed-only Mesa.x86_64
Loading repository data...
Reading installed packages...

S  | Name                      | Type    | Version              | Arch   | Repository
---+---------------------------+---------+----------------------+--------+-----------------------
i+ | Mesa                      | package | 24.0.3-1699.373.pm.1 | x86_64 | Packman
i+ | Mesa-demo-x               | package | 9.0.0-3.3            | x86_64 | Haupt-Repository (OSS)
i+ | Mesa-dri                  | package | 24.0.3-1699.372.pm.2 | x86_64 | Packman
i+ | Mesa-gallium              | package | 24.0.3-1699.372.pm.2 | x86_64 | Packman
i+ | Mesa-libEGL1              | package | 24.0.3-1699.373.pm.1 | x86_64 | Packman
i+ | Mesa-libGL1               | package | 24.0.3-1699.373.pm.1 | x86_64 | Packman
i+ | Mesa-libglapi0            | package | 24.0.3-1699.373.pm.1 | x86_64 | Packman
i+ | Mesa-libva                | package | 24.0.3-1699.372.pm.2 | x86_64 | Packman
i+ | Mesa-vulkan-device-select | package | 24.0.3-1699.372.pm.2 | x86_64 | Packman
erlangen:~ # 

Cleaning dependencies have sometimes resulted in a lot of packages (useful) being removed by default.

zypper remove --clean-deps and future zypper dist-upgrade --remove-unneeded delete auto-installed packages only.

  1. Packages reinstalled with zypper install ... will be flagged as " i+" (installed by user request) and will be never removed again.
  2. Alternatively users may remove packages from /var/lib/zypp/AutoInstalled.
1 Like

Thanks, I think I understand your setup/workflow better now.

  1. solver.onlyRequires = true means zypper would only pull in the absolute minimum and everything else would have to be explicitly installed which would prevent any accidental deletions by solver.cleandepsOnRemove = true.
  2. solver.dupAllowVendorChange = true with correct repo priorities means zypper would pull in the highest version from the available vendors without complaining. Performing dup every week or two (possibly on the weekends?) insulates you from Packman for example being a few days late to build their new/higher version of packages, thereby preventing flip-flopping between the two vendors.

Very cool setup btw :sunglasses:

Completed yet another successful nightly remote backup and atomic dup:

Apr 06 03:00:00 suse-pc systemd[1]: Starting Backup and atomic update...
Apr 06 03:00:00 suse-pc check-device[28749]: Checks passed. Proceeding...
Apr 06 03:00:01 suse-pc borgmatic[28761]: /etc/borgmatic/config.yaml: Running 7 commands for pre-backup hook
...
Apr 06 03:06:12 suse-pc flatpak[1437]: Nothing to do.
Apr 06 03:06:12 suse-pc atomic-update[1459]: 2024-04-06 03:06:12,983: INFO: Starting atomic distribution upgrade...
Apr 06 03:06:14 suse-pc atomic-update[1459]: 2024-04-06 03:06:14,410: INFO: Using snapshot 910 as base for new snapshot 937
Apr 06 03:06:15 suse-pc atomic-update[1459]: 2024-04-06 03:06:15,613: INFO: Verifying snapshot prior to update...
Apr 06 03:06:20 suse-pc atomic-update[1459]: 2024-04-06 03:06:20,045: INFO: Checking for packages to upgrade
Apr 06 03:06:22 suse-pc atomic-update[1459]: 2024-04-06 03:06:22,324: INFO: Performing distribution upgrade within chroot...
...
Apr 06 03:06:45 suse-pc atomic-update[1459]: 2024-04-06 03:06:45,261: INFO: Distribution upgrade completed successfully
Apr 06 03:06:45 suse-pc atomic-update[1459]: 2024-04-06 03:06:45,261: INFO: Verifying snapshot post update...
Apr 06 03:06:50 suse-pc atomic-update[1459]: 2024-04-06 03:06:50,937: INFO: Setting snapshot 937 (/.snapshots/937/snapshot) as the new default
Apr 06 03:06:50 suse-pc atomic-update[1459]: 2024-04-06 03:06:50,956: INFO: Cleaning up...
Apr 06 03:06:51 suse-pc atomic-update[1459]: 2024-04-06 03:06:51,796: INFO: Using default snapshot 937 to replace running system...
Apr 06 03:06:51 suse-pc atomic-update[1459]: 2024-04-06 03:06:51,796: INFO: Applying /usr...
Apr 06 03:06:51 suse-pc atomic-update[1459]: 2024-04-06 03:06:51,813: INFO: Applying /etc...
Apr 06 03:06:51 suse-pc atomic-update[1459]: 2024-04-06 03:06:51,817: INFO: Applying /boot...
Apr 06 03:06:51 suse-pc atomic-update[1459]: 2024-04-06 03:06:51,845: INFO: Executing systemctl daemon-reexec...
Apr 06 03:06:53 suse-pc atomic-update[1459]: 2024-04-06 03:06:53,189: INFO: Executing systemd-tmpfiles --create...
Apr 06 03:06:53 suse-pc atomic-update[1459]: 2024-04-06 03:06:53,215: INFO: Applied default snapshot as new base for running system
Apr 06 03:06:53 suse-pc atomic-update[1459]: 2024-04-06 03:06:53,215: INFO: Running processes will not be restarted automatically
Apr 06 03:06:53 suse-pc atomic-update[1459]: 2024-04-06 03:06:53,215: INFO: Until the next reboot, bootloader changes must be made from a new atomic snapshot
Apr 06 03:06:53 suse-pc systemd[1]: bkupd.service: Deactivated successfully.
Apr 06 03:06:53 suse-pc systemd[1]: Finished Backup and atomic update.
Apr 06 03:06:53 suse-pc systemd[1]: bkupd.service: Consumed 2min 42.657s CPU time.

Systemd units:

pavin@suse-pc:~> systemctl cat bkupd.*
# /etc/systemd/system/bkupd.service
[Unit]
Description=Backup and atomic update

[Service]
Type=oneshot
ExecStartPre=/usr/local/bin/check-device
ExecStartPre=/usr/bin/borgmatic --verbosity 1 --syslog-verbosity 1
ExecStartPre=-/usr/bin/zypperoni ref
ExecStartPre=-/usr/bin/zypperoni --no-confirm dup-download
ExecStartPre=-/usr/bin/flatpak update --noninteractive
ExecStart=/usr/bin/atomic-update --apply dup

# /etc/systemd/system/bkupd.timer
[Unit]
Description=Backup and atomic update

[Timer]
Unit=bkupd.service
OnCalendar=*-*-* 03:00:00

[Install]
WantedBy=timers.target

Gave ZYPP_SINGLE_RPMTRANS a try:

6700k:~ # head /etc/zypp/zypp.conf
## Configuration file for software management
## /etc/zypp/zypp.conf
##
## Boolean values are 0 1 yes no on off true false


[main]
techpreview.ZYPP_SINGLE_RPMTRANS=1

##
6700k:~ # 

From: libzypp: Environment Variables

Variables related to commit

  • ZYPP_IS_RUNNING=1 Set during commit so packages pre/post/trigger scripts can detect whether rpm was called from within libzypp.
  • ZYPP_SINGLE_RPMTRANS=1 Enable alternative and !!!experimental!!! commit strategy where all rpm operations are executed in a single rpm transaction, which results in much faster commits.

Backend: classic_rpmtrans

6700k:~ # journalctl -b -1 -u dup -g 'following|Consumed'
Apr 06 05:04:27 6700k zypper[8741]: The following 2605 packages are going to be upgraded:
Apr 06 05:04:27 6700k zypper[8741]: The following 32 patterns are going to be upgraded:
Apr 06 05:04:27 6700k zypper[8741]: The following product is going to be upgraded:
Apr 06 05:04:27 6700k zypper[8741]: The following 17 NEW packages are going to be installed:
Apr 06 05:04:27 6700k zypper[8741]: The following 2 packages are going to be REMOVED:
Apr 06 05:04:27 6700k zypper[8741]: The following package requires a system reboot:
Apr 06 05:20:51 6700k systemd[1]: dup.service: Consumed 11min 39.317s CPU time.
6700k:~ # 

Backend: single_rpmtrans

6700k:~ # journalctl -b -u dup -g 'following|Consumed'
Apr 06 05:28:15 6700k zypper[3292]: The following 2605 packages are going to be upgraded:
Apr 06 05:28:15 6700k zypper[3292]: The following 32 patterns are going to be upgraded:
Apr 06 05:28:15 6700k zypper[3292]: The following product is going to be upgraded:
Apr 06 05:28:15 6700k zypper[3292]: The following 17 NEW packages are going to be installed:
Apr 06 05:28:15 6700k zypper[3292]: The following 2 packages are going to be REMOVED:
Apr 06 05:28:15 6700k zypper[3292]: The following package requires a system reboot:
Apr 06 05:39:53 6700k systemd[1]: dup.service: Consumed 9min 6.579s CPU time.
6700k:~ # 

11min 39s vs. 9min 6s corresponds to a 28% speedup. Commit time is a small fraction of total time needed to upgrade,

1 Like

Matches with my own results. :white_check_mark:

Indeed, the main time sink right now is the sequential processing of RPM scripts.
According to zypp devs, this is an upstream RPM drawback that’s unlikely to be fixed improved in the near future.

Yep. Both zypper and rpm are running single threads. While duping infamous host erlangen is virtually idle. Multi-threaded code nearly always keeps all cores busy:

erlangen:~ # inxi -C
CPU:
  Info: 8-core model: AMD Ryzen 7 5700G with Radeon Graphics bits: 64
    type: MT MCP cache: L2: 4 MiB
  Speed (MHz): avg: 1049 min/max: 400/4673 cores: 1: 2997 2: 400 3: 2999
    4: 400 5: 400 6: 3006 7: 400 8: 400 9: 400 10: 2996 11: 400 12: 400 13: 400
    14: 400 15: 400 16: 400
erlangen:~ # 
1 Like

Yep. Infamous host erlangen is optimized with regard to performance/€ as well as performance/maintenance.

The builtin backup drive holds another Tumbleweed installation which gets quarterly upgrades:

erlangen:/Backup # journalctl --directory /Backup/@/var/log/journal/ -b -u transactional-update.service -g 'following|Consumed'
Apr 07 12:13:35 backup transactional-update[2951]: The following 2664 packages are going to be upgraded:
Apr 07 12:13:35 backup transactional-update[2951]: The following 27 patterns are going to be upgraded:
Apr 07 12:13:35 backup transactional-update[2951]: The following product is going to be upgraded:
Apr 07 12:13:35 backup transactional-update[2951]: The following 33 NEW packages are going to be installed:
Apr 07 12:13:35 backup transactional-update[2951]: The following 10 packages are going to be REMOVED:
Apr 07 12:13:35 backup transactional-update[2951]: The following package requires a system reboot:
Apr 07 12:32:06 backup transactional-update[23336]: The following package is going to be REMOVED:
Apr 07 12:32:08 backup transactional-update[1707]: Warning: The following files were changed in the snapshot, but are shadowed by
Apr 07 12:32:08 backup systemd[1]: transactional-update.service: Consumed 5min 41.734s CPU time.
erlangen:/Backup # 

Consumed cpu time is 5min 41s. Total upgrade time including download at 6 MB/s is 18min 33s.

1 Like

Had a major DE upgrade from Gnome 45 → 46 on Slowroll today. Smooth upgrade:

pavin@suse-pc:~> sudo journalctl --since today -u bkupd.service -g 'following|consumed'
Apr 09 03:17:51 suse-pc atomic-update[31107]: The following item is locked and will not be changed by any action:
Apr 09 03:17:51 suse-pc atomic-update[31107]: The following 2069 packages are going to be upgraded:
Apr 09 03:17:51 suse-pc atomic-update[31107]: The following 19 patterns are going to be upgraded:
Apr 09 03:17:51 suse-pc atomic-update[31107]: The following product is going to be upgraded:
Apr 09 03:17:51 suse-pc atomic-update[31107]: The following 256 packages are going to be downgraded:
Apr 09 03:17:51 suse-pc atomic-update[31107]: The following 11 packages are going to be reinstalled:
Apr 09 03:17:51 suse-pc atomic-update[31107]: The following 43 NEW packages are going to be installed:
Apr 09 03:17:51 suse-pc atomic-update[31107]: The following 30 packages are going to be REMOVED:
Apr 09 03:50:03 suse-pc systemd[1]: bkupd.service: Consumed 1h 37min 14.888s CPU time.

Smooth experience with ThinkBook :

thinkbook:~ # systemctl cat aup.service 
# /etc/systemd/system/aup.service
[Unit]
Description=Distribution Upgrade 

[Service]
ExecStartPre=/usr/bin/nm-online
ExecStart=/usr/bin/atomic-update --no-verify dup
thinkbook:~ # 
thinkbook:~ # journalctl -b -u aup -g 'following|Consumed'
Apr 13 08:31:37 thinkbook atomic-update[11434]: The following 2 items are locked and will not be changed by any action:
Apr 13 08:31:37 thinkbook atomic-update[11434]: The following 326 packages are going to be upgraded:
Apr 13 08:31:37 thinkbook atomic-update[11434]: The following 10 patterns are going to be upgraded:
Apr 13 08:31:37 thinkbook atomic-update[11434]: The following product is going to be upgraded:
Apr 13 08:31:37 thinkbook atomic-update[11434]: The following NEW package is going to be installed:
Apr 13 08:32:53 thinkbook systemd[1]: aup.service: Consumed 1min 9.953s CPU time.
thinkbook:~ # 

I am wondering about snapshots #506 and #507:

thinkbook:~ # snapper list
   # | Type   | Pre # | Date                     | User | Cleanup | Description           | Userdata       
-----+--------+-------+--------------------------+------+---------+-----------------------+----------------
  0  | single |       |                          | root |         | current               |                
  1- | single |       | Sat Jun  3 10:46:58 2023 | root |         | first root filesystem |                
474  | pre    |       | Tue Mar 26 21:51:46 2024 | root | number  | zypp(zypper)          | important=yes  
475  | post   |   474 | Tue Mar 26 21:52:01 2024 | root | number  |                       | important=yes  
482  | pre    |       | Thu Mar 28 05:53:53 2024 | root | number  | zypp(zypper)          | important=yes  
493  | pre    |       | Sat Mar 30 18:35:24 2024 | root | number  | zypp(zypper)          | important=no   
494  | post   |   493 | Sat Mar 30 18:35:27 2024 | root | number  |                       | important=no   
495  | pre    |       | Sat Mar 30 22:56:51 2024 | root | number  | zypp(zypper)          | important=yes  
496  | post   |   495 | Sat Mar 30 23:01:31 2024 | root | number  |                       | important=yes  
497  | pre    |       | Thu Apr  4 21:25:24 2024 | root | number  | zypp(zypper)          | important=yes  
498  | post   |   497 | Thu Apr  4 21:25:56 2024 | root | number  |                       | important=yes  
499  | pre    |       | Thu Apr  4 21:26:26 2024 | root | number  | zypp(zypper)          | important=yes  
500  | post   |   499 | Thu Apr  4 21:26:28 2024 | root | number  |                       | important=yes  
501  | pre    |       | Mon Apr  8 15:01:34 2024 | root | number  | zypp(zypper)          | important=yes  
502  | post   |   501 | Mon Apr  8 15:02:31 2024 | root | number  |                       | important=yes  
503  | pre    |       | Sat Apr 13 08:24:43 2024 | root | number  | zypp(zypper)          | important=yes  
504  | post   |   503 | Sat Apr 13 08:24:48 2024 | root | number  |                       | important=yes  
505+ | single |       | Sat Apr 13 08:31:34 2024 | root | number  | Atomic update of #1   | atomic=finished
506  | pre    |       | Sat Apr 13 08:31:37 2024 | root | number  | zypp(zypper)          | important=yes  
507  | post   |   506 | Sat Apr 13 08:32:52 2024 | root | number  |                       | important=yes  
thinkbook:~ # 

atomic-update (AU) without options --apply and --reboot and with option --no-verify is only recommended when performing aup interactively.
Otherwise high risk of losing changes made to root filesystem after aup and relatively lower risk of rebooting into or applying a faulty update that breaks existing systemd services. The latter part is where AU has some advantage over TU.

These are read-only snapshots created by the zypper plugin pre/post zypper action. Useful to keep it even when using AU as AU/TU snaps are read-write and there’s the potential to clobber it. No such risk with the read-only snaps even if everything goes catastrophically wrong.

I got it.

Tested manual rollback:

  1. btrfs subvolume set-default 266 /

  2. Booted into first root filesystem:

thinkbook:~ # snapper list
   # | Type   | Pre # | Date                     | User | Cleanup | Description           | Userdata     
-----+--------+-------+--------------------------+------+---------+-----------------------+--------------
  0  | single |       |                          | root |         | current               |              
  1* | single |       | Sat Jun  3 10:46:58 2023 | root |         | first root filesystem |              
501  | pre    |       | Mon Apr  8 15:01:34 2024 | root | number  | zypp(zypper)          | important=yes
502  | post   |   501 | Mon Apr  8 15:02:31 2024 | root | number  |                       | important=yes
503  | pre    |       | Sat Apr 13 08:24:43 2024 | root | number  | zypp(zypper)          | important=yes
504  | post   |   503 | Sat Apr 13 08:24:48 2024 | root | number  |                       | important=yes
505  | pre    |       | Sat Apr 13 12:26:22 2024 | root | number  | zypp(zypper)          | important=yes
506  | post   |   505 | Sat Apr 13 12:27:37 2024 | root | number  |                       | important=yes
507  | pre    |       | Sat Apr 13 19:57:37 2024 | root | number  | zypp(zypper)          | important=yes
508  | post   |   507 | Sat Apr 13 19:58:10 2024 | root | number  |                       | important=yes
509  | pre    |       | Sat Apr 13 19:58:39 2024 | root | number  | zypp(zypper)          | important=yes
510  | post   |   509 | Sat Apr 13 19:58:42 2024 | root | number  |                       | important=yes
511  | pre    |       | Sun Apr 14 03:56:42 2024 | root | number  | zypp(zypper)          | important=no 
512  | post   |   511 | Sun Apr 14 03:57:10 2024 | root | number  |                       | important=no 
thinkbook:~ # 
  1. Deleted subvolume created by AU.

  2. zypper dist-upgrade worked as expected:

thinkbook:~ # journalctl -b -2 -u dup| grep -EA2 'following|Consumed|Tumbleweed'
Apr 13 19:57:37 thinkbook zypper[12293]: The following 75 packages are going to be upgraded:
Apr 13 19:57:37 thinkbook zypper[12293]:   akonadi-calendar akonadi-calendar-tools akonadi-calendar-tools-lang akonadi-import-wizard akonadi-import-wizard-lang akonadi-plugin-calendar akregator akregator-lang calendarsupport cpupower cpupower-bash-completion cpupower-lang eventviews grep grep-lang incidenceeditor kaccounts-providers kaccounts-providers-lang kalendarac kdepim-addons kdepim-addons-lang kdepim-runtime kdepim-runtime-lang kdeplasma6-addons kdeplasma6-addons-lang khelpcenter khelpcenter-lang kmail kmail-application-icons kmail-lang kontact kontact-lang korganizer korganizer-lang ktnef lensfun-data libcpupower1 libKPim6AkonadiCalendar6 libKPim6AkonadiCalendar6-lang libKPim6CalendarSupport6 libKPim6CalendarSupport6-lang libKPim6EventViews6 libKPim6EventViews6-lang libKPim6ImportWizard6 libKPim6IncidenceEditor6 libKPim6IncidenceEditor6-lang libKPim6MailCommon6 libksieve libksieve6 libksieve-lang liblensfun1 mailcommon mailcommon-lang mbox-importer mbox-importer-lang messagelib messagelib-lang openSUSE-build-key openSUSE-release openSUSE-release-appliance-custom pam pam-config pam-manpages pim-data-exporter pim-data-exporter-lang pim-sieve-editor pim-sieve-editor-lang plasma6-nm plasma6-nm-lang plasma6-nm-openconnect plasma6-nm-openvpn plasma6-nm-pptp postfix signon-ui update-alternatives
Apr 13 19:57:37 thinkbook zypper[12293]: The following product is going to be upgraded:
Apr 13 19:57:37 thinkbook zypper[12293]: openSUSE Tumbleweed
Apr 13 19:57:37 thinkbook zypper[12293]:   20240411-0 -> 20240412-0
Apr 13 19:57:37 thinkbook zypper[12293]: The following NEW package is going to be installed:
Apr 13 19:57:37 thinkbook zypper[12293]:   kernel-default-6.8.5-1.1
Apr 13 19:57:37 thinkbook zypper[12293]: The following package requires a system reboot:
Apr 13 19:57:37 thinkbook zypper[12293]:   kernel-default-6.8.5-1.1
Apr 13 19:57:37 thinkbook zypper[12293]: 75 packages to upgrade, 1 new.
--
Apr 13 19:58:10 thinkbook systemd[1]: dup.service: Consumed 32.437s CPU time.
thinkbook:~ # 

These are read-only snapshots created by the zypper plugin pre/post zypper action. Useful to keep it even when using AU as AU/TU snaps are read-write and there’s the potential to clobber it. No such risk with the read-only snaps even if everything goes catastrophically wrong.

atomic-update is indeed a safe and convenient way to perform system updates:

  1. without interfering with the running system
  2. roll back if necessary without damaging the system.

I love it. :smiley:

1 Like

Thanks for the kind words, glad it’s working for you :innocent:
I will have to see how to package it for OBS!

I haven’t read this thread fully but just want to point out there are existing packaged solutions with systemd timers for updates/upgrades, one doesn’t need to re-invent the wheel. :slight_smile:
For example os-update is available on Leap and Tumbleweed.

Thanks, didn’t know about os-update project from the authors of transactional-update.

atomic-update (AU) is an adaptation of transactional-update (TU) for regular read-write openSUSE systems, not really comparable to os-update.

Unlike os-update which simply logs and/or notifies in case of a bad update, AU/TU prevents a bad update from being applied in the first place.