123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- // +build linux
- package server
- import (
- "fmt"
- "net/http"
- "os"
- "syscall"
- "github.com/docker/docker/engine"
- "github.com/docker/docker/pkg/systemd"
- )
- // NewServer sets up the required Server and does protocol specific checking.
- func NewServer(proto, addr string, job *engine.Job) (Server, error) {
- // Basic error and sanity checking
- switch proto {
- case "fd":
- return nil, serveFd(addr, job)
- case "tcp":
- return setupTcpHttp(addr, job)
- case "unix":
- return setupUnixHttp(addr, job)
- default:
- return nil, fmt.Errorf("Invalid protocol format.")
- }
- }
- func setupUnixHttp(addr string, job *engine.Job) (*HttpServer, error) {
- r := createRouter(job.Eng, job.GetenvBool("Logging"), job.GetenvBool("EnableCors"), job.Getenv("CorsHeaders"), job.Getenv("Version"))
- if err := syscall.Unlink(addr); err != nil && !os.IsNotExist(err) {
- return nil, err
- }
- mask := syscall.Umask(0777)
- defer syscall.Umask(mask)
- l, err := newListener("unix", addr, job.GetenvBool("BufferRequests"))
- if err != nil {
- return nil, err
- }
- if err := setSocketGroup(addr, job.Getenv("SocketGroup")); err != nil {
- return nil, err
- }
- if err := os.Chmod(addr, 0660); err != nil {
- return nil, err
- }
- return &HttpServer{&http.Server{Addr: addr, Handler: r}, l}, nil
- }
- // serveFd creates an http.Server and sets it up to serve given a socket activated
- // argument.
- func serveFd(addr string, job *engine.Job) error {
- r := createRouter(job.Eng, job.GetenvBool("Logging"), job.GetenvBool("EnableCors"), job.Getenv("CorsHeaders"), job.Getenv("Version"))
- ls, e := systemd.ListenFD(addr)
- if e != nil {
- return e
- }
- chErrors := make(chan error, len(ls))
- // We don't want to start serving on these sockets until the
- // daemon is initialized and installed. Otherwise required handlers
- // won't be ready.
- <-activationLock
- // Since ListenFD will return one or more sockets we have
- // to create a go func to spawn off multiple serves
- for i := range ls {
- listener := ls[i]
- go func() {
- httpSrv := http.Server{Handler: r}
- chErrors <- httpSrv.Serve(listener)
- }()
- }
- for i := 0; i < len(ls); i++ {
- err := <-chErrors
- if err != nil {
- return err
- }
- }
- return nil
- }
- // Called through eng.Job("acceptconnections")
- func AcceptConnections(job *engine.Job) engine.Status {
- // Tell the init daemon we are accepting requests
- go systemd.SdNotify("READY=1")
- // close the lock so the listeners start accepting connections
- if activationLock != nil {
- close(activationLock)
- }
- return engine.StatusOK
- }
|