| ... | ... |
@@ -833,6 +833,7 @@ func postBuild(srv *Server, version float64, w http.ResponseWriter, r *http.Requ |
| 833 | 833 |
repoName := r.FormValue("t")
|
| 834 | 834 |
rawSuppressOutput := r.FormValue("q")
|
| 835 | 835 |
rawNoCache := r.FormValue("nocache")
|
| 836 |
+ rawRm := r.FormValue("rm")
|
|
| 836 | 837 |
repoName, tag := utils.ParseRepositoryTag(repoName) |
| 837 | 838 |
|
| 838 | 839 |
var context io.Reader |
| ... | ... |
@@ -883,8 +884,12 @@ func postBuild(srv *Server, version float64, w http.ResponseWriter, r *http.Requ |
| 883 | 883 |
if err != nil {
|
| 884 | 884 |
return err |
| 885 | 885 |
} |
| 886 |
+ rm, err := getBoolParam(rawRm) |
|
| 887 |
+ if err != nil {
|
|
| 888 |
+ return err |
|
| 889 |
+ } |
|
| 886 | 890 |
|
| 887 |
- b := NewBuildFile(srv, utils.NewWriteFlusher(w), !suppressOutput, !noCache) |
|
| 891 |
+ b := NewBuildFile(srv, utils.NewWriteFlusher(w), !suppressOutput, !noCache, rm) |
|
| 888 | 892 |
id, err := b.Build(context) |
| 889 | 893 |
if err != nil {
|
| 890 | 894 |
fmt.Fprintf(w, "Error build: %s\n", err) |
| ... | ... |
@@ -30,6 +30,7 @@ type buildFile struct {
|
| 30 | 30 |
context string |
| 31 | 31 |
verbose bool |
| 32 | 32 |
utilizeCache bool |
| 33 |
+ rm bool |
|
| 33 | 34 |
|
| 34 | 35 |
tmpContainers map[string]struct{}
|
| 35 | 36 |
tmpImages map[string]struct{}
|
| ... | ... |
@@ -37,15 +38,11 @@ type buildFile struct {
|
| 37 | 37 |
out io.Writer |
| 38 | 38 |
} |
| 39 | 39 |
|
| 40 |
-func (b *buildFile) clearTmp(containers, images map[string]struct{}) {
|
|
| 40 |
+func (b *buildFile) clearTmp(containers map[string]struct{}) {
|
|
| 41 | 41 |
for c := range containers {
|
| 42 | 42 |
tmp := b.runtime.Get(c) |
| 43 | 43 |
b.runtime.Destroy(tmp) |
| 44 |
- utils.Debugf("Removing container %s", c)
|
|
| 45 |
- } |
|
| 46 |
- for i := range images {
|
|
| 47 |
- b.runtime.graph.Delete(i) |
|
| 48 |
- utils.Debugf("Removing image %s", i)
|
|
| 44 |
+ fmt.Fprintf(b.out, "Removing intermediate container %s\n", utils.TruncateID(c)) |
|
| 49 | 45 |
} |
| 50 | 46 |
} |
| 51 | 47 |
|
| ... | ... |
@@ -514,12 +511,15 @@ func (b *buildFile) Build(context io.Reader) (string, error) {
|
| 514 | 514 |
} |
| 515 | 515 |
if b.image != "" {
|
| 516 | 516 |
fmt.Fprintf(b.out, "Successfully built %s\n", utils.TruncateID(b.image)) |
| 517 |
+ if b.rm {
|
|
| 518 |
+ b.clearTmp(b.tmpContainers) |
|
| 519 |
+ } |
|
| 517 | 520 |
return b.image, nil |
| 518 | 521 |
} |
| 519 | 522 |
return "", fmt.Errorf("An error occurred during the build\n")
|
| 520 | 523 |
} |
| 521 | 524 |
|
| 522 |
-func NewBuildFile(srv *Server, out io.Writer, verbose, utilizeCache bool) BuildFile {
|
|
| 525 |
+func NewBuildFile(srv *Server, out io.Writer, verbose, utilizeCache, rm bool) BuildFile {
|
|
| 523 | 526 |
return &buildFile{
|
| 524 | 527 |
runtime: srv.runtime, |
| 525 | 528 |
srv: srv, |
| ... | ... |
@@ -529,5 +529,6 @@ func NewBuildFile(srv *Server, out io.Writer, verbose, utilizeCache bool) BuildF |
| 529 | 529 |
tmpImages: make(map[string]struct{}),
|
| 530 | 530 |
verbose: verbose, |
| 531 | 531 |
utilizeCache: utilizeCache, |
| 532 |
+ rm: rm, |
|
| 532 | 533 |
} |
| 533 | 534 |
} |
| ... | ... |
@@ -257,7 +257,7 @@ func buildImage(context testContextTemplate, t *testing.T, srv *Server, useCache |
| 257 | 257 |
ip := srv.runtime.networkManager.bridgeNetwork.IP |
| 258 | 258 |
dockerfile := constructDockerfile(context.dockerfile, ip, port) |
| 259 | 259 |
|
| 260 |
- buildfile := NewBuildFile(srv, ioutil.Discard, false, useCache) |
|
| 260 |
+ buildfile := NewBuildFile(srv, ioutil.Discard, false, useCache, false) |
|
| 261 | 261 |
id, err := buildfile.Build(mkTestContext(dockerfile, context.files, t)) |
| 262 | 262 |
if err != nil {
|
| 263 | 263 |
t.Fatal(err) |
| ... | ... |
@@ -498,7 +498,7 @@ func TestForbiddenContextPath(t *testing.T) {
|
| 498 | 498 |
ip := srv.runtime.networkManager.bridgeNetwork.IP |
| 499 | 499 |
dockerfile := constructDockerfile(context.dockerfile, ip, port) |
| 500 | 500 |
|
| 501 |
- buildfile := NewBuildFile(srv, ioutil.Discard, false, true) |
|
| 501 |
+ buildfile := NewBuildFile(srv, ioutil.Discard, false, true, false) |
|
| 502 | 502 |
_, err = buildfile.Build(mkTestContext(dockerfile, context.files, t)) |
| 503 | 503 |
|
| 504 | 504 |
if err == nil {
|
| ... | ... |
@@ -546,7 +546,7 @@ func TestBuildADDFileNotFound(t *testing.T) {
|
| 546 | 546 |
ip := srv.runtime.networkManager.bridgeNetwork.IP |
| 547 | 547 |
dockerfile := constructDockerfile(context.dockerfile, ip, port) |
| 548 | 548 |
|
| 549 |
- buildfile := NewBuildFile(srv, ioutil.Discard, false, true) |
|
| 549 |
+ buildfile := NewBuildFile(srv, ioutil.Discard, false, true, false) |
|
| 550 | 550 |
_, err = buildfile.Build(mkTestContext(dockerfile, context.files, t)) |
| 551 | 551 |
|
| 552 | 552 |
if err == nil {
|
| ... | ... |
@@ -165,6 +165,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
|
| 165 | 165 |
tag := cmd.String("t", "", "Repository name (and optionally a tag) to be applied to the resulting image in case of success")
|
| 166 | 166 |
suppressOutput := cmd.Bool("q", false, "Suppress verbose build output")
|
| 167 | 167 |
noCache := cmd.Bool("no-cache", false, "Do not use cache when building the image")
|
| 168 |
+ rm := cmd.Bool("rm", false, "Remove intermediate containers after a successful build")
|
|
| 168 | 169 |
if err := cmd.Parse(args); err != nil {
|
| 169 | 170 |
return nil |
| 170 | 171 |
} |
| ... | ... |
@@ -215,6 +216,9 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
|
| 215 | 215 |
if *noCache {
|
| 216 | 216 |
v.Set("nocache", "1")
|
| 217 | 217 |
} |
| 218 |
+ if *rm {
|
|
| 219 |
+ v.Set("rm", "1")
|
|
| 220 |
+ } |
|
| 218 | 221 |
req, err := http.NewRequest("POST", fmt.Sprintf("/v%g/build?%s", APIVERSION, v.Encode()), body)
|
| 219 | 222 |
if err != nil {
|
| 220 | 223 |
return err |
| ... | ... |
@@ -976,6 +976,7 @@ Build an image from Dockerfile via stdin |
| 976 | 976 |
:query t: repository name (and optionally a tag) to be applied to the resulting image in case of success |
| 977 | 977 |
:query q: suppress verbose build output |
| 978 | 978 |
:query nocache: do not use the cache when building the image |
| 979 |
+ :query rm: remove intermediate containers after a successful build |
|
| 979 | 980 |
:statuscode 200: no error |
| 980 | 981 |
:statuscode 500: server error |
| 981 | 982 |
|
| ... | ... |
@@ -13,6 +13,7 @@ |
| 13 | 13 |
-t="": Repository name (and optionally a tag) to be applied to the resulting image in case of success. |
| 14 | 14 |
-q=false: Suppress verbose build output. |
| 15 | 15 |
-no-cache: Do not use the cache when building the image. |
| 16 |
+ -rm: Remove intermediate containers after a successful build |
|
| 16 | 17 |
When a single Dockerfile is given as URL, then no context is set. When a git repository is set as URL, the repository is used as context |
| 17 | 18 |
|
| 18 | 19 |
|