Extract sockets initialization to a package.

Because I just used it somewhere else and it would be nice if I didn't have to copy and paste the code.

Signed-off-by: David Calavera <david.calavera@gmail.com>
This commit is contained in:
David Calavera
2015-05-20 16:48:39 -07:00
parent 2bf409d4ef
commit 0bfbc6e788
6 changed files with 37 additions and 31 deletions

View File

@@ -30,6 +30,7 @@ import (
"github.com/docker/docker/pkg/parsers/filters"
"github.com/docker/docker/pkg/parsers/kernel"
"github.com/docker/docker/pkg/signal"
"github.com/docker/docker/pkg/sockets"
"github.com/docker/docker/pkg/stdcopy"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/version"
@@ -1402,6 +1403,26 @@ func (s *Server) ping(version version.Version, w http.ResponseWriter, r *http.Re
return err
}
func (s *Server) initTcpSocket(addr string) (l net.Listener, err error) {
if !s.cfg.TlsVerify {
logrus.Warn("/!\\ DON'T BIND ON ANY IP ADDRESS WITHOUT setting -tlsverify IF YOU DON'T KNOW WHAT YOU'RE DOING /!\\")
}
var c *sockets.TlsConfig
if s.cfg.Tls || s.cfg.TlsVerify {
c = sockets.NewTlsConfig(s.cfg.TlsCert, s.cfg.TlsKey, s.cfg.TlsCa, s.cfg.TlsVerify)
}
if l, err = sockets.NewTcpSocket(addr, c, s.start); err != nil {
return nil, err
}
if err := allocateDaemonPort(addr); err != nil {
return nil, err
}
return
}
func makeHttpHandler(logging bool, localMethod string, localRoute string, handlerFunc HttpApiFunc, corsHeaders string, dockerVersion version.Version) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// log the request

View File

@@ -7,8 +7,8 @@ import (
"net"
"net/http"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/daemon"
"github.com/docker/docker/pkg/sockets"
"github.com/docker/docker/pkg/systemd"
)
@@ -45,17 +45,12 @@ func (s *Server) newServer(proto, addr string) (serverCloser, error) {
}
return nil, nil
case "tcp":
if !s.cfg.TlsVerify {
logrus.Warn("/!\\ DON'T BIND ON ANY IP ADDRESS WITHOUT setting -tlsverify IF YOU DON'T KNOW WHAT YOU'RE DOING /!\\")
}
if l, err = NewTcpSocket(addr, tlsConfigFromServerConfig(s.cfg), s.start); err != nil {
return nil, err
}
if err := allocateDaemonPort(addr); err != nil {
l, err = s.initTcpSocket(addr)
if err != nil {
return nil, err
}
case "unix":
if l, err = NewUnixSocket(addr, s.cfg.SocketGroup, s.start); err != nil {
if l, err = sockets.NewUnixSocket(addr, s.cfg.SocketGroup, s.start); err != nil {
return nil, err
}
default:

View File

@@ -7,7 +7,6 @@ import (
"net"
"net/http"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/daemon"
)
@@ -19,13 +18,8 @@ func (s *Server) newServer(proto, addr string) (Server, error) {
)
switch proto {
case "tcp":
if !s.cfg.TlsVerify {
logrus.Warn("/!\\ DON'T BIND ON ANY IP ADDRESS WITHOUT setting -tlsverify IF YOU DON'T KNOW WHAT YOU'RE DOING /!\\")
}
if l, err = NewTcpSocket(addr, tlsConfigFromServerConfig(s.cfg)); err != nil {
return nil, err
}
if err := allocateDaemonPort(addr); err != nil {
l, err = s.initTcpSocket(addr)
if err != nil {
return nil, err
}
default:

View File

@@ -1,73 +0,0 @@
package server
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"net"
"os"
"github.com/docker/docker/pkg/listenbuffer"
)
type tlsConfig struct {
CA string
Certificate string
Key string
Verify bool
}
func tlsConfigFromServerConfig(conf *ServerConfig) *tlsConfig {
verify := conf.TlsVerify
if !conf.Tls && !conf.TlsVerify {
return nil
}
return &tlsConfig{
Verify: verify,
Certificate: conf.TlsCert,
Key: conf.TlsKey,
CA: conf.TlsCa,
}
}
func NewTcpSocket(addr string, config *tlsConfig, activate <-chan struct{}) (net.Listener, error) {
l, err := listenbuffer.NewListenBuffer("tcp", addr, activate)
if err != nil {
return nil, err
}
if config != nil {
if l, err = setupTls(l, config); err != nil {
return nil, err
}
}
return l, nil
}
func setupTls(l net.Listener, config *tlsConfig) (net.Listener, error) {
tlsCert, err := tls.LoadX509KeyPair(config.Certificate, config.Key)
if err != nil {
if os.IsNotExist(err) {
return nil, fmt.Errorf("Could not load X509 key pair (%s, %s): %v", config.Certificate, config.Key, err)
}
return nil, fmt.Errorf("Error reading X509 key pair (%s, %s): %q. Make sure the key is encrypted.",
config.Certificate, config.Key, err)
}
tlsConfig := &tls.Config{
NextProtos: []string{"http/1.1"},
Certificates: []tls.Certificate{tlsCert},
// Avoid fallback on insecure SSL protocols
MinVersion: tls.VersionTLS10,
}
if config.CA != "" {
certPool := x509.NewCertPool()
file, err := ioutil.ReadFile(config.CA)
if err != nil {
return nil, fmt.Errorf("Could not read CA certificate: %v", err)
}
certPool.AppendCertsFromPEM(file)
tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
tlsConfig.ClientCAs = certPool
}
return tls.NewListener(l, tlsConfig), nil
}

View File

@@ -1,80 +0,0 @@
// +build linux
package server
import (
"fmt"
"net"
"os"
"strconv"
"syscall"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/pkg/listenbuffer"
"github.com/docker/libcontainer/user"
)
func NewUnixSocket(path, group string, activate <-chan struct{}) (net.Listener, error) {
if err := syscall.Unlink(path); err != nil && !os.IsNotExist(err) {
return nil, err
}
mask := syscall.Umask(0777)
defer syscall.Umask(mask)
l, err := listenbuffer.NewListenBuffer("unix", path, activate)
if err != nil {
return nil, err
}
if err := setSocketGroup(path, group); err != nil {
l.Close()
return nil, err
}
if err := os.Chmod(path, 0660); err != nil {
l.Close()
return nil, err
}
return l, nil
}
func setSocketGroup(path, group string) error {
if group == "" {
return nil
}
if err := changeGroup(path, group); err != nil {
if group != "docker" {
return err
}
logrus.Debugf("Warning: could not change group %s to docker: %v", path, err)
}
return nil
}
func changeGroup(path string, nameOrGid string) error {
gid, err := lookupGidByName(nameOrGid)
if err != nil {
return err
}
logrus.Debugf("%s group found. gid: %d", nameOrGid, gid)
return os.Chown(path, 0, gid)
}
func lookupGidByName(nameOrGid string) (int, error) {
groupFile, err := user.GetGroupPath()
if err != nil {
return -1, err
}
groups, err := user.ParseGroupFileFilter(groupFile, func(g user.Group) bool {
return g.Name == nameOrGid || strconv.Itoa(g.Gid) == nameOrGid
})
if err != nil {
return -1, err
}
if groups != nil && len(groups) > 0 {
return groups[0].Gid, nil
}
gid, err := strconv.Atoi(nameOrGid)
if err == nil {
logrus.Warnf("Could not find GID %d", gid)
return gid, nil
}
return -1, fmt.Errorf("Group %s not found", nameOrGid)
}