blob: ba4ae31f19baedfaaab7c77e1f2705147d51c578 [file] [log] [blame]
Matthias Andreas Benkard832a54e2019-01-29 09:27:38 +01001// Copyright 2014 Docker, Inc.
2// Copyright 2015-2018 CoreOS, Inc.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17// Package daemon provides a Go implementation of the sd_notify protocol.
18// It can be used to inform systemd of service start-up completion, watchdog
19// events, and other status changes.
20//
21// https://www.freedesktop.org/software/systemd/man/sd_notify.html#Description
22package daemon
23
24import (
25 "net"
26 "os"
27)
28
29const (
30 // SdNotifyReady tells the service manager that service startup is finished
31 // or the service finished loading its configuration.
32 SdNotifyReady = "READY=1"
33
34 // SdNotifyStopping tells the service manager that the service is beginning
35 // its shutdown.
36 SdNotifyStopping = "STOPPING=1"
37
38 // SdNotifyReloading tells the service manager that this service is
39 // reloading its configuration. Note that you must call SdNotifyReady when
40 // it completed reloading.
41 SdNotifyReloading = "RELOADING=1"
42
43 // SdNotifyWatchdog tells the service manager to update the watchdog
44 // timestamp for the service.
45 SdNotifyWatchdog = "WATCHDOG=1"
46)
47
48// SdNotify sends a message to the init daemon. It is common to ignore the error.
49// If `unsetEnvironment` is true, the environment variable `NOTIFY_SOCKET`
50// will be unconditionally unset.
51//
52// It returns one of the following:
53// (false, nil) - notification not supported (i.e. NOTIFY_SOCKET is unset)
54// (false, err) - notification supported, but failure happened (e.g. error connecting to NOTIFY_SOCKET or while sending data)
55// (true, nil) - notification supported, data has been sent
56func SdNotify(unsetEnvironment bool, state string) (bool, error) {
57 socketAddr := &net.UnixAddr{
58 Name: os.Getenv("NOTIFY_SOCKET"),
59 Net: "unixgram",
60 }
61
62 // NOTIFY_SOCKET not set
63 if socketAddr.Name == "" {
64 return false, nil
65 }
66
67 if unsetEnvironment {
68 if err := os.Unsetenv("NOTIFY_SOCKET"); err != nil {
69 return false, err
70 }
71 }
72
73 conn, err := net.DialUnix(socketAddr.Net, nil, socketAddr)
74 // Error connecting to NOTIFY_SOCKET
75 if err != nil {
76 return false, err
77 }
78 defer conn.Close()
79
80 if _, err = conn.Write([]byte(state)); err != nil {
81 return false, err
82 }
83 return true, nil
84}