diff --git a/openchamber-boostrap.sh b/openchamber-boostrap.sh index 0da1f41..be0cadd 100644 --- a/openchamber-boostrap.sh +++ b/openchamber-boostrap.sh @@ -53,6 +53,10 @@ INVITE=0 INVITE_PORT=3000 NO_ENTERPRISE=0 ALLOW_PROVIDERS_STR="" +info() { printf '\033[1;34m[info]\033[0m %s\n' "$*"; } +ok() { printf '\033[1;32m[ ok ]\033[0m %s\n' "$*"; } +warn() { printf '\033[1;33m[warn]\033[0m %s\n' "$*"; } +die() { printf '\033[1;31m[fail]\033[0m %s\n' "$*" >&2; exit 1; } while [ $# -gt 0 ]; do case "$1" in --relay-url) RELAY_URL="$2"; shift 2 ;; @@ -69,11 +73,6 @@ while [ $# -gt 0 ]; do esac done -info() { printf '\033[1;34m[info]\033[0m %s\n' "$*"; } -ok() { printf '\033[1;32m[ ok ]\033[0m %s\n' "$*"; } -warn() { printf '\033[1;33m[warn]\033[0m %s\n' "$*"; } -die() { printf '\033[1;31m[fail]\033[0m %s\n' "$*" >&2; exit 1; } - # ---- helpers ---------------------------------------------------------------- # policy_json — emit the enterprise policy file content on stdout @@ -97,6 +96,7 @@ write_policy_file() { warn "$(basename "$f"): differs from enforced policy — overwriting" fi mv "$tmp" "$f" + chmod 644 "$f" ok "$(basename "$f"): installed" } @@ -104,10 +104,24 @@ write_policy_file() { # (sudo when available); without root, pin OPENCHAMBER_ENTERPRISE_MODE=1 in # the rc files instead and say so loudly. install_enterprise_policy() { - local dir sudo="" + local dir sudo="" tmp current dir="$(dirname "$POLICY_FILE")" + tmp="$(mktemp)" + policy_json > "$tmp" + + # Already correct? Then we're done regardless of root. + if [ -r "$POLICY_FILE" ]; then + current="$(cat "$POLICY_FILE" 2>/dev/null || true)" + if [ "$current" = "$(cat "$tmp")" ]; then + rm -f "$tmp" + ok "$(basename "$POLICY_FILE"): already enforced" + return 0 + fi + fi + if [ -d "$dir" ] && [ -w "$dir" ]; then write_policy_file "$POLICY_FILE" + rm -f "$tmp" return 0 fi if sudo -n true 2>/dev/null; then @@ -115,9 +129,20 @@ install_enterprise_policy() { elif [ -t 0 ]; then sudo="sudo" fi - if [ -n "$sudo" ] && $sudo mkdir -p "$dir" 2>/dev/null && $sudo tee "$POLICY_FILE" >/dev/null <<< "$(policy_json)" 2>/dev/null; then - ok "enterprise policy installed at $POLICY_FILE" - return 0 + if [ -n "$sudo" ]; then + if [ -f "$POLICY_FILE" ]; then + warn "$(basename "$POLICY_FILE"): differs from enforced policy — overwriting" + fi + if $sudo mkdir -p "$dir" 2>/dev/null && $sudo tee "$POLICY_FILE" >/dev/null < "$tmp" && $sudo chmod 644 "$POLICY_FILE" 2>/dev/null; then + rm -f "$tmp" + ok "enterprise policy installed at $POLICY_FILE" + return 0 + fi + fi + rm -f "$tmp" + if [ -f "$POLICY_FILE" ]; then + warn "no root: $POLICY_FILE exists but differs from enforced policy and could not be repaired" + return 1 fi warn "no root: cannot write $POLICY_FILE — falling back to env-var mode" warn "env-var mode is a weaker lock (the user can edit their own rc files)" @@ -142,11 +167,11 @@ pin_enterprise_env() { # derived from the config's own providers block, the baseline list, and any # extras (deduped, in that order). Uses python3, falls back to bun. merge_policies() { - local in="$1" out="$2" tmp + local in="$1" out="$2" tmp status=0 local extras="${*:3}" tmp="$(mktemp)" if command -v python3 >/dev/null 2>&1; then - python3 - "$in" "$tmp" "$BASELINE_ALLOWED_PROVIDERS" "$extras" <<'PY' + python3 - "$in" "$tmp" "$BASELINE_ALLOWED_PROVIDERS" "$extras" <<'PY' || status=1 import json, sys src, dst, baseline, extras = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4] cfg = json.load(open(src)) @@ -177,10 +202,14 @@ for (const p of [...derived, cfg.experimental = cfg.experimental || {}; cfg.experimental.policies = rules; fs.writeFileSync(process.env.OUT, JSON.stringify(cfg, null, 2) + "\n"); -' +' || status=1 else die "need python3 or bun to inject provider policies" fi + if [ "$status" -ne 0 ]; then + rm -f "$tmp" + die "could not inject provider policies into $in (bad JSON or interpreter failure) — existing config left untouched" + fi mv "$tmp" "$out" }