Skip to content

Commit 164dd28

Browse files
authored
Merge pull request #6675 from ipfs/feat/systemd-activation
add systemd support
2 parents fdcdcb8 + 0d0b4fc commit 164dd28

File tree

8 files changed

+119
-73
lines changed

8 files changed

+119
-73
lines changed

cmd/ipfs/daemon.go

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
nodeMount "github.com/ipfs/go-ipfs/fuse/node"
2727
fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
2828
migrate "github.com/ipfs/go-ipfs/repo/fsrepo/migrations"
29+
sockets "github.com/libp2p/go-socket-activation"
2930

3031
"github.com/hashicorp/go-multierror"
3132
cmds "github.com/ipfs/go-ipfs-cmds"
@@ -291,11 +292,6 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
291292
// fail before we get to that. It can't hurt to close it twice.
292293
defer repo.Close()
293294

294-
cfg, err := cctx.GetConfig()
295-
if err != nil {
296-
return err
297-
}
298-
299295
offline, _ := req.Options[offlineKwd].(bool)
300296
ipnsps, _ := req.Options[enableIPNSPubSubKwd].(bool)
301297
pubsub, _ := req.Options[enablePubSubKwd].(bool)
@@ -405,14 +401,10 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
405401
return err
406402
}
407403

408-
// construct http gateway - if it is set in the config
409-
var gwErrc <-chan error
410-
if len(cfg.Addresses.Gateway) > 0 {
411-
var err error
412-
gwErrc, err = serveHTTPGateway(req, cctx)
413-
if err != nil {
414-
return err
415-
}
404+
// construct http gateway
405+
gwErrc, err := serveHTTPGateway(req, cctx)
406+
if err != nil {
407+
return err
416408
}
417409

418410
// Add ipfs version info to prometheous metrics
@@ -432,10 +424,12 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
432424

433425
// The daemon is *finally* ready.
434426
fmt.Printf("Daemon is ready\n")
427+
notifyReady()
435428

436429
// Give the user some immediate feedback when they hit C-c
437430
go func() {
438431
<-req.Context.Done()
432+
notifyStopping()
439433
fmt.Println("Received interrupt signal, shutting down...")
440434
fmt.Println("(Hit ctrl-c again to force-shutdown the daemon.)")
441435
}()
@@ -459,6 +453,11 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error
459453
return nil, fmt.Errorf("serveHTTPApi: GetConfig() failed: %s", err)
460454
}
461455

456+
listeners, err := sockets.TakeListeners("io.ipfs.api")
457+
if err != nil {
458+
return nil, fmt.Errorf("serveHTTPApi: socket activation failed: %s", err)
459+
}
460+
462461
apiAddrs := make([]string, 0, 2)
463462
apiAddr, _ := req.Options[commands.ApiOption].(string)
464463
if apiAddr == "" {
@@ -467,25 +466,35 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error
467466
apiAddrs = append(apiAddrs, apiAddr)
468467
}
469468

470-
listeners := make([]manet.Listener, 0, len(apiAddrs))
469+
listenerAddrs := make(map[string]bool, len(listeners))
470+
for _, listener := range listeners {
471+
listenerAddrs[string(listener.Multiaddr().Bytes())] = true
472+
}
473+
471474
for _, addr := range apiAddrs {
472475
apiMaddr, err := ma.NewMultiaddr(addr)
473476
if err != nil {
474477
return nil, fmt.Errorf("serveHTTPApi: invalid API address: %q (err: %s)", apiAddr, err)
475478
}
479+
if listenerAddrs[string(apiMaddr.Bytes())] {
480+
continue
481+
}
476482

477483
apiLis, err := manet.Listen(apiMaddr)
478484
if err != nil {
479485
return nil, fmt.Errorf("serveHTTPApi: manet.Listen(%s) failed: %s", apiMaddr, err)
480486
}
481487

482-
// we might have listened to /tcp/0 - lets see what we are listing on
483-
apiMaddr = apiLis.Multiaddr()
484-
fmt.Printf("API server listening on %s\n", apiMaddr)
485-
fmt.Printf("WebUI: http://%s/webui\n", apiLis.Addr())
488+
listenerAddrs[string(apiMaddr.Bytes())] = true
486489
listeners = append(listeners, apiLis)
487490
}
488491

