提交 429c4b53 作者: Steven Allen

implement systemd socket activation

License: MIT
Signed-off-by: 's avatarSteven Allen <steven@stebalien.com>
上级 9ea7c6a1
......@@ -15,6 +15,7 @@ import (
version "github.com/ipfs/go-ipfs"
config "github.com/ipfs/go-ipfs-config"
cserial "github.com/ipfs/go-ipfs-config/serialize"
sockets "github.com/ipfs/go-ipfs/cmd/ipfs/sockets"
utilmain "github.com/ipfs/go-ipfs/cmd/ipfs/util"
oldcmds "github.com/ipfs/go-ipfs/commands"
"github.com/ipfs/go-ipfs/core"
......@@ -290,11 +291,6 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
// fail before we get to that. It can't hurt to close it twice.
defer repo.Close()
cfg, err := cctx.GetConfig()
if err != nil {
return err
}
offline, _ := req.Options[offlineKwd].(bool)
ipnsps, _ := req.Options[enableIPNSPubSubKwd].(bool)
pubsub, _ := req.Options[enablePubSubKwd].(bool)
......@@ -404,14 +400,10 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
return err
}
// construct http gateway - if it is set in the config
var gwErrc <-chan error
if len(cfg.Addresses.Gateway) > 0 {
var err error
gwErrc, err = serveHTTPGateway(req, cctx)
if err != nil {
return err
}
// construct http gateway
gwErrc, err := serveHTTPGateway(req, cctx)
if err != nil {
return err
}
// initialize metrics collector
......@@ -446,31 +438,40 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error
return nil, fmt.Errorf("serveHTTPApi: GetConfig() failed: %s", err)
}
apiAddrs := make([]string, 0, 2)
apiAddr, _ := req.Options[commands.ApiOption].(string)
if apiAddr == "" {
apiAddrs = cfg.Addresses.API
} else {
apiAddrs = append(apiAddrs, apiAddr)
listeners, err := sockets.TakeSockets("io.ipfs.api")
if err != nil {
return nil, fmt.Errorf("serveHTTPGateway: socket activation failed: %s", err)
}
listeners := make([]manet.Listener, 0, len(apiAddrs))
for _, addr := range apiAddrs {
apiMaddr, err := ma.NewMultiaddr(addr)
if err != nil {
return nil, fmt.Errorf("serveHTTPApi: invalid API address: %q (err: %s)", apiAddr, err)
if len(listeners) == 0 {
apiAddrs := make([]string, 0, 2)
apiAddr, _ := req.Options[commands.ApiOption].(string)
if apiAddr == "" {
apiAddrs = cfg.Addresses.API
} else {
apiAddrs = append(apiAddrs, apiAddr)
}
apiLis, err := manet.Listen(apiMaddr)
if err != nil {
return nil, fmt.Errorf("serveHTTPApi: manet.Listen(%s) failed: %s", apiMaddr, err)
listeners := make([]manet.Listener, 0, len(apiAddrs))
for _, addr := range apiAddrs {
apiMaddr, err := ma.NewMultiaddr(addr)
if err != nil {
return nil, fmt.Errorf("serveHTTPApi: invalid API address: %q (err: %s)", apiAddr, err)
}
apiLis, err := manet.Listen(apiMaddr)
if err != nil {
return nil, fmt.Errorf("serveHTTPApi: manet.Listen(%s) failed: %s", apiMaddr, err)
}
listeners = append(listeners, apiLis)
}
}
for _, listener := range listeners {
// we might have listened to /tcp/0 - lets see what we are listing on
apiMaddr = apiLis.Multiaddr()
fmt.Printf("API server listening on %s\n", apiMaddr)
fmt.Printf("WebUI: http://%s/webui\n", apiLis.Addr())
listeners = append(listeners, apiLis)
fmt.Printf("API server listening on %s\n", listener.Multiaddr())
fmt.Printf("WebUI: http://%s/webui\n", listener.Addr())
}
// by default, we don't let you load arbitrary ipfs objects through the api,
......@@ -571,28 +572,35 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e
writable = cfg.Gateway.Writable
}
gatewayAddrs := cfg.Addresses.Gateway
listeners := make([]manet.Listener, 0, len(gatewayAddrs))
for _, addr := range gatewayAddrs {
gatewayMaddr, err := ma.NewMultiaddr(addr)
if err != nil {
return nil, fmt.Errorf("serveHTTPGateway: invalid gateway address: %q (err: %s)", addr, err)
}
listeners, err := sockets.TakeSockets("io.ipfs.gateway")
if err != nil {
return nil, fmt.Errorf("serveHTTPGateway: socket activation failed: %s", err)
}
gwLis, err := manet.Listen(gatewayMaddr)
if err != nil {
return nil, fmt.Errorf("serveHTTPGateway: manet.Listen(%s) failed: %s", gatewayMaddr, err)
}
// we might have listened to /tcp/0 - lets see what we are listing on
gatewayMaddr = gwLis.Multiaddr()
if len(listeners) == 0 {
gatewayAddrs := cfg.Addresses.Gateway
for _, addr := range gatewayAddrs {
gatewayMaddr, err := ma.NewMultiaddr(addr)
if err != nil {
return nil, fmt.Errorf("serveHTTPGateway: invalid gateway address: %q (err: %s)", addr, err)
}
if writable {
fmt.Printf("Gateway (writable) server listening on %s\n", gatewayMaddr)
} else {
fmt.Printf("Gateway (readonly) server listening on %s\n", gatewayMaddr)
gwLis, err := manet.Listen(gatewayMaddr)
if err != nil {
return nil, fmt.Errorf("serveHTTPGateway: manet.Listen(%s) failed: %s", gatewayMaddr, err)
}
listeners = append(listeners, gwLis)
}
}
// we might have listened to /tcp/0 - lets see what we are listing on
gwType := "readonly"
if writable {
gwType = "writable"
}
listeners = append(listeners, gwLis)
for _, listener := range listeners {
fmt.Printf("Gateway (%s) server listening on %s\n", gwType, listener.Multiaddr())
}
cmdctx := *cctx
......
// +build !linux
package sockets
import (
manet "github.com/multiformats/go-multiaddr-net"
)
// TakeSockets takes the sockets associated with the given name.
func TakeSockets(name string) ([]manet.Listener, error) {
return nil, nil
}
// +build linux
package sockets
import (
"net"
"sync"
activation "github.com/coreos/go-systemd/activation"
logging "github.com/ipfs/go-log"
manet "github.com/multiformats/go-multiaddr-net"
)
var log = logging.Logger("socket-activation")
var socketsMu sync.Mutex
var sockets map[string][]manet.Listener
func initSockets() {
if sockets != nil {
return
}
nlisteners, err := activation.ListenersWithNames()
// Do this before checking the error. We need this to be non-nil so we
// don't try again.
sockets = make(map[string][]manet.Listener, len(nlisteners))
if err != nil {
log.Errorf("error parsing systemd sockets: %s", err)
return
}
for name, nls := range nlisteners {
mls := make([]manet.Listener, 0, len(nls))
for _, nl := range nls {
ml, err := manet.WrapNetListener(nl)
if err != nil {
log.Errorf("error converting a systemd-socket to a multiaddr listener: %s", err)
nl.Close()
continue
}
mls = append(mls, ml)
}
sockets[name] = mls
}
}
func mapListeners(nls []net.Listener) ([]manet.Listener, error) {
mls := make([]manet.Listener, len(nls))
return mls, nil
}
// TakeSockets takes the sockets associated with the given name.
func TakeSockets(name string) ([]manet.Listener, error) {
socketsMu.Lock()
defer socketsMu.Unlock()
initSockets()
s := sockets[name]
delete(sockets, name)
return s, nil
}
......@@ -5,6 +5,7 @@ require (
github.com/AndreasBriese/bbloom v0.0.0-20190823232136-616930265c33 // indirect
github.com/blang/semver v3.5.1+incompatible
github.com/bren2010/proquint v0.0.0-20160323162903-38337c27106d
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f
github.com/dustin/go-humanize v1.0.0
github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302
github.com/fatih/color v1.7.0 // indirect
......
......@@ -51,6 +51,8 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/coreos/go-semver v0.2.1-0.20180108230905-e214231b295a/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0=
github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis=
......
# Enabling this will *completely override* any API listeners configured in your
# config.
[Unit]
Description=IPFS API Socket
[Socket]
Service=ipfs.service
FileDescriptorName=io.ipfs.api
BindIPv6Only=true
ListenStream=127.0.0.1:5001
ListenStream=[::1]:5001
[Install]
WantedBy=sockets.target
# Enabling this will *completely override* any Gateway listeners configured in
# your config.
[Unit]
Description=IPFS Gateway Socket
[Socket]
Service=ipfs.service
FileDescriptorName=io.ipfs.gateway
BindIPv6Only=true
ListenStream=127.0.0.1:8080
ListenStream=[::1]:8080
[Install]
WantedBy=sockets.target
[Unit]
Description=IPFS Daemon
[Service]
ExecStart=/usr/bin/ipfs daemon --init --migrate
KillSignal=SIGINT
[Install]
WantedBy=default.target
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论