|
@@ -40,10 +40,6 @@ import (
|
|
"github.com/docker/docker/utils"
|
|
"github.com/docker/docker/utils"
|
|
)
|
|
)
|
|
|
|
|
|
-var (
|
|
|
|
- activationLock = make(chan struct{})
|
|
|
|
-)
|
|
|
|
-
|
|
|
|
type ServerConfig struct {
|
|
type ServerConfig struct {
|
|
Logging bool
|
|
Logging bool
|
|
EnableCors bool
|
|
EnableCors bool
|
|
@@ -57,6 +53,75 @@ type ServerConfig struct {
|
|
TlsKey string
|
|
TlsKey string
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+type Server struct {
|
|
|
|
+ daemon *daemon.Daemon
|
|
|
|
+ cfg *ServerConfig
|
|
|
|
+ router *mux.Router
|
|
|
|
+ start chan struct{}
|
|
|
|
+
|
|
|
|
+ // TODO: delete engine
|
|
|
|
+ eng *engine.Engine
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func New(cfg *ServerConfig, eng *engine.Engine) *Server {
|
|
|
|
+ srv := &Server{
|
|
|
|
+ cfg: cfg,
|
|
|
|
+ start: make(chan struct{}),
|
|
|
|
+ eng: eng,
|
|
|
|
+ }
|
|
|
|
+ r := createRouter(srv, eng)
|
|
|
|
+ srv.router = r
|
|
|
|
+ return srv
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *Server) SetDaemon(d *daemon.Daemon) {
|
|
|
|
+ s.daemon = d
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+type serverCloser interface {
|
|
|
|
+ Serve() error
|
|
|
|
+ Close() error
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// ServeApi loops through all of the protocols sent in to docker and spawns
|
|
|
|
+// off a go routine to setup a serving http.Server for each.
|
|
|
|
+func (s *Server) ServeApi(protoAddrs []string) error {
|
|
|
|
+ var chErrors = make(chan error, len(protoAddrs))
|
|
|
|
+
|
|
|
|
+ for _, protoAddr := range protoAddrs {
|
|
|
|
+ protoAddrParts := strings.SplitN(protoAddr, "://", 2)
|
|
|
|
+ if len(protoAddrParts) != 2 {
|
|
|
|
+ return fmt.Errorf("bad format, expected PROTO://ADDR")
|
|
|
|
+ }
|
|
|
|
+ go func(proto, addr string) {
|
|
|
|
+ logrus.Infof("Listening for HTTP on %s (%s)", proto, addr)
|
|
|
|
+ srv, err := s.newServer(proto, addr)
|
|
|
|
+ if err != nil {
|
|
|
|
+ chErrors <- err
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ s.eng.OnShutdown(func() {
|
|
|
|
+ if err := srv.Close(); err != nil {
|
|
|
|
+ logrus.Error(err)
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ if err = srv.Serve(); err != nil && strings.Contains(err.Error(), "use of closed network connection") {
|
|
|
|
+ err = nil
|
|
|
|
+ }
|
|
|
|
+ chErrors <- err
|
|
|
|
+ }(protoAddrParts[0], protoAddrParts[1])
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for i := 0; i < len(protoAddrs); i++ {
|
|
|
|
+ err := <-chErrors
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
+
|
|
type HttpServer struct {
|
|
type HttpServer struct {
|
|
srv *http.Server
|
|
srv *http.Server
|
|
l net.Listener
|
|
l net.Listener
|
|
@@ -180,19 +245,14 @@ func streamJSON(job *engine.Job, w http.ResponseWriter, flush bool) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-func getDaemon(eng *engine.Engine) *daemon.Daemon {
|
|
|
|
- return eng.HackGetGlobalVar("httpapi.daemon").(*daemon.Daemon)
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-func postAuth(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postAuth(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
var config *registry.AuthConfig
|
|
var config *registry.AuthConfig
|
|
err := json.NewDecoder(r.Body).Decode(&config)
|
|
err := json.NewDecoder(r.Body).Decode(&config)
|
|
r.Body.Close()
|
|
r.Body.Close()
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
- d := getDaemon(eng)
|
|
|
|
- status, err := d.RegistryService.Auth(config)
|
|
|
|
|
|
+ status, err := s.daemon.RegistryService.Auth(config)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -201,7 +261,7 @@ func postAuth(eng *engine.Engine, version version.Version, w http.ResponseWriter
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
-func getVersion(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) getVersion(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Header().Set("Content-Type", "application/json")
|
|
|
|
|
|
v := &types.Version{
|
|
v := &types.Version{
|
|
@@ -219,7 +279,7 @@ func getVersion(eng *engine.Engine, version version.Version, w http.ResponseWrit
|
|
return writeJSON(w, http.StatusOK, v)
|
|
return writeJSON(w, http.StatusOK, v)
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainersKill(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postContainersKill(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
@@ -247,7 +307,7 @@ func postContainersKill(eng *engine.Engine, version version.Version, w http.Resp
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if err = getDaemon(eng).ContainerKill(name, sig); err != nil {
|
|
|
|
|
|
+ if err = s.daemon.ContainerKill(name, sig); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
|
|
|
|
@@ -255,7 +315,7 @@ func postContainersKill(eng *engine.Engine, version version.Version, w http.Resp
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainersPause(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postContainersPause(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
@@ -264,8 +324,7 @@ func postContainersPause(eng *engine.Engine, version version.Version, w http.Res
|
|
}
|
|
}
|
|
|
|
|
|
name := vars["name"]
|
|
name := vars["name"]
|
|
- d := getDaemon(eng)
|
|
|
|
- cont, err := d.Get(name)
|
|
|
|
|
|
+ cont, err := s.daemon.Get(name)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -280,7 +339,7 @@ func postContainersPause(eng *engine.Engine, version version.Version, w http.Res
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainersUnpause(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postContainersUnpause(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
@@ -289,8 +348,7 @@ func postContainersUnpause(eng *engine.Engine, version version.Version, w http.R
|
|
}
|
|
}
|
|
|
|
|
|
name := vars["name"]
|
|
name := vars["name"]
|
|
- d := getDaemon(eng)
|
|
|
|
- cont, err := d.Get(name)
|
|
|
|
|
|
+ cont, err := s.daemon.Get(name)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -305,17 +363,15 @@ func postContainersUnpause(eng *engine.Engine, version version.Version, w http.R
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func getContainersExport(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) getContainersExport(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
|
|
|
|
- d := getDaemon(eng)
|
|
|
|
-
|
|
|
|
- return d.ContainerExport(vars["name"], w)
|
|
|
|
|
|
+ return s.daemon.ContainerExport(vars["name"], w)
|
|
}
|
|
}
|
|
|
|
|
|
-func getImagesJSON(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) getImagesJSON(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -327,7 +383,7 @@ func getImagesJSON(eng *engine.Engine, version version.Version, w http.ResponseW
|
|
All: toBool(r.Form.Get("all")),
|
|
All: toBool(r.Form.Get("all")),
|
|
}
|
|
}
|
|
|
|
|
|
- images, err := getDaemon(eng).Repositories().Images(&imagesConfig)
|
|
|
|
|
|
+ images, err := s.daemon.Repositories().Images(&imagesConfig)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -356,7 +412,7 @@ func getImagesJSON(eng *engine.Engine, version version.Version, w http.ResponseW
|
|
return writeJSON(w, http.StatusOK, legacyImages)
|
|
return writeJSON(w, http.StatusOK, legacyImages)
|
|
}
|
|
}
|
|
|
|
|
|
-func getImagesViz(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) getImagesViz(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if version.GreaterThan("1.6") {
|
|
if version.GreaterThan("1.6") {
|
|
w.WriteHeader(http.StatusNotFound)
|
|
w.WriteHeader(http.StatusNotFound)
|
|
return fmt.Errorf("This is now implemented in the client.")
|
|
return fmt.Errorf("This is now implemented in the client.")
|
|
@@ -365,10 +421,10 @@ func getImagesViz(eng *engine.Engine, version version.Version, w http.ResponseWr
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func getInfo(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) getInfo(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Header().Set("Content-Type", "application/json")
|
|
|
|
|
|
- info, err := getDaemon(eng).SystemInfo()
|
|
|
|
|
|
+ info, err := s.daemon.SystemInfo()
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -376,7 +432,7 @@ func getInfo(eng *engine.Engine, version version.Version, w http.ResponseWriter,
|
|
return writeJSON(w, http.StatusOK, info)
|
|
return writeJSON(w, http.StatusOK, info)
|
|
}
|
|
}
|
|
|
|
|
|
-func getEvents(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) getEvents(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -427,7 +483,7 @@ func getEvents(eng *engine.Engine, version version.Version, w http.ResponseWrite
|
|
return true
|
|
return true
|
|
}
|
|
}
|
|
|
|
|
|
- d := getDaemon(eng)
|
|
|
|
|
|
+ d := s.daemon
|
|
es := d.EventsService
|
|
es := d.EventsService
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Header().Set("Content-Type", "application/json")
|
|
enc := json.NewEncoder(utils.NewWriteFlusher(w))
|
|
enc := json.NewEncoder(utils.NewWriteFlusher(w))
|
|
@@ -480,13 +536,13 @@ func getEvents(eng *engine.Engine, version version.Version, w http.ResponseWrite
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-func getImagesHistory(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) getImagesHistory(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
|
|
|
|
name := vars["name"]
|
|
name := vars["name"]
|
|
- history, err := getDaemon(eng).Repositories().History(name)
|
|
|
|
|
|
+ history, err := s.daemon.Repositories().History(name)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -494,14 +550,13 @@ func getImagesHistory(eng *engine.Engine, version version.Version, w http.Respon
|
|
return writeJSON(w, http.StatusOK, history)
|
|
return writeJSON(w, http.StatusOK, history)
|
|
}
|
|
}
|
|
|
|
|
|
-func getContainersChanges(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) getContainersChanges(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
|
|
|
|
name := vars["name"]
|
|
name := vars["name"]
|
|
- d := getDaemon(eng)
|
|
|
|
- cont, err := d.Get(name)
|
|
|
|
|
|
+ cont, err := s.daemon.Get(name)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -514,7 +569,7 @@ func getContainersChanges(eng *engine.Engine, version version.Version, w http.Re
|
|
return writeJSON(w, http.StatusOK, changes)
|
|
return writeJSON(w, http.StatusOK, changes)
|
|
}
|
|
}
|
|
|
|
|
|
-func getContainersTop(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) getContainersTop(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if version.LessThan("1.4") {
|
|
if version.LessThan("1.4") {
|
|
return fmt.Errorf("top was improved a lot since 1.3, Please upgrade your docker client.")
|
|
return fmt.Errorf("top was improved a lot since 1.3, Please upgrade your docker client.")
|
|
}
|
|
}
|
|
@@ -527,7 +582,7 @@ func getContainersTop(eng *engine.Engine, version version.Version, w http.Respon
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
|
|
|
|
- procList, err := getDaemon(eng).ContainerTop(vars["name"], r.Form.Get("ps_args"))
|
|
|
|
|
|
+ procList, err := s.daemon.ContainerTop(vars["name"], r.Form.Get("ps_args"))
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -535,7 +590,7 @@ func getContainersTop(eng *engine.Engine, version version.Version, w http.Respon
|
|
return writeJSON(w, http.StatusOK, procList)
|
|
return writeJSON(w, http.StatusOK, procList)
|
|
}
|
|
}
|
|
|
|
|
|
-func getContainersJSON(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) getContainersJSON(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -556,7 +611,7 @@ func getContainersJSON(eng *engine.Engine, version version.Version, w http.Respo
|
|
config.Limit = limit
|
|
config.Limit = limit
|
|
}
|
|
}
|
|
|
|
|
|
- containers, err := getDaemon(eng).Containers(config)
|
|
|
|
|
|
+ containers, err := s.daemon.Containers(config)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -564,7 +619,7 @@ func getContainersJSON(eng *engine.Engine, version version.Version, w http.Respo
|
|
return writeJSON(w, http.StatusOK, containers)
|
|
return writeJSON(w, http.StatusOK, containers)
|
|
}
|
|
}
|
|
|
|
|
|
-func getContainersStats(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) getContainersStats(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -572,12 +627,10 @@ func getContainersStats(eng *engine.Engine, version version.Version, w http.Resp
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
|
|
|
|
- d := getDaemon(eng)
|
|
|
|
-
|
|
|
|
- return d.ContainerStats(vars["name"], utils.NewWriteFlusher(w))
|
|
|
|
|
|
+ return s.daemon.ContainerStats(vars["name"], utils.NewWriteFlusher(w))
|
|
}
|
|
}
|
|
|
|
|
|
-func getContainersLogs(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) getContainersLogs(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -600,15 +653,14 @@ func getContainersLogs(eng *engine.Engine, version version.Version, w http.Respo
|
|
OutStream: utils.NewWriteFlusher(w),
|
|
OutStream: utils.NewWriteFlusher(w),
|
|
}
|
|
}
|
|
|
|
|
|
- d := getDaemon(eng)
|
|
|
|
- if err := d.ContainerLogs(vars["name"], logsConfig); err != nil {
|
|
|
|
|
|
+ if err := s.daemon.ContainerLogs(vars["name"], logsConfig); err != nil {
|
|
fmt.Fprintf(w, "Error running logs job: %s\n", err)
|
|
fmt.Fprintf(w, "Error running logs job: %s\n", err)
|
|
}
|
|
}
|
|
|
|
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postImagesTag(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postImagesTag(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -616,18 +668,17 @@ func postImagesTag(eng *engine.Engine, version version.Version, w http.ResponseW
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
|
|
|
|
- d := getDaemon(eng)
|
|
|
|
repo := r.Form.Get("repo")
|
|
repo := r.Form.Get("repo")
|
|
tag := r.Form.Get("tag")
|
|
tag := r.Form.Get("tag")
|
|
force := toBool(r.Form.Get("force"))
|
|
force := toBool(r.Form.Get("force"))
|
|
- if err := d.Repositories().Tag(repo, tag, vars["name"], force); err != nil {
|
|
|
|
|
|
+ if err := s.daemon.Repositories().Tag(repo, tag, vars["name"], force); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
w.WriteHeader(http.StatusCreated)
|
|
w.WriteHeader(http.StatusCreated)
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postCommit(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postCommit(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -653,9 +704,7 @@ func postCommit(eng *engine.Engine, version version.Version, w http.ResponseWrit
|
|
Config: r.Body,
|
|
Config: r.Body,
|
|
}
|
|
}
|
|
|
|
|
|
- d := getDaemon(eng)
|
|
|
|
-
|
|
|
|
- imgID, err := d.ContainerCommit(cont, containerCommitConfig)
|
|
|
|
|
|
+ imgID, err := s.daemon.ContainerCommit(cont, containerCommitConfig)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -666,7 +715,7 @@ func postCommit(eng *engine.Engine, version version.Version, w http.ResponseWrit
|
|
}
|
|
}
|
|
|
|
|
|
// Creates an image from Pull or from Import
|
|
// Creates an image from Pull or from Import
|
|
-func postImagesCreate(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postImagesCreate(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -687,8 +736,6 @@ func postImagesCreate(eng *engine.Engine, version version.Version, w http.Respon
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- d := getDaemon(eng)
|
|
|
|
-
|
|
|
|
if image != "" { //pull
|
|
if image != "" { //pull
|
|
if tag == "" {
|
|
if tag == "" {
|
|
image, tag = parsers.ParseRepositoryTag(image)
|
|
image, tag = parsers.ParseRepositoryTag(image)
|
|
@@ -713,7 +760,7 @@ func postImagesCreate(eng *engine.Engine, version version.Version, w http.Respon
|
|
imagePullConfig.Json = false
|
|
imagePullConfig.Json = false
|
|
}
|
|
}
|
|
|
|
|
|
- if err := d.Repositories().Pull(image, tag, imagePullConfig, eng); err != nil {
|
|
|
|
|
|
+ if err := s.daemon.Repositories().Pull(image, tag, imagePullConfig, eng); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
} else { //import
|
|
} else { //import
|
|
@@ -734,7 +781,7 @@ func postImagesCreate(eng *engine.Engine, version version.Version, w http.Respon
|
|
imageImportConfig.Json = false
|
|
imageImportConfig.Json = false
|
|
}
|
|
}
|
|
|
|
|
|
- if err := d.Repositories().Import(src, repo, tag, imageImportConfig, eng); err != nil {
|
|
|
|
|
|
+ if err := s.daemon.Repositories().Import(src, repo, tag, imageImportConfig, eng); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
|
|
|
|
@@ -743,7 +790,7 @@ func postImagesCreate(eng *engine.Engine, version version.Version, w http.Respon
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func getImagesSearch(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) getImagesSearch(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -766,15 +813,14 @@ func getImagesSearch(eng *engine.Engine, version version.Version, w http.Respons
|
|
headers[k] = v
|
|
headers[k] = v
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- d := getDaemon(eng)
|
|
|
|
- query, err := d.RegistryService.Search(r.Form.Get("term"), config, headers)
|
|
|
|
|
|
+ query, err := s.daemon.RegistryService.Search(r.Form.Get("term"), config, headers)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
return json.NewEncoder(w).Encode(query.Results)
|
|
return json.NewEncoder(w).Encode(query.Results)
|
|
}
|
|
}
|
|
|
|
|
|
-func postImagesPush(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postImagesPush(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
@@ -826,7 +872,7 @@ func postImagesPush(eng *engine.Engine, version version.Version, w http.Response
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func getImagesGet(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) getImagesGet(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
@@ -846,14 +892,14 @@ func getImagesGet(eng *engine.Engine, version version.Version, w http.ResponseWr
|
|
return job.Run()
|
|
return job.Run()
|
|
}
|
|
}
|
|
|
|
|
|
-func postImagesLoad(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postImagesLoad(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
job := eng.Job("load")
|
|
job := eng.Job("load")
|
|
job.Stdin.Add(r.Body)
|
|
job.Stdin.Add(r.Body)
|
|
job.Stdout.Add(w)
|
|
job.Stdout.Add(w)
|
|
return job.Run()
|
|
return job.Run()
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainersCreate(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postContainersCreate(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
@@ -870,7 +916,7 @@ func postContainersCreate(eng *engine.Engine, version version.Version, w http.Re
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
|
|
|
|
- containerId, warnings, err := getDaemon(eng).ContainerCreate(name, config, hostConfig)
|
|
|
|
|
|
+ containerId, warnings, err := s.daemon.ContainerCreate(name, config, hostConfig)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -881,7 +927,7 @@ func postContainersCreate(eng *engine.Engine, version version.Version, w http.Re
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainersRestart(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postContainersRestart(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -889,13 +935,12 @@ func postContainersRestart(eng *engine.Engine, version version.Version, w http.R
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
|
|
|
|
- s, err := strconv.Atoi(r.Form.Get("t"))
|
|
|
|
|
|
+ timeout, err := strconv.Atoi(r.Form.Get("t"))
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
|
|
|
|
- d := getDaemon(eng)
|
|
|
|
- if err := d.ContainerRestart(vars["name"], s); err != nil {
|
|
|
|
|
|
+ if err := s.daemon.ContainerRestart(vars["name"], timeout); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
|
|
|
|
@@ -904,7 +949,7 @@ func postContainersRestart(eng *engine.Engine, version version.Version, w http.R
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainerRename(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postContainerRename(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -912,17 +957,16 @@ func postContainerRename(eng *engine.Engine, version version.Version, w http.Res
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
|
|
|
|
- d := getDaemon(eng)
|
|
|
|
name := vars["name"]
|
|
name := vars["name"]
|
|
newName := r.Form.Get("name")
|
|
newName := r.Form.Get("name")
|
|
- if err := d.ContainerRename(name, newName); err != nil {
|
|
|
|
|
|
+ if err := s.daemon.ContainerRename(name, newName); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
w.WriteHeader(http.StatusNoContent)
|
|
w.WriteHeader(http.StatusNoContent)
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func deleteContainers(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) deleteContainers(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -931,14 +975,13 @@ func deleteContainers(eng *engine.Engine, version version.Version, w http.Respon
|
|
}
|
|
}
|
|
|
|
|
|
name := vars["name"]
|
|
name := vars["name"]
|
|
- d := getDaemon(eng)
|
|
|
|
config := &daemon.ContainerRmConfig{
|
|
config := &daemon.ContainerRmConfig{
|
|
ForceRemove: toBool(r.Form.Get("force")),
|
|
ForceRemove: toBool(r.Form.Get("force")),
|
|
RemoveVolume: toBool(r.Form.Get("v")),
|
|
RemoveVolume: toBool(r.Form.Get("v")),
|
|
RemoveLink: toBool(r.Form.Get("link")),
|
|
RemoveLink: toBool(r.Form.Get("link")),
|
|
}
|
|
}
|
|
|
|
|
|
- if err := d.ContainerRm(name, config); err != nil {
|
|
|
|
|
|
+ if err := s.daemon.ContainerRm(name, config); err != nil {
|
|
// Force a 404 for the empty string
|
|
// Force a 404 for the empty string
|
|
if strings.Contains(strings.ToLower(err.Error()), "prefix can't be empty") {
|
|
if strings.Contains(strings.ToLower(err.Error()), "prefix can't be empty") {
|
|
return fmt.Errorf("no such id: \"\"")
|
|
return fmt.Errorf("no such id: \"\"")
|
|
@@ -951,7 +994,7 @@ func deleteContainers(eng *engine.Engine, version version.Version, w http.Respon
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func deleteImages(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) deleteImages(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -959,12 +1002,11 @@ func deleteImages(eng *engine.Engine, version version.Version, w http.ResponseWr
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
|
|
|
|
- d := getDaemon(eng)
|
|
|
|
name := vars["name"]
|
|
name := vars["name"]
|
|
force := toBool(r.Form.Get("force"))
|
|
force := toBool(r.Form.Get("force"))
|
|
noprune := toBool(r.Form.Get("noprune"))
|
|
noprune := toBool(r.Form.Get("noprune"))
|
|
|
|
|
|
- list, err := d.ImageDelete(name, force, noprune)
|
|
|
|
|
|
+ list, err := s.daemon.ImageDelete(name, force, noprune)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -972,7 +1014,7 @@ func deleteImages(eng *engine.Engine, version version.Version, w http.ResponseWr
|
|
return writeJSON(w, http.StatusOK, list)
|
|
return writeJSON(w, http.StatusOK, list)
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainersStart(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postContainersStart(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
@@ -997,7 +1039,7 @@ func postContainersStart(eng *engine.Engine, version version.Version, w http.Res
|
|
hostConfig = c
|
|
hostConfig = c
|
|
}
|
|
}
|
|
|
|
|
|
- if err := getDaemon(eng).ContainerStart(vars["name"], hostConfig); err != nil {
|
|
|
|
|
|
+ if err := s.daemon.ContainerStart(vars["name"], hostConfig); err != nil {
|
|
if err.Error() == "Container already started" {
|
|
if err.Error() == "Container already started" {
|
|
w.WriteHeader(http.StatusNotModified)
|
|
w.WriteHeader(http.StatusNotModified)
|
|
return nil
|
|
return nil
|
|
@@ -1008,7 +1050,7 @@ func postContainersStart(eng *engine.Engine, version version.Version, w http.Res
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainersStop(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postContainersStop(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -1016,13 +1058,12 @@ func postContainersStop(eng *engine.Engine, version version.Version, w http.Resp
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
|
|
|
|
- d := getDaemon(eng)
|
|
|
|
seconds, err := strconv.Atoi(r.Form.Get("t"))
|
|
seconds, err := strconv.Atoi(r.Form.Get("t"))
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
|
|
|
|
- if err := d.ContainerStop(vars["name"], seconds); err != nil {
|
|
|
|
|
|
+ if err := s.daemon.ContainerStop(vars["name"], seconds); err != nil {
|
|
if err.Error() == "Container already stopped" {
|
|
if err.Error() == "Container already stopped" {
|
|
w.WriteHeader(http.StatusNotModified)
|
|
w.WriteHeader(http.StatusNotModified)
|
|
return nil
|
|
return nil
|
|
@@ -1034,14 +1075,13 @@ func postContainersStop(eng *engine.Engine, version version.Version, w http.Resp
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainersWait(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postContainersWait(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
|
|
|
|
name := vars["name"]
|
|
name := vars["name"]
|
|
- d := getDaemon(eng)
|
|
|
|
- cont, err := d.Get(name)
|
|
|
|
|
|
+ cont, err := s.daemon.Get(name)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -1053,7 +1093,7 @@ func postContainersWait(eng *engine.Engine, version version.Version, w http.Resp
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainersResize(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postContainersResize(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -1070,8 +1110,7 @@ func postContainersResize(eng *engine.Engine, version version.Version, w http.Re
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
|
|
|
|
- d := getDaemon(eng)
|
|
|
|
- cont, err := d.Get(vars["name"])
|
|
|
|
|
|
+ cont, err := s.daemon.Get(vars["name"])
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -1079,7 +1118,7 @@ func postContainersResize(eng *engine.Engine, version version.Version, w http.Re
|
|
return cont.Resize(height, width)
|
|
return cont.Resize(height, width)
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainersAttach(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postContainersAttach(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -1087,9 +1126,7 @@ func postContainersAttach(eng *engine.Engine, version version.Version, w http.Re
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
|
|
|
|
- d := getDaemon(eng)
|
|
|
|
-
|
|
|
|
- cont, err := d.Get(vars["name"])
|
|
|
|
|
|
+ cont, err := s.daemon.Get(vars["name"])
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -1136,16 +1173,14 @@ func postContainersAttach(eng *engine.Engine, version version.Version, w http.Re
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func wsContainersAttach(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) wsContainersAttach(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
- d := getDaemon(eng)
|
|
|
|
-
|
|
|
|
- cont, err := d.Get(vars["name"])
|
|
|
|
|
|
+ cont, err := s.daemon.Get(vars["name"])
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -1164,7 +1199,7 @@ func wsContainersAttach(eng *engine.Engine, version version.Version, w http.Resp
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func getContainersByName(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) getContainersByName(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
@@ -1176,13 +1211,12 @@ func getContainersByName(eng *engine.Engine, version version.Version, w http.Res
|
|
return job.Run()
|
|
return job.Run()
|
|
}
|
|
}
|
|
|
|
|
|
-func getExecByID(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) getExecByID(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter 'id'")
|
|
return fmt.Errorf("Missing parameter 'id'")
|
|
}
|
|
}
|
|
|
|
|
|
- d := getDaemon(eng)
|
|
|
|
- eConfig, err := d.ContainerExecInspect(vars["id"])
|
|
|
|
|
|
+ eConfig, err := s.daemon.ContainerExecInspect(vars["id"])
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -1190,7 +1224,7 @@ func getExecByID(eng *engine.Engine, version version.Version, w http.ResponseWri
|
|
return writeJSON(w, http.StatusOK, eConfig)
|
|
return writeJSON(w, http.StatusOK, eConfig)
|
|
}
|
|
}
|
|
|
|
|
|
-func getImagesByName(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) getImagesByName(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
@@ -1202,7 +1236,7 @@ func getImagesByName(eng *engine.Engine, version version.Version, w http.Respons
|
|
return job.Run()
|
|
return job.Run()
|
|
}
|
|
}
|
|
|
|
|
|
-func postBuild(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postBuild(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if version.LessThan("1.3") {
|
|
if version.LessThan("1.3") {
|
|
return fmt.Errorf("Multipart upload for build is no longer supported. Please upgrade your docker client.")
|
|
return fmt.Errorf("Multipart upload for build is no longer supported. Please upgrade your docker client.")
|
|
}
|
|
}
|
|
@@ -1292,7 +1326,7 @@ func postBuild(eng *engine.Engine, version version.Version, w http.ResponseWrite
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainersCopy(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postContainersCopy(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if vars == nil {
|
|
if vars == nil {
|
|
return fmt.Errorf("Missing parameter")
|
|
return fmt.Errorf("Missing parameter")
|
|
}
|
|
}
|
|
@@ -1316,7 +1350,7 @@ func postContainersCopy(eng *engine.Engine, version version.Version, w http.Resp
|
|
res = res[1:]
|
|
res = res[1:]
|
|
}
|
|
}
|
|
|
|
|
|
- cont, err := getDaemon(eng).Get(vars["name"])
|
|
|
|
|
|
+ cont, err := s.daemon.Get(vars["name"])
|
|
if err != nil {
|
|
if err != nil {
|
|
logrus.Errorf("%v", err)
|
|
logrus.Errorf("%v", err)
|
|
if strings.Contains(strings.ToLower(err.Error()), "no such id") {
|
|
if strings.Contains(strings.ToLower(err.Error()), "no such id") {
|
|
@@ -1342,7 +1376,7 @@ func postContainersCopy(eng *engine.Engine, version version.Version, w http.Resp
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainerExecCreate(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postContainerExecCreate(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
@@ -1379,7 +1413,7 @@ func postContainerExecCreate(eng *engine.Engine, version version.Version, w http
|
|
}
|
|
}
|
|
|
|
|
|
// TODO(vishh): Refactor the code to avoid having to specify stream config as part of both create and start.
|
|
// TODO(vishh): Refactor the code to avoid having to specify stream config as part of both create and start.
|
|
-func postContainerExecStart(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postContainerExecStart(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
@@ -1430,7 +1464,7 @@ func postContainerExecStart(eng *engine.Engine, version version.Version, w http.
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func postContainerExecResize(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) postContainerExecResize(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
if err := parseForm(r); err != nil {
|
|
if err := parseForm(r); err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -1447,12 +1481,10 @@ func postContainerExecResize(eng *engine.Engine, version version.Version, w http
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
|
|
|
|
- d := getDaemon(eng)
|
|
|
|
-
|
|
|
|
- return d.ContainerExecResize(vars["name"], height, width)
|
|
|
|
|
|
+ return s.daemon.ContainerExecResize(vars["name"], height, width)
|
|
}
|
|
}
|
|
|
|
|
|
-func optionsHandler(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) optionsHandler(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
w.WriteHeader(http.StatusOK)
|
|
w.WriteHeader(http.StatusOK)
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
@@ -1463,7 +1495,7 @@ func writeCorsHeaders(w http.ResponseWriter, r *http.Request, corsHeaders string
|
|
w.Header().Add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS")
|
|
w.Header().Add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS")
|
|
}
|
|
}
|
|
|
|
|
|
-func ping(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
|
|
|
|
+func (s *Server) ping(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
_, err := w.Write([]byte{'O', 'K'})
|
|
_, err := w.Write([]byte{'O', 'K'})
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -1504,71 +1536,72 @@ func makeHttpHandler(eng *engine.Engine, logging bool, localMethod string, local
|
|
}
|
|
}
|
|
|
|
|
|
// we keep enableCors just for legacy usage, need to be removed in the future
|
|
// we keep enableCors just for legacy usage, need to be removed in the future
|
|
-func createRouter(eng *engine.Engine, logging, enableCors bool, corsHeaders string, dockerVersion string) *mux.Router {
|
|
|
|
|
|
+func createRouter(s *Server, eng *engine.Engine) *mux.Router {
|
|
r := mux.NewRouter()
|
|
r := mux.NewRouter()
|
|
if os.Getenv("DEBUG") != "" {
|
|
if os.Getenv("DEBUG") != "" {
|
|
ProfilerSetup(r, "/debug/")
|
|
ProfilerSetup(r, "/debug/")
|
|
}
|
|
}
|
|
m := map[string]map[string]HttpApiFunc{
|
|
m := map[string]map[string]HttpApiFunc{
|
|
"GET": {
|
|
"GET": {
|
|
- "/_ping": ping,
|
|
|
|
- "/events": getEvents,
|
|
|
|
- "/info": getInfo,
|
|
|
|
- "/version": getVersion,
|
|
|
|
- "/images/json": getImagesJSON,
|
|
|
|
- "/images/viz": getImagesViz,
|
|
|
|
- "/images/search": getImagesSearch,
|
|
|
|
- "/images/get": getImagesGet,
|
|
|
|
- "/images/{name:.*}/get": getImagesGet,
|
|
|
|
- "/images/{name:.*}/history": getImagesHistory,
|
|
|
|
- "/images/{name:.*}/json": getImagesByName,
|
|
|
|
- "/containers/ps": getContainersJSON,
|
|
|
|
- "/containers/json": getContainersJSON,
|
|
|
|
- "/containers/{name:.*}/export": getContainersExport,
|
|
|
|
- "/containers/{name:.*}/changes": getContainersChanges,
|
|
|
|
- "/containers/{name:.*}/json": getContainersByName,
|
|
|
|
- "/containers/{name:.*}/top": getContainersTop,
|
|
|
|
- "/containers/{name:.*}/logs": getContainersLogs,
|
|
|
|
- "/containers/{name:.*}/stats": getContainersStats,
|
|
|
|
- "/containers/{name:.*}/attach/ws": wsContainersAttach,
|
|
|
|
- "/exec/{id:.*}/json": getExecByID,
|
|
|
|
|
|
+ "/_ping": s.ping,
|
|
|
|
+ "/events": s.getEvents,
|
|
|
|
+ "/info": s.getInfo,
|
|
|
|
+ "/version": s.getVersion,
|
|
|
|
+ "/images/json": s.getImagesJSON,
|
|
|
|
+ "/images/viz": s.getImagesViz,
|
|
|
|
+ "/images/search": s.getImagesSearch,
|
|
|
|
+ "/images/get": s.getImagesGet,
|
|
|
|
+ "/images/{name:.*}/get": s.getImagesGet,
|
|
|
|
+ "/images/{name:.*}/history": s.getImagesHistory,
|
|
|
|
+ "/images/{name:.*}/json": s.getImagesByName,
|
|
|
|
+ "/containers/ps": s.getContainersJSON,
|
|
|
|
+ "/containers/json": s.getContainersJSON,
|
|
|
|
+ "/containers/{name:.*}/export": s.getContainersExport,
|
|
|
|
+ "/containers/{name:.*}/changes": s.getContainersChanges,
|
|
|
|
+ "/containers/{name:.*}/json": s.getContainersByName,
|
|
|
|
+ "/containers/{name:.*}/top": s.getContainersTop,
|
|
|
|
+ "/containers/{name:.*}/logs": s.getContainersLogs,
|
|
|
|
+ "/containers/{name:.*}/stats": s.getContainersStats,
|
|
|
|
+ "/containers/{name:.*}/attach/ws": s.wsContainersAttach,
|
|
|
|
+ "/exec/{id:.*}/json": s.getExecByID,
|
|
},
|
|
},
|
|
"POST": {
|
|
"POST": {
|
|
- "/auth": postAuth,
|
|
|
|
- "/commit": postCommit,
|
|
|
|
- "/build": postBuild,
|
|
|
|
- "/images/create": postImagesCreate,
|
|
|
|
- "/images/load": postImagesLoad,
|
|
|
|
- "/images/{name:.*}/push": postImagesPush,
|
|
|
|
- "/images/{name:.*}/tag": postImagesTag,
|
|
|
|
- "/containers/create": postContainersCreate,
|
|
|
|
- "/containers/{name:.*}/kill": postContainersKill,
|
|
|
|
- "/containers/{name:.*}/pause": postContainersPause,
|
|
|
|
- "/containers/{name:.*}/unpause": postContainersUnpause,
|
|
|
|
- "/containers/{name:.*}/restart": postContainersRestart,
|
|
|
|
- "/containers/{name:.*}/start": postContainersStart,
|
|
|
|
- "/containers/{name:.*}/stop": postContainersStop,
|
|
|
|
- "/containers/{name:.*}/wait": postContainersWait,
|
|
|
|
- "/containers/{name:.*}/resize": postContainersResize,
|
|
|
|
- "/containers/{name:.*}/attach": postContainersAttach,
|
|
|
|
- "/containers/{name:.*}/copy": postContainersCopy,
|
|
|
|
- "/containers/{name:.*}/exec": postContainerExecCreate,
|
|
|
|
- "/exec/{name:.*}/start": postContainerExecStart,
|
|
|
|
- "/exec/{name:.*}/resize": postContainerExecResize,
|
|
|
|
- "/containers/{name:.*}/rename": postContainerRename,
|
|
|
|
|
|
+ "/auth": s.postAuth,
|
|
|
|
+ "/commit": s.postCommit,
|
|
|
|
+ "/build": s.postBuild,
|
|
|
|
+ "/images/create": s.postImagesCreate,
|
|
|
|
+ "/images/load": s.postImagesLoad,
|
|
|
|
+ "/images/{name:.*}/push": s.postImagesPush,
|
|
|
|
+ "/images/{name:.*}/tag": s.postImagesTag,
|
|
|
|
+ "/containers/create": s.postContainersCreate,
|
|
|
|
+ "/containers/{name:.*}/kill": s.postContainersKill,
|
|
|
|
+ "/containers/{name:.*}/pause": s.postContainersPause,
|
|
|
|
+ "/containers/{name:.*}/unpause": s.postContainersUnpause,
|
|
|
|
+ "/containers/{name:.*}/restart": s.postContainersRestart,
|
|
|
|
+ "/containers/{name:.*}/start": s.postContainersStart,
|
|
|
|
+ "/containers/{name:.*}/stop": s.postContainersStop,
|
|
|
|
+ "/containers/{name:.*}/wait": s.postContainersWait,
|
|
|
|
+ "/containers/{name:.*}/resize": s.postContainersResize,
|
|
|
|
+ "/containers/{name:.*}/attach": s.postContainersAttach,
|
|
|
|
+ "/containers/{name:.*}/copy": s.postContainersCopy,
|
|
|
|
+ "/containers/{name:.*}/exec": s.postContainerExecCreate,
|
|
|
|
+ "/exec/{name:.*}/start": s.postContainerExecStart,
|
|
|
|
+ "/exec/{name:.*}/resize": s.postContainerExecResize,
|
|
|
|
+ "/containers/{name:.*}/rename": s.postContainerRename,
|
|
},
|
|
},
|
|
"DELETE": {
|
|
"DELETE": {
|
|
- "/containers/{name:.*}": deleteContainers,
|
|
|
|
- "/images/{name:.*}": deleteImages,
|
|
|
|
|
|
+ "/containers/{name:.*}": s.deleteContainers,
|
|
|
|
+ "/images/{name:.*}": s.deleteImages,
|
|
},
|
|
},
|
|
"OPTIONS": {
|
|
"OPTIONS": {
|
|
- "": optionsHandler,
|
|
|
|
|
|
+ "": s.optionsHandler,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
|
|
// If "api-cors-header" is not given, but "api-enable-cors" is true, we set cors to "*"
|
|
// If "api-cors-header" is not given, but "api-enable-cors" is true, we set cors to "*"
|
|
// otherwise, all head values will be passed to HTTP handler
|
|
// otherwise, all head values will be passed to HTTP handler
|
|
- if corsHeaders == "" && enableCors {
|
|
|
|
|
|
+ corsHeaders := s.cfg.CorsHeaders
|
|
|
|
+ if corsHeaders == "" && s.cfg.EnableCors {
|
|
corsHeaders = "*"
|
|
corsHeaders = "*"
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1581,7 +1614,7 @@ func createRouter(eng *engine.Engine, logging, enableCors bool, corsHeaders stri
|
|
localMethod := method
|
|
localMethod := method
|
|
|
|
|
|
// build the handler function
|
|
// build the handler function
|
|
- f := makeHttpHandler(eng, logging, localMethod, localRoute, localFct, corsHeaders, version.Version(dockerVersion))
|
|
|
|
|
|
+ f := makeHttpHandler(eng, s.cfg.Logging, localMethod, localRoute, localFct, corsHeaders, version.Version(s.cfg.Version))
|
|
|
|
|
|
// add the new route
|
|
// add the new route
|
|
if localRoute == "" {
|
|
if localRoute == "" {
|
|
@@ -1600,7 +1633,14 @@ func createRouter(eng *engine.Engine, logging, enableCors bool, corsHeaders stri
|
|
// FIXME: refactor this to be part of Server and not require re-creating a new
|
|
// FIXME: refactor this to be part of Server and not require re-creating a new
|
|
// router each time. This requires first moving ListenAndServe into Server.
|
|
// router each time. This requires first moving ListenAndServe into Server.
|
|
func ServeRequest(eng *engine.Engine, apiversion version.Version, w http.ResponseWriter, req *http.Request) {
|
|
func ServeRequest(eng *engine.Engine, apiversion version.Version, w http.ResponseWriter, req *http.Request) {
|
|
- router := createRouter(eng, false, true, "", "")
|
|
|
|
|
|
+ cfg := &ServerConfig{
|
|
|
|
+ EnableCors: true,
|
|
|
|
+ Version: string(apiversion),
|
|
|
|
+ }
|
|
|
|
+ api := New(cfg, eng)
|
|
|
|
+ daemon, _ := eng.HackGetGlobalVar("httpapi.daemon").(*daemon.Daemon)
|
|
|
|
+ api.AcceptConnections(daemon)
|
|
|
|
+ router := createRouter(api, eng)
|
|
// Insert APIVERSION into the request as a convenience
|
|
// Insert APIVERSION into the request as a convenience
|
|
req.URL.Path = fmt.Sprintf("/v%s%s", apiversion, req.URL.Path)
|
|
req.URL.Path = fmt.Sprintf("/v%s%s", apiversion, req.URL.Path)
|
|
router.ServeHTTP(w, req)
|
|
router.ServeHTTP(w, req)
|
|
@@ -1632,50 +1672,6 @@ func allocateDaemonPort(addr string) error {
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-type Server interface {
|
|
|
|
- Serve() error
|
|
|
|
- Close() error
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// ServeApi loops through all of the protocols sent in to docker and spawns
|
|
|
|
-// off a go routine to setup a serving http.Server for each.
|
|
|
|
-func ServeApi(protoAddrs []string, conf *ServerConfig, eng *engine.Engine) error {
|
|
|
|
- var chErrors = make(chan error, len(protoAddrs))
|
|
|
|
-
|
|
|
|
- for _, protoAddr := range protoAddrs {
|
|
|
|
- protoAddrParts := strings.SplitN(protoAddr, "://", 2)
|
|
|
|
- if len(protoAddrParts) != 2 {
|
|
|
|
- return fmt.Errorf("bad format, expected PROTO://ADDR")
|
|
|
|
- }
|
|
|
|
- go func() {
|
|
|
|
- logrus.Infof("Listening for HTTP on %s (%s)", protoAddrParts[0], protoAddrParts[1])
|
|
|
|
- srv, err := NewServer(protoAddrParts[0], protoAddrParts[1], conf, eng)
|
|
|
|
- if err != nil {
|
|
|
|
- chErrors <- err
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
- eng.OnShutdown(func() {
|
|
|
|
- if err := srv.Close(); err != nil {
|
|
|
|
- logrus.Error(err)
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
- if err = srv.Serve(); err != nil && strings.Contains(err.Error(), "use of closed network connection") {
|
|
|
|
- err = nil
|
|
|
|
- }
|
|
|
|
- chErrors <- err
|
|
|
|
- }()
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- for i := 0; i < len(protoAddrs); i++ {
|
|
|
|
- err := <-chErrors
|
|
|
|
- if err != nil {
|
|
|
|
- return err
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return nil
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
func toBool(s string) bool {
|
|
func toBool(s string) bool {
|
|
s = strings.ToLower(strings.TrimSpace(s))
|
|
s = strings.ToLower(strings.TrimSpace(s))
|
|
return !(s == "" || s == "0" || s == "no" || s == "false" || s == "none")
|
|
return !(s == "" || s == "0" || s == "no" || s == "false" || s == "none")
|