Patch to commit-change patch to add docker import support
| ... | ... |
@@ -1156,6 +1156,8 @@ func (cli *DockerCli) CmdKill(args ...string) error {
|
| 1156 | 1156 |
|
| 1157 | 1157 |
func (cli *DockerCli) CmdImport(args ...string) error {
|
| 1158 | 1158 |
cmd := cli.Subcmd("import", "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)
|
| 1159 |
+ flChanges := opts.NewListOpts(nil) |
|
| 1160 |
+ cmd.Var(&flChanges, []string{"c", "-change"}, "Apply Dockerfile instruction to the created image.")
|
|
| 1159 | 1161 |
cmd.Require(flag.Min, 1) |
| 1160 | 1162 |
|
| 1161 | 1163 |
utils.ParseFlags(cmd, args, true) |
| ... | ... |
@@ -1168,7 +1170,9 @@ func (cli *DockerCli) CmdImport(args ...string) error {
|
| 1168 | 1168 |
|
| 1169 | 1169 |
v.Set("fromSrc", src)
|
| 1170 | 1170 |
v.Set("repo", repository)
|
| 1171 |
- |
|
| 1171 |
+ for _, change := range flChanges.GetAll() {
|
|
| 1172 |
+ v.Add("changes", change)
|
|
| 1173 |
+ } |
|
| 1172 | 1174 |
if cmd.NArg() == 3 {
|
| 1173 | 1175 |
fmt.Fprintf(cli.err, "[DEPRECATED] The format 'URL|- [REPOSITORY [TAG]]' has been deprecated. Please use URL|- [REPOSITORY[:TAG]]\n") |
| 1174 | 1176 |
v.Set("tag", cmd.Arg(2))
|
| ... | ... |
@@ -1702,6 +1706,8 @@ func (cli *DockerCli) CmdCommit(args ...string) error {
|
| 1702 | 1702 |
flPause := cmd.Bool([]string{"p", "-pause"}, true, "Pause container during commit")
|
| 1703 | 1703 |
flComment := cmd.String([]string{"m", "-message"}, "", "Commit message")
|
| 1704 | 1704 |
flAuthor := cmd.String([]string{"a", "#author", "-author"}, "", "Author (e.g., \"John Hannibal Smith <hannibal@a-team.com>\")")
|
| 1705 |
+ flChanges := opts.NewListOpts(nil) |
|
| 1706 |
+ cmd.Var(&flChanges, []string{"c", "-change"}, "Apply Dockerfile instruction to the created image.")
|
|
| 1705 | 1707 |
// FIXME: --run is deprecated, it will be replaced with inline Dockerfile commands. |
| 1706 | 1708 |
flConfig := cmd.String([]string{"#run", "#-run"}, "", "This option is deprecated and will be removed in a future version in favor of inline Dockerfile-compatible commands")
|
| 1707 | 1709 |
cmd.Require(flag.Max, 2) |
| ... | ... |
@@ -1726,6 +1732,9 @@ func (cli *DockerCli) CmdCommit(args ...string) error {
|
| 1726 | 1726 |
v.Set("tag", tag)
|
| 1727 | 1727 |
v.Set("comment", *flComment)
|
| 1728 | 1728 |
v.Set("author", *flAuthor)
|
| 1729 |
+ for _, change := range flChanges.GetAll() {
|
|
| 1730 |
+ v.Add("changes", change)
|
|
| 1731 |
+ } |
|
| 1729 | 1732 |
|
| 1730 | 1733 |
if *flPause != true {
|
| 1731 | 1734 |
v.Set("pause", "0")
|
| ... | ... |
@@ -518,6 +518,7 @@ func postCommit(eng *engine.Engine, version version.Version, w http.ResponseWrit |
| 518 | 518 |
job.Setenv("tag", r.Form.Get("tag"))
|
| 519 | 519 |
job.Setenv("author", r.Form.Get("author"))
|
| 520 | 520 |
job.Setenv("comment", r.Form.Get("comment"))
|
| 521 |
+ job.SetenvList("changes", r.Form["changes"])
|
|
| 521 | 522 |
job.SetenvSubEnv("config", &config)
|
| 522 | 523 |
|
| 523 | 524 |
job.Stdout.Add(stdoutBuffer) |
| ... | ... |
@@ -570,6 +571,7 @@ func postImagesCreate(eng *engine.Engine, version version.Version, w http.Respon |
| 570 | 570 |
} |
| 571 | 571 |
job = eng.Job("import", r.Form.Get("fromSrc"), repo, tag)
|
| 572 | 572 |
job.Stdin.Add(r.Body) |
| 573 |
+ job.SetenvList("changes", r.Form["changes"])
|
|
| 573 | 574 |
} |
| 574 | 575 |
|
| 575 | 576 |
if version.GreaterThan("1.0") {
|
| ... | ... |
@@ -96,6 +96,11 @@ type Builder struct {
|
| 96 | 96 |
ForceRemove bool |
| 97 | 97 |
Pull bool |
| 98 | 98 |
|
| 99 |
+ // set this to true if we want the builder to not commit between steps. |
|
| 100 |
+ // This is useful when we only want to use the evaluator table to generate |
|
| 101 |
+ // the final configs of the Dockerfile but dont want the layers |
|
| 102 |
+ disableCommit bool |
|
| 103 |
+ |
|
| 99 | 104 |
AuthConfig *registry.AuthConfig |
| 100 | 105 |
AuthConfigFile *registry.ConfigFile |
| 101 | 106 |
|
| ... | ... |
@@ -60,6 +60,9 @@ func (b *Builder) readContext(context io.Reader) error {
|
| 60 | 60 |
} |
| 61 | 61 |
|
| 62 | 62 |
func (b *Builder) commit(id string, autoCmd []string, comment string) error {
|
| 63 |
+ if b.disableCommit {
|
|
| 64 |
+ return nil |
|
| 65 |
+ } |
|
| 63 | 66 |
if b.image == "" && !b.noBaseImage {
|
| 64 | 67 |
return fmt.Errorf("Please provide a source image with `from` prior to commit")
|
| 65 | 68 |
} |
| ... | ... |
@@ -1,12 +1,16 @@ |
| 1 | 1 |
package builder |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "bytes" |
|
| 5 |
+ "encoding/json" |
|
| 4 | 6 |
"io" |
| 5 | 7 |
"io/ioutil" |
| 6 | 8 |
"os" |
| 7 | 9 |
"os/exec" |
| 10 |
+ "strings" |
|
| 8 | 11 |
|
| 9 | 12 |
"github.com/docker/docker/api" |
| 13 |
+ "github.com/docker/docker/builder/parser" |
|
| 10 | 14 |
"github.com/docker/docker/daemon" |
| 11 | 15 |
"github.com/docker/docker/engine" |
| 12 | 16 |
"github.com/docker/docker/graph" |
| ... | ... |
@@ -14,9 +18,22 @@ import ( |
| 14 | 14 |
"github.com/docker/docker/pkg/parsers" |
| 15 | 15 |
"github.com/docker/docker/pkg/urlutil" |
| 16 | 16 |
"github.com/docker/docker/registry" |
| 17 |
+ "github.com/docker/docker/runconfig" |
|
| 17 | 18 |
"github.com/docker/docker/utils" |
| 18 | 19 |
) |
| 19 | 20 |
|
| 21 |
+// whitelist of commands allowed for a commit/import |
|
| 22 |
+var validCommitCommands = map[string]bool{
|
|
| 23 |
+ "entrypoint": true, |
|
| 24 |
+ "cmd": true, |
|
| 25 |
+ "user": true, |
|
| 26 |
+ "workdir": true, |
|
| 27 |
+ "env": true, |
|
| 28 |
+ "volume": true, |
|
| 29 |
+ "expose": true, |
|
| 30 |
+ "onbuild": true, |
|
| 31 |
+} |
|
| 32 |
+ |
|
| 20 | 33 |
type BuilderJob struct {
|
| 21 | 34 |
Engine *engine.Engine |
| 22 | 35 |
Daemon *daemon.Daemon |
| ... | ... |
@@ -24,6 +41,7 @@ type BuilderJob struct {
|
| 24 | 24 |
|
| 25 | 25 |
func (b *BuilderJob) Install() {
|
| 26 | 26 |
b.Engine.Register("build", b.CmdBuild)
|
| 27 |
+ b.Engine.Register("build_config", b.CmdBuildConfig)
|
|
| 27 | 28 |
} |
| 28 | 29 |
|
| 29 | 30 |
func (b *BuilderJob) CmdBuild(job *engine.Job) engine.Status {
|
| ... | ... |
@@ -138,3 +156,50 @@ func (b *BuilderJob) CmdBuild(job *engine.Job) engine.Status {
|
| 138 | 138 |
} |
| 139 | 139 |
return engine.StatusOK |
| 140 | 140 |
} |
| 141 |
+ |
|
| 142 |
+func (b *BuilderJob) CmdBuildConfig(job *engine.Job) engine.Status {
|
|
| 143 |
+ if len(job.Args) != 0 {
|
|
| 144 |
+ return job.Errorf("Usage: %s\n", job.Name)
|
|
| 145 |
+ } |
|
| 146 |
+ |
|
| 147 |
+ var ( |
|
| 148 |
+ changes = job.GetenvList("changes")
|
|
| 149 |
+ newConfig runconfig.Config |
|
| 150 |
+ ) |
|
| 151 |
+ |
|
| 152 |
+ if err := job.GetenvJson("config", &newConfig); err != nil {
|
|
| 153 |
+ return job.Error(err) |
|
| 154 |
+ } |
|
| 155 |
+ |
|
| 156 |
+ ast, err := parser.Parse(bytes.NewBufferString(strings.Join(changes, "\n"))) |
|
| 157 |
+ if err != nil {
|
|
| 158 |
+ return job.Error(err) |
|
| 159 |
+ } |
|
| 160 |
+ |
|
| 161 |
+ // ensure that the commands are valid |
|
| 162 |
+ for _, n := range ast.Children {
|
|
| 163 |
+ if !validCommitCommands[n.Value] {
|
|
| 164 |
+ return job.Errorf("%s is not a valid change command", n.Value)
|
|
| 165 |
+ } |
|
| 166 |
+ } |
|
| 167 |
+ |
|
| 168 |
+ builder := &Builder{
|
|
| 169 |
+ Daemon: b.Daemon, |
|
| 170 |
+ Engine: b.Engine, |
|
| 171 |
+ Config: &newConfig, |
|
| 172 |
+ OutStream: ioutil.Discard, |
|
| 173 |
+ ErrStream: ioutil.Discard, |
|
| 174 |
+ disableCommit: true, |
|
| 175 |
+ } |
|
| 176 |
+ |
|
| 177 |
+ for i, n := range ast.Children {
|
|
| 178 |
+ if err := builder.dispatch(i, n); err != nil {
|
|
| 179 |
+ return job.Error(err) |
|
| 180 |
+ } |
|
| 181 |
+ } |
|
| 182 |
+ |
|
| 183 |
+ if err := json.NewEncoder(job.Stdout).Encode(builder.Config); err != nil {
|
|
| 184 |
+ return job.Error(err) |
|
| 185 |
+ } |
|
| 186 |
+ return engine.StatusOK |
|
| 187 |
+} |
| ... | ... |
@@ -1,6 +1,9 @@ |
| 1 | 1 |
package daemon |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "bytes" |
|
| 5 |
+ "encoding/json" |
|
| 6 |
+ |
|
| 4 | 7 |
"github.com/docker/docker/engine" |
| 5 | 8 |
"github.com/docker/docker/image" |
| 6 | 9 |
"github.com/docker/docker/runconfig" |
| ... | ... |
@@ -18,11 +21,21 @@ func (daemon *Daemon) ContainerCommit(job *engine.Job) engine.Status {
|
| 18 | 18 |
} |
| 19 | 19 |
|
| 20 | 20 |
var ( |
| 21 |
- config = container.Config |
|
| 22 |
- newConfig runconfig.Config |
|
| 21 |
+ config = container.Config |
|
| 22 |
+ stdoutBuffer = bytes.NewBuffer(nil) |
|
| 23 |
+ newConfig runconfig.Config |
|
| 23 | 24 |
) |
| 24 | 25 |
|
| 25 |
- if err := job.GetenvJson("config", &newConfig); err != nil {
|
|
| 26 |
+ buildConfigJob := daemon.eng.Job("build_config")
|
|
| 27 |
+ buildConfigJob.Stdout.Add(stdoutBuffer) |
|
| 28 |
+ buildConfigJob.Setenv("changes", job.Getenv("changes"))
|
|
| 29 |
+ // FIXME this should be remove when we remove deprecated config param |
|
| 30 |
+ buildConfigJob.Setenv("config", job.Getenv("config"))
|
|
| 31 |
+ |
|
| 32 |
+ if err := buildConfigJob.Run(); err != nil {
|
|
| 33 |
+ return job.Error(err) |
|
| 34 |
+ } |
|
| 35 |
+ if err := json.NewDecoder(stdoutBuffer).Decode(&newConfig); err != nil {
|
|
| 26 | 36 |
return job.Error(err) |
| 27 | 37 |
} |
| 28 | 38 |
|
| ... | ... |
@@ -8,6 +8,7 @@ docker-commit - Create a new image from a container's changes |
| 8 | 8 |
**docker commit** |
| 9 | 9 |
[**-a**|**--author**[=*AUTHOR*]] |
| 10 | 10 |
[**--help**] |
| 11 |
+[**-c**|**--change**[= []**]] |
|
| 11 | 12 |
[**-m**|**--message**[=*MESSAGE*]] |
| 12 | 13 |
[**-p**|**--pause**[=*true*]] |
| 13 | 14 |
CONTAINER [REPOSITORY[:TAG]] |
| ... | ... |
@@ -19,6 +20,10 @@ Using an existing container's name or ID you can create a new image. |
| 19 | 19 |
**-a**, **--author**="" |
| 20 | 20 |
Author (e.g., "John Hannibal Smith <hannibal@a-team.com>") |
| 21 | 21 |
|
| 22 |
+**-c** , **--change**=[] |
|
| 23 |
+ Apply specified Dockerfile instructions while committing the image |
|
| 24 |
+ Supported Dockerfile instructions: CMD, ENTRYPOINT, ENV, EXPOSE, ONBUILD, USER, VOLUME, WORKDIR |
|
| 25 |
+ |
|
| 22 | 26 |
**--help** |
| 23 | 27 |
Print usage statement |
| 24 | 28 |
|
| ... | ... |
@@ -38,8 +43,17 @@ create a new image run docker ps to find the container's ID and then run: |
| 38 | 38 |
# docker commit -m="Added Apache to Fedora base image" \ |
| 39 | 39 |
-a="A D Ministrator" 98bd7fc99854 fedora/fedora_httpd:20 |
| 40 | 40 |
|
| 41 |
+## Apply specified Dockerfile instructions while committing the image |
|
| 42 |
+If an existing container was created without the DEBUG environment |
|
| 43 |
+variable set to "true", you can create a new image based on that |
|
| 44 |
+container by first getting the container's ID with docker ps and |
|
| 45 |
+then running: |
|
| 46 |
+ |
|
| 47 |
+ # docker commit -c="ENV DEBUG true" 98bd7fc99854 debug-image |
|
| 48 |
+ |
|
| 41 | 49 |
# HISTORY |
| 42 | 50 |
April 2014, Originally compiled by William Henry (whenry at redhat dot com) |
| 43 | 51 |
based on docker.com source material and in |
| 44 | 52 |
June 2014, updated by Sven Dowideit <SvenDowideit@home.org.au> |
| 45 | 53 |
July 2014, updated by Sven Dowideit <SvenDowideit@home.org.au> |
| 54 |
+Oct 2014, updated by Daniel, Dao Quang Minh <daniel at nitrous dot io> |
| ... | ... |
@@ -6,9 +6,15 @@ docker-import - Create an empty filesystem image and import the contents of the |
| 6 | 6 |
|
| 7 | 7 |
# SYNOPSIS |
| 8 | 8 |
**docker import** |
| 9 |
+[**-c**|**--change**[= []**]] |
|
| 9 | 10 |
[**--help**] |
| 10 | 11 |
URL|- [REPOSITORY[:TAG]] |
| 11 | 12 |
|
| 13 |
+# OPTIONS |
|
| 14 |
+**-c**, **--change**=[] |
|
| 15 |
+ Apply specified Dockerfile instructions while importing the image |
|
| 16 |
+ Supported Dockerfile instructions: CMD, ENTRYPOINT, ENV, EXPOSE, ONBUILD, USER, VOLUME, WORKDIR |
|
| 17 |
+ |
|
| 12 | 18 |
# DESCRIPTION |
| 13 | 19 |
Create a new filesystem image from the contents of a tarball (`.tar`, |
| 14 | 20 |
`.tar.gz`, `.tgz`, `.bzip`, `.tar.xz`, `.txz`) into it, then optionally tag it. |
| ... | ... |
@@ -39,6 +45,11 @@ Import to docker via pipe and stdin: |
| 39 | 39 |
|
| 40 | 40 |
# tar -c . | docker import - exampleimagedir |
| 41 | 41 |
|
| 42 |
+## Apply specified Dockerfile instructions while importing the image |
|
| 43 |
+This example sets the docker image ENV variable DEBUG to true by default. |
|
| 44 |
+ |
|
| 45 |
+ # tar -c . | docker import -c="ENV DEBUG true" - exampleimagedir |
|
| 46 |
+ |
|
| 42 | 47 |
# HISTORY |
| 43 | 48 |
April 2014, Originally compiled by William Henry (whenry at redhat dot com) |
| 44 | 49 |
based on docker.com source material and internal work. |
| ... | ... |
@@ -694,6 +694,7 @@ you refer to it on the command line. |
| 694 | 694 |
Create a new image from a container's changes |
| 695 | 695 |
|
| 696 | 696 |
-a, --author="" Author (e.g., "John Hannibal Smith <hannibal@a-team.com>") |
| 697 |
+ -c, --change=[] Apply specified Dockerfile instructions while committing the image |
|
| 697 | 698 |
-m, --message="" Commit message |
| 698 | 699 |
-p, --pause=true Pause container during commit |
| 699 | 700 |
|
| ... | ... |
@@ -708,7 +709,12 @@ while the image is committed. This reduces the likelihood of |
| 708 | 708 |
encountering data corruption during the process of creating the commit. |
| 709 | 709 |
If this behavior is undesired, set the 'p' option to false. |
| 710 | 710 |
|
| 711 |
-#### Commit an existing container |
|
| 711 |
+The `--change` option will apply `Dockerfile` instructions to the image |
|
| 712 |
+that is created. |
|
| 713 |
+Supported `Dockerfile` instructions: `CMD`, `ENTRYPOINT`, `ENV`, `EXPOSE`, |
|
| 714 |
+`ONBUILD`, `USER`, `VOLUME`, `WORKDIR` |
|
| 715 |
+ |
|
| 716 |
+#### Commit a container |
|
| 712 | 717 |
|
| 713 | 718 |
$ sudo docker ps |
| 714 | 719 |
ID IMAGE COMMAND CREATED STATUS PORTS |
| ... | ... |
@@ -720,6 +726,19 @@ If this behavior is undesired, set the 'p' option to false. |
| 720 | 720 |
REPOSITORY TAG ID CREATED VIRTUAL SIZE |
| 721 | 721 |
SvenDowideit/testimage version3 f5283438590d 16 seconds ago 335.7 MB |
| 722 | 722 |
|
| 723 |
+#### Commit a container with new configurations |
|
| 724 |
+ |
|
| 725 |
+ $ sudo docker ps |
|
| 726 |
+ ID IMAGE COMMAND CREATED STATUS PORTS |
|
| 727 |
+ c3f279d17e0a ubuntu:12.04 /bin/bash 7 days ago Up 25 hours |
|
| 728 |
+ 197387f1b436 ubuntu:12.04 /bin/bash 7 days ago Up 25 hours |
|
| 729 |
+ $ sudo docker inspect -f "{{ .Config.Env }}" c3f279d17e0a
|
|
| 730 |
+ [HOME=/ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin] |
|
| 731 |
+ $ sudo docker commit --change "ENV DEBUG true" c3f279d17e0a SvenDowideit/testimage:version3 |
|
| 732 |
+ f5283438590d |
|
| 733 |
+ $ sudo docker inspect -f "{{ .Config.Env }}" f5283438590d
|
|
| 734 |
+ [HOME=/ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin DEBUG=true] |
|
| 735 |
+ |
|
| 723 | 736 |
## cp |
| 724 | 737 |
|
| 725 | 738 |
Copy files/folders from a container's filesystem to the host |
| ... | ... |
@@ -1137,11 +1156,18 @@ NOTE: Docker will warn you if any containers exist that are using these untagged |
| 1137 | 1137 |
tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) into it, then |
| 1138 | 1138 |
optionally tag it. |
| 1139 | 1139 |
|
| 1140 |
+ -c, --change=[] Apply specified Dockerfile instructions while importing the image |
|
| 1141 |
+ |
|
| 1140 | 1142 |
URLs must start with `http` and point to a single file archive (.tar, |
| 1141 | 1143 |
.tar.gz, .tgz, .bzip, .tar.xz, or .txz) containing a root filesystem. If |
| 1142 | 1144 |
you would like to import from a local directory or archive, you can use |
| 1143 | 1145 |
the `-` parameter to take the data from `STDIN`. |
| 1144 | 1146 |
|
| 1147 |
+The `--change` option will apply `Dockerfile` instructions to the image |
|
| 1148 |
+that is created. |
|
| 1149 |
+Supported `Dockerfile` instructions: `CMD`, `ENTRYPOINT`, `ENV`, `EXPOSE`, |
|
| 1150 |
+`ONBUILD`, `USER`, `VOLUME`, `WORKDIR` |
|
| 1151 |
+ |
|
| 1145 | 1152 |
#### Examples |
| 1146 | 1153 |
|
| 1147 | 1154 |
**Import from a remote location:** |
| ... | ... |
@@ -1160,6 +1186,10 @@ Import to docker via pipe and `STDIN`. |
| 1160 | 1160 |
|
| 1161 | 1161 |
$ sudo tar -c . | sudo docker import - exampleimagedir |
| 1162 | 1162 |
|
| 1163 |
+**Import from a local directory with new configurations:** |
|
| 1164 |
+ |
|
| 1165 |
+ $ sudo tar -c . | sudo docker import --change "ENV DEBUG true" - exampleimagedir |
|
| 1166 |
+ |
|
| 1163 | 1167 |
Note the `sudo` in this example – you must preserve |
| 1164 | 1168 |
the ownership of the files (especially root ownership) during the |
| 1165 | 1169 |
archiving with tar. If you are not root (or the sudo command) when you |
| ... | ... |
@@ -1,12 +1,15 @@ |
| 1 | 1 |
package graph |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "bytes" |
|
| 5 |
+ "encoding/json" |
|
| 4 | 6 |
"net/http" |
| 5 | 7 |
"net/url" |
| 6 | 8 |
|
| 7 | 9 |
log "github.com/Sirupsen/logrus" |
| 8 | 10 |
"github.com/docker/docker/engine" |
| 9 | 11 |
"github.com/docker/docker/pkg/archive" |
| 12 |
+ "github.com/docker/docker/runconfig" |
|
| 10 | 13 |
"github.com/docker/docker/utils" |
| 11 | 14 |
) |
| 12 | 15 |
|
| ... | ... |
@@ -15,12 +18,14 @@ func (s *TagStore) CmdImport(job *engine.Job) engine.Status {
|
| 15 | 15 |
return job.Errorf("Usage: %s SRC REPO [TAG]", job.Name)
|
| 16 | 16 |
} |
| 17 | 17 |
var ( |
| 18 |
- src = job.Args[0] |
|
| 19 |
- repo = job.Args[1] |
|
| 20 |
- tag string |
|
| 21 |
- sf = utils.NewStreamFormatter(job.GetenvBool("json"))
|
|
| 22 |
- archive archive.ArchiveReader |
|
| 23 |
- resp *http.Response |
|
| 18 |
+ src = job.Args[0] |
|
| 19 |
+ repo = job.Args[1] |
|
| 20 |
+ tag string |
|
| 21 |
+ sf = utils.NewStreamFormatter(job.GetenvBool("json"))
|
|
| 22 |
+ archive archive.ArchiveReader |
|
| 23 |
+ resp *http.Response |
|
| 24 |
+ stdoutBuffer = bytes.NewBuffer(nil) |
|
| 25 |
+ newConfig runconfig.Config |
|
| 24 | 26 |
) |
| 25 | 27 |
if len(job.Args) > 2 {
|
| 26 | 28 |
tag = job.Args[2] |
| ... | ... |
@@ -47,7 +52,21 @@ func (s *TagStore) CmdImport(job *engine.Job) engine.Status {
|
| 47 | 47 |
defer progressReader.Close() |
| 48 | 48 |
archive = progressReader |
| 49 | 49 |
} |
| 50 |
- img, err := s.graph.Create(archive, "", "", "Imported from "+src, "", nil, nil) |
|
| 50 |
+ |
|
| 51 |
+ buildConfigJob := job.Eng.Job("build_config")
|
|
| 52 |
+ buildConfigJob.Stdout.Add(stdoutBuffer) |
|
| 53 |
+ buildConfigJob.Setenv("changes", job.Getenv("changes"))
|
|
| 54 |
+ // FIXME this should be remove when we remove deprecated config param |
|
| 55 |
+ buildConfigJob.Setenv("config", job.Getenv("config"))
|
|
| 56 |
+ |
|
| 57 |
+ if err := buildConfigJob.Run(); err != nil {
|
|
| 58 |
+ return job.Error(err) |
|
| 59 |
+ } |
|
| 60 |
+ if err := json.NewDecoder(stdoutBuffer).Decode(&newConfig); err != nil {
|
|
| 61 |
+ return job.Error(err) |
|
| 62 |
+ } |
|
| 63 |
+ |
|
| 64 |
+ img, err := s.graph.Create(archive, "", "", "Imported from "+src, "", nil, &newConfig) |
|
| 51 | 65 |
if err != nil {
|
| 52 | 66 |
return job.Error(err) |
| 53 | 67 |
} |
| ... | ... |
@@ -240,3 +240,41 @@ func TestCommitWithHostBindMount(t *testing.T) {
|
| 240 | 240 |
|
| 241 | 241 |
logDone("commit - commit bind mounted file")
|
| 242 | 242 |
} |
| 243 |
+ |
|
| 244 |
+func TestCommitChange(t *testing.T) {
|
|
| 245 |
+ defer deleteAllContainers() |
|
| 246 |
+ |
|
| 247 |
+ cmd := exec.Command(dockerBinary, "run", "--name", "test", "busybox", "true") |
|
| 248 |
+ if _, err := runCommand(cmd); err != nil {
|
|
| 249 |
+ t.Fatal(err) |
|
| 250 |
+ } |
|
| 251 |
+ |
|
| 252 |
+ cmd = exec.Command(dockerBinary, "commit", |
|
| 253 |
+ "--change", "EXPOSE 8080", |
|
| 254 |
+ "--change", "ENV DEBUG true", |
|
| 255 |
+ "--change", "ENV test 1", |
|
| 256 |
+ "test", "test-commit") |
|
| 257 |
+ imageId, _, err := runCommandWithOutput(cmd) |
|
| 258 |
+ if err != nil {
|
|
| 259 |
+ t.Fatal(imageId, err) |
|
| 260 |
+ } |
|
| 261 |
+ imageId = strings.Trim(imageId, "\r\n") |
|
| 262 |
+ defer deleteImages(imageId) |
|
| 263 |
+ |
|
| 264 |
+ expected := map[string]string{
|
|
| 265 |
+ "Config.ExposedPorts": "map[8080/tcp:map[]]", |
|
| 266 |
+ "Config.Env": "[DEBUG=true test=1]", |
|
| 267 |
+ } |
|
| 268 |
+ |
|
| 269 |
+ for conf, value := range expected {
|
|
| 270 |
+ res, err := inspectField(imageId, conf) |
|
| 271 |
+ if err != nil {
|
|
| 272 |
+ t.Errorf("failed to get value %s, error: %s", conf, err)
|
|
| 273 |
+ } |
|
| 274 |
+ if res != value {
|
|
| 275 |
+ t.Errorf("%s('%s'), expected %s", conf, res, value)
|
|
| 276 |
+ } |
|
| 277 |
+ } |
|
| 278 |
+ |
|
| 279 |
+ logDone("commit - commit --change")
|
|
| 280 |
+} |
| ... | ... |
@@ -16,6 +16,7 @@ import ( |
| 16 | 16 |
|
| 17 | 17 |
"github.com/docker/docker/api" |
| 18 | 18 |
"github.com/docker/docker/api/server" |
| 19 |
+ "github.com/docker/docker/builder" |
|
| 19 | 20 |
"github.com/docker/docker/engine" |
| 20 | 21 |
"github.com/docker/docker/runconfig" |
| 21 | 22 |
"github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar" |
| ... | ... |
@@ -158,6 +159,8 @@ func TestGetContainersTop(t *testing.T) {
|
| 158 | 158 |
|
| 159 | 159 |
func TestPostCommit(t *testing.T) {
|
| 160 | 160 |
eng := NewTestEngine(t) |
| 161 |
+ b := &builder.BuilderJob{Engine: eng}
|
|
| 162 |
+ b.Install() |
|
| 161 | 163 |
defer mkDaemonFromEngine(eng, t).Nuke() |
| 162 | 164 |
|
| 163 | 165 |
// Create a container and remove a file |
| ... | ... |
@@ -5,6 +5,7 @@ import ( |
| 5 | 5 |
"testing" |
| 6 | 6 |
"time" |
| 7 | 7 |
|
| 8 |
+ "github.com/docker/docker/builder" |
|
| 8 | 9 |
"github.com/docker/docker/engine" |
| 9 | 10 |
) |
| 10 | 11 |
|
| ... | ... |
@@ -22,6 +23,8 @@ func TestCreateNumberHostname(t *testing.T) {
|
| 22 | 22 |
|
| 23 | 23 |
func TestCommit(t *testing.T) {
|
| 24 | 24 |
eng := NewTestEngine(t) |
| 25 |
+ b := &builder.BuilderJob{Engine: eng}
|
|
| 26 |
+ b.Install() |
|
| 25 | 27 |
defer mkDaemonFromEngine(eng, t).Nuke() |
| 26 | 28 |
|
| 27 | 29 |
config, _, _, err := parseRun([]string{unitTestImageID, "/bin/cat"})
|
| ... | ... |
@@ -42,6 +45,8 @@ func TestCommit(t *testing.T) {
|
| 42 | 42 |
|
| 43 | 43 |
func TestMergeConfigOnCommit(t *testing.T) {
|
| 44 | 44 |
eng := NewTestEngine(t) |
| 45 |
+ b := &builder.BuilderJob{Engine: eng}
|
|
| 46 |
+ b.Install() |
|
| 45 | 47 |
runtime := mkDaemonFromEngine(eng, t) |
| 46 | 48 |
defer runtime.Nuke() |
| 47 | 49 |
|