systemd.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0
  3. package systemd // import "miniflux.app/v2/internal/systemd"
  4. import (
  5. "fmt"
  6. "net"
  7. "os"
  8. "strconv"
  9. "time"
  10. )
  11. const (
  12. // SdNotifyReady tells the service manager that service startup is
  13. // finished, or the service finished loading its configuration.
  14. // https://www.freedesktop.org/software/systemd/man/sd_notify.html#READY=1
  15. SdNotifyReady = "READY=1"
  16. // SdNotifyWatchdog the service manager to update the watchdog timestamp.
  17. // https://www.freedesktop.org/software/systemd/man/sd_notify.html#WATCHDOG=1
  18. SdNotifyWatchdog = "WATCHDOG=1"
  19. )
  20. // HasNotifySocket checks if the process is supervised by Systemd and has the notify socket.
  21. func HasNotifySocket() bool {
  22. return os.Getenv("NOTIFY_SOCKET") != ""
  23. }
  24. // HasSystemdWatchdog checks if the watchdog is configured in Systemd unit file.
  25. func HasSystemdWatchdog() bool {
  26. return os.Getenv("WATCHDOG_USEC") != ""
  27. }
  28. // WatchdogInterval returns the watchdog interval configured in systemd unit file.
  29. func WatchdogInterval() (time.Duration, error) {
  30. s, err := strconv.Atoi(os.Getenv("WATCHDOG_USEC"))
  31. if err != nil {
  32. return 0, fmt.Errorf(`systemd: error converting WATCHDOG_USEC: %v`, err)
  33. }
  34. if s <= 0 {
  35. return 0, fmt.Errorf(`systemd: error WATCHDOG_USEC must be a positive number`)
  36. }
  37. return time.Duration(s) * time.Microsecond, nil
  38. }
  39. // SdNotify sends a message to systemd using the sd_notify protocol.
  40. // See https://www.freedesktop.org/software/systemd/man/sd_notify.html.
  41. func SdNotify(state string) error {
  42. addr := &net.UnixAddr{
  43. Net: "unixgram",
  44. Name: os.Getenv("NOTIFY_SOCKET"),
  45. }
  46. if addr.Name == "" {
  47. // We're not running under systemd (NOTIFY_SOCKET is not set).
  48. return nil
  49. }
  50. conn, err := net.DialUnix(addr.Net, nil, addr)
  51. if err != nil {
  52. return err
  53. }
  54. defer conn.Close()
  55. if _, err = conn.Write([]byte(state)); err != nil {
  56. return err
  57. }
  58. return nil
  59. }