|
1 | | -# atomic-update |
2 | | -Atomic (transactional) update for openSUSE Tumbleweed |
| 1 | +# atomic-update ⚛️ |
| 2 | +Never let another update break your read-write [openSUSE](https://en.wikipedia.org/wiki/OpenSUSE) system! |
3 | 3 |
|
4 | | -# WIP |
| 4 | +## Synopsis |
| 5 | +atomic-update is a simple single file program with just one external dependency that can be used to perform atomic (transactional) updates of openSUSE systems with read-write root filesystems such as Tumbleweed and Slowroll. It can also be used on Leap, even though Leap-specific update commands are yet to be added. |
| 6 | + |
| 7 | +atomic-update uses [btrfs subvolumes](https://btrfs.readthedocs.io/en/latest/Subvolumes.html) and [snapper snapshots](http://snapper.io/) to safely perform updates to a new root filesystem snapshot while minimizing any side-effects to your currently running system/snapshot. |
| 8 | + |
| 9 | +### How it works |
| 10 | +- On performing an update or running a command using atomic-update, a new root filesystem snapshot is created |
| 11 | +- The new snapshot is used to boot an ephemeral container to see which services are in a failed state, for later comparison |
| 12 | +- All changes are made against this new snapshot and not to the currently running system's snapshot |
| 13 | +- The snapshot is booted again in an ephemeral container to see if the changes broke any new services |
| 14 | +- If the changes are successful, the new snapshot is set as the default snapshot. The changes can be either applied live or the system rebooted into the new default snapshot |
| 15 | +- If the changes are unsuccessful, the new snapshot is discarded |
| 16 | + |
| 17 | +Performing updates like this have a number of benefits: |
| 18 | +- Prevent a broken system due to system crash, power loss, etc. |
| 19 | +- Prevent non-interactive updates from breaking system due to conflicts/errors causing zypper to abort (the default action on conflicts/errors) in the middle of an update |
| 20 | +- Prevent updates from causing an inconsistent system state due to failing scripts but an otherwise successful update |
| 21 | +- Avoid having to reboot into read-only grub snapshots to perform rollback |
| 22 | + |
| 23 | +Downsides: |
| 24 | +- Updates must be either applied live or the system rebooted shortly thereafter to avoid losing changes made to the old root filesystem. |
| 25 | + |
| 26 | +### Acknowledgements |
| 27 | +atomic-update is heavily inspired by the excellent [transactional-update](https://github.com/openSUSE/transactional-update) package for read-only root filesystems. All the credit goes to them 🤗 |
| 28 | + |
| 29 | +Even though transactional-update works on read-write systems as of version 4.6.0, it's not officially supported and the lead developer has [stated](https://bugzilla.opensuse.org/show_bug.cgi?id=1221742#c27) support may be removed in the future if there are conflicts with read-only filesystem features. |
| 30 | + |
| 31 | +## Installation |
| 32 | +1. Install external dependency for booting snapshots in an ephemeral container to check for issues. `systemd-nspawn` is part of systemd and very small 👼 |
| 33 | +``` |
| 34 | +sudo zypper install systemd-container |
| 35 | +``` |
| 36 | + |
| 37 | +2. Install atomic-update, just a single python script you can read through in a few minutes 📜 |
| 38 | +``` |
| 39 | +curl -s https://raw.githubusercontent.com/pavinjosdev/atomic-update/main/atomic-update | sudo tee /usr/bin/atomic-update > /dev/null |
| 40 | +sudo chmod 755 /usr/bin/atomic-update |
| 41 | +``` |
| 42 | + |
| 43 | +## Usage |
| 44 | +Type in `atomic-update --help` for usage help. |
| 45 | + |
| 46 | +``` |
| 47 | +Usage: atomic-update [options] command |
| 48 | +
|
| 49 | +atomic-update provides safer transactional operations |
| 50 | +for openSUSE systems with read-write root filesystems. |
| 51 | +
|
| 52 | +Commands: |
| 53 | + dup - Perform distribution upgrade |
| 54 | + run <cmd> - Run a command in a new snapshot |
| 55 | + rollback [number] - Set the current or given snapshot as default snapshot |
| 56 | +
|
| 57 | +Options: |
| 58 | + --reboot - Reboot after update |
| 59 | + --apply - Switch into default snapshot without reboot |
| 60 | + --shell - Open shell in new snapshot before exiting |
| 61 | + --continue [number] - Use latest or given snapshot as base |
| 62 | + --no-verify - Skip verification of snapshot |
| 63 | + --interactive - Run dup in interactive mode |
| 64 | + --debug - Enable debug output |
| 65 | + --help - Print this help and exit |
| 66 | + --version - Print version number and exit |
| 67 | +``` |
| 68 | + |
| 69 | +## Examples |
| 70 | +1. Perform distribution upgrade on Tumbleweed and reboot |
| 71 | +``` |
| 72 | +sudo atomic-update --reboot dup |
| 73 | +``` |
| 74 | + |
| 75 | +2. Perform distribution upgrade on Tumbleweed and apply it live without rebooting |
| 76 | +``` |
| 77 | +sudo atomic-update --apply dup |
| 78 | +``` |
| 79 | + |
| 80 | +3. Update packages on Leap and reboot |
| 81 | +``` |
| 82 | +sudo atomic-update --reboot run zypper update |
| 83 | +``` |
| 84 | + |
| 85 | +4. Drop into a bash shell in a new snapshot |
| 86 | +``` |
| 87 | +sudo atomic-update --shell run true |
| 88 | +``` |
| 89 | + |
| 90 | +5. Run bash script in a new snapshot and drop into a bash shell in the same snapshot afterward |
| 91 | +``` |
| 92 | +sudo atomic-update --shell run bash -c 'date | awk "{print \$1}" && whoami' |
| 93 | +``` |
| 94 | + |
| 95 | +6. Rollback to currently booted snapshot |
| 96 | +``` |
| 97 | +sudo atomic-update rollback |
| 98 | +``` |
| 99 | + |
| 100 | +## Uninstallation |
| 101 | +1. Remove atomic-update |
| 102 | +``` |
| 103 | +sudo rm /usr/bin/atomic-update |
| 104 | +``` |
| 105 | + |
| 106 | +2. Optionally, uninstall `systemd-nspawn` |
| 107 | +``` |
| 108 | +sudo zypper remove systemd-container |
| 109 | +``` |
| 110 | + |
| 111 | +## Troubleshooting |
| 112 | +Specify the `--debug` option for troubleshooting. |
| 113 | +atomic-update is intended to catch SIGINT (Ctrl+C) and properly cleanup. |
| 114 | +If for some reason it does not cleanup such as when receiving SIGTERM or SIGKILL, current or future operations should not be affected. |
| 115 | +atomic-update keeps its working directory in `/tmp/atomic-update_*`, so a reboot would always cleanup. |
| 116 | + |
| 117 | +## Known issues |
| 118 | +- When switching to a new snapshot without reboot using the `--apply` option, future updates to the bootloader (prior to a reboot) such as running `update-bootloader` script must be performed from a new atomic snapshot. |
0 commit comments