diff --git a/backend/src/routes/updates.rs b/backend/src/routes/updates.rs index b0341f1f..80c9f220 100644 --- a/backend/src/routes/updates.rs +++ b/backend/src/routes/updates.rs @@ -306,12 +306,18 @@ pub async fn install_update( command .arg(&version_clone) - // Redirect stdout/stderr to /dev/null since we detach - .stdin(std::process::Stdio::null()) - .stdout(std::process::Stdio::null()) - .stderr(std::process::Stdio::null()); + // Redirect stdout/stderr to log file for debugging + .stdin(std::process::Stdio::null()); + + // Keep stdout/stderr open so we can see errors in the log + // The script itself redirects to /var/tmp/csf-core-update.log tracing::info!("Executing command: {:?}", command); + tracing::info!( + "Command environment: PATH={}, HOME={}", + std::env::var("PATH").unwrap_or_default(), + std::env::var("HOME").unwrap_or_default() + ); match command.spawn() { Ok(child) => { diff --git a/csf-core.service b/csf-core.service index b3b374e5..a69a044c 100644 --- a/csf-core.service +++ b/csf-core.service @@ -26,10 +26,12 @@ Environment="ORIGIN=http://localhost:8000" PrivateTmp=true ProtectSystem=strict ProtectHome=true +NoNewPrivileges=false ReadWritePaths=/opt/csf-core ReadWritePaths=/var/lib/csf-core ReadWritePaths=/var/log/csf-core ReadWritePaths=/tmp +ReadWritePaths=/var/tmp SupplementaryGroups=docker # Startup: Use unified startup script diff --git a/csf-core.sudoers b/csf-core.sudoers index 3fb3969b..41122f49 100644 --- a/csf-core.sudoers +++ b/csf-core.sudoers @@ -7,6 +7,9 @@ csf-core ALL=(ALL) NOPASSWD: /bin/bash /opt/csf-core/scripts/update.sh* csf-core ALL=(ALL) NOPASSWD: /usr/bin/bash /opt/csf-core/scripts/update.sh* csf-core ALL=(ALL) NOPASSWD: /usr/bin/nohup /bin/bash /opt/csf-core/scripts/update.sh* csf-core ALL=(ALL) NOPASSWD: /usr/bin/nohup /usr/bin/bash /opt/csf-core/scripts/update.sh* +csf-core ALL=(ALL) NOPASSWD: /usr/bin/nohup sudo /bin/bash /opt/csf-core/scripts/update.sh* +csf-core ALL=(ALL) NOPASSWD: /bin/nohup /bin/bash /opt/csf-core/scripts/update.sh* +csf-core ALL=(ALL) NOPASSWD: /usr/bin/sudo /usr/bin/nohup /bin/bash /opt/csf-core/scripts/update.sh* csf-core ALL=(ALL) NOPASSWD: /bin/systemctl daemon-reload csf-core ALL=(ALL) NOPASSWD: /bin/systemctl start csf-core.service csf-core ALL=(ALL) NOPASSWD: /bin/systemctl stop csf-core.service diff --git a/scripts/update.sh b/scripts/update.sh index 4f6e35c0..125e111e 100755 --- a/scripts/update.sh +++ b/scripts/update.sh @@ -11,6 +11,18 @@ REPO="CS-Foundry/CSF-Core" INSTALL_DIR="/opt/csf-core" # Use /var/tmp instead of /tmp to avoid systemd PrivateTmp isolation STATUS_FILE="/var/tmp/csf-core-update-status.json" +LOG_FILE="/var/tmp/csf-core-update.log" + +# Redirect all output to log file (and still show on console) +exec > >(tee -a "${LOG_FILE}") 2>&1 + +echo "[$(date +'%Y-%m-%d %H:%M:%S')] ========================================" +echo "[$(date +'%Y-%m-%d %H:%M:%S')] CSF-Core Update Script Started" +echo "[$(date +'%Y-%m-%d %H:%M:%S')] Version: ${VERSION}" +echo "[$(date +'%Y-%m-%d %H:%M:%S')] User: $(whoami)" +echo "[$(date +'%Y-%m-%d %H:%M:%S')] UID: $EUID" +echo "[$(date +'%Y-%m-%d %H:%M:%S')] PWD: $(pwd)" +echo "[$(date +'%Y-%m-%d %H:%M:%S')] ========================================" # Determine if we need sudo early if [ "$EUID" -eq 0 ]; then