Support running on demand systemd socket activation

This commit is contained in:
Alexander Neumann
2021-08-09 16:06:35 +02:00
parent 32784a3072
commit f90205eefe
8 changed files with 92 additions and 9 deletions

View File

@@ -0,0 +1,45 @@
// +build !windows
package main
import (
"fmt"
"log"
"net"
"github.com/coreos/go-systemd/activation"
)
// findListener tries to find a listener via systemd socket activation. If that
// fails, it tries to create a listener on addr.
func findListener(addr string) (listener net.Listener, err error) {
// try systemd socket activation
listeners, err := activation.Listeners()
if err != nil {
panic(err)
}
switch len(listeners) {
case 0:
// no listeners found, listen manually
listener, err = net.Listen("tcp", addr)
if err != nil {
return nil, fmt.Errorf("listen on %v failed: %w", addr, err)
}
log.Printf("start server on %v", addr)
return listener, nil
case 1:
// one listener supplied by systemd, use that one
//
// for testing, run rest-server with systemd-socket-activate as follows:
//
// systemd-socket-activate -l 8080 ./rest-server
log.Printf("systemd socket activation mode")
return listeners[0], nil
default:
return nil, fmt.Errorf("got %d listeners from systemd, expected one", len(listeners))
}
}

View File

@@ -0,0 +1,19 @@
package main
import (
"fmt"
"log"
"net"
)
// findListener creates a listener.
func findListener(addr string) (listener net.Listener, err error) {
// listen manually
listener, err = net.Listen("tcp", addr)
if err != nil {
return nil, fmt.Errorf("listen on %v failed: %w", addr, err)
}
log.Printf("start server on %v", addr)
return listener, nil
}

View File

@@ -129,16 +129,17 @@ func runRoot(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
if !enabledTLS {
log.Printf("Starting server on %s\n", server.Listen)
err = http.ListenAndServe(server.Listen, handler)
} else {
log.Println("TLS enabled")
log.Printf("Private key: %s", privateKey)
log.Printf("Public key(certificate): %s", publicKey)
log.Printf("Starting server on %s\n", server.Listen)
err = http.ListenAndServeTLS(server.Listen, publicKey, privateKey, handler)
listener, err := findListener(server.Listen)
if err != nil {
return fmt.Errorf("unable to listen: %w", err)
}
if !enabledTLS {
err = http.Serve(listener, handler)
} else {
log.Printf("TLS enabled, private key %s, pubkey %v", privateKey, publicKey)
err = http.ServeTLS(listener, handler, publicKey, privateKey)
}
return err