#!/usr/bin/env bash # context-poller.sh — lightweight deltas replacing git pull. # Polls GET /api/v1/clients/{slug}/context?since= every 5 min. # Installed by bootstrap.sh via launchd (macOS) or systemd timer (Linux). # # Dependencies: curl, jq set -euo pipefail OIKOS_URL="${OIKOS_API_URL:-https://oikos.hubris.network/api/v1}" HNAME=$(scutil --get LocalHostName 2>/dev/null || hostname -s) CONTEXT_DIR="${HOMELAB_CONTEXT_DIR:-/opt/homelab}" RAW_URL="${HOMELAB_RAW_URL:-https://git.hubris.network/dtoro/oikos/raw/main}" STATE_FILE="$CONTEXT_DIR/.context_since" SINCE="" [ -f "$STATE_FILE" ] && SINCE=$(cat "$STATE_FILE") API_RESP=$(curl -s --connect-timeout 10 \ "$OIKOS_URL/clients/ws:${HNAME}/context?since=${SINCE}" 2>/dev/null || true) if [ -z "$API_RESP" ] || ! echo "$API_RESP" | jq -e '.version' >/dev/null 2>&1; then exit 0 fi NEW_SINCE=$(echo "$API_RESP" | jq -r '.since // empty') VERSION=$(echo "$API_RESP" | jq -r '.version // 0') CHANGED_FILES=$(echo "$API_RESP" | jq -r '.agent_files_changed // [] | .[]' 2>/dev/null || true) SOPS_CHANGED=$(echo "$API_RESP" | jq -r '.sops_config_changed // false' 2>/dev/null || true) TOOLS_CHANGED=$(echo "$API_RESP" | jq -r '.tools_changed // [] | .[]' 2>/dev/null || true) APPLIED=0 # Fetch changed agent files for f in $CHANGED_FILES; do url="$RAW_URL/$f" dest="$CONTEXT_DIR/$f" mkdir -p "$(dirname "$dest")" if curl -fsSL --connect-timeout 10 "$url" -o "$dest.tmp" 2>/dev/null; then mv "$dest.tmp" "$dest" APPLIED=$((APPLIED + 1)) fi done # Fetch changed tools and re-run them for t in $TOOLS_CHANGED; do url="$RAW_URL/$t" dest="$CONTEXT_DIR/$t" mkdir -p "$(dirname "$dest")" if curl -fsSL --connect-timeout 10 "$url" -o "$dest.tmp" 2>/dev/null; then mv "$dest.tmp" "$dest" chmod +x "$dest" 2>/dev/null || true if [ "$t" != "tools/post-pull.sh" ] && [ "$t" != "tools/context-poller.sh" ]; then bash "$dest" 2>/dev/null || true fi APPLIED=$((APPLIED + 1)) fi done # Fetch .sops.yaml if changed if [ "$SOPS_CHANGED" = "true" ]; then url="$RAW_URL/.sops.yaml" dest="$CONTEXT_DIR/.sops.yaml" if curl -fsSL --connect-timeout 10 "$url" -o "$dest.tmp" 2>/dev/null; then mv "$dest.tmp" "$dest" APPLIED=$((APPLIED + 1)) fi fi if [ "$APPLIED" -gt 0 ] && [ -n "$NEW_SINCE" ]; then echo "$NEW_SINCE" > "$STATE_FILE" echo "[oikos] context updated: version=$VERSION, applied=$APPLIED files ($(date -u +%Y-%m-%dT%H:%M:%SZ))" fi