Signed-off-by: Taylor Jones <monitorjbl@gmail.com>
Taylor Jones authored on 2015/08/20 13:01:50... | ... |
@@ -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 |