diff --git a/commands.go b/commands.go index 4b23204854..7a6e4b332c 100644 --- a/commands.go +++ b/commands.go @@ -531,33 +531,22 @@ func (srv *Server) CmdPs(stdin io.ReadCloser, stdout io.Writer, args ...string) func (srv *Server) CmdCommit(stdin io.ReadCloser, stdout io.Writer, args ...string) error { cmd := rcli.Subcmd(stdout, - "commit", "[OPTIONS] CONTAINER [DEST]", + "commit", "[OPTIONS] CONTAINER [REPOSITORY [TAG]]", "Create a new image from a container's changes") if err := cmd.Parse(args); err != nil { return nil } - containerName, imgName := cmd.Arg(0), cmd.Arg(1) - if containerName == "" || imgName == "" { + containerName, repository, tag := cmd.Arg(0), cmd.Arg(1), cmd.Arg(2) + if containerName == "" { cmd.Usage() return nil } - if container := srv.runtime.Get(containerName); container != nil { - // FIXME: freeze the container before copying it to avoid data corruption? - // FIXME: this shouldn't be in commands. - rwTar, err := container.ExportRw() - if err != nil { - return err - } - // Create a new image from the container's base layers + a new layer from container changes - img, err := srv.runtime.graph.Create(rwTar, container.Image, "") - if err != nil { - return err - } - - fmt.Fprintln(stdout, img.Id) - return nil + img, err := srv.runtime.Commit(containerName, repository, tag) + if err != nil { + return err } - return errors.New("No such container: " + containerName) + fmt.Fprintln(stdout, img.Id) + return nil } func (srv *Server) CmdExport(stdin io.ReadCloser, stdout io.Writer, args ...string) error { diff --git a/runtime.go b/runtime.go index 9aa213f7e2..5df3b7b5b8 100644 --- a/runtime.go +++ b/runtime.go @@ -200,6 +200,33 @@ func (runtime *Runtime) Destroy(container *Container) error { return nil } +// Commit creates a new filesystem image from the current state of a container. +// The image can optionally be tagged into a repository +func (runtime *Runtime) Commit(id, repository, tag string) (*Image, error) { + container := runtime.Get(id) + if container == nil { + return nil, fmt.Errorf("No such container: %s", id) + } + // FIXME: freeze the container before copying it to avoid data corruption? + // FIXME: this shouldn't be in commands. + rwTar, err := container.ExportRw() + if err != nil { + return nil, err + } + // Create a new image from the container's base layers + a new layer from container changes + img, err := runtime.graph.Create(rwTar, container.Image, "") + if err != nil { + return nil, err + } + // Register the image if needed + if repository != "" { + if err := runtime.repositories.Set(repository, tag, img.Id); err != nil { + return img, err + } + } + return img, nil +} + func (runtime *Runtime) restore() error { dir, err := ioutil.ReadDir(runtime.repository) if err != nil {