From 134435a79c06bd178aa6f687fcabeb2caced485a Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Wed, 15 Jan 2014 17:09:05 -0800 Subject: [PATCH 1/3] move inspect to 2 jobs Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- api.go | 35 +++++++++++++++++----------------- api_params.go | 4 ---- server.go | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 21 deletions(-) diff --git a/api.go b/api.go index 698e5b429a..ea685c68dc 100644 --- a/api.go +++ b/api.go @@ -838,41 +838,42 @@ func getContainersByName(srv *Server, version float64, w http.ResponseWriter, r if vars == nil { return fmt.Errorf("Missing parameter") } - name := vars["name"] + var ( + buffer = bytes.NewBuffer(nil) + job = srv.Eng.Job("inspect_container", vars["name"]) + ) - container, err := srv.ContainerInspect(name) - if err != nil { + job.Stdout.Add(buffer) + if err := job.Run(); err != nil { return err } - _, err = srv.ImageInspect(name) - if err == nil { + if err := srv.Eng.Job("inspect_image", vars["name"]).Run(); err == nil { return fmt.Errorf("Conflict between containers and images") } - - container.readHostConfig() - c := APIContainer{container, container.hostConfig} - - return writeJSON(w, http.StatusOK, c) + _, err := io.Copy(w, buffer) + return err } func getImagesByName(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error { if vars == nil { return fmt.Errorf("Missing parameter") } - name := vars["name"] + var ( + buffer = bytes.NewBuffer(nil) + job = srv.Eng.Job("inspect_image", vars["name"]) + ) - image, err := srv.ImageInspect(name) - if err != nil { + job.Stdout.Add(buffer) + if err := job.Run(); err != nil { return err } - _, err = srv.ContainerInspect(name) - if err == nil { + if err := srv.Eng.Job("inspect_container", vars["name"]).Run(); err == nil { return fmt.Errorf("Conflict between containers and images") } - - return writeJSON(w, http.StatusOK, image) + _, err := io.Copy(w, buffer) + return err } func postBuild(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error { diff --git a/api_params.go b/api_params.go index 92dde2906a..5de1255524 100644 --- a/api_params.go +++ b/api_params.go @@ -67,10 +67,6 @@ type ( Resource string HostPath string } - APIContainer struct { - *Container - HostConfig *HostConfig - } ) func (api APIContainers) ToLegacy() *APIContainersOld { diff --git a/server.go b/server.go index 95b8433676..a52fd20693 100644 --- a/server.go +++ b/server.go @@ -337,6 +337,14 @@ func (srv *Server) ImageExport(job *engine.Job) engine.Status { job.Error(err) return engine.StatusErr } + if err := job.Eng.Register("inspect_image", srv.JobImageInspect); err != nil { + job.Error(err) + return engine.StatusErr + } + if err := job.Eng.Register("inspect_container", srv.JobContainerInspect); err != nil { + job.Error(err) + return engine.StatusErr + } return engine.StatusOK } @@ -2303,6 +2311,31 @@ func (srv *Server) ContainerInspect(name string) (*Container, error) { return nil, fmt.Errorf("No such container: %s", name) } +func (srv *Server) JobContainerInspect(job *engine.Job) engine.Status { + if n := len(job.Args); n != 1 { + job.Errorf("Usage: %s CONTAINER", job.Name) + return engine.StatusErr + } + container, err := srv.ContainerInspect(job.Args[0]) + if err != nil { + job.Error(err) + return engine.StatusErr + } + + type HostConfigPacker struct { + *Container + HostConfig *HostConfig + } + + b, err := json.Marshal(&HostConfigPacker{container, container.hostConfig}) + if err != nil { + job.Error(err) + return engine.StatusErr + } + job.Stdout.Write(b) + return engine.StatusOK +} + func (srv *Server) ImageInspect(name string) (*Image, error) { if image, err := srv.runtime.repositories.LookupImage(name); err == nil && image != nil { return image, nil @@ -2310,6 +2343,25 @@ func (srv *Server) ImageInspect(name string) (*Image, error) { return nil, fmt.Errorf("No such image: %s", name) } +func (srv *Server) JobImageInspect(job *engine.Job) engine.Status { + if n := len(job.Args); n != 1 { + job.Errorf("Usage: %s IMAGE", job.Name) + return engine.StatusErr + } + image, err := srv.ImageInspect(job.Args[0]) + if err != nil { + job.Error(err) + return engine.StatusErr + } + b, err := json.Marshal(image) + if err != nil { + job.Error(err) + return engine.StatusErr + } + job.Stdout.Write(b) + return engine.StatusOK +} + func (srv *Server) ContainerCopy(job *engine.Job) engine.Status { if len(job.Args) != 2 { job.Errorf("Usage: %s CONTAINER RESOURCE\n", job.Name) From a7e9baaf89ae86dba4f93fb76a436e4c86249e4c Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Wed, 15 Jan 2014 17:43:57 -0800 Subject: [PATCH 2/3] update attach to use the new job Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- api.go | 17 +++++++++++++---- server.go | 6 ++---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/api.go b/api.go index ea685c68dc..ee3cbf9d94 100644 --- a/api.go +++ b/api.go @@ -751,8 +751,17 @@ func postContainersAttach(srv *Server, version float64, w http.ResponseWriter, r return fmt.Errorf("Missing parameter") } - c, err := srv.ContainerInspect(vars["name"]) - if err != nil { + var ( + job = srv.Eng.Job("inspect_container", vars["name"]) + buffer = bytes.NewBuffer(nil) + c Container + ) + job.Stdout.Add(buffer) + if err := job.Run(); err != nil { + return err + } + + if err := json.Unmarshal(buffer.Bytes(), &c); err != nil { return err } @@ -786,7 +795,7 @@ func postContainersAttach(srv *Server, version float64, w http.ResponseWriter, r errStream = outStream } - job := srv.Eng.Job("attach", vars["name"]) + job = srv.Eng.Job("attach", vars["name"]) job.Setenv("logs", r.Form.Get("logs")) job.Setenv("stream", r.Form.Get("stream")) job.Setenv("stdin", r.Form.Get("stdin")) @@ -810,7 +819,7 @@ func wsContainersAttach(srv *Server, version float64, w http.ResponseWriter, r * return fmt.Errorf("Missing parameter") } - if _, err := srv.ContainerInspect(vars["name"]); err != nil { + if err := srv.Eng.Job("inspect_container", vars["name"]).Run(); err != nil { return err } diff --git a/server.go b/server.go index a52fd20693..2dd4c7ce23 100644 --- a/server.go +++ b/server.go @@ -2322,12 +2322,10 @@ func (srv *Server) JobContainerInspect(job *engine.Job) engine.Status { return engine.StatusErr } - type HostConfigPacker struct { + b, err := json.Marshal(&struct { *Container HostConfig *HostConfig - } - - b, err := json.Marshal(&HostConfigPacker{container, container.hostConfig}) + }{container, container.hostConfig}) if err != nil { job.Error(err) return engine.StatusErr From 5fd8aa02bae6602bfe6bff541be1e1dc5c1e0fb8 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Mon, 20 Jan 2014 15:15:00 -0800 Subject: [PATCH 3/3] merge 2 jobs, no more buffer Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- api.go | 43 ++++++++----------------------- server.go | 77 ++++++++++++++++++++++++++++--------------------------- 2 files changed, 50 insertions(+), 70 deletions(-) diff --git a/api.go b/api.go index ee3cbf9d94..864a577fd1 100644 --- a/api.go +++ b/api.go @@ -751,8 +751,9 @@ func postContainersAttach(srv *Server, version float64, w http.ResponseWriter, r return fmt.Errorf("Missing parameter") } + // TODO: replace the buffer by job.AddEnv() var ( - job = srv.Eng.Job("inspect_container", vars["name"]) + job = srv.Eng.Job("inspect", vars["name"], "container") buffer = bytes.NewBuffer(nil) c Container ) @@ -819,7 +820,7 @@ func wsContainersAttach(srv *Server, version float64, w http.ResponseWriter, r * return fmt.Errorf("Missing parameter") } - if err := srv.Eng.Job("inspect_container", vars["name"]).Run(); err != nil { + if err := srv.Eng.Job("inspect", vars["name"], "container").Run(); err != nil { return err } @@ -847,42 +848,20 @@ func getContainersByName(srv *Server, version float64, w http.ResponseWriter, r if vars == nil { return fmt.Errorf("Missing parameter") } - var ( - buffer = bytes.NewBuffer(nil) - job = srv.Eng.Job("inspect_container", vars["name"]) - ) - - job.Stdout.Add(buffer) - if err := job.Run(); err != nil { - return err - } - - if err := srv.Eng.Job("inspect_image", vars["name"]).Run(); err == nil { - return fmt.Errorf("Conflict between containers and images") - } - _, err := io.Copy(w, buffer) - return err + var job = srv.Eng.Job("inspect", vars["name"], "container") + job.Stdout.Add(w) + job.SetenvBool("conflict", true) //conflict=true to detect conflict between containers and images in the job + return job.Run() } func getImagesByName(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error { if vars == nil { return fmt.Errorf("Missing parameter") } - var ( - buffer = bytes.NewBuffer(nil) - job = srv.Eng.Job("inspect_image", vars["name"]) - ) - - job.Stdout.Add(buffer) - if err := job.Run(); err != nil { - return err - } - - if err := srv.Eng.Job("inspect_container", vars["name"]).Run(); err == nil { - return fmt.Errorf("Conflict between containers and images") - } - _, err := io.Copy(w, buffer) - return err + var job = srv.Eng.Job("inspect", vars["name"], "image") + job.Stdout.Add(w) + job.SetenvBool("conflict", true) //conflict=true to detect conflict between containers and images in the job + return job.Run() } func postBuild(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error { diff --git a/server.go b/server.go index 2dd4c7ce23..f7aaf90812 100644 --- a/server.go +++ b/server.go @@ -100,6 +100,7 @@ func jobInitApi(job *engine.Job) engine.Status { "pull": srv.ImagePull, "import": srv.ImageImport, "image_delete": srv.ImageDelete, + "inspect": srv.JobInspect, } { if err := job.Eng.Register(name, handler); err != nil { job.Error(err) @@ -337,14 +338,6 @@ func (srv *Server) ImageExport(job *engine.Job) engine.Status { job.Error(err) return engine.StatusErr } - if err := job.Eng.Register("inspect_image", srv.JobImageInspect); err != nil { - job.Error(err) - return engine.StatusErr - } - if err := job.Eng.Register("inspect_container", srv.JobContainerInspect); err != nil { - job.Error(err) - return engine.StatusErr - } return engine.StatusOK } @@ -2311,29 +2304,6 @@ func (srv *Server) ContainerInspect(name string) (*Container, error) { return nil, fmt.Errorf("No such container: %s", name) } -func (srv *Server) JobContainerInspect(job *engine.Job) engine.Status { - if n := len(job.Args); n != 1 { - job.Errorf("Usage: %s CONTAINER", job.Name) - return engine.StatusErr - } - container, err := srv.ContainerInspect(job.Args[0]) - if err != nil { - job.Error(err) - return engine.StatusErr - } - - b, err := json.Marshal(&struct { - *Container - HostConfig *HostConfig - }{container, container.hostConfig}) - if err != nil { - job.Error(err) - return engine.StatusErr - } - job.Stdout.Write(b) - return engine.StatusOK -} - func (srv *Server) ImageInspect(name string) (*Image, error) { if image, err := srv.runtime.repositories.LookupImage(name); err == nil && image != nil { return image, nil @@ -2341,17 +2311,48 @@ func (srv *Server) ImageInspect(name string) (*Image, error) { return nil, fmt.Errorf("No such image: %s", name) } -func (srv *Server) JobImageInspect(job *engine.Job) engine.Status { - if n := len(job.Args); n != 1 { - job.Errorf("Usage: %s IMAGE", job.Name) +func (srv *Server) JobInspect(job *engine.Job) engine.Status { + // TODO: deprecate KIND/conflict + if n := len(job.Args); n != 2 { + job.Errorf("Usage: %s CONTAINER|IMAGE KIND", job.Name) return engine.StatusErr } - image, err := srv.ImageInspect(job.Args[0]) - if err != nil { - job.Error(err) + var ( + name = job.Args[0] + kind = job.Args[1] + object interface{} + conflict = job.GetenvBool("conflict") //should the job detect conflict between containers and images + image, errImage = srv.ImageInspect(name) + container, errContainer = srv.ContainerInspect(name) + ) + + if conflict && image != nil && container != nil { + job.Errorf("Conflict between containers and images") return engine.StatusErr } - b, err := json.Marshal(image) + + switch kind { + case "image": + if errImage != nil { + job.Error(errImage) + return engine.StatusErr + } + object = image + case "container": + if errContainer != nil { + job.Error(errContainer) + return engine.StatusErr + } + object = &struct { + *Container + HostConfig *HostConfig + }{container, container.hostConfig} + default: + job.Errorf("Unknown kind: %s", kind) + return engine.StatusErr + } + + b, err := json.Marshal(object) if err != nil { job.Error(err) return engine.StatusErr