#!/bin/bash # Run ONCE, as root, on a fresh Proxmox host - not part of the claude-deploy # workflow, since claude-deploy is exactly the account this script is # widening permissions FOR. Idempotent: safe to re-run. # # Installs fix-lxc-apparmor.sh (root-owned, not writable by claude-deploy) # and a narrow sudoers rule that lets claude-deploy invoke it - and only # it, only with a VMID argument in the 200-299 range - so create-graylog-lxc.sh # can clear the "Docker-in-unprivileged-LXC AppArmor block" quirk (see # README.md) without a human editing /etc/pve/lxc/*.conf by hand every time. # # Deliberately does NOT grant broader access (e.g. `tee -a` or `sh -c` on # the conf file): those let the caller write arbitrary content to any # 200-299 container's config, not just this one fixed line. See the # "Automating the AppArmor fix" note in README.md for why. set -euo pipefail [ "$(id -u)" -eq 0 ] || { echo "Must run as root." >&2; exit 1; } SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" TARGET="/usr/local/sbin/fix-lxc-apparmor.sh" SUDOERS_FILE="/etc/sudoers.d/claude-deploy-apparmor" SUDOERS_LINE="claude-deploy ALL=(root) NOPASSWD: ${TARGET} 2[0-9][0-9]" if [ -f "$TARGET" ] && cmp -s "$SCRIPT_DIR/fix-lxc-apparmor.sh" "$TARGET"; then echo "⏭ $TARGET already up to date" else install -o root -g root -m 700 "$SCRIPT_DIR/fix-lxc-apparmor.sh" "$TARGET" echo "✓ installed $TARGET (root-owned, 700)" fi if [ -f "$SUDOERS_FILE" ] && grep -qxF "$SUDOERS_LINE" "$SUDOERS_FILE"; then echo "⏭ sudoers rule already present in $SUDOERS_FILE" else tmp="$(mktemp)" echo "$SUDOERS_LINE" > "$tmp" chmod 440 "$tmp" visudo -c -f "$tmp" || { echo "generated sudoers snippet failed validation" >&2; rm -f "$tmp"; exit 1; } mv "$tmp" "$SUDOERS_FILE" chown root:root "$SUDOERS_FILE" echo "✓ installed sudoers rule at $SUDOERS_FILE" fi echo "Done. claude-deploy can now run: sudo $TARGET "