diff options
author | 2021-08-17 21:39:42 +0200 | |
---|---|---|
committer | 2021-08-17 21:39:42 +0200 | |
commit | d2813ea61b37e7c8bc40c9afec7990cbe2ffd199 (patch) | |
tree | e1841e2ee30e13e8fbc3b50561dacfdfbdf1e3ac | |
parent | 32784a30723e9b7c47282724fca1907912e6244d (diff) | |
parent | f90205eefe13f5e64cf59cd1b77c6f510451d5cf (diff) | |
download | rest-server-d2813ea61b37e7c8bc40c9afec7990cbe2ffd199.tar.gz rest-server-d2813ea61b37e7c8bc40c9afec7990cbe2ffd199.tar.zst rest-server-d2813ea61b37e7c8bc40c9afec7990cbe2ffd199.zip |
Merge pull request #151 from restic/add-socket-activation
Support running on demand via systemd
-rw-r--r-- | changelog/unreleased/issue-126 | 7 | ||||
-rw-r--r-- | cmd/rest-server/listener_unix.go | 45 | ||||
-rw-r--r-- | cmd/rest-server/listener_windows.go | 19 | ||||
-rw-r--r-- | cmd/rest-server/main.go | 17 | ||||
-rw-r--r-- | examples/systemd/rest-server.service | 3 | ||||
-rw-r--r-- | examples/systemd/rest-server.socket | 5 | ||||
-rw-r--r-- | go.mod | 1 | ||||
-rw-r--r-- | go.sum | 2 |
8 files changed, 91 insertions, 8 deletions
diff --git a/changelog/unreleased/issue-126 b/changelog/unreleased/issue-126 new file mode 100644 index 0000000..58903cb --- /dev/null +++ b/changelog/unreleased/issue-126 @@ -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 diff --git a/cmd/rest-server/listener_unix.go b/cmd/rest-server/listener_unix.go new file mode 100644 index 0000000..3b3f695 --- /dev/null +++ b/cmd/rest-server/listener_unix.go @@ -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)) + } +} diff --git a/cmd/rest-server/listener_windows.go b/cmd/rest-server/listener_windows.go new file mode 100644 index 0000000..b1d8071 --- /dev/null +++ b/cmd/rest-server/listener_windows.go @@ -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 +} diff --git a/cmd/rest-server/main.go b/cmd/rest-server/main.go index 1de3607..5fb16de 100644 --- a/cmd/rest-server/main.go +++ b/cmd/rest-server/main.go @@ -129,16 +129,17 @@ func runRoot(cmd *cobra.Command, args []string) error { if err != nil { return err } + + listener, err := findListener(server.Listen) + if err != nil { + return fmt.Errorf("unable to listen: %w", err) + } + if !enabledTLS { - log.Printf("Starting server on %s\n", server.Listen) - err = http.ListenAndServe(server.Listen, handler) + err = http.Serve(listener, 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) + log.Printf("TLS enabled, private key %s, pubkey %v", privateKey, publicKey) + err = http.ServeTLS(listener, handler, publicKey, privateKey) } return err diff --git a/examples/systemd/rest-server.service b/examples/systemd/rest-server.service index 360d39f..b5f28bd 100644 --- a/examples/systemd/rest-server.service +++ b/examples/systemd/rest-server.service @@ -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. diff --git a/examples/systemd/rest-server.socket b/examples/systemd/rest-server.socket new file mode 100644 index 0000000..ba3262a --- /dev/null +++ b/examples/systemd/rest-server.socket @@ -0,0 +1,5 @@ +[Socket] +ListenStream = 8080 + +[Install] +WantedBy = sockets.target @@ -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 @@ -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= |