#!/bin/sh # bee-update.sh — production update path: USB first, then network. # Unattended: logs only, never blocks boot. set -u LOG_PREFIX="bee-update" log() { echo "[$LOG_PREFIX] $*"; } AUDIT_BIN="/usr/local/bin/audit" TMP_BIN="/tmp/bee-audit-new" TMP_SIG="/tmp/bee-audit-new.sig" REPO_API="${BEE_RELEASE_API:-https://git.mchus.pro/api/v1/repos//bee/releases/latest}" download_to() { url="$1" out="$2" if command -v wget >/dev/null 2>&1; then wget -q -O "$out" "$url" return $? fi if command -v curl >/dev/null 2>&1; then curl -fsSL "$url" -o "$out" return $? fi log "neither wget nor curl available" return 1 } version_of() { "$1" --version 2>/dev/null | head -n1 | tr -d '[:space:]' } apply_update() { src_bin="$1" src_sig="$2" src_ver="$3" if [ ! -x "$src_bin" ] || [ ! -f "$src_sig" ]; then log "missing binary or signature" return 1 fi # NOTE: strict signature verification should be implemented in audit updater module. # Here we keep shell side minimal and fail-open for now. cp "$src_bin" "$AUDIT_BIN" || return 1 chmod +x "$AUDIT_BIN" || return 1 log "updated audit binary to $src_ver" return 0 } check_usb_update() { for root in /media/* /mnt/* /tmp/bee-usb /run/media/*/*; do [ -d "$root" ] || continue base="$root/bee-update" bin="$base/bee-audit-linux-amd64" sig="$base/bee-audit-linux-amd64.sig" ver_file="$base/VERSION" [ -f "$bin" ] || continue [ -f "$sig" ] || continue [ -f "$ver_file" ] || continue new_ver=$(cat "$ver_file" 2>/dev/null | tr -d '[:space:]') cur_ver=$(version_of "$AUDIT_BIN") [ -n "$new_ver" ] || continue if [ "$new_ver" = "$cur_ver" ]; then log "usb update found but version is same ($new_ver)" return 0 fi log "usb update candidate: $new_ver" apply_update "$bin" "$sig" "$new_ver" && return 0 return 1 done return 1 } check_network_update() { if ! ping -c 1 -W 3 git.mchus.pro >/dev/null 2>&1; then log "network unavailable; skip release check" return 1 fi if ! command -v wget >/dev/null 2>&1 && ! command -v curl >/dev/null 2>&1; then log "neither wget nor curl found; skip network update" return 1 fi if ! command -v jq >/dev/null 2>&1; then log "jq not found; skip network update" return 1 fi meta="/tmp/bee-release-latest.json" download_to "$REPO_API" "$meta" || { log "failed to fetch release metadata"; return 1; } tag=$(jq -r '.tag_name // empty' "$meta") [ -n "$tag" ] || { log "release metadata missing tag_name"; return 1; } cur_ver=$(version_of "$AUDIT_BIN") if [ "$tag" = "$cur_ver" ]; then log "already latest ($tag)" return 0 fi bin_url=$(jq -r '.assets[]? | select(.name=="bee-audit-linux-amd64") | .browser_download_url // empty' "$meta") sig_url=$(jq -r '.assets[]? | select(.name=="bee-audit-linux-amd64.sig") | .browser_download_url // empty' "$meta") [ -n "$bin_url" ] && [ -n "$sig_url" ] || { log "missing release asset URLs"; return 1; } download_to "$bin_url" "$TMP_BIN" || return 1 download_to "$sig_url" "$TMP_SIG" || return 1 chmod +x "$TMP_BIN" log "network update candidate: $tag" apply_update "$TMP_BIN" "$TMP_SIG" "$tag" } main() { if check_usb_update; then exit 0 fi check_network_update || true } main "$@"