github.com/grange74/docker@v1.6.0-rc3/daemon/commit.go (about) 1 package daemon 2 3 import ( 4 "bytes" 5 "encoding/json" 6 7 "github.com/docker/docker/engine" 8 "github.com/docker/docker/image" 9 "github.com/docker/docker/runconfig" 10 ) 11 12 func (daemon *Daemon) ContainerCommit(job *engine.Job) engine.Status { 13 if len(job.Args) != 1 { 14 return job.Errorf("Not enough arguments. Usage: %s CONTAINER\n", job.Name) 15 } 16 name := job.Args[0] 17 18 container, err := daemon.Get(name) 19 if err != nil { 20 return job.Error(err) 21 } 22 23 var ( 24 config = container.Config 25 stdoutBuffer = bytes.NewBuffer(nil) 26 newConfig runconfig.Config 27 ) 28 29 buildConfigJob := daemon.eng.Job("build_config") 30 buildConfigJob.Stdout.Add(stdoutBuffer) 31 buildConfigJob.Setenv("changes", job.Getenv("changes")) 32 // FIXME this should be remove when we remove deprecated config param 33 buildConfigJob.Setenv("config", job.Getenv("config")) 34 35 if err := buildConfigJob.Run(); err != nil { 36 return job.Error(err) 37 } 38 if err := json.NewDecoder(stdoutBuffer).Decode(&newConfig); err != nil { 39 return job.Error(err) 40 } 41 42 if err := runconfig.Merge(&newConfig, config); err != nil { 43 return job.Error(err) 44 } 45 46 img, err := daemon.Commit(container, job.Getenv("repo"), job.Getenv("tag"), job.Getenv("comment"), job.Getenv("author"), job.GetenvBool("pause"), &newConfig) 47 if err != nil { 48 return job.Error(err) 49 } 50 job.Printf("%s\n", img.ID) 51 return engine.StatusOK 52 } 53 54 // Commit creates a new filesystem image from the current state of a container. 55 // The image can optionally be tagged into a repository 56 func (daemon *Daemon) Commit(container *Container, repository, tag, comment, author string, pause bool, config *runconfig.Config) (*image.Image, error) { 57 if pause && !container.IsPaused() { 58 container.Pause() 59 defer container.Unpause() 60 } 61 62 if err := container.Mount(); err != nil { 63 return nil, err 64 } 65 defer container.Unmount() 66 67 rwTar, err := container.ExportRw() 68 if err != nil { 69 return nil, err 70 } 71 defer rwTar.Close() 72 73 // Create a new image from the container's base layers + a new layer from container changes 74 var ( 75 containerID, parentImageID string 76 containerConfig *runconfig.Config 77 ) 78 79 if container != nil { 80 containerID = container.ID 81 parentImageID = container.ImageID 82 containerConfig = container.Config 83 } 84 85 img, err := daemon.graph.Create(rwTar, containerID, parentImageID, comment, author, containerConfig, config) 86 if err != nil { 87 return nil, err 88 } 89 90 // Register the image if needed 91 if repository != "" { 92 if err := daemon.repositories.Set(repository, tag, img.ID, true); err != nil { 93 return img, err 94 } 95 } 96 return img, nil 97 }