Skip to content

Commit

Permalink
docs/atomic-rollbacks: Add a section on rollbacks
Browse files Browse the repository at this point in the history
Describing how different types of rollbacks work.

Signed-off-by: Eric Curtin <[email protected]>
  • Loading branch information
ericcurtin committed Feb 13, 2024
1 parent a3f9276 commit 6ddb3d9
Show file tree
Hide file tree
Showing 11 changed files with 186 additions and 10 deletions.
2 changes: 1 addition & 1 deletion docs/adapting-existing.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
nav_order: 6
nav_order: 7
---

# Adapting existing mainstream distributions
Expand Down
176 changes: 176 additions & 0 deletions docs/atomic-rollbacks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
---
nav_order: 6
---

# Atomic Rollbacks
{: .no_toc }

1. TOC
{:toc}

## Automatic rollbacks

See [greenboot](https://github.com/fedora-iot/greenboot/blob/main/README.md) for information on automatic rollbacks and how to integrate
without your bootloader.

## Manual rollbacks

To manually rollback you can select an older entry via GRUB bootloader or in
the case of an Android bootloader, trigger a slot switch using an AB switching
tool. This may be useful for testing purposes.

## Rollbacks

```
+------------------------------------------------+
+------------------+ | |
| | | |
| | | |
| | | (ostree:0) latest (multi-user.target) |
| | | |
| Bootloader |--->+ root |
| | | |
| | | (ostree:1) latest - 1 (multi-user.target) |
| | | |
| | | |
+------------------+ | |
+------------------------------------------------+
```

Bootloaders have multiple boot entries to choose from after upgrade. On
rollback, the bootloader will boot the "latest - 1" version, rather than the
latest version of the OS.

## Alternate rollback techniques

An alternate technique to rolling back can be used. We can rollback into a
different runtime by using systemd targets.

```
+------------------------------------------------+
+------------------+ | |
| | | |
| | | |
| | | (ostree:0) latest (multi-user.target) |
| | | |
| Bootloader |--->+ root |
| | | |
| | | (ostree:1) latest - 1 (rescue.target) |
| | | |
| | | |
+------------------+ | |
+------------------------------------------------+
```

In this case instead of only rollback back to the last version, we also boot
into an alternate systemd target. Here we will describe how you can put
togther an alternate systemd target, using the built-in rescue.target as an
example.

Below is a rescue.service file, it essentially executes:

/usr/lib/systemd/systemd-sulogin-shell rescue

when this service is activated.

rescue.service:

```
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Rescue Shell
Documentation=man:sulogin(8)
DefaultDependencies=no
Conflicts=shutdown.target
After=sysinit.target plymouth-start.service
Before=shutdown.target
[Service]
Environment=HOME=/root
WorkingDirectory=-/root
ExecStartPre=-/usr/bin/plymouth --wait quit
ExecStart=-/usr/lib/systemd/systemd-sulogin-shell rescue
Type=idle
StandardInput=tty-force
StandardOutput=inherit
StandardError=inherit
KillMode=process
IgnoreSIGPIPE=no
SendSIGHUP=yes
```

Below is a rescue.target file, it is reached once rescue.service is complete.

rescue.target:

```
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Rescue Mode
Documentation=man:systemd.special(7)
Requires=sysinit.target rescue.service
After=sysinit.target rescue.service
AllowIsolate=yes
```

This is a simple bash script, it checks whether `ostree admin status -D` is
`not-default` and if it is, it notifies systemd to alternatively boot into
rescue.target.

In the happy path, when we have not rolled back `ostree admin status -D` would
output `default`.

ostree-rollback-to-rescue:

```
#!/usr/bin/bash
set -ex
if [ "$(ostree admin status -D)" = "not-default" ]; then
exec systemctl --no-block isolate rescue.target
fi
```

This is a systemd service file that checks early in the boot sequence if we
have rolled back (it executes ostree-rollback-to-rescue), it is essential that
this service is run early to ensure we don't execute a full boot sequence,
hence options `DefaultDependencies=no` and `Before=` are used.

ostree-rollback-to-rescue.service

```
[Unit]
Description=OSTree rollback to rescue
DefaultDependencies=no
OnFailure=emergency.target
OnFailureJobMode=replace-irreversibly
After=initrd-root-fs.target initrd-fs.target initrd.target boot.mount
Before=cryptsetup.target integritysetup.target remote-fs.target slices.target swap.target veritysetup.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/ostree-rollback-to-rescue
[Install]
WantedBy=sysinit.target
```

###### Licensing for this document:
`SPDX-License-Identifier: (CC-BY-SA-3.0 OR GFDL-1.3-or-later)`
2 changes: 1 addition & 1 deletion docs/authenticated-repos.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
nav_order: 9
nav_order: 10
---

# Handling access to authenticated remote repositories
Expand Down
2 changes: 1 addition & 1 deletion docs/bootloaders.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
nav_order: 11
nav_order: 12
---

# Bootloaders
Expand Down
2 changes: 1 addition & 1 deletion docs/buildsystem-and-repos.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
nav_order: 8
nav_order: 9
---

# Writing a buildsystem and managing repositories
Expand Down
2 changes: 1 addition & 1 deletion docs/composefs.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
nav_order: 10
nav_order: 11
---

# Using composefs with OSTree
Expand Down
2 changes: 1 addition & 1 deletion docs/formats.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
nav_order: 7
nav_order: 8
---

# OSTree data formats
Expand Down
2 changes: 1 addition & 1 deletion docs/ima.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
nav_order: 10
nav_order: 11
---

# Using Linux IMA with OSTree
Expand Down
2 changes: 1 addition & 1 deletion docs/related-projects.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
nav_order: 10
nav_order: 11
---

# Related Projects
Expand Down
2 changes: 1 addition & 1 deletion docs/repository-management.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
nav_order: 9
nav_order: 10
---

# Managing content in OSTree repositories
Expand Down
2 changes: 1 addition & 1 deletion docs/var.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
nav_order: 6
nav_order: 7
---

# OSTree and /var handling
Expand Down

0 comments on commit 6ddb3d9

Please sign in to comment.