1 // 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 22 package daemon 23 24 import ( 25 "net" 26 "os" 27 ) 28 29 const ( 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 56 func 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 } 85