mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-09-30 03:01:21 +02:00
fix(install): make macOS native install rootless (brew + venv permission errors)
macOS mixed root-only steps (default /opt path, sudo git clone) with steps
that must not run as root: brew refuses to run as root, and a root-owned
venv/node_modules can't be managed by the launchd agent. The installer now
refuses sudo on macOS, defaults to ~/bambuddy, and drops sudo from the
download/venv/frontend/env/dir steps. A --path under a root-owned parent still
works via a single elevate-and-chown. Linux (service user + systemd) unchanged.
This commit is contained in:
+71
-7
@@ -332,6 +332,26 @@ create_user() {
|
||||
log_success "Service user created"
|
||||
}
|
||||
|
||||
# Ensure a directory exists and is owned by the current user. Used on macOS so
|
||||
# the install tree stays user-owned (git/venv/npm never touch a root-owned dir).
|
||||
# Only elevates when the target's parent is root-owned (e.g. /opt); a path under
|
||||
# $HOME is created without any sudo prompt.
|
||||
ensure_user_owned_dir() {
|
||||
local dir="$1"
|
||||
|
||||
if [[ -d "$dir" ]] && [[ -w "$dir" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if mkdir -p "$dir" 2>/dev/null; then
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "Creating $dir (requires your password)..."
|
||||
sudo mkdir -p "$dir"
|
||||
sudo chown "$(id -un):$(id -gn)" "$dir"
|
||||
}
|
||||
|
||||
download_bambuddy() {
|
||||
log_info "Downloading BamBuddy..."
|
||||
|
||||
@@ -343,7 +363,23 @@ download_bambuddy() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -d "$INSTALL_PATH/.git" ]]; then
|
||||
if [[ "$OS_TYPE" == "macos" ]]; then
|
||||
# macOS has no service user — the whole install runs as the current user.
|
||||
# Create the target user-owned (elevating only if its parent is root-owned,
|
||||
# e.g. /opt), then clone/update without sudo so the venv/frontend the user
|
||||
# builds next aren't fighting a root-owned tree.
|
||||
ensure_user_owned_dir "$INSTALL_PATH"
|
||||
if [[ -d "$INSTALL_PATH/.git" ]]; then
|
||||
log_info "Existing installation found, updating..."
|
||||
git config --global --add safe.directory "$INSTALL_PATH" 2>/dev/null || true
|
||||
cd "$INSTALL_PATH"
|
||||
git fetch origin
|
||||
git checkout "$BRANCH" 2>/dev/null || git checkout -b "$BRANCH" "origin/$BRANCH"
|
||||
git reset --hard "origin/$BRANCH"
|
||||
else
|
||||
git clone --branch "$BRANCH" https://github.com/maziggy/bambuddy.git "$INSTALL_PATH"
|
||||
fi
|
||||
elif [[ -d "$INSTALL_PATH/.git" ]]; then
|
||||
log_info "Existing installation found, updating..."
|
||||
# Add safe.directory to avoid "dubious ownership" error when running as root
|
||||
git config --global --add safe.directory "$INSTALL_PATH" 2>/dev/null || true
|
||||
@@ -472,9 +508,12 @@ build_frontend() {
|
||||
create_directories() {
|
||||
log_info "Creating data directories..."
|
||||
|
||||
sudo mkdir -p "$DATA_DIR" "$LOG_DIR"
|
||||
|
||||
if [[ "$OS_TYPE" != "macos" ]]; then
|
||||
if [[ "$OS_TYPE" == "macos" ]]; then
|
||||
# Rootless: DATA_DIR/LOG_DIR default under the user-owned install path.
|
||||
ensure_user_owned_dir "$DATA_DIR"
|
||||
ensure_user_owned_dir "$LOG_DIR"
|
||||
else
|
||||
sudo mkdir -p "$DATA_DIR" "$LOG_DIR"
|
||||
sudo chown -R "$SERVICE_USER:$SERVICE_USER" "$DATA_DIR" "$LOG_DIR"
|
||||
fi
|
||||
|
||||
@@ -503,11 +542,15 @@ LOG_LEVEL=$LOG_LEVEL
|
||||
LOG_TO_FILE=true
|
||||
EOF
|
||||
|
||||
sudo mv /tmp/bambuddy.env "$env_file"
|
||||
if [[ "$OS_TYPE" != "macos" ]]; then
|
||||
if [[ "$OS_TYPE" == "macos" ]]; then
|
||||
# Rootless: install path is user-owned, so write it directly.
|
||||
mv /tmp/bambuddy.env "$env_file"
|
||||
chmod 600 "$env_file"
|
||||
else
|
||||
sudo mv /tmp/bambuddy.env "$env_file"
|
||||
sudo chown "$SERVICE_USER:$SERVICE_USER" "$env_file"
|
||||
sudo chmod 600 "$env_file"
|
||||
fi
|
||||
sudo chmod 600 "$env_file"
|
||||
|
||||
log_success "Environment file created at $env_file"
|
||||
}
|
||||
@@ -845,6 +888,27 @@ main() {
|
||||
detect_os
|
||||
log_success "Detected: $OS_TYPE (package manager: $PKG_MANAGER)"
|
||||
|
||||
# macOS must run rootless. Homebrew hard-refuses to run as root, and a venv
|
||||
# / node_modules created by root can't be managed by the launchd agent (which
|
||||
# runs as the user). Bail early with an actionable message instead of dying
|
||||
# halfway through on "brew: running as root is not supported".
|
||||
if [[ "$OS_TYPE" == "macos" ]]; then
|
||||
if [[ "$EUID" -eq 0 ]]; then
|
||||
log_error "Don't run the macOS installer with sudo."
|
||||
log_info "Homebrew, the Python venv, and the launchd agent must all be created as your"
|
||||
log_info "normal user. Re-run without sudo (the script elevates only when it truly needs to):"
|
||||
echo ""
|
||||
echo " ./install.sh"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
# /opt requires sudo to create and would leave a root-owned tree; default
|
||||
# macOS installs to a user-owned location so the whole flow stays rootless.
|
||||
if [[ "$DEFAULT_INSTALL_PATH" == "/opt/bambuddy" ]]; then
|
||||
DEFAULT_INSTALL_PATH="$HOME/bambuddy"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check/install Python
|
||||
if ! detect_python; then
|
||||
log_info "Python 3.10+ not found, will install..."
|
||||
|
||||
Reference in New Issue
Block a user