aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexander Neumann <123276+fd0@users.noreply.github.com> 2021-08-17 21:39:42 +0200
committerGravatar GitHub <noreply@github.com> 2021-08-17 21:39:42 +0200
commitd2813ea61b37e7c8bc40c9afec7990cbe2ffd199 (patch)
treee1841e2ee30e13e8fbc3b50561dacfdfbdf1e3ac
parent32784a30723e9b7c47282724fca1907912e6244d (diff)
parentf90205eefe13f5e64cf59cd1b77c6f510451d5cf (diff)
downloadrest-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-1267
-rw-r--r--cmd/rest-server/listener_unix.go45
-rw-r--r--cmd/rest-server/listener_windows.go19
-rw-r--r--cmd/rest-server/main.go17
-rw-r--r--examples/systemd/rest-server.service3
-rw-r--r--examples/systemd/rest-server.socket5
-rw-r--r--go.mod1
-rw-r--r--go.sum2
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
diff --git a/go.mod b/go.mod
index 1176fd0..5f49c0a 100644
--- a/go.mod
+++ b/go.mod
@@ -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
diff --git a/go.sum b/go.sum
index 7d6cad5..e698e88 100644
--- a/go.sum
+++ b/go.sum
@@ -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=