mirror of https://github.com/docker/docs.git
Merge pull request #1848 from dotcloud/build-clean
Add rm option to docker build to remove intermediate containers
This commit is contained in:
commit
33972627b7
7
api.go
7
api.go
|
@ -833,6 +833,7 @@ func postBuild(srv *Server, version float64, w http.ResponseWriter, r *http.Requ
|
||||||
repoName := r.FormValue("t")
|
repoName := r.FormValue("t")
|
||||||
rawSuppressOutput := r.FormValue("q")
|
rawSuppressOutput := r.FormValue("q")
|
||||||
rawNoCache := r.FormValue("nocache")
|
rawNoCache := r.FormValue("nocache")
|
||||||
|
rawRm := r.FormValue("rm")
|
||||||
repoName, tag := utils.ParseRepositoryTag(repoName)
|
repoName, tag := utils.ParseRepositoryTag(repoName)
|
||||||
|
|
||||||
var context io.Reader
|
var context io.Reader
|
||||||
|
@ -883,8 +884,12 @@ func postBuild(srv *Server, version float64, w http.ResponseWriter, r *http.Requ
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
rm, err := getBoolParam(rawRm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
b := NewBuildFile(srv, utils.NewWriteFlusher(w), !suppressOutput, !noCache)
|
b := NewBuildFile(srv, utils.NewWriteFlusher(w), !suppressOutput, !noCache, rm)
|
||||||
id, err := b.Build(context)
|
id, err := b.Build(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(w, "Error build: %s\n", err)
|
fmt.Fprintf(w, "Error build: %s\n", err)
|
||||||
|
|
15
buildfile.go
15
buildfile.go
|
@ -30,6 +30,7 @@ type buildFile struct {
|
||||||
context string
|
context string
|
||||||
verbose bool
|
verbose bool
|
||||||
utilizeCache bool
|
utilizeCache bool
|
||||||
|
rm bool
|
||||||
|
|
||||||
tmpContainers map[string]struct{}
|
tmpContainers map[string]struct{}
|
||||||
tmpImages map[string]struct{}
|
tmpImages map[string]struct{}
|
||||||
|
@ -37,15 +38,11 @@ type buildFile struct {
|
||||||
out io.Writer
|
out io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *buildFile) clearTmp(containers, images map[string]struct{}) {
|
func (b *buildFile) clearTmp(containers map[string]struct{}) {
|
||||||
for c := range containers {
|
for c := range containers {
|
||||||
tmp := b.runtime.Get(c)
|
tmp := b.runtime.Get(c)
|
||||||
b.runtime.Destroy(tmp)
|
b.runtime.Destroy(tmp)
|
||||||
utils.Debugf("Removing container %s", c)
|
fmt.Fprintf(b.out, "Removing intermediate container %s\n", utils.TruncateID(c))
|
||||||
}
|
|
||||||
for i := range images {
|
|
||||||
b.runtime.graph.Delete(i)
|
|
||||||
utils.Debugf("Removing image %s", i)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,12 +511,15 @@ func (b *buildFile) Build(context io.Reader) (string, error) {
|
||||||
}
|
}
|
||||||
if b.image != "" {
|
if b.image != "" {
|
||||||
fmt.Fprintf(b.out, "Successfully built %s\n", utils.TruncateID(b.image))
|
fmt.Fprintf(b.out, "Successfully built %s\n", utils.TruncateID(b.image))
|
||||||
|
if b.rm {
|
||||||
|
b.clearTmp(b.tmpContainers)
|
||||||
|
}
|
||||||
return b.image, nil
|
return b.image, nil
|
||||||
}
|
}
|
||||||
return "", fmt.Errorf("An error occurred during the build\n")
|
return "", fmt.Errorf("An error occurred during the build\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBuildFile(srv *Server, out io.Writer, verbose, utilizeCache bool) BuildFile {
|
func NewBuildFile(srv *Server, out io.Writer, verbose, utilizeCache, rm bool) BuildFile {
|
||||||
return &buildFile{
|
return &buildFile{
|
||||||
runtime: srv.runtime,
|
runtime: srv.runtime,
|
||||||
srv: srv,
|
srv: srv,
|
||||||
|
@ -529,5 +529,6 @@ func NewBuildFile(srv *Server, out io.Writer, verbose, utilizeCache bool) BuildF
|
||||||
tmpImages: make(map[string]struct{}),
|
tmpImages: make(map[string]struct{}),
|
||||||
verbose: verbose,
|
verbose: verbose,
|
||||||
utilizeCache: utilizeCache,
|
utilizeCache: utilizeCache,
|
||||||
|
rm: rm,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,7 +257,7 @@ func buildImage(context testContextTemplate, t *testing.T, srv *Server, useCache
|
||||||
ip := srv.runtime.networkManager.bridgeNetwork.IP
|
ip := srv.runtime.networkManager.bridgeNetwork.IP
|
||||||
dockerfile := constructDockerfile(context.dockerfile, ip, port)
|
dockerfile := constructDockerfile(context.dockerfile, ip, port)
|
||||||
|
|
||||||
buildfile := NewBuildFile(srv, ioutil.Discard, false, useCache)
|
buildfile := NewBuildFile(srv, ioutil.Discard, false, useCache, false)
|
||||||
id, err := buildfile.Build(mkTestContext(dockerfile, context.files, t))
|
id, err := buildfile.Build(mkTestContext(dockerfile, context.files, t))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -498,7 +498,7 @@ func TestForbiddenContextPath(t *testing.T) {
|
||||||
ip := srv.runtime.networkManager.bridgeNetwork.IP
|
ip := srv.runtime.networkManager.bridgeNetwork.IP
|
||||||
dockerfile := constructDockerfile(context.dockerfile, ip, port)
|
dockerfile := constructDockerfile(context.dockerfile, ip, port)
|
||||||
|
|
||||||
buildfile := NewBuildFile(srv, ioutil.Discard, false, true)
|
buildfile := NewBuildFile(srv, ioutil.Discard, false, true, false)
|
||||||
_, err = buildfile.Build(mkTestContext(dockerfile, context.files, t))
|
_, err = buildfile.Build(mkTestContext(dockerfile, context.files, t))
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -546,7 +546,7 @@ func TestBuildADDFileNotFound(t *testing.T) {
|
||||||
ip := srv.runtime.networkManager.bridgeNetwork.IP
|
ip := srv.runtime.networkManager.bridgeNetwork.IP
|
||||||
dockerfile := constructDockerfile(context.dockerfile, ip, port)
|
dockerfile := constructDockerfile(context.dockerfile, ip, port)
|
||||||
|
|
||||||
buildfile := NewBuildFile(srv, ioutil.Discard, false, true)
|
buildfile := NewBuildFile(srv, ioutil.Discard, false, true, false)
|
||||||
_, err = buildfile.Build(mkTestContext(dockerfile, context.files, t))
|
_, err = buildfile.Build(mkTestContext(dockerfile, context.files, t))
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
|
@ -165,6 +165,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
|
||||||
tag := cmd.String("t", "", "Repository name (and optionally a tag) to be applied to the resulting image in case of success")
|
tag := cmd.String("t", "", "Repository name (and optionally a tag) to be applied to the resulting image in case of success")
|
||||||
suppressOutput := cmd.Bool("q", false, "Suppress verbose build output")
|
suppressOutput := cmd.Bool("q", false, "Suppress verbose build output")
|
||||||
noCache := cmd.Bool("no-cache", false, "Do not use cache when building the image")
|
noCache := cmd.Bool("no-cache", false, "Do not use cache when building the image")
|
||||||
|
rm := cmd.Bool("rm", false, "Remove intermediate containers after a successful build")
|
||||||
if err := cmd.Parse(args); err != nil {
|
if err := cmd.Parse(args); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -215,6 +216,9 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
|
||||||
if *noCache {
|
if *noCache {
|
||||||
v.Set("nocache", "1")
|
v.Set("nocache", "1")
|
||||||
}
|
}
|
||||||
|
if *rm {
|
||||||
|
v.Set("rm", "1")
|
||||||
|
}
|
||||||
req, err := http.NewRequest("POST", fmt.Sprintf("/v%g/build?%s", APIVERSION, v.Encode()), body)
|
req, err := http.NewRequest("POST", fmt.Sprintf("/v%g/build?%s", APIVERSION, v.Encode()), body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -114,7 +114,7 @@ _docker_build()
|
||||||
|
|
||||||
case "$cur" in
|
case "$cur" in
|
||||||
-*)
|
-*)
|
||||||
COMPREPLY=( $( compgen -W "-no-cache -t -q" -- "$cur" ) )
|
COMPREPLY=( $( compgen -W "-no-cache -t -q -rm" -- "$cur" ) )
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
_filedir
|
_filedir
|
||||||
|
|
|
@ -976,6 +976,7 @@ Build an image from Dockerfile via stdin
|
||||||
:query t: repository name (and optionally a tag) to be applied to the resulting image in case of success
|
:query t: repository name (and optionally a tag) to be applied to the resulting image in case of success
|
||||||
:query q: suppress verbose build output
|
:query q: suppress verbose build output
|
||||||
:query nocache: do not use the cache when building the image
|
:query nocache: do not use the cache when building the image
|
||||||
|
:query rm: remove intermediate containers after a successful build
|
||||||
:statuscode 200: no error
|
:statuscode 200: no error
|
||||||
:statuscode 500: server error
|
:statuscode 500: server error
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
-t="": Repository name (and optionally a tag) to be applied to the resulting image in case of success.
|
-t="": Repository name (and optionally a tag) to be applied to the resulting image in case of success.
|
||||||
-q=false: Suppress verbose build output.
|
-q=false: Suppress verbose build output.
|
||||||
-no-cache: Do not use the cache when building the image.
|
-no-cache: Do not use the cache when building the image.
|
||||||
|
-rm: Remove intermediate containers after a successful build
|
||||||
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
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue