Created
December 3, 2019 07:46
-
-
Save jn0/21b0c8b8128f6293d3319b9413fb9e62 to your computer and use it in GitHub Desktop.
Implement the sd_notify protocol to talk to systemd (Type=notify)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
// https://github.com/coreos/go-systemd/blob/master/daemon/sdnotify.go | |
import ( | |
"net" | |
"os" | |
"fmt" | |
) | |
const ( | |
sdNotifyEnvVar = "NOTIFY_SOCKET" | |
sdNotifyNet = "unixgram" | |
// SdNotifyReady tells the service manager that service startup is | |
// finished or the service finished loading its configuration. | |
sdNotifyReady = "READY=1" | |
// SdNotifyStopping tells the service manager that the service is | |
// beginning its shutdown. | |
sdNotifyStopping = "STOPPING=1" | |
// SdNotifyReloading tells the service manager that this service is | |
// reloading its configuration. Note that you must call SdNotifyReady | |
// when it completed reloading. | |
sdNotifyReloading = "RELOADING=1" | |
// SdNotifyWatchdog tells the service manager to update the watchdog | |
// timestamp for the service. | |
sdNotifyWatchdog = "WATCHDOG=1" | |
sdNotifyStatus = "STATUS=" // ... | |
) | |
type SdNotifier struct{ | |
socketAddr *net.UnixAddr | |
} | |
func (self *SdNotifier) Available() bool { | |
return self != nil && self.socketAddr != nil && self.socketAddr.Name != "" | |
} | |
func (self *SdNotifier) notify(state string) (bool, error) { | |
if !self.Available() { | |
return false, nil // that's a quiet thing | |
} | |
log.Info("sd_notify(%+q)", state) | |
conn, err := net.DialUnix(self.socketAddr.Net, nil, self.socketAddr) | |
if err != nil { | |
log.Error("notify(%+q) dial: %v", state, err) | |
return false, err | |
} | |
defer conn.Close() | |
if _, err = conn.Write([]byte(state)); err != nil { | |
log.Error("notify(%+q) write: %v", state, err) | |
return false, err | |
} | |
return true, nil | |
} | |
func (self *SdNotifier) ImAlive() (bool, error) { | |
return self.notify(sdNotifyWatchdog) | |
} | |
func (self *SdNotifier) Reloading() (bool, error) { | |
return self.notify(sdNotifyReloading) | |
} | |
func (self *SdNotifier) Ready() (bool, error) { | |
return self.notify(sdNotifyReady) | |
} | |
func (self *SdNotifier) Stopping() (bool, error) { | |
return self.notify(sdNotifyStopping) | |
} | |
func (self *SdNotifier) Status(message string, args ...interface{}) (bool, error) { | |
return self.notify(sdNotifyStatus + fmt.Sprintf(message, args...)) | |
} | |
func NewSdNotifier(unsetEnvironment bool) (*SdNotifier, error) { | |
env := os.Getenv(sdNotifyEnvVar) | |
if unsetEnvironment { | |
if err := os.Unsetenv(sdNotifyEnvVar); err != nil { | |
return nil, err | |
} | |
} | |
log.Debug("$%v=%#v", sdNotifyEnvVar, env) | |
if env == "" { return nil, nil; } | |
sdn := &SdNotifier{ | |
socketAddr: &net.UnixAddr{ | |
Name: env, | |
Net: sdNotifyNet, | |
}, | |
} | |
return sdn, nil | |
} | |
/* EOF */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment