service_linux.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. //go:build linux
  2. package docker
  3. /*
  4. service_linux.go
  5. Docker daemon service control on Linux via systemctl. Isolated behind a
  6. build tag so non-systemd platforms compile against service_other.go.
  7. These operations require root; when ArozOS is not privileged enough,
  8. systemctl's own error message is surfaced back to the caller.
  9. */
  10. import (
  11. "errors"
  12. "os/exec"
  13. "strings"
  14. )
  15. func systemctlAvailable() bool {
  16. _, err := exec.LookPath("systemctl")
  17. return err == nil
  18. }
  19. // dockerServiceStatus reports the docker unit's active/enabled state.
  20. func dockerServiceStatus() ServiceStatus {
  21. st := ServiceStatus{}
  22. if !systemctlAvailable() {
  23. st.Message = "systemctl is not available on this host"
  24. return st
  25. }
  26. st.Available = true
  27. // `is-active` exits non-zero when inactive, but still prints the state on
  28. // stdout — parse the output rather than relying on the exit code.
  29. out, _ := exec.Command("systemctl", "is-active", "docker").CombinedOutput()
  30. st.State = strings.TrimSpace(string(out))
  31. st.Active = st.State == "active"
  32. outEnabled, _ := exec.Command("systemctl", "is-enabled", "docker").CombinedOutput()
  33. st.Enabled = strings.TrimSpace(string(outEnabled)) == "enabled"
  34. return st
  35. }
  36. // dockerServiceAction runs `systemctl <action> docker` for a whitelisted action.
  37. func dockerServiceAction(action string) error {
  38. if !systemctlAvailable() {
  39. return errors.New("systemctl is not available on this host")
  40. }
  41. out, err := exec.Command("systemctl", action, "docker").CombinedOutput()
  42. if err != nil {
  43. msg := strings.TrimSpace(string(out))
  44. if msg == "" {
  45. msg = err.Error()
  46. }
  47. return errors.New(msg)
  48. }
  49. return nil
  50. }