add support for systemd notify
This commit is contained in:
		
							parent
							
								
									d3360f0fd9
								
							
						
					
					
						commit
						f54a736353
					
				
							
								
								
									
										83
									
								
								cmd/root.go
									
									
									
									
									
								
							
							
						
						
									
										83
									
								
								cmd/root.go
									
									
									
									
									
								
							| 
						 | 
					@ -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,43 +311,57 @@ 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.
 | 
				
			||||||
	if autotls {
 | 
						go func(s *http.Server, api config.ApiConfiguration, sys config.SystemConfiguration, autotls bool, tlshostname string) {
 | 
				
			||||||
		m := autocert.Manager{
 | 
							if autotls {
 | 
				
			||||||
			Prompt:     autocert.AcceptTOS,
 | 
								m := autocert.Manager{
 | 
				
			||||||
			Cache:      autocert.DirCache(path.Join(sys.RootDirectory, "/.tls-cache")),
 | 
									Prompt:     autocert.AcceptTOS,
 | 
				
			||||||
			HostPolicy: autocert.HostWhitelist(tlshostname),
 | 
									Cache:      autocert.DirCache(path.Join(sys.RootDirectory, "/.tls-cache")),
 | 
				
			||||||
		}
 | 
									HostPolicy: autocert.HostWhitelist(tlshostname),
 | 
				
			||||||
 | 
					 | 
				
			||||||
		log.WithField("hostname", tlshostname).Info("webserver is now listening with auto-TLS enabled; certificates will be automatically generated by Let's Encrypt")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Hook autocert into the main http server.
 | 
					 | 
				
			||||||
		s.TLSConfig.GetCertificate = m.GetCertificate
 | 
					 | 
				
			||||||
		s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, acme.ALPNProto) // enable tls-alpn ACME challenges
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Start the autocert server.
 | 
					 | 
				
			||||||
		go func() {
 | 
					 | 
				
			||||||
			if err := http.ListenAndServe(":http", m.HTTPHandler(nil)); err != nil {
 | 
					 | 
				
			||||||
				log.WithError(err).Error("failed to serve autocert http server")
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}()
 | 
					
 | 
				
			||||||
		// Start the main http server with TLS using autocert.
 | 
								log.WithField("hostname", tlshostname).Info("webserver is now listening with auto-TLS enabled; certificates will be automatically generated by Let's Encrypt")
 | 
				
			||||||
		if err := s.ListenAndServeTLS("", ""); err != nil {
 | 
					
 | 
				
			||||||
			log.WithFields(log.Fields{"auto_tls": true, "tls_hostname": tlshostname, "error": err}).Fatal("failed to configure HTTP server using auto-tls")
 | 
								// Hook autocert into the main http server.
 | 
				
			||||||
 | 
								s.TLSConfig.GetCertificate = m.GetCertificate
 | 
				
			||||||
 | 
								s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, acme.ALPNProto) // enable tls-alpn ACME challenges
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Start the autocert server.
 | 
				
			||||||
 | 
								go func() {
 | 
				
			||||||
 | 
									if err := http.ListenAndServe(":http", m.HTTPHandler(nil)); err != nil {
 | 
				
			||||||
 | 
										log.WithError(err).Error("failed to serve autocert http server")
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}()
 | 
				
			||||||
 | 
								// Start the main http server with TLS using autocert.
 | 
				
			||||||
 | 
								if err := s.ListenAndServeTLS("", ""); err != nil {
 | 
				
			||||||
 | 
									log.WithFields(log.Fields{"auto_tls": true, "tls_hostname": tlshostname, "error": err}).Fatal("failed to configure HTTP server using auto-tls")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return
 | 
					
 | 
				
			||||||
 | 
							// Check if main http server should run with TLS. Otherwise reset the TLS
 | 
				
			||||||
 | 
							// config on the server and then serve it over normal HTTP.
 | 
				
			||||||
 | 
							if api.Ssl.Enabled {
 | 
				
			||||||
 | 
								if err := s.ListenAndServeTLS(strings.ToLower(api.Ssl.CertificateFile), strings.ToLower(api.Ssl.KeyFile)); err != nil {
 | 
				
			||||||
 | 
									log.WithFields(log.Fields{"auto_tls": false, "error": err}).Fatal("failed to configure HTTPS server")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							s.TLSConfig = nil
 | 
				
			||||||
 | 
							if err := s.ListenAndServe(); err != nil {
 | 
				
			||||||
 | 
								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")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Check if main http server should run with TLS. Otherwise reset the TLS
 | 
						c := make(chan os.Signal, 1)
 | 
				
			||||||
	// config on the server and then serve it over normal HTTP.
 | 
						signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
 | 
				
			||||||
	if api.Ssl.Enabled {
 | 
						<-c
 | 
				
			||||||
		if err := s.ListenAndServeTLS(strings.ToLower(api.Ssl.CertificateFile), strings.ToLower(api.Ssl.KeyFile)); err != nil {
 | 
					
 | 
				
			||||||
			log.WithFields(log.Fields{"auto_tls": false, "error": err}).Fatal("failed to configure HTTPS server")
 | 
						if err := notify.Stopping(); err != nil {
 | 
				
			||||||
		}
 | 
							log.WithField("error", err).Error("failed to notify systemd of stopping state")
 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s.TLSConfig = nil
 | 
					 | 
				
			||||||
	if err := s.ListenAndServe(); err != nil {
 | 
					 | 
				
			||||||
		log.WithField("error", err).Fatal("failed to configure HTTP server")
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										19
									
								
								internal/notify/notify.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								internal/notify/notify.go
									
									
									
									
									
										Normal 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()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										48
									
								
								internal/notify/notify_linux.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								internal/notify/notify_linux.go
									
									
									
									
									
										Normal 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")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								internal/notify/notify_other.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								internal/notify/notify_other.go
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					// +build !linux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package notify
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func readiness() error {
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func reloading() error {
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func stopping() error {
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user