From e91e3c75d35344001ebd77ca3619506c66eef6c7 Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" Date: Wed, 24 Apr 2013 13:37:00 -0700 Subject: [PATCH] Add insert command in order to insert external files within an image Upstream-commit: 97514831128a7bc7bc6a2f740275bf6336ede999 Component: engine --- components/engine/commands.go | 43 ++++++++++++++++++++++++++++++++++ components/engine/container.go | 12 ++++++++++ 2 files changed, 55 insertions(+) diff --git a/components/engine/commands.go b/components/engine/commands.go index 7116d919f3..21c8b68abc 100644 --- a/components/engine/commands.go +++ b/components/engine/commands.go @@ -43,6 +43,7 @@ func (srv *Server) Help() string { {"images", "List images"}, {"import", "Create a new filesystem image from the contents of a tarball"}, {"info", "Display system-wide information"}, + {"insert", "Insert a file in an image"}, {"inspect", "Return low-level information on a container"}, {"kill", "Kill a running container"}, {"login", "Register or Login to the docker registry server"}, @@ -66,6 +67,48 @@ func (srv *Server) Help() string { return help } +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() + + b := NewBuilder(srv.runtime) + c, err := b.Run(img, "echo", "insert", url, path) + 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) + if err != nil { + return err + } + fmt.Fprintf(stdout, "%s\n", img) + return nil +} + func (srv *Server) CmdBuild(stdin io.ReadCloser, stdout rcli.DockerConn, args ...string) error { stdout.Flush() cmd := rcli.Subcmd(stdout, "build", "[Dockerfile|-]", "Build a container from Dockerfile") diff --git a/components/engine/container.go b/components/engine/container.go index 311e475ac1..ed3bdce94a 100644 --- a/components/engine/container.go +++ b/components/engine/container.go @@ -178,6 +178,18 @@ func (settings *NetworkSettings) PortMappingHuman() string { return strings.Join(mapping, ", ") } +// Inject the io.Reader at the given path. Note: do not close the reader +func (container *Container) Inject(file io.Reader, pth string) error { + dest, err := os.Open(path.Join(container.rwPath(), pth)) + if err != nil { + return err + } + if _, err := io.Copy(dest, file); err != nil { + return err + } + return nil +} + func (container *Container) Cmd() *exec.Cmd { return container.cmd }