diff --git a/server/deploy.sh b/server/deploy.sh index 55d667c..dd9204e 100755 --- a/server/deploy.sh +++ b/server/deploy.sh @@ -202,7 +202,7 @@ if [[ -f "${REPO_DIR}/auth/password.py" ]]; then fi # Corporate memory directory -if [[ -d "${REPO_DIR}/services/corporate-memory" ]]; then +if [[ -d "${REPO_DIR}/services/corporate_memory" ]]; then log "Setting up corporate memory directory..." sudo /usr/bin/mkdir -p /data/corporate-memory sudo /usr/bin/chown root:data-ops /data/corporate-memory @@ -238,6 +238,24 @@ for unit_file in "${REPO_DIR}"/services/*/systemd/*.service "${REPO_DIR}"/servic fi done if [[ "$SYSTEMD_CHANGED" == "true" ]]; then + # Ensure all ReadWritePaths directories exist before daemon-reload. + # ProtectSystem=strict uses mount namespaces for ReadWritePaths — if any + # listed path is missing, the service fails at NAMESPACE step before any + # Exec* directive runs. This loop prevents that class of failures. + log "Validating ReadWritePaths directories..." + for installed_unit in /etc/systemd/system/*.service; do + [[ -f "$installed_unit" ]] || continue + rw_paths=$(grep -oP '^ReadWritePaths=\K.*' "$installed_unit" 2>/dev/null || true) + for rw_path in $rw_paths; do + if [[ ! -d "$rw_path" ]]; then + log " Creating missing ReadWritePaths: $rw_path (required by $(basename "$installed_unit"))" + sudo /usr/bin/mkdir -p "$rw_path" + sudo /usr/bin/chown root:data-ops "$rw_path" + sudo /usr/bin/chmod 2770 "$rw_path" + fi + done + done + sudo /usr/bin/systemctl daemon-reload log " systemd daemon-reload completed" fi diff --git a/services/data_refresh/systemd/data-refresh.service b/services/data_refresh/systemd/data-refresh.service index 7ed0b9c..14e9a49 100644 --- a/services/data_refresh/systemd/data-refresh.service +++ b/services/data_refresh/systemd/data-refresh.service @@ -15,9 +15,9 @@ EnvironmentFile=/opt/data-analyst/.env Environment=PYTHONPATH=/opt/data-analyst/repo Environment=CONFIG_DIR=/opt/data-analyst/instance/config -# Write access to data directory and logs +# Write access to data directory, logs, and /tmp (for staging + lock file) ProtectSystem=strict -ReadWritePaths=/data /opt/data-analyst/logs /tmp/data_analyst_staging +ReadWritePaths=/data /opt/data-analyst/logs /tmp PrivateTmp=false # Sync can take a while for large tables