systemd.go 1.9 KB

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