11 "github.com/Sirupsen/logrus"
12 "github.com/opencontainers/runtime-spec/specs-go"
13 "github.com/urfave/cli"
16 type notifySocket struct {
22 func newNotifySocket(context *cli.Context, notifySocketHost string, id string) *notifySocket {
23 if notifySocketHost == "" {
27 root := filepath.Join(context.GlobalString("root"), id)
28 path := filepath.Join(root, "notify.sock")
30 notifySocket := ¬ifySocket{
32 host: notifySocketHost,
39 func (ns *notifySocket) Close() error {
40 return ns.socket.Close()
43 // If systemd is supporting sd_notify protocol, this function will add support
44 // for sd_notify protocol from within the container.
45 func (s *notifySocket) setupSpec(context *cli.Context, spec *specs.Spec) {
46 mount := specs.Mount{Destination: s.host, Type: "bind", Source: s.socketPath, Options: []string{"bind"}}
47 spec.Mounts = append(spec.Mounts, mount)
48 spec.Process.Env = append(spec.Process.Env, fmt.Sprintf("NOTIFY_SOCKET=%s", s.host))
51 func (s *notifySocket) setupSocket() error {
57 socket, err := net.ListenUnixgram("unixgram", &addr)
66 // pid1 must be set only with -d, as it is used to set the new process as the main process
67 // for the service in systemd
68 func (notifySocket *notifySocket) run(pid1 int) {
69 buf := make([]byte, 512)
70 notifySocketHostAddr := net.UnixAddr{Name: notifySocket.host, Net: "unixgram"}
71 client, err := net.DialUnix("unixgram", nil, ¬ifySocketHostAddr)
77 r, err := notifySocket.socket.Read(buf)
82 for _, line := range bytes.Split(buf[0:r], []byte{'\n'}) {
83 if bytes.HasPrefix(line, []byte("READY=")) {
84 _, err = out.Write(line)
89 _, err = out.Write([]byte{'\n'})
94 _, err = client.Write(out.Bytes())
99 // now we can inform systemd to use pid1 as the pid to monitor
101 newPid := fmt.Sprintf("MAINPID=%d\n", pid1)
102 client.Write([]byte(newPid))