Skip to content

Commit

Permalink
Add systemd socket activation support
Browse files Browse the repository at this point in the history
  • Loading branch information
PhracturedBlue committed Sep 2, 2023
1 parent ff4b8c8 commit fbca399
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 28 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module github.com/photoprism/photoprism

require (
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
github.com/coreos/go-systemd/v22 v22.5.0
github.com/disintegration/imaging v1.6.2
github.com/djherbis/times v1.5.0
github.com/dsoprea/go-exif/v3 v3.0.1
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04=
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
Expand Down Expand Up @@ -165,6 +167,7 @@ github.com/goccmack/gocc v0.0.0-20230228185258-2292f9e40198/go.mod h1:DTh/Y2+Nbn
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
Expand Down
65 changes: 37 additions & 28 deletions internal/server/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"golang.org/x/crypto/acme/autocert"
"golang.org/x/sync/errgroup"

"github.com/coreos/go-systemd/v22/activation"

"github.com/gin-contrib/gzip"
"github.com/gin-gonic/gin"

Expand Down Expand Up @@ -74,13 +76,32 @@ func Start(ctx context.Context, conf *config.Config) {

var tlsErr error
var tlsManager *autocert.Manager
var server *http.Server
var listener net.Listener

server := &http.Server{Handler: router}

// Start HTTP server.
if unixSocket := conf.HttpSocket(); unixSocket != "" {
var listener net.Listener
// 1st check for socket activation
listeners, err := activation.Listeners()
if err != nil {
log.Errorf("server: Socket activation detection failed (%s)", err)
return
}
if len(listeners) > 1 {
log.Errorf("server: Only expected 1 activated socket, found %d", len(listeners))
return
} else if len(listeners) == 1 {
if publicCert, privateKey := conf.TLS(); publicCert != "" && privateKey != "" {
log.Infof("server: starting in tls mode")

go StartTLS(server, listeners[0], publicCert, privateKey)
} else {
log.Infof("server: %s", tlsErr)

go StartHttp(server, listeners[0])
}
} else if unixSocket := conf.HttpSocket(); unixSocket != "" {
var unixAddr *net.UnixAddr
var err error

if unixAddr, err = net.ResolveUnixAddr("unix", unixSocket); err != nil {
log.Errorf("server: resolve unix address failed (%s)", err)
Expand All @@ -89,11 +110,6 @@ func Start(ctx context.Context, conf *config.Config) {
log.Errorf("server: listen unix address failed (%s)", err)
return
} else {
server = &http.Server{
Addr: unixSocket,
Handler: router,
}

log.Infof("server: listening on %s [%s]", unixSocket, time.Since(start))

go StartHttp(server, listener)
Expand All @@ -106,38 +122,31 @@ func Start(ctx context.Context, conf *config.Config) {
}
log.Infof("server: starting in auto tls mode on %s [%s]", server.Addr, time.Since(start))
go StartAutoTLS(server, tlsManager, conf)
} else if publicCert, privateKey := conf.TLS(); unixSocket == "" && publicCert != "" && privateKey != "" {
log.Infof("server: starting in tls mode")
server = &http.Server{
Addr: fmt.Sprintf("%s:%d", conf.HttpHost(), conf.HttpPort()),
Handler: router,
}
log.Infof("server: listening on %s [%s]", server.Addr, time.Since(start))
go StartTLS(server, publicCert, privateKey)
} else {
log.Infof("server: %s", tlsErr)
var listener net.Listener
var err error

socket := fmt.Sprintf("%s:%d", conf.HttpHost(), conf.HttpPort())

if listener, err := net.Listen("tcp", socket); err != nil {
if listener, err = net.Listen("tcp", socket); err != nil {
log.Errorf("server: %s", err)
return
} else {
server = &http.Server{
Addr: socket,
Handler: router,
}
}

log.Infof("server: listening on %s [%s]", socket, time.Since(start))
log.Infof("server: listening on %s [%s]", socket, time.Since(start))

if publicCert, privateKey := conf.TLS(); unixSocket == "" && publicCert != "" && privateKey != "" {
log.Infof("server: starting in tls mode")
go StartTLS(server, listener, publicCert, privateKey)
} else {
go StartHttp(server, listener)
}
}

// Graceful HTTP server shutdown.
<-ctx.Done()
log.Info("server: shutting down")
err := server.Close()
err = server.Close()
if err != nil {
log.Errorf("server: shutdown failed (%s)", err)
}
Expand All @@ -155,8 +164,8 @@ func StartHttp(s *http.Server, l net.Listener) {
}

// StartTLS starts the web server in https mode.
func StartTLS(s *http.Server, httpsCert, privateKey string) {
if err := s.ListenAndServeTLS(httpsCert, privateKey); err != nil {
func StartTLS(s *http.Server, listener net.Listener, httpsCert, privateKey string) {
if err := s.ServeTLS(listener, httpsCert, privateKey); err != nil {
if err == http.ErrServerClosed {
log.Info("server: shutdown complete")
} else {
Expand Down

0 comments on commit fbca399

Please sign in to comment.