492+
for _, listener := range listeners {
493+
// we might have listened to /tcp/0 - lets see what we are listing on
494+
fmt.Printf("API server listening on %s\n", listener.Multiaddr())
495+
fmt.Printf("WebUI: http://%s/webui\n", listener.Addr())
496+
}
497+
489498
// by default, we don't let you load arbitrary ipfs objects through the api,
490499
// because this would open up the api to scripting vulnerabilities.
491500
// only the webui objects are allowed.
@@ -584,28 +593,43 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e
584593
writable = cfg.Gateway.Writable
585594
}
586595

596+
listeners, err := sockets.TakeListeners("io.ipfs.gateway")
597+
if err != nil {
598+
return nil, fmt.Errorf("serveHTTPGateway: socket activation failed: %s", err)
599+
}
600+
601+
listenerAddrs := make(map[string]bool, len(listeners))
602+
for _, listener := range listeners {
603+
listenerAddrs[string(listener.Multiaddr().Bytes())] = true
604+
}
605+
587606
gatewayAddrs := cfg.Addresses.Gateway
588-
listeners := make([]manet.Listener, 0, len(gatewayAddrs))
589607
for _, addr := range gatewayAddrs {
590608
gatewayMaddr, err := ma.NewMultiaddr(addr)
591609
if err != nil {
592610
return nil, fmt.Errorf("serveHTTPGateway: invalid gateway address: %q (err: %s)", addr, err)
593611
}
594612

613+
if listenerAddrs[string(gatewayMaddr.Bytes())] {
614+
continue
615+
}
616+
595617
gwLis, err := manet.Listen(gatewayMaddr)
596618
if err != nil {
597619
return nil, fmt.Errorf("serveHTTPGateway: manet.Listen(%s) failed: %s", gatewayMaddr, err)
598620
}
599-
// we might have listened to /tcp/0 - lets see what we are listing on
600-
gatewayMaddr = gwLis.Multiaddr()
621+
listenerAddrs[string(gatewayMaddr.Bytes())] = true
622+
listeners = append(listeners, gwLis)
623+
}
601624

602-
if writable {
603-
fmt.Printf("Gateway (writable) server listening on %s\n", gatewayMaddr)
604-
} else {
605-
fmt.Printf("Gateway (readonly) server listening on %s\n", gatewayMaddr)
606-
}
625+
// we might have listened to /tcp/0 - lets see what we are listing on
626+
gwType := "readonly"
627+
if writable {
628+
gwType = "writable"
629+
}
607630

608-
listeners = append(listeners, gwLis)
631+
for _, listener := range listeners {
632+
fmt.Printf("Gateway (%s) server listening on %s\n", gwType, listener.Multiaddr())
609633
}
610634

611635
cmdctx := *cctx

cmd/ipfs/daemon_linux.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// +build linux
2+
3+
package main
4+
5+
import (
6+
daemon "github.com/coreos/go-systemd/daemon"
7+
)
8+
9+
func notifyReady() {
10+
_, _ = daemon.SdNotify(false, daemon.SdNotifyReady)
11+
}
12+
13+
func notifyStopping() {
14+
_, _ = daemon.SdNotify(false, daemon.SdNotifyStopping)
15+
}

cmd/ipfs/daemon_other.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// +build !linux
2+
3+
package main
4+
5+
func notifyReady() {}
6+
7+
func notifyStopping() {}

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ require (
55
github.com/AndreasBriese/bbloom v0.0.0-20190823232136-616930265c33 // indirect
66
github.com/blang/semver v3.5.1+incompatible
77
github.com/bren2010/proquint v0.0.0-20160323162903-38337c27106d
8+
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f
89
github.com/dustin/go-humanize v1.0.0
910
github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302
1011
github.com/fatih/color v1.7.0 // indirect
@@ -78,6 +79,7 @@ require (
7879
github.com/libp2p/go-libp2p-tls v0.1.1
7980
github.com/libp2p/go-libp2p-yamux v0.2.1
8081
github.com/libp2p/go-maddr-filter v0.0.5
82+
github.com/libp2p/go-socket-activation v0.0.1
8183
github.com/mattn/go-runewidth v0.0.4 // indirect
8284
github.com/mitchellh/go-homedir v1.1.0
8385
github.com/mr-tron/base58 v1.1.2

0 commit comments

Comments
 (0)