111 lines
3.4 KiB
Bash
111 lines
3.4 KiB
Bash
#!/usr/bin/env bash
|
|
set -Eeuo pipefail
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
# shellcheck source=common.sh
|
|
source "$SCRIPT_DIR/common.sh"
|
|
cd "$PROJECT_ROOT"
|
|
|
|
RUN_TESTS=1
|
|
|
|
usage() {
|
|
cat <<'TXT'
|
|
Update an existing systemd/LXC GREE Controller installation from this source tree.
|
|
|
|
Usage:
|
|
sudo ./scripts/update.sh
|
|
sudo ./scripts/update.sh --skip-tests
|
|
|
|
The updater:
|
|
1. builds and tests the new release while the old service is still running,
|
|
2. stops the service,
|
|
3. backs up the binary, systemd unit, environment file and SQLite database,
|
|
4. installs the new binary and unit,
|
|
5. restarts and checks /api/health,
|
|
6. rolls back the binary/unit/database automatically if startup fails.
|
|
TXT
|
|
}
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--skip-tests) RUN_TESTS=0; shift ;;
|
|
-h|--help) usage; exit 0 ;;
|
|
*) echo "Unknown argument: $1" >&2; usage; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
require_root
|
|
require_systemd
|
|
[[ -x "$INSTALL_BINARY" ]] || fail "No installed binary at $INSTALL_BINARY. Run scripts/install.sh first."
|
|
[[ -f "$SERVICE_FILE" ]] || fail "No installed systemd unit at $SERVICE_FILE. Run scripts/install.sh first."
|
|
|
|
install_build_dependencies
|
|
ensure_rust
|
|
version="$(project_version)"
|
|
say "Preparing update to GREE Controller ${version:-unknown}"
|
|
|
|
if [[ "$RUN_TESTS" -eq 1 ]]; then
|
|
say "Running Rust tests before touching the running service"
|
|
cargo test --all-targets
|
|
fi
|
|
say "Building release binary"
|
|
cargo build --release
|
|
|
|
stamp="$(backup_timestamp)"
|
|
backup_dir="$BACKUP_ROOT/$stamp"
|
|
install -d -o root -g root -m 0700 "$backup_dir"
|
|
db_path="$(database_path)"
|
|
|
|
rollback() {
|
|
local rc=$?
|
|
trap - ERR
|
|
set +e
|
|
warn "Update failed; restoring previous installation from $backup_dir"
|
|
systemctl stop "$SERVICE_NAME" >/dev/null 2>&1 || true
|
|
if [[ -f "$backup_dir/gree-controller.binary" ]]; then
|
|
install -o root -g root -m 0755 "$backup_dir/gree-controller.binary" "$INSTALL_BINARY"
|
|
fi
|
|
if [[ -f "$backup_dir/gree-controller.service" ]]; then
|
|
install -o root -g root -m 0644 "$backup_dir/gree-controller.service" "$SERVICE_FILE"
|
|
fi
|
|
if [[ -f "$backup_dir/gree-controller.env" ]]; then
|
|
install -o root -g root -m 0600 "$backup_dir/gree-controller.env" "$ENV_FILE"
|
|
fi
|
|
if [[ -f "$backup_dir/gree-controller.db" ]]; then
|
|
install -o "$SERVICE_USER" -g "$SERVICE_GROUP" -m 0640 "$backup_dir/gree-controller.db" "$db_path"
|
|
fi
|
|
rm -f "${db_path}-wal" "${db_path}-shm"
|
|
systemctl daemon-reload
|
|
systemctl start "$SERVICE_NAME" >/dev/null 2>&1 || true
|
|
exit "$rc"
|
|
}
|
|
trap rollback ERR
|
|
|
|
say "Stopping service for a consistent SQLite backup"
|
|
systemctl stop "$SERVICE_NAME"
|
|
|
|
cp -a "$INSTALL_BINARY" "$backup_dir/gree-controller.binary"
|
|
cp -a "$SERVICE_FILE" "$backup_dir/gree-controller.service"
|
|
[[ -f "$ENV_FILE" ]] && cp -a "$ENV_FILE" "$backup_dir/gree-controller.env"
|
|
if [[ -f "$db_path" ]]; then
|
|
cp -a "$db_path" "$backup_dir/gree-controller.db"
|
|
fi
|
|
say "Backup created: $backup_dir"
|
|
|
|
say "Installing new release binary"
|
|
install -o root -g root -m 0755 target/release/gree-controller "$INSTALL_BINARY.new"
|
|
mv -f "$INSTALL_BINARY.new" "$INSTALL_BINARY"
|
|
install -o root -g root -m 0644 systemd/gree-controller.service "$SERVICE_FILE"
|
|
systemctl daemon-reload
|
|
systemctl start "$SERVICE_NAME"
|
|
|
|
if ! wait_for_health 80; then
|
|
journalctl -u "$SERVICE_NAME" -n 100 --no-pager || true
|
|
false
|
|
fi
|
|
|
|
trap - ERR
|
|
say "Update complete"
|
|
printf 'Version: %s\n' "${version:-unknown}"
|
|
printf 'Panel: %s\n' "$(panel_url)"
|
|
printf 'Backup: %s\n' "$backup_dir"
|