mirror of
https://github.com/kemko/nomad.git
synced 2026-01-02 00:15:43 +03:00
First of all, we should not send the unix time, but the monotonic time. Second of all, RELOADING= and MONOTONIC_USEC fields should be sent in *single* message not two separate messages. From the man page of [systemd.service](https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html#Type=) > notification message via sd_notify(3) that contains the "RELOADING=1" field in > combination with "MONOTONIC_USEC=" set to the current monotonic time (i.e. > CLOCK_MONOTONIC in clock_gettime(2)) in μs, formatted as decimal string. [sd_notify](https://www.freedesktop.org/software/systemd/man/latest/sd_notify.html) now has code samples of the protocol to clarify. Without these changes, if you'd set Type=notify-reload on the agen'ts systemd unit, systemd would kill the service due to the service not responding to reload correctly.
50 lines
1.2 KiB
Go
50 lines
1.2 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
//go:build linux
|
|
|
|
package agent
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
"os"
|
|
"time"
|
|
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
const sdNotifySocketEnvVar = "NOTIFY_SOCKET"
|
|
|
|
// openNotify opens the systemd notify socket only if the expected env var has
|
|
// been set, because the systemd unit file is Type=notify or Type=notify-reload
|
|
// (systemd 253+). It then unsets the env var in the agent process so that child
|
|
// processes can't accidentally inherit it. This function returns (nil, nil) if
|
|
// the env var isn't set.
|
|
func openNotify() (io.WriteCloser, error) {
|
|
socketPath := os.Getenv(sdNotifySocketEnvVar)
|
|
if socketPath == "" {
|
|
return nil, nil
|
|
}
|
|
|
|
defer os.Unsetenv(sdNotifySocketEnvVar)
|
|
conn, err := net.DialTimeout("unixgram", socketPath, time.Second)
|
|
return conn, err
|
|
}
|
|
|
|
// sdNotify sends the message on the systemd notify socket, and gracefully
|
|
// handles a nil socket
|
|
func sdNotify(w io.Writer, msg string) {
|
|
if w == nil || msg == "" {
|
|
return
|
|
}
|
|
w.Write([]byte(msg))
|
|
}
|
|
|
|
func sdNotifyReloading(w io.Writer) {
|
|
var ts unix.Timespec
|
|
unix.ClockGettime(unix.CLOCK_MONOTONIC, &ts)
|
|
sdNotify(w, fmt.Sprintf("RELOADING=1\nMONOTONIC_USEC=%d", ts.Nano()/1000))
|
|
}
|