github.com/leoh0/docker@v1.6.0-rc4/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  }