func (srv *Server) CmdAttach(stdin io.ReadCloser, stdout rcli.DockerConn, args ...string) error { cmd := rcli.Subcmd(stdout, "attach", "CONTAINER", "Attach to a running container") if err := cmd.Parse(args); err != nil { return nil } if cmd.NArg() != 1 { 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.State.Ghost { return fmt.Errorf("Impossible to attach to a ghost container") } if container.Config.Tty { stdout.SetOptionRawTerminal() } // Flush the options to make sure the client sets the raw mode stdout.Flush() return <-container.Attach(stdin, nil, stdout, stdout) }
func (srv *Server) CmdBuild(stdin io.ReadCloser, stdout rcli.DockerConn, args ...string) error { stdout.Flush() cmd := rcli.Subcmd(stdout, "build", "-", "Build a container from Dockerfile via stdin") if err := cmd.Parse(args); err != nil { return nil } img, err := NewBuilder(srv.runtime).Build(stdin, stdout) if err != nil { return err } fmt.Fprintf(stdout, "%s\n", img.ShortId()) return nil }
func (srv *Server) CmdImport(stdin io.ReadCloser, stdout rcli.DockerConn, args ...string) error { stdout.Flush() cmd := rcli.Subcmd(stdout, "import", "URL|- [REPOSITORY [TAG]]", "Create a new filesystem image from the contents of a tarball") var archive io.Reader var resp *http.Response if err := cmd.Parse(args); err != nil { return nil } if cmd.NArg() < 1 { cmd.Usage() return nil } src := cmd.Arg(0) if src == "-" { archive = stdin } else { u, err := url.Parse(src) if err != nil { return err } if u.Scheme == "" { u.Scheme = "http" u.Host = src u.Path = "" } fmt.Fprintln(stdout, "Downloading from", u) // Download with curl (pretty progress bar) // If curl is not available, fallback to http.Get() resp, err = Download(u.String(), stdout) if err != nil { return err } archive = ProgressReader(resp.Body, int(resp.ContentLength), stdout) } img, err := srv.runtime.graph.Create(archive, nil, "Imported from "+src, "") if err != nil { return err } // Optionally register the image at REPO/TAG if repository := cmd.Arg(1); repository != "" { tag := cmd.Arg(2) // Repository will handle an empty tag properly if err := srv.runtime.repositories.Set(repository, tag, img.Id, true); err != nil { return err } } fmt.Fprintln(stdout, img.ShortId()) return nil }
func (srv *Server) CmdInsert(stdin io.ReadCloser, stdout rcli.DockerConn, args ...string) error { stdout.Flush() cmd := rcli.Subcmd(stdout, "insert", "IMAGE URL PATH", "Insert a file from URL in the IMAGE at PATH") if err := cmd.Parse(args); err != nil { return nil } if cmd.NArg() != 3 { cmd.Usage() return nil } imageId := cmd.Arg(0) url := cmd.Arg(1) path := cmd.Arg(2) img, err := srv.runtime.repositories.LookupImage(imageId) if err != nil { return err } file, err := Download(url, stdout) if err != nil { return err } defer file.Body.Close() config, err := ParseRun([]string{img.Id, "echo", "insert", url, path}, nil, srv.runtime.capabilities) if err != nil { return err } b := NewBuilder(srv.runtime) c, err := b.Create(config) if err != nil { return err } if err := c.Inject(ProgressReader(file.Body, int(file.ContentLength), stdout, "Downloading %v/%v (%v)"), path); err != nil { return err } // FIXME: Handle custom repo, tag comment, author img, err = b.Commit(c, "", "", img.Comment, img.Author, nil) if err != nil { return err } fmt.Fprintf(stdout, "%s\n", img.Id) return nil }
func (srv *Server) CmdRun(stdin io.ReadCloser, stdout rcli.DockerConn, args ...string) error { config, err := ParseRun(args, stdout) if err != nil { return err } if config.Image == "" { fmt.Fprintln(stdout, "Error: Image not specified") return fmt.Errorf("Image not specified") } if len(config.Cmd) == 0 { fmt.Fprintln(stdout, "Error: Command not specified") return fmt.Errorf("Command not specified") } if config.Tty { stdout.SetOptionRawTerminal() } // Flush the options to make sure the client sets the raw mode // or tell the client there is no options stdout.Flush() // Create new container container, err := srv.runtime.Create(config) if err != nil { // If container not found, try to pull it if srv.runtime.graph.IsNotExist(err) { fmt.Fprintf(stdout, "Image %s not found, trying to pull it from registry.\r\n", config.Image) if err = srv.CmdPull(stdin, stdout, config.Image); err != nil { return err } if container, err = srv.runtime.Create(config); err != nil { return err } } else { return err } } var ( cStdin io.ReadCloser cStdout, cStderr io.Writer ) if config.AttachStdin { r, w := io.Pipe() go func() { defer w.Close() defer Debugf("Closing buffered stdin pipe") io.Copy(w, stdin) }() cStdin = r } if config.AttachStdout { cStdout = stdout } if config.AttachStderr { cStderr = stdout // FIXME: rcli can't differentiate stdout from stderr } attachErr := container.Attach(cStdin, stdin, cStdout, cStderr) Debugf("Starting\n") if err := container.Start(); err != nil { return err } if cStdout == nil && cStderr == nil { fmt.Fprintln(stdout, container.ShortId()) } Debugf("Waiting for attach to return\n") <-attachErr container.Wait() // Expecting I/O pipe error, discarding return nil }