github.com/eatbyte/docker@v1.6.0/api/server/server_linux.go (about) 1 // +build linux 2 3 package server 4 5 import ( 6 "fmt" 7 "net/http" 8 "os" 9 "syscall" 10 11 "github.com/docker/docker/engine" 12 "github.com/docker/docker/pkg/systemd" 13 ) 14 15 // NewServer sets up the required Server and does protocol specific checking. 16 func NewServer(proto, addr string, job *engine.Job) (Server, error) { 17 // Basic error and sanity checking 18 switch proto { 19 case "fd": 20 return nil, serveFd(addr, job) 21 case "tcp": 22 return setupTcpHttp(addr, job) 23 case "unix": 24 return setupUnixHttp(addr, job) 25 default: 26 return nil, fmt.Errorf("Invalid protocol format.") 27 } 28 } 29 30 func setupUnixHttp(addr string, job *engine.Job) (*HttpServer, error) { 31 r := createRouter(job.Eng, job.GetenvBool("Logging"), job.GetenvBool("EnableCors"), job.Getenv("CorsHeaders"), job.Getenv("Version")) 32 33 if err := syscall.Unlink(addr); err != nil && !os.IsNotExist(err) { 34 return nil, err 35 } 36 mask := syscall.Umask(0777) 37 defer syscall.Umask(mask) 38 39 l, err := newListener("unix", addr, job.GetenvBool("BufferRequests")) 40 if err != nil { 41 return nil, err 42 } 43 44 if err := setSocketGroup(addr, job.Getenv("SocketGroup")); err != nil { 45 return nil, err 46 } 47 48 if err := os.Chmod(addr, 0660); err != nil { 49 return nil, err 50 } 51 52 return &HttpServer{&http.Server{Addr: addr, Handler: r}, l}, nil 53 } 54 55 // serveFd creates an http.Server and sets it up to serve given a socket activated 56 // argument. 57 func serveFd(addr string, job *engine.Job) error { 58 r := createRouter(job.Eng, job.GetenvBool("Logging"), job.GetenvBool("EnableCors"), job.Getenv("CorsHeaders"), job.Getenv("Version")) 59 60 ls, e := systemd.ListenFD(addr) 61 if e != nil { 62 return e 63 } 64 65 chErrors := make(chan error, len(ls)) 66 67 // We don't want to start serving on these sockets until the 68 // daemon is initialized and installed. Otherwise required handlers 69 // won't be ready. 70 <-activationLock 71 72 // Since ListenFD will return one or more sockets we have 73 // to create a go func to spawn off multiple serves 74 for i := range ls { 75 listener := ls[i] 76 go func() { 77 httpSrv := http.Server{Handler: r} 78 chErrors <- httpSrv.Serve(listener) 79 }() 80 } 81 82 for i := 0; i < len(ls); i++ { 83 err := <-chErrors 84 if err != nil { 85 return err 86 } 87 } 88 89 return nil 90 } 91 92 // Called through eng.Job("acceptconnections") 93 func AcceptConnections(job *engine.Job) engine.Status { 94 // Tell the init daemon we are accepting requests 95 go systemd.SdNotify("READY=1") 96 97 // close the lock so the listeners start accepting connections 98 select { 99 case <-activationLock: 100 default: 101 close(activationLock) 102 } 103 104 return engine.StatusOK 105 }