Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compatibility for bootc image #146

Merged
merged 2 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading