Signed-off-by: Taylor Jones <monitorjbl@gmail.com>
| ... | ... |
@@ -23,6 +23,7 @@ func (cli *DockerCli) CmdImport(args ...string) error {
|
| 23 | 23 |
cmd := Cli.Subcmd("import", []string{"file|URL|- [REPOSITORY[:TAG]]"}, "Create an empty filesystem image and import the contents of the\ntarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) into it, then\noptionally tag it.", true)
|
| 24 | 24 |
flChanges := opts.NewListOpts(nil) |
| 25 | 25 |
cmd.Var(&flChanges, []string{"c", "-change"}, "Apply Dockerfile instruction to the created image")
|
| 26 |
+ message := cmd.String([]string{"m", "-message"}, "", "Set commit message for imported image")
|
|
| 26 | 27 |
cmd.Require(flag.Min, 1) |
| 27 | 28 |
|
| 28 | 29 |
cmd.ParseFlags(args, true) |
| ... | ... |
@@ -35,6 +36,7 @@ func (cli *DockerCli) CmdImport(args ...string) error {
|
| 35 | 35 |
|
| 36 | 36 |
v.Set("fromSrc", src)
|
| 37 | 37 |
v.Set("repo", repository)
|
| 38 |
+ v.Set("message", *message)
|
|
| 38 | 39 |
for _, change := range flChanges.GetAll() {
|
| 39 | 40 |
v.Add("changes", change)
|
| 40 | 41 |
} |
| ... | ... |
@@ -70,9 +70,10 @@ func (s *Server) postImagesCreate(version version.Version, w http.ResponseWriter |
| 70 | 70 |
} |
| 71 | 71 |
|
| 72 | 72 |
var ( |
| 73 |
- image = r.Form.Get("fromImage")
|
|
| 74 |
- repo = r.Form.Get("repo")
|
|
| 75 |
- tag = r.Form.Get("tag")
|
|
| 73 |
+ image = r.Form.Get("fromImage")
|
|
| 74 |
+ repo = r.Form.Get("repo")
|
|
| 75 |
+ tag = r.Form.Get("tag")
|
|
| 76 |
+ message = r.Form.Get("message")
|
|
| 76 | 77 |
) |
| 77 | 78 |
authEncoded := r.Header.Get("X-Registry-Auth")
|
| 78 | 79 |
authConfig := &cliconfig.AuthConfig{}
|
| ... | ... |
@@ -126,7 +127,7 @@ func (s *Server) postImagesCreate(version version.Version, w http.ResponseWriter |
| 126 | 126 |
return err |
| 127 | 127 |
} |
| 128 | 128 |
|
| 129 |
- err = s.daemon.Repositories().Import(src, repo, tag, r.Body, output, newConfig) |
|
| 129 |
+ err = s.daemon.Repositories().Import(src, repo, tag, message, r.Body, output, newConfig) |
|
| 130 | 130 |
} |
| 131 | 131 |
if err != nil {
|
| 132 | 132 |
if !output.Flushed() {
|
| ... | ... |
@@ -18,6 +18,7 @@ weight=1 |
| 18 | 18 |
optionally tag it. |
| 19 | 19 |
|
| 20 | 20 |
-c, --change=[] Apply specified Dockerfile instructions while importing the image |
| 21 |
+ -m, --message= Set commit message for imported image |
|
| 21 | 22 |
|
| 22 | 23 |
You can specify a `URL` or `-` (dash) to take data directly from `STDIN`. The |
| 23 | 24 |
`URL` can point to an archive (.tar, .tar.gz, .tgz, .bzip, .tar.xz, or .txz) |
| ... | ... |
@@ -46,6 +47,10 @@ Import to docker via pipe and `STDIN`. |
| 46 | 46 |
|
| 47 | 47 |
$ cat exampleimage.tgz | docker import - exampleimagelocal:new |
| 48 | 48 |
|
| 49 |
+Import with a commit message |
|
| 50 |
+ |
|
| 51 |
+ $ cat exampleimage.tgz | docker import --message "New image imported from tarball" - exampleimagelocal:new |
|
| 52 |
+ |
|
| 49 | 53 |
Import to docker from a local archive. |
| 50 | 54 |
|
| 51 | 55 |
$ docker import /path/to/exampleimage.tgz |
| ... | ... |
@@ -16,7 +16,7 @@ import ( |
| 16 | 16 |
// inConfig (if src is "-"), or from a URI specified in src. Progress output is |
| 17 | 17 |
// written to outStream. Repository and tag names can optionally be given in |
| 18 | 18 |
// the repo and tag arguments, respectively. |
| 19 |
-func (s *TagStore) Import(src string, repo string, tag string, inConfig io.ReadCloser, outStream io.Writer, containerConfig *runconfig.Config) error {
|
|
| 19 |
+func (s *TagStore) Import(src string, repo string, tag string, msg string, inConfig io.ReadCloser, outStream io.Writer, containerConfig *runconfig.Config) error {
|
|
| 20 | 20 |
var ( |
| 21 | 21 |
sf = streamformatter.NewJSONStreamFormatter() |
| 22 | 22 |
archive io.ReadCloser |
| ... | ... |
@@ -54,7 +54,11 @@ func (s *TagStore) Import(src string, repo string, tag string, inConfig io.ReadC |
| 54 | 54 |
} |
| 55 | 55 |
|
| 56 | 56 |
defer archive.Close() |
| 57 |
- img, err := s.graph.Create(archive, "", "", "Imported from "+src, "", nil, containerConfig) |
|
| 57 |
+ if len(msg) == 0 {
|
|
| 58 |
+ msg = "Imported from " + src |
|
| 59 |
+ } |
|
| 60 |
+ |
|
| 61 |
+ img, err := s.graph.Create(archive, "", "", msg, "", nil, containerConfig) |
|
| 58 | 62 |
if err != nil {
|
| 59 | 63 |
return err |
| 60 | 64 |
} |
| ... | ... |
@@ -5,6 +5,7 @@ import ( |
| 5 | 5 |
"io/ioutil" |
| 6 | 6 |
"os" |
| 7 | 7 |
"os/exec" |
| 8 |
+ "regexp" |
|
| 8 | 9 |
"strings" |
| 9 | 10 |
|
| 10 | 11 |
"github.com/go-check/check" |
| ... | ... |
@@ -72,6 +73,49 @@ func (s *DockerSuite) TestImportFile(c *check.C) {
|
| 72 | 72 |
} |
| 73 | 73 |
} |
| 74 | 74 |
|
| 75 |
+func (s *DockerSuite) TestImportFileWithMessage(c *check.C) {
|
|
| 76 |
+ dockerCmd(c, "run", "--name", "test-import", "busybox", "true") |
|
| 77 |
+ |
|
| 78 |
+ temporaryFile, err := ioutil.TempFile("", "exportImportTest")
|
|
| 79 |
+ if err != nil {
|
|
| 80 |
+ c.Fatal("failed to create temporary file", "", err)
|
|
| 81 |
+ } |
|
| 82 |
+ defer os.Remove(temporaryFile.Name()) |
|
| 83 |
+ |
|
| 84 |
+ runCmd := exec.Command(dockerBinary, "export", "test-import") |
|
| 85 |
+ runCmd.Stdout = bufio.NewWriter(temporaryFile) |
|
| 86 |
+ |
|
| 87 |
+ _, err = runCommand(runCmd) |
|
| 88 |
+ if err != nil {
|
|
| 89 |
+ c.Fatal("failed to export a container", err)
|
|
| 90 |
+ } |
|
| 91 |
+ |
|
| 92 |
+ message := "Testing commit message" |
|
| 93 |
+ out, _ := dockerCmd(c, "import", "-m", message, temporaryFile.Name()) |
|
| 94 |
+ if n := strings.Count(out, "\n"); n != 1 {
|
|
| 95 |
+ c.Fatalf("display is messed up: %d '\\n' instead of 1:\n%s", n, out)
|
|
| 96 |
+ } |
|
| 97 |
+ image := strings.TrimSpace(out) |
|
| 98 |
+ |
|
| 99 |
+ out, _ = dockerCmd(c, "history", image) |
|
| 100 |
+ split := strings.Split(out, "\n") |
|
| 101 |
+ |
|
| 102 |
+ if len(split) != 3 {
|
|
| 103 |
+ c.Fatalf("expected 3 lines from image history, got %d", len(split))
|
|
| 104 |
+ } |
|
| 105 |
+ r := regexp.MustCompile("[\\s]{2,}")
|
|
| 106 |
+ split = r.Split(split[1], -1) |
|
| 107 |
+ |
|
| 108 |
+ if message != split[3] {
|
|
| 109 |
+ c.Fatalf("expected %s in commit message, got %s", message, split[3])
|
|
| 110 |
+ } |
|
| 111 |
+ |
|
| 112 |
+ out, _ = dockerCmd(c, "run", "--rm", image, "true") |
|
| 113 |
+ if out != "" {
|
|
| 114 |
+ c.Fatalf("command output should've been nothing, was %q", out)
|
|
| 115 |
+ } |
|
| 116 |
+} |
|
| 117 |
+ |
|
| 75 | 118 |
func (s *DockerSuite) TestImportFileNonExistentFile(c *check.C) {
|
| 76 | 119 |
_, exitCode, err := dockerCmdWithError("import", "example.com/myImage.tar")
|
| 77 | 120 |
if exitCode == 0 || err == nil {
|
| ... | ... |
@@ -7,6 +7,7 @@ docker-import - Create an empty filesystem image and import the contents of the |
| 7 | 7 |
# SYNOPSIS |
| 8 | 8 |
**docker import** |
| 9 | 9 |
[**-c**|**--change**[= []**]] |
| 10 |
+[**-m**|**--message**[=*MESSAGE*]] |
|
| 10 | 11 |
[**--help**] |
| 11 | 12 |
file|URL|- [REPOSITORY[:TAG]] |
| 12 | 13 |
|
| ... | ... |
@@ -15,6 +16,9 @@ file|URL|- [REPOSITORY[:TAG]] |
| 15 | 15 |
Apply specified Dockerfile instructions while importing the image |
| 16 | 16 |
Supported Dockerfile instructions: `CMD`|`ENTRYPOINT`|`ENV`|`EXPOSE`|`ONBUILD`|`USER`|`VOLUME`|`WORKDIR` |
| 17 | 17 |
|
| 18 |
+**-m**, **--message**="" |
|
| 19 |
+ Set commit message for imported image |
|
| 20 |
+ |
|
| 18 | 21 |
# DESCRIPTION |
| 19 | 22 |
Create a new filesystem image from the contents of a tarball (`.tar`, |
| 20 | 23 |
`.tar.gz`, `.tgz`, `.bzip`, `.tar.xz`, `.txz`) into it, then optionally tag it. |
| ... | ... |
@@ -35,6 +39,10 @@ Import to docker via pipe and stdin: |
| 35 | 35 |
|
| 36 | 36 |
# cat exampleimage.tgz | docker import - example/imagelocal |
| 37 | 37 |
|
| 38 |
+Import with a commit message |
|
| 39 |
+ |
|
| 40 |
+ # cat exampleimage.tgz | docker import --message "New image imported from tarball" - exampleimagelocal:new |
|
| 41 |
+ |
|
| 38 | 42 |
Import to a Docker image from a local file. |
| 39 | 43 |
|
| 40 | 44 |
# docker import /path/to/exampleimage.tgz |