| ... | ... |
@@ -42,6 +42,7 @@ func (srv *Server) Help() string {
|
| 42 | 42 |
{"images", "List images"},
|
| 43 | 43 |
{"import", "Create a new filesystem image from the contents of a tarball"},
|
| 44 | 44 |
{"info", "Display system-wide information"},
|
| 45 |
+ {"insert", "Insert a file in an image"},
|
|
| 45 | 46 |
{"inspect", "Return low-level information on a container"},
|
| 46 | 47 |
{"kill", "Kill a running container"},
|
| 47 | 48 |
{"login", "Register or Login to the docker registry server"},
|
| ... | ... |
@@ -65,6 +66,48 @@ func (srv *Server) Help() string {
|
| 65 | 65 |
return help |
| 66 | 66 |
} |
| 67 | 67 |
|
| 68 |
+func (srv *Server) CmdInsert(stdin io.ReadCloser, stdout rcli.DockerConn, args ...string) error {
|
|
| 69 |
+ stdout.Flush() |
|
| 70 |
+ cmd := rcli.Subcmd(stdout, "insert", "IMAGE URL PATH", "Insert a file from URL in the IMAGE at PATH") |
|
| 71 |
+ if err := cmd.Parse(args); err != nil {
|
|
| 72 |
+ return nil |
|
| 73 |
+ } |
|
| 74 |
+ if cmd.NArg() != 3 {
|
|
| 75 |
+ cmd.Usage() |
|
| 76 |
+ return nil |
|
| 77 |
+ } |
|
| 78 |
+ imageId := cmd.Arg(0) |
|
| 79 |
+ url := cmd.Arg(1) |
|
| 80 |
+ path := cmd.Arg(2) |
|
| 81 |
+ |
|
| 82 |
+ img, err := srv.runtime.repositories.LookupImage(imageId) |
|
| 83 |
+ if err != nil {
|
|
| 84 |
+ return err |
|
| 85 |
+ } |
|
| 86 |
+ file, err := Download(url, stdout) |
|
| 87 |
+ if err != nil {
|
|
| 88 |
+ return err |
|
| 89 |
+ } |
|
| 90 |
+ defer file.Body.Close() |
|
| 91 |
+ |
|
| 92 |
+ b := NewBuilder(srv.runtime) |
|
| 93 |
+ c, err := b.Run(img, "echo", "insert", url, path) |
|
| 94 |
+ if err != nil {
|
|
| 95 |
+ return err |
|
| 96 |
+ } |
|
| 97 |
+ |
|
| 98 |
+ if err := c.Inject(ProgressReader(file.Body, int(file.ContentLength), stdout, "Downloading %v/%v (%v)"), path); err != nil {
|
|
| 99 |
+ return err |
|
| 100 |
+ } |
|
| 101 |
+ // FIXME: Handle custom repo, tag comment, author |
|
| 102 |
+ img, err = b.Commit(c, "", "", img.Comment, img.Author) |
|
| 103 |
+ if err != nil {
|
|
| 104 |
+ return err |
|
| 105 |
+ } |
|
| 106 |
+ fmt.Fprintf(stdout, "%s\n", img) |
|
| 107 |
+ return nil |
|
| 108 |
+} |
|
| 109 |
+ |
|
| 68 | 110 |
func (srv *Server) CmdBuild(stdin io.ReadCloser, stdout rcli.DockerConn, args ...string) error {
|
| 69 | 111 |
stdout.Flush() |
| 70 | 112 |
cmd := rcli.Subcmd(stdout, "build", "[Dockerfile|-]", "Build a container from Dockerfile") |
| ... | ... |
@@ -168,6 +168,18 @@ func (settings *NetworkSettings) PortMappingHuman() string {
|
| 168 | 168 |
return strings.Join(mapping, ", ") |
| 169 | 169 |
} |
| 170 | 170 |
|
| 171 |
+// Inject the io.Reader at the given path. Note: do not close the reader |
|
| 172 |
+func (container *Container) Inject(file io.Reader, pth string) error {
|
|
| 173 |
+ dest, err := os.Open(path.Join(container.rwPath(), pth)) |
|
| 174 |
+ if err != nil {
|
|
| 175 |
+ return err |
|
| 176 |
+ } |
|
| 177 |
+ if _, err := io.Copy(dest, file); err != nil {
|
|
| 178 |
+ return err |
|
| 179 |
+ } |
|
| 180 |
+ return nil |
|
| 181 |
+} |
|
| 182 |
+ |
|
| 171 | 183 |
func (container *Container) Cmd() *exec.Cmd {
|
| 172 | 184 |
return container.cmd |
| 173 | 185 |
} |