mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-15 17:12:59 -04:00
99 lines
3.1 KiB
Bash
Executable File
99 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Fixed-purpose self-update helper for Raspberry Pi rover hosts.
|
|
#
|
|
# roverd itself runs as the unprivileged "roverd" service user, but updating the
|
|
# installed agent requires root because the installer writes to /usr/local/bin,
|
|
# /etc, /opt, /var/lib/roverd, and systemd unit locations. This helper is the
|
|
# narrow privilege boundary: sudoers allows roverd to run this exact file with no
|
|
# arguments, and this file decides the complete update sequence internally.
|
|
|
|
set -euo pipefail
|
|
|
|
ENV_FILE="/etc/roverd-update.env"
|
|
LOCK_FILE="/var/lock/roverd-self-update.lock"
|
|
LOG_FILE="/var/log/roverd-self-update.log"
|
|
|
|
log() {
|
|
# Log to stdout so systemd/journal captures the message when launched by
|
|
# roverd, and also append to a stable file so an admin can inspect the last
|
|
# update attempt after the roverd service restarts.
|
|
local message
|
|
message="[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $*"
|
|
echo "$message"
|
|
echo "$message" >> "$LOG_FILE"
|
|
}
|
|
|
|
if [[ "${EUID}" -ne 0 ]]; then
|
|
echo "roverd-self-update must run as root" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "${ROVERD_SELF_UPDATE_SYSTEMD:-}" != "1" ]] && command -v systemd-run >/dev/null 2>&1; then
|
|
exec systemd-run \
|
|
--unit=roverd-self-update \
|
|
--collect \
|
|
--property=Type=exec \
|
|
--setenv=ROVERD_SELF_UPDATE_SYSTEMD=1 \
|
|
"$0"
|
|
fi
|
|
|
|
if [[ ! -f "$ENV_FILE" ]]; then
|
|
echo "Missing $ENV_FILE; run pi/install_roverd.sh once to register the repository path" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# shellcheck disable=SC1090
|
|
source "$ENV_FILE"
|
|
|
|
if [[ -z "${ROVERD_REPO_DIR:-}" ]]; then
|
|
echo "ROVERD_REPO_DIR is not set in $ENV_FILE" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -d "$ROVERD_REPO_DIR/.git" ]]; then
|
|
echo "ROVERD_REPO_DIR does not point at a git checkout: $ROVERD_REPO_DIR" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -x "$ROVERD_REPO_DIR/pi/install_roverd.sh" ]]; then
|
|
echo "Installer is missing or not executable: $ROVERD_REPO_DIR/pi/install_roverd.sh" >&2
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p "$(dirname "$LOCK_FILE")" "$(dirname "$LOG_FILE")"
|
|
touch "$LOG_FILE"
|
|
chmod 0644 "$LOG_FILE"
|
|
|
|
exec 9>"$LOCK_FILE"
|
|
if ! flock -n 9; then
|
|
log "Another roverd self-update is already running; refusing to start a second one"
|
|
exit 1
|
|
fi
|
|
|
|
cd "$ROVERD_REPO_DIR"
|
|
log "Starting roverd self-update in $ROVERD_REPO_DIR"
|
|
|
|
repo_uid="$(stat -c '%u' "$ROVERD_REPO_DIR")"
|
|
|
|
# Fetch through the normal git remote instead of downloading just one artifact.
|
|
# That keeps the binary, installer, scripts, systemd units, and any other rover
|
|
# files from this repository on the same commit.
|
|
if [[ "$repo_uid" -eq 0 ]]; then
|
|
git pull --ff-only
|
|
else
|
|
# The helper runs as root only for installation privileges. The git checkout
|
|
# usually belongs to the human deploy user, so running the pull as that owner
|
|
# avoids Git's dubious-ownership protection and preserves whatever SSH/HTTPS
|
|
# credentials that user normally uses for this repository.
|
|
sudo -H -u "#${repo_uid}" git -C "$ROVERD_REPO_DIR" pull --ff-only
|
|
fi
|
|
log "Repository fast-forward pull complete"
|
|
|
|
# The installer already owns the full desired rover host state. Reusing it here
|
|
# prevents this update helper from becoming a second, partial installer that can
|
|
# drift away from the normal manual install path.
|
|
"$ROVERD_REPO_DIR/pi/install_roverd.sh"
|
|
log "Installer completed successfully"
|
|
systemctl reboot
|