From a48eb4dff869631221854bb85380c15bf7b9d0eb Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Fri, 26 Apr 2013 15:08:33 +0200 Subject: [PATCH] run now try to pull if unknown image --- api.go | 88 ++++++++++++++++++++++++++++++++++++++--------------- commands.go | 36 +++++++++------------- 2 files changed, 78 insertions(+), 46 deletions(-) diff --git a/api.go b/api.go index 1b9507dd6e..3de2479a44 100644 --- a/api.go +++ b/api.go @@ -130,7 +130,7 @@ func ListenAndServe(addr string, rtime *Runtime) error { var allImages map[string]*Image var err error - if All == "true" { + if All == "1" { allImages, err = rtime.graph.Map() } else { allImages, err = rtime.graph.Heads() @@ -152,7 +152,7 @@ func ListenAndServe(addr string, rtime *Runtime) error { continue } delete(allImages, id) - if Quiet != "true" { + if Quiet != "1" { out.Repository = name out.Tag = tag out.Id = TruncateId(id) @@ -167,7 +167,7 @@ func ListenAndServe(addr string, rtime *Runtime) error { if NameFilter == "" { for id, image := range allImages { var out ApiImages - if Quiet != "true" { + if Quiet != "1" { out.Repository = "" out.Tag = "" out.Id = TruncateId(id) @@ -355,7 +355,7 @@ func ListenAndServe(addr string, rtime *Runtime) error { var outs []ApiContainers for i, container := range rtime.List() { - if !container.State.Running && All != "true" && n == -1 { + if !container.State.Running && All != "1" && n == -1 { continue } if i == n { @@ -363,9 +363,9 @@ func ListenAndServe(addr string, rtime *Runtime) error { } var out ApiContainers out.Id = container.ShortId() - if Quiet != "true" { + if Quiet != "1" { command := fmt.Sprintf("%s %s", container.Path, strings.Join(container.Args, " ")) - if NoTrunc != "true" { + if NoTrunc != "1" { command = Trunc(command, 20) } out.Image = rtime.repositories.ImageName(container.Image) @@ -420,7 +420,7 @@ func ListenAndServe(addr string, rtime *Runtime) error { repo := r.Form.Get("repo") tag := r.Form.Get("tag") var force bool - if r.Form.Get("force") == "true" { + if r.Form.Get("force") == "1" { force = true } @@ -451,14 +451,14 @@ func ListenAndServe(addr string, rtime *Runtime) error { fmt.Fprintln(file, "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n") if rtime.graph.LookupRemoteImage(name, rtime.authConfig) { - if err := rtime.graph.PullImage(file, name, rtime.authConfig); err != nil { - fmt.Fprintln(file, "Error: "+err.Error()) - } - return - } - if err := rtime.graph.PullRepository(file, name, "", rtime.repositories, rtime.authConfig); err != nil { - fmt.Fprintln(file, "Error: "+err.Error()) - } + if err := rtime.graph.PullImage(file, name, rtime.authConfig); err != nil { + fmt.Fprintln(file, "Error: "+err.Error()) + } + return nil + } + if err := rtime.graph.PullRepository(file, name, "", rtime.repositories, rtime.authConfig); err != nil { + fmt.Fprintln(file, "Error: "+err.Error()) + } }) r.Path("/containers").Methods("POST").HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -488,14 +488,19 @@ func ListenAndServe(addr string, rtime *Runtime) error { // If container not found, try to pull it if rtime.graph.IsNotExist(err) { fmt.Fprintf(file, "Image %s not found, trying to pull it from registry.\r\n", config.Image) - //if err = srv.CmdPull(stdin, stdout, config.Image); err != nil { - // fmt.Fprintln(file, "Error: "+err.Error()) - // return - //} - //if container, err = srv.runtime.Create(config); err != nil { - // fmt.Fprintln(file, "Error: "+err.Error()) - // return - //} + if rtime.graph.LookupRemoteImage(name, rtime.authConfig) { + if err := rtime.graph.PullImage(file, name, rtime.authConfig); err != nil { + fmt.Fprintln(file, "Error: "+err.Error()) + return + } + } else if err := rtime.graph.PullRepository(file, name, "", rtime.repositories, rtime.authConfig); err != nil { + fmt.Fprintln(file, "Error: "+err.Error()) + return + } + if container, err = rtime.Create(&config); err != nil { + fmt.Fprintln(file, "Error: "+err.Error()) + return + } } else { fmt.Fprintln(file, "Error: "+err.Error()) return @@ -532,8 +537,43 @@ func ListenAndServe(addr string, rtime *Runtime) error { } Debugf("Waiting for attach to return\n") <-attachErr - // Expecting I/O pipe error, discarding + // Expecting I/O pipe error, discarding + }) + r.Path("/containers/{name:.*}/attach").Methods("POST").HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + log.Println(r.Method, r.RequestURI) + vars := mux.Vars(r) + name := vars["name"] + if container := rtime.Get(name); container != nil { + conn, _, err := w.(http.Hijacker).Hijack() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + defer conn.Close() + file, err := conn.(*net.TCPConn).File() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + defer file.Close() + + fmt.Fprintln(file, "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n") + r, w := io.Pipe() + go func() { + defer w.Close() + defer Debugf("Closing buffered stdin pipe") + io.Copy(w, file) + }() + cStdin := r + + <-container.Attach(cStdin, nil, file, file) + // Expecting I/O pipe error, discarding + + } else { + http.Error(w, "No such container: "+name, http.StatusNotFound) + return + } }) r.Path("/containers/{name:.*}/restart").Methods("POST").HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/commands.go b/commands.go index e9458d43be..e39c03f242 100644 --- a/commands.go +++ b/commands.go @@ -26,6 +26,7 @@ var ( func ParseCommands(args []string) error { cmds := map[string]func(args []string) error{ + "attach": CmdAttach, "commit": CmdCommit, "diff": CmdDiff, "export": CmdExport, @@ -63,7 +64,7 @@ func ParseCommands(args []string) error { func cmdHelp(args []string) error { help := "Usage: docker COMMAND [arg...]\n\nA self-sufficient runtime for linux containers.\n\nCommands:\n" for _, cmd := range [][]string{ - // {"attach", "Attach to a running container"}, + {"attach", "Attach to a running container"}, {"commit", "Create a new image from a container's changes"}, {"diff", "Inspect changes on a container's filesystem"}, {"export", "Stream the contents of a container as a tar archive"}, @@ -631,10 +632,10 @@ func CmdImages(args []string) error { v.Set("filter", cmd.Arg(0)) } if *quiet { - v.Set("quiet", "true") + v.Set("quiet", "1") } if *all { - v.Set("all", "true") + v.Set("all", "1") } body, err := call("GET", "/images?"+v.Encode()) @@ -682,13 +683,13 @@ func CmdPs(args []string) error { *last = 1 } if *quiet { - v.Set("quiet", "true") + v.Set("quiet", "1") } if *all { - v.Set("all", "true") + v.Set("all", "1") } if *noTrunc { - v.Set("notrunc", "true") + v.Set("notrunc", "1") } if *last != -1 { v.Set("n", strconv.Itoa(*last)) @@ -822,9 +823,8 @@ func CmdLogs(args []string) error { return nil } -/* -func (srv *Server) CmdAttach(stdin io.ReadCloser, stdout rcli.DockerConn, args ...string) error { - cmd := rcli.Subcmd(stdout, "attach", "CONTAINER", "Attach to a running container") +func CmdAttach(args []string) error { + cmd := Subcmd("attach", "CONTAINER", "Attach to a running container") if err := cmd.Parse(args); err != nil { return nil } @@ -832,20 +832,13 @@ func (srv *Server) CmdAttach(stdin io.ReadCloser, stdout rcli.DockerConn, args . cmd.Usage() return nil } - name := cmd.Arg(0) - container := srv.runtime.Get(name) - if container == nil { - return fmt.Errorf("No such container: %s", name) - } - if container.Config.Tty { - stdout.SetOptionRawTerminal() + if err := callStream("POST", "/containers/"+cmd.Arg(0)+"/attach", nil, true); err != nil { + return err } - // Flush the options to make sure the client sets the raw mode - stdout.Flush() - return <-container.Attach(stdin, nil, stdout, stdout) + return nil } -*/ + /* // Ports type - Used to parse multiple -p flags type ports []int @@ -921,7 +914,7 @@ func CmdTag(args []string) error { } if *force { - v.Set("force", "true") + v.Set("force", "1") } if err := callStream("POST", "/images/"+cmd.Arg(0)+"/tag?"+v.Encode(), nil, false); err != nil { @@ -931,7 +924,6 @@ func CmdTag(args []string) error { } func CmdRun(args []string) error { - fmt.Println("CmdRun") config, cmd, err := ParseRun(args) if err != nil { return err