github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/engine/daemon/listeners/listeners_linux.go (about) 1 package listeners // import "github.com/docker/docker/daemon/listeners" 2 3 import ( 4 "crypto/tls" 5 "net" 6 "os" 7 "strconv" 8 9 "github.com/coreos/go-systemd/v22/activation" 10 "github.com/docker/docker/pkg/homedir" 11 "github.com/docker/go-connections/sockets" 12 "github.com/pkg/errors" 13 "github.com/sirupsen/logrus" 14 ) 15 16 // Init creates new listeners for the server. 17 // TODO: Clean up the fact that socketGroup and tlsConfig aren't always used. 18 func Init(proto, addr, socketGroup string, tlsConfig *tls.Config) ([]net.Listener, error) { 19 ls := []net.Listener{} 20 21 switch proto { 22 case "fd": 23 fds, err := listenFD(addr, tlsConfig) 24 if err != nil { 25 return nil, err 26 } 27 ls = append(ls, fds...) 28 case "tcp": 29 l, err := sockets.NewTCPSocket(addr, tlsConfig) 30 if err != nil { 31 return nil, err 32 } 33 ls = append(ls, l) 34 case "unix": 35 gid, err := lookupGID(socketGroup) 36 if err != nil { 37 if socketGroup != "" { 38 if socketGroup != defaultSocketGroup { 39 return nil, err 40 } 41 logrus.Warnf("could not change group %s to %s: %v", addr, defaultSocketGroup, err) 42 } 43 gid = os.Getgid() 44 } 45 l, err := sockets.NewUnixSocket(addr, gid) 46 if err != nil { 47 return nil, errors.Wrapf(err, "can't create unix socket %s", addr) 48 } 49 if _, err := homedir.StickRuntimeDirContents([]string{addr}); err != nil { 50 // StickRuntimeDirContents returns nil error if XDG_RUNTIME_DIR is just unset 51 logrus.WithError(err).Warnf("cannot set sticky bit on socket %s under XDG_RUNTIME_DIR", addr) 52 } 53 ls = append(ls, l) 54 default: 55 return nil, errors.Errorf("invalid protocol format: %q", proto) 56 } 57 58 return ls, nil 59 } 60 61 // listenFD returns the specified socket activated files as a slice of 62 // net.Listeners or all of the activated files if "*" is given. 63 func listenFD(addr string, tlsConfig *tls.Config) ([]net.Listener, error) { 64 var ( 65 err error 66 listeners []net.Listener 67 ) 68 // socket activation 69 if tlsConfig != nil { 70 listeners, err = activation.TLSListeners(tlsConfig) 71 } else { 72 listeners, err = activation.Listeners() 73 } 74 if err != nil { 75 return nil, err 76 } 77 78 if len(listeners) == 0 { 79 return nil, errors.New("no sockets found via socket activation: make sure the service was started by systemd") 80 } 81 82 // default to all fds just like unix:// and tcp:// 83 if addr == "" || addr == "*" { 84 return listeners, nil 85 } 86 87 fdNum, err := strconv.Atoi(addr) 88 if err != nil { 89 return nil, errors.Errorf("failed to parse systemd fd address: should be a number: %v", addr) 90 } 91 fdOffset := fdNum - 3 92 if len(listeners) < fdOffset+1 { 93 return nil, errors.New("too few socket activated files passed in by systemd") 94 } 95 if listeners[fdOffset] == nil { 96 return nil, errors.Errorf("failed to listen on systemd activated file: fd %d", fdOffset+3) 97 } 98 for i, ls := range listeners { 99 if i == fdOffset || ls == nil { 100 continue 101 } 102 if err := ls.Close(); err != nil { 103 return nil, errors.Wrapf(err, "failed to close systemd activated file: fd %d", fdOffset+3) 104 } 105 } 106 return []net.Listener{listeners[fdOffset]}, nil 107 }