add support for systemd notify

This commit is contained in:
Matthew Penner 2021-07-19 13:05:54 -06:00
parent d3360f0fd9
commit f54a736353
4 changed files with 132 additions and 33 deletions

View File

@ -7,10 +7,12 @@ import (
log2 "log" log2 "log"
"net/http" "net/http"
"os" "os"
"os/signal"
"path" "path"
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
"syscall"
"time" "time"
"github.com/NYTimes/logrotate" "github.com/NYTimes/logrotate"
@ -26,6 +28,7 @@ import (
"github.com/pterodactyl/wings/config" "github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment" "github.com/pterodactyl/wings/environment"
"github.com/pterodactyl/wings/internal/notify"
"github.com/pterodactyl/wings/loggers/cli" "github.com/pterodactyl/wings/loggers/cli"
"github.com/pterodactyl/wings/remote" "github.com/pterodactyl/wings/remote"
"github.com/pterodactyl/wings/router" "github.com/pterodactyl/wings/router"
@ -308,6 +311,7 @@ func rootCmdRun(cmd *cobra.Command, _ []string) {
} }
// Check if the server should run with TLS but using autocert. // Check if the server should run with TLS but using autocert.
go func(s *http.Server, api config.ApiConfiguration, sys config.SystemConfiguration, autotls bool, tlshostname string) {
if autotls { if autotls {
m := autocert.Manager{ m := autocert.Manager{
Prompt: autocert.AcceptTOS, Prompt: autocert.AcceptTOS,
@ -346,6 +350,19 @@ func rootCmdRun(cmd *cobra.Command, _ []string) {
if err := s.ListenAndServe(); err != nil { if err := s.ListenAndServe(); err != nil {
log.WithField("error", err).Fatal("failed to configure HTTP server") log.WithField("error", err).Fatal("failed to configure HTTP server")
} }
}(s, api, sys, autotls, tlshostname)
if err := notify.Readiness(); err != nil {
log.WithField("error", err).Error("failed to notify systemd of readiness state")
}
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
<-c
if err := notify.Stopping(); err != nil {
log.WithField("error", err).Error("failed to notify systemd of stopping state")
}
} }
// Reads the configuration from the disk and then sets up the global singleton // Reads the configuration from the disk and then sets up the global singleton

19
internal/notify/notify.go Normal file
View File

@ -0,0 +1,19 @@
// Package notify handles notifying the operating system of the program's state.
//
// For linux based operating systems, this is done through the systemd socket
// set by "NOTIFY_SOCKET" environment variable.
//
// Currently, no other operating systems are supported.
package notify
func Readiness() error {
return readiness()
}
func Reloading() error {
return reloading()
}
func Stopping() error {
return stopping()
}

View File

@ -0,0 +1,48 @@
package notify
import (
"io"
"net"
"os"
"strings"
)
func notify(path string, r io.Reader) error {
s := &net.UnixAddr{
Name: path,
Net: "unixgram",
}
c, err := net.DialUnix(s.Net, nil, s)
if err != nil {
return err
}
defer c.Close()
if _, err := io.Copy(c, r); err != nil {
return err
}
return nil
}
func socketNotify(payload string) error {
v, ok := os.LookupEnv("NOTIFY_SOCKET")
if !ok || v == "" {
return nil
}
if err := notify(v, strings.NewReader(payload)); err != nil {
return err
}
return nil
}
func readiness() error {
return socketNotify("READY=1")
}
func reloading() error {
return socketNotify("RELOADING=1")
}
func stopping() error {
return socketNotify("STOPPING=1")
}

View File

@ -0,0 +1,15 @@
// +build !linux
package notify
func readiness() error {
return nil
}
func reloading() error {
return nil
}
func stopping() error {
return nil
}