diff --git a/changelog/9802.txt b/changelog/9802.txt new file mode 100644 index 0000000000000..f5102a04e21ef --- /dev/null +++ b/changelog/9802.txt @@ -0,0 +1,3 @@ +```release-note:improvement +agent: Send notifications to systemd on start and stop. +``` diff --git a/command/agent.go b/command/agent.go index 16fa9fa38e18d..959a7ddbb6e6c 100644 --- a/command/agent.go +++ b/command/agent.go @@ -16,6 +16,7 @@ import ( "sync" "time" + systemd "github.com/coreos/go-systemd/daemon" log "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-secure-stdlib/gatedwriter" "github.com/hashicorp/vault/api" @@ -794,6 +795,8 @@ func (c *AgentCommand) Run(args []string) int { select { case <-c.ShutdownCh: c.UI.Output("==> Vault agent shutdown triggered") + // Notify systemd that the server is shutting down + c.notifySystemd(systemd.SdNotifyStopping) // Let the lease cache know this is a shutdown; no need to evict // everything if leaseCache != nil { @@ -801,6 +804,7 @@ func (c *AgentCommand) Run(args []string) int { } return nil case <-ctx.Done(): + c.notifySystemd(systemd.SdNotifyStopping) return nil case <-winsvc.ShutdownChannel(): return nil @@ -928,6 +932,9 @@ func (c *AgentCommand) Run(args []string) int { return 1 } + // Notify systemd that the server is ready (if applicable) + c.notifySystemd(systemd.SdNotifyReady) + defer func() { if err := c.removePidFile(config.PidFile); err != nil { c.UI.Error(fmt.Sprintf("Error deleting the PID file: %s", err)) @@ -958,6 +965,19 @@ func verifyRequestHeader(handler http.Handler) http.Handler { }) } +func (c *AgentCommand) notifySystemd(status string) { + sent, err := systemd.SdNotify(false, status) + if err != nil { + c.logger.Error("error notifying systemd", "error", err) + } else { + if sent { + c.logger.Debug("sent systemd notification", "notification", status) + } else { + c.logger.Debug("would have sent systemd notification (systemd not present)", "notification", status) + } + } +} + func (c *AgentCommand) setStringFlag(f *FlagSets, configVal string, fVar *StringVar) { var isFlagSet bool f.Visit(func(f *flag.Flag) {