Skip to content

Commit

Permalink
Merge pull request fedora-iot#146 from say-paul/boot_compatibility
Browse files Browse the repository at this point in the history
compatibility for bootc image
  • Loading branch information
runcom authored Aug 16, 2024
2 parents e99a3a2 + 6b51ec9 commit 223f41d
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 7 deletions.
2 changes: 2 additions & 0 deletions greenboot.spec
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ install -DpZm 0644 etc/greenboot/greenboot.conf %{buildroot}%{_sysconfdir}/%{nam
%{_prefix}/lib/bootupd/grub2-static/configs.d/*.cfg
%{_unitdir}/greenboot-status.service
%{_libexecdir}/%{name}/greenboot-grub2-set-counter
%{_libexecdir}/%{name}/greenboot-grub2-set-success
%{_libexecdir}/%{name}/greenboot-boot-remount
%{_unitdir}/greenboot-grub2-set-success.service
%{_unitdir}/greenboot-grub2-set-counter.service
%{_libexecdir}/%{name}/greenboot-rpm-ostree-grub2-check-fallback
Expand Down
1 change: 1 addition & 0 deletions usr/lib/systemd/system/greenboot-grub2-set-counter.service
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ RequiresMountsFor=/boot
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/libexec/greenboot/greenboot-grub2-set-counter
PrivateMounts=yes

[Install]
RequiredBy=ostree-finalize-staged.service
4 changes: 2 additions & 2 deletions usr/lib/systemd/system/greenboot-grub2-set-success.service
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ After=boot-complete.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/grub2-editenv - set boot_success=1
ExecStart=/usr/bin/grub2-editenv - unset boot_counter
ExecStart=/usr/libexec/greenboot/greenboot-grub2-set-success
PrivateMounts=yes

[Install]
WantedBy=multi-user.target
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Before=greenboot-grub2-set-success.service
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/libexec/greenboot/greenboot-rpm-ostree-grub2-check-fallback
PrivateMounts=yes

[Install]
RequiredBy=greenboot-healthcheck.service
23 changes: 23 additions & 0 deletions usr/libexec/greenboot/greenboot-boot-remount
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash
set -eo pipefail

# Boolean variable to track if /boot was initially mounted as read-only
# Ensure compatibility with rpm-ostree where /boot is rw but in bootc /boot is ro
boot_was_ro=false

# Remount /boot as read-only if it was mounted as read-only ealier
function remount_boot_ro {
if $boot_was_ro; then
mount -o remount,ro /boot || exit 13
fi
return
}

# Remount /boot as read-write if it was mounted as read-only
function remount_boot_rw {
if grep -q " /boot .* ro," /proc/mounts; then
mount -o remount,rw /boot || exit 13
boot_was_ro=true
fi
return
}
22 changes: 20 additions & 2 deletions usr/libexec/greenboot/greenboot-grub2-set-counter
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/bin/bash
set -eo pipefail

source /usr/libexec/greenboot/greenboot-boot-remount

GREENBOOT_CONFIGURATION_FILE=/etc/greenboot/greenboot.conf
if test -f "$GREENBOOT_CONFIGURATION_FILE"; then
# shellcheck source=etc/greenboot/greenboot.conf
Expand All @@ -14,7 +16,23 @@ elif [ -n "$GREENBOOT_MAX_BOOT_ATTEMPTS" ]; then
else
max_boot_attempts=3 # default to 3 attempts
fi
grub2-editenv - set boot_counter="$max_boot_attempts"
grub2-editenv - set boot_success=0


remount_boot_rw

if ! /usr/bin/grub2-editenv - set boot_counter="$max_boot_attempts"; then
# If the first command fails, remount /boot as read-only and exit with failure
remount_boot_ro
exit 1
fi

if ! /usr/bin/grub2-editenv /boot/grub2/grubenv set boot_success=0; then
# If the first command fails, remount /boot as read-only and exit with failure
remount_boot_ro
exit 1
fi

# Revert /boot as read-only
remount_boot_ro

echo "<3>GRUB2 environment variables have been set for system upgrade. Max boot attempts is $max_boot_attempts"
25 changes: 25 additions & 0 deletions usr/libexec/greenboot/greenboot-grub2-set-success
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash

set -eo pipefail

source /usr/libexec/greenboot/greenboot-boot-remount
remount_boot_rw

# Run the grub2-editenv commands
if ! /usr/bin/grub2-editenv /boot/grub2/grubenv set boot_success=1; then
# If the first command fails, remount /boot as read-only and exit with failure
remount_boot_ro
exit 1
fi

if ! /usr/bin/grub2-editenv /boot/grubenv unset boot_counter; then
# If the second command fails, remount /boot as read-only and exit with failure
remount_boot_ro
exit 1
fi

# Remount /boot as read-only if it was mounted as read-write
remount_boot_ro

# If everything succeeded, exit with success
exit 0
37 changes: 34 additions & 3 deletions usr/libexec/greenboot/greenboot-rpm-ostree-grub2-check-fallback
Original file line number Diff line number Diff line change
@@ -1,16 +1,47 @@
#!/bin/bash
set -euo pipefail

source /usr/libexec/greenboot/greenboot-boot-remount

function attempt_rollback {
# Check if the bootc command is available
if command -v bootc &> /dev/null; then
status_type=$(bootc status --booted --json 2>/dev/null | jq -r .status.type 2>/dev/null)
if [ "$status_type" == "bootcHost" ]; then
bootc rollback
echo "<3>FALLBACK BOOT DETECTED! Default bootc deployment has been rolled back."
fi
return
fi
# Check if its ostree based os
if [ -f /run/ostree-booted ]; then
rpm-ostree rollback
echo "<3>FALLBACK BOOT DETECTED! Default rpm-ostree deployment has been rolled back."
return
fi
echo "<3>Rollback is only supported in ostree or bootc based os."
return
}

# Determine if the current boot is a fallback boot
# If booted into fallback deployment, clean up bootloader entries (rollback)
if grub2-editenv list | grep -q "^boot_counter=-1$"; then
# Logs from previous boot may be unavailable on systems without internal RTC; defaulting to empty string
prev_logs="$(journalctl -u greenboot-healthcheck.service -p 2 -b -1 -o cat)" || true
rpm-ostree rollback
echo "<3>FALLBACK BOOT DETECTED! Default rpm-ostree deployment has been rolled back."
attempt_rollback
if [ -n "$prev_logs" ]; then
echo "<3>Health check logs from previous boot:"
echo "<3>$prev_logs"
fi
grub2-editenv - unset boot_counter

remount_boot_rw

if ! /usr/bin/grub2-editenv - unset boot_counter; then
# If the above command fails, remount /boot as read-only and exit with failure
remount_boot_ro
exit 1
fi
fi

# Remount /boot as read-only if it was mounted as read-write
remount_boot_ro

0 comments on commit 223f41d

Please sign in to comment.