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,7 @@
Feature: Allow running rest-server via systemd socket activation
We've added the option to have systemd create the listening socket and start the rest-server on demand.
https://github.com/restic/rest-server/issues/126
https://github.com/restic/rest-server/pull/151
https://github.com/restic/rest-server/pull/127

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

View file

@ -3,6 +3,9 @@ Description=Rest Server
After=syslog.target
After=network.target
# if you want to use socket activation, make sure to require the socket here
#Requires=rest-server.socket
[Service]
Type=simple
# You may prefer to use a different user or group on your system.

View file

@ -0,0 +1,5 @@
[Socket]
ListenStream = 8080
[Install]
WantedBy = sockets.target

1
go.mod
View file

@ -3,6 +3,7 @@ module github.com/restic/rest-server
go 1.14
require (
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
github.com/felixge/httpsnoop v1.0.2 // indirect
github.com/gorilla/handlers v1.5.1
github.com/miolini/datacounter v1.0.2

2
go.sum
View file

@ -65,6 +65,8 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU=
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=