Implement -config and -command in CmdCommit in order to allow autorun

This commit is contained in:
Guillaume J. Charmes 2013-04-25 16:48:31 -07:00
Родитель ee298d1420
Коммит 51d6228261
4 изменённых файлов: 74 добавлений и 11 удалений

Просмотреть файл

@ -477,7 +477,7 @@ func (srv *Server) CmdImport(stdin io.ReadCloser, stdout rcli.DockerConn, args .
}
archive = ProgressReader(resp.Body, int(resp.ContentLength), stdout, "Importing %v/%v (%v)")
}
img, err := srv.runtime.graph.Create(archive, nil, "Imported from "+src, "")
img, err := srv.runtime.graph.Create(archive, nil, "Imported from "+src, "", nil)
if err != nil {
return err
}
@ -726,6 +726,8 @@ func (srv *Server) CmdCommit(stdin io.ReadCloser, stdout io.Writer, args ...stri
"Create a new image from a container's changes")
flComment := cmd.String("m", "", "Commit message")
flAuthor := cmd.String("author", "", "Author (eg. \"John Hannibal Smith <hannibal@a-team.com>\"")
flConfig := cmd.String("config", "", "Config automatically applied when the image is run. This option must be the last one.")
flCommand := cmd.String("command", "", "Command to run when starting the image")
if err := cmd.Parse(args); err != nil {
return nil
}
@ -734,7 +736,22 @@ func (srv *Server) CmdCommit(stdin io.ReadCloser, stdout io.Writer, args ...stri
cmd.Usage()
return nil
}
img, err := srv.runtime.Commit(containerName, repository, tag, *flComment, *flAuthor)
var config []string
if *flConfig != "" {
config = strings.Split(*flConfig, " ")
}
if *flCommand != "" {
config = append(config, "", "/bin/sh", "-c", *flCommand)
} else if *flConfig != "" {
config = append(config, "", "")
}
c, err := ParseRun(config, stdout, srv.runtime.capabilities)
if err != nil {
return err
}
img, err := srv.runtime.Commit(containerName, repository, tag, *flComment, *flAuthor, c)
if err != nil {
return err
}
@ -925,10 +942,6 @@ func (srv *Server) CmdRun(stdin io.ReadCloser, stdout rcli.DockerConn, args ...s
fmt.Fprintln(stdout, "Error: Image not specified")
return fmt.Errorf("Image not specified")
}
if len(config.Cmd) == 0 {
fmt.Fprintln(stdout, "Error: Command not specified")
return fmt.Errorf("Command not specified")
}
if config.Tty {
stdout.SetOptionRawTerminal()

Просмотреть файл

@ -84,13 +84,14 @@ func (graph *Graph) Get(name string) (*Image, error) {
}
// Create creates a new image and registers it in the graph.
func (graph *Graph) Create(layerData Archive, container *Container, comment, author string) (*Image, error) {
func (graph *Graph) Create(layerData Archive, container *Container, comment, author string, config *Config) (*Image, error) {
img := &Image{
Id: GenerateId(),
Comment: comment,
Created: time.Now(),
DockerVersion: VERSION,
Author: author,
Config: config,
}
if container != nil {
img.Parent = container.Image

Просмотреть файл

@ -24,6 +24,7 @@ type Image struct {
ContainerConfig Config `json:"container_config,omitempty"`
DockerVersion string `json:"docker_version,omitempty"`
Author string `json:"author,omitempty"`
Config *Config `json:"config,omitempty"`
graph *Graph
}

Просмотреть файл

@ -77,12 +77,59 @@ func (runtime *Runtime) containerRoot(id string) string {
return path.Join(runtime.repository, id)
}
func (runtime *Runtime) mergeConfig(userConf, imageConf *Config) {
if userConf.Hostname != "" {
userConf.Hostname = imageConf.Hostname
}
if userConf.User != "" {
userConf.User = imageConf.User
}
if userConf.Memory == 0 {
userConf.Memory = imageConf.Memory
}
if userConf.MemorySwap == 0 {
userConf.MemorySwap = imageConf.MemorySwap
}
if userConf.PortSpecs == nil || len(userConf.PortSpecs) == 0 {
userConf.PortSpecs = imageConf.PortSpecs
}
if !userConf.Tty {
userConf.Tty = userConf.Tty
}
if !userConf.OpenStdin {
userConf.OpenStdin = imageConf.OpenStdin
}
if !userConf.StdinOnce {
userConf.StdinOnce = imageConf.StdinOnce
}
if userConf.Env == nil || len(userConf.Env) == 0 {
userConf.Env = imageConf.Env
}
if userConf.Cmd == nil || len(userConf.Cmd) == 0 {
userConf.Cmd = imageConf.Cmd
}
if userConf.Dns == nil || len(userConf.Dns) == 0 {
userConf.Dns = imageConf.Dns
}
}
func (runtime *Runtime) Create(config *Config) (*Container, error) {
// Lookup image
img, err := runtime.repositories.LookupImage(config.Image)
if err != nil {
return nil, err
}
//runtime.mergeConfig(config, img.Config)
if img.Config != nil {
config = img.Config
}
if config.Cmd == nil {
return nil, fmt.Errorf("No command specified")
}
// Generate id
id := GenerateId()
// Generate default hostname
@ -103,6 +150,7 @@ func (runtime *Runtime) Create(config *Config) (*Container, error) {
// FIXME: do we need to store this in the container?
SysInitPath: sysInitPath,
}
container.root = runtime.containerRoot(container.Id)
// Step 1: create the container directory.
// This doubles as a barrier to avoid race conditions.
@ -249,7 +297,7 @@ func (runtime *Runtime) Destroy(container *Container) error {
// 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, comment, author string) (*Image, error) {
func (runtime *Runtime) Commit(id, repository, tag, comment, author string, config *Config) (*Image, error) {
container := runtime.Get(id)
if container == nil {
return nil, fmt.Errorf("No such container: %s", id)
@ -261,7 +309,7 @@ func (runtime *Runtime) Commit(id, repository, tag, comment, author string) (*Im
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, comment, author)
img, err := runtime.graph.Create(rwTar, container, comment, author, config)
if err != nil {
return nil, err
}
@ -314,13 +362,13 @@ func NewRuntime() (*Runtime, error) {
_, err2 := ioutil.ReadFile(path.Join(cgroupMemoryMountpoint, "memory.soft_limit_in_bytes"))
runtime.capabilities.MemoryLimit = err1 == nil && err2 == nil
if !runtime.capabilities.MemoryLimit {
log.Printf("WARNING: Your kernel does not support cgroup memory limit.")
log.Printf("WARNING: Your kernel does not support cgroup memory limit.")
}
_, err = ioutil.ReadFile(path.Join(cgroupMemoryMountpoint, "memory.memsw.limit_in_bytes"))
runtime.capabilities.SwapLimit = err == nil
if !runtime.capabilities.SwapLimit {
log.Printf("WARNING: Your kernel does not support cgroup swap limit.")
log.Printf("WARNING: Your kernel does not support cgroup swap limit.")
}
}
return runtime, nil