mirror of
https://github.com/clearlinux/docker.git
synced 2026-10-04 15:58:39 +00:00
docker save: ability to save multiple images
Now from a single invocation of `docker save`, you can specify multiple
images to include in the output tar, or even just multiple tags of a
particular image/repo.
```
> docker save -o bundle.tar busybox ubuntu:lucid ubuntu:saucy fedora:latest
> tar tf ./bundle.tar | wc -l
42
> tar xOf ./bundle.tar repositories
{"busybox":{"latest":"2d8e5b282c81244037eb15b2068e1c46319c1a42b80493acb128da24b2090739"},"fedora":{"latest":"58394af373423902a1b97f209a31e3777932d9321ef10e64feaaa7b4df609cf9"},"ubuntu":{"lucid":"9cc9ea5ea540116b89e41898dd30858107c1175260fb7ff50322b34704092232","saucy":"9f676bd305a43a931a8d98b13e5840ffbebcd908370765373315926024c7c35e"}}
```
Further, this fixes the bug where the `repositories` file is not created
when saving a specific tag of an image (e.g. ubuntu:latest)
document multi-image save and updated API docs
Docker-DCO-1.1-Signed-off-by: Vincent Batts <vbatts@redhat.com> (github: vbatts)
This commit is contained in:
+15
-5
@@ -2257,14 +2257,14 @@ func (cli *DockerCli) CmdCp(args ...string) error {
|
||||
}
|
||||
|
||||
func (cli *DockerCli) CmdSave(args ...string) error {
|
||||
cmd := cli.Subcmd("save", "IMAGE", "Save an image to a tar archive (streamed to STDOUT by default)")
|
||||
cmd := cli.Subcmd("save", "IMAGE [IMAGE...]", "Save an image(s) to a tar archive (streamed to STDOUT by default)")
|
||||
outfile := cmd.String([]string{"o", "-output"}, "", "Write to an file, instead of STDOUT")
|
||||
|
||||
if err := cmd.Parse(args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cmd.NArg() != 1 {
|
||||
if cmd.NArg() < 1 {
|
||||
cmd.Usage()
|
||||
return nil
|
||||
}
|
||||
@@ -2279,9 +2279,19 @@ func (cli *DockerCli) CmdSave(args ...string) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
image := cmd.Arg(0)
|
||||
if err := cli.stream("GET", "/images/"+image+"/get", nil, output, nil); err != nil {
|
||||
return err
|
||||
if len(cmd.Args()) == 1 {
|
||||
image := cmd.Arg(0)
|
||||
if err := cli.stream("GET", "/images/"+image+"/get", nil, output, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
v := url.Values{}
|
||||
for _, arg := range cmd.Args() {
|
||||
v.Add("names", arg)
|
||||
}
|
||||
if err := cli.stream("GET", "/images/get?"+v.Encode(), nil, output, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
+10
-1
@@ -611,10 +611,18 @@ func getImagesGet(eng *engine.Engine, version version.Version, w http.ResponseWr
|
||||
if vars == nil {
|
||||
return fmt.Errorf("Missing parameter")
|
||||
}
|
||||
if err := parseForm(r); err != nil {
|
||||
return err
|
||||
}
|
||||
if version.GreaterThan("1.0") {
|
||||
w.Header().Set("Content-Type", "application/x-tar")
|
||||
}
|
||||
job := eng.Job("image_export", vars["name"])
|
||||
var job *engine.Job
|
||||
if name, ok := vars["name"]; ok {
|
||||
job = eng.Job("image_export", name)
|
||||
} else {
|
||||
job = eng.Job("image_export", r.Form["names"]...)
|
||||
}
|
||||
job.Stdout.Add(w)
|
||||
return job.Run()
|
||||
}
|
||||
@@ -1105,6 +1113,7 @@ func createRouter(eng *engine.Engine, logging, enableCors bool, dockerVersion st
|
||||
"/images/json": getImagesJSON,
|
||||
"/images/viz": getImagesViz,
|
||||
"/images/search": getImagesSearch,
|
||||
"/images/get": getImagesGet,
|
||||
"/images/{name:.*}/get": getImagesGet,
|
||||
"/images/{name:.*}/history": getImagesHistory,
|
||||
"/images/{name:.*}/json": getImagesByName,
|
||||
|
||||
Reference in New Issue
Block a user