diff --git a/audit/internal/platform/services.go b/audit/internal/platform/services.go index b21cb09..7c9d090 100644 --- a/audit/internal/platform/services.go +++ b/audit/internal/platform/services.go @@ -61,7 +61,9 @@ func (s *System) ServiceState(name string) string { } func (s *System) ServiceDo(name string, action ServiceAction) (string, error) { - raw, err := exec.Command("systemctl", string(action), name).CombinedOutput() + // bee-web runs as the bee user; sudo is required to control system services. + // /etc/sudoers.d/bee grants bee NOPASSWD:ALL. + raw, err := exec.Command("sudo", "systemctl", string(action), name).CombinedOutput() return string(raw), err } diff --git a/audit/internal/webui/api.go b/audit/internal/webui/api.go index f9cdf8c..4144f70 100644 --- a/audit/internal/webui/api.go +++ b/audit/internal/webui/api.go @@ -383,11 +383,13 @@ func (h *handler) handleAPIServicesAction(w http.ResponseWriter, r *http.Request return } result, err := h.opts.App.ServiceActionResult(req.Name, action) + status := "ok" if err != nil { - writeError(w, http.StatusInternalServerError, err.Error()) - return + status = "error" } - writeJSON(w, map[string]string{"status": "ok", "output": result.Body}) + // Always return 200 with output so the frontend can display the actual + // systemctl error message instead of a generic "exit status 1". + writeJSON(w, map[string]string{"status": status, "output": result.Body}) } // ── Network ─────────────────────────────────────────────────────────────────── diff --git a/audit/internal/webui/pages.go b/audit/internal/webui/pages.go index bc7adae..3080fc6 100644 --- a/audit/internal/webui/pages.go +++ b/audit/internal/webui/pages.go @@ -2107,9 +2107,12 @@ func renderServicesInline() string { return `
` + html.EscapeString(`bee-selfheal.timer is expected to be active; the oneshot bee-selfheal.service itself is not shown as a long-running service.`) + `
Loading...