feat(deploy): self-update + auto-reboot on boot-file changes

Two ergonomics fixes so one invocation does the right thing:

  1. After git pull, re-exec the script if the installer itself changed
     in the pull. Previously you'd need a second run to pick up new
     logic. BF_REEXEC=1 guard prevents loops.

  2. Track REBOOT_NEEDED when cmdline.txt / config.txt get edited or
     /var/run/reboot-required appears (apt kernel/libc update). At end
     of run, auto-reboot after a 10s cancellable window. Override with
     BF_NO_REBOOT=1.
This commit is contained in:
Mitchell R 2026-05-13 12:58:20 +02:00
parent 786febbb9b
commit d5bd64d05c

View file

@ -24,6 +24,7 @@
# BF_HOME=/path/to/repo override repo location (default: $HOME/betterframe) # BF_HOME=/path/to/repo override repo location (default: $HOME/betterframe)
# BF_REPO_URL=git@… override clone URL (default: github) # BF_REPO_URL=git@… override clone URL (default: github)
# SKIP_BUILD=1 skip kiosk cargo build (expects existing binary) # SKIP_BUILD=1 skip kiosk cargo build (expects existing binary)
# BF_NO_REBOOT=1 don't auto-reboot when boot-time files changed
set -euo pipefail set -euo pipefail
@ -67,8 +68,9 @@ apt-get install -y --no-install-recommends \
git ca-certificates curl gnupg lsb-release sudo git ca-certificates curl gnupg lsb-release sudo
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# 2. Clone or update repo # 2. Clone or update repo (always — pull is safety-first)
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
SELF_HASH_BEFORE="$(sha256sum "$0" 2>/dev/null | cut -d' ' -f1 || true)"
if [ -d "${BF_HOME}/.git" ]; then if [ -d "${BF_HOME}/.git" ]; then
echo "==> Updating repo at ${BF_HOME}" echo "==> Updating repo at ${BF_HOME}"
run_as_user "git -C '${BF_HOME}' fetch --prune origin && git -C '${BF_HOME}' pull --ff-only" run_as_user "git -C '${BF_HOME}' fetch --prune origin && git -C '${BF_HOME}' pull --ff-only"
@ -79,6 +81,21 @@ else
fi fi
REPO_ROOT="${BF_HOME}" REPO_ROOT="${BF_HOME}"
# If the setup script itself changed in the pull, re-exec the new version so
# this run uses the latest logic. Otherwise the user has to re-run anyway.
NEW_SELF="${REPO_ROOT}/deploy/scripts/setup-pi-kiosk.sh"
if [ -f "${NEW_SELF}" ] && [ -n "${SELF_HASH_BEFORE}" ] && [ "${BF_REEXEC:-0}" != "1" ]; then
SELF_HASH_AFTER="$(sha256sum "${NEW_SELF}" | cut -d' ' -f1)"
if [ "${SELF_HASH_BEFORE}" != "${SELF_HASH_AFTER}" ]; then
echo "==> Installer changed in pull — re-executing newer version"
chmod +x "${NEW_SELF}"
exec env BF_REEXEC=1 "${NEW_SELF}" "${MODE}"
fi
fi
# Track whether anything we change requires a reboot to take effect.
REBOOT_NEEDED=0
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# 3. Docker engine + compose plugin # 3. Docker engine + compose plugin
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
@ -238,6 +255,7 @@ EOF
for flag in quiet splash plymouth.ignore-serial-consoles "loglevel=0" "vt.global_cursor_default=0" logo.nologo; do for flag in quiet splash plymouth.ignore-serial-consoles "loglevel=0" "vt.global_cursor_default=0" logo.nologo; do
if ! grep -qw -- "${flag}" "${CMDLINE}"; then if ! grep -qw -- "${flag}" "${CMDLINE}"; then
sed -i "s|\$| ${flag}|" "${CMDLINE}" sed -i "s|\$| ${flag}|" "${CMDLINE}"
REBOOT_NEEDED=1
fi fi
done done
fi fi
@ -245,10 +263,16 @@ EOF
# Pi firmware rainbow splash off. # Pi firmware rainbow splash off.
if ! grep -q "^disable_splash=1" "${CONFIG}"; then if ! grep -q "^disable_splash=1" "${CONFIG}"; then
printf '\n# BetterFrame: disable firmware rainbow splash\ndisable_splash=1\n' >> "${CONFIG}" printf '\n# BetterFrame: disable firmware rainbow splash\ndisable_splash=1\n' >> "${CONFIG}"
REBOOT_NEEDED=1
fi fi
fi fi
fi fi
# apt creates this when a kernel / libc / linker update needs a reboot.
if [ -f /var/run/reboot-required ]; then
REBOOT_NEEDED=1
fi
echo "==> Done." echo "==> Done."
if [ "${INSTALL_SERVER}" = "1" ]; then if [ "${INSTALL_SERVER}" = "1" ]; then
echo " Server stack: http://$(hostname -I | awk '{print $1}')/" echo " Server stack: http://$(hostname -I | awk '{print $1}')/"
@ -256,3 +280,10 @@ fi
if [ "${INSTALL_KIOSK}" = "1" ]; then if [ "${INSTALL_KIOSK}" = "1" ]; then
echo " Kiosk service: systemctl status betterframe-kiosk" echo " Kiosk service: systemctl status betterframe-kiosk"
fi fi
if [ "${REBOOT_NEEDED}" = "1" ] && [ "${BF_NO_REBOOT:-0}" != "1" ]; then
echo
echo "==> Reboot required to apply boot-time changes. Rebooting in 10s. Ctrl-C to cancel."
sleep 10
systemctl reboot
fi