mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Implement -config and -command in CmdCommit in order to allow autorun
This commit is contained in:
parent
ee298d1420
commit
51d6228261
4 changed files with 74 additions and 11 deletions
25
commands.go
25
commands.go
|
@ -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)")
|
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 {
|
if err != nil {
|
||||||
return err
|
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")
|
"Create a new image from a container's changes")
|
||||||
flComment := cmd.String("m", "", "Commit message")
|
flComment := cmd.String("m", "", "Commit message")
|
||||||
flAuthor := cmd.String("author", "", "Author (eg. \"John Hannibal Smith <hannibal@a-team.com>\"")
|
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 {
|
if err := cmd.Parse(args); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -734,7 +736,22 @@ func (srv *Server) CmdCommit(stdin io.ReadCloser, stdout io.Writer, args ...stri
|
||||||
cmd.Usage()
|
cmd.Usage()
|
||||||
return nil
|
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 {
|
if err != nil {
|
||||||
return err
|
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")
|
fmt.Fprintln(stdout, "Error: Image not specified")
|
||||||
return fmt.Errorf("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 {
|
if config.Tty {
|
||||||
stdout.SetOptionRawTerminal()
|
stdout.SetOptionRawTerminal()
|
||||||
|
|
3
graph.go
3
graph.go
|
@ -84,13 +84,14 @@ func (graph *Graph) Get(name string) (*Image, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates a new image and registers it in the graph.
|
// 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{
|
img := &Image{
|
||||||
Id: GenerateId(),
|
Id: GenerateId(),
|
||||||
Comment: comment,
|
Comment: comment,
|
||||||
Created: time.Now(),
|
Created: time.Now(),
|
||||||
DockerVersion: VERSION,
|
DockerVersion: VERSION,
|
||||||
Author: author,
|
Author: author,
|
||||||
|
Config: config,
|
||||||
}
|
}
|
||||||
if container != nil {
|
if container != nil {
|
||||||
img.Parent = container.Image
|
img.Parent = container.Image
|
||||||
|
|
1
image.go
1
image.go
|
@ -24,6 +24,7 @@ type Image struct {
|
||||||
ContainerConfig Config `json:"container_config,omitempty"`
|
ContainerConfig Config `json:"container_config,omitempty"`
|
||||||
DockerVersion string `json:"docker_version,omitempty"`
|
DockerVersion string `json:"docker_version,omitempty"`
|
||||||
Author string `json:"author,omitempty"`
|
Author string `json:"author,omitempty"`
|
||||||
|
Config *Config `json:"config,omitempty"`
|
||||||
graph *Graph
|
graph *Graph
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
56
runtime.go
56
runtime.go
|
@ -77,12 +77,59 @@ func (runtime *Runtime) containerRoot(id string) string {
|
||||||
return path.Join(runtime.repository, id)
|
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) {
|
func (runtime *Runtime) Create(config *Config) (*Container, error) {
|
||||||
|
|
||||||
// Lookup image
|
// Lookup image
|
||||||
img, err := runtime.repositories.LookupImage(config.Image)
|
img, err := runtime.repositories.LookupImage(config.Image)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
// Generate id
|
||||||
id := GenerateId()
|
id := GenerateId()
|
||||||
// Generate default hostname
|
// 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?
|
// FIXME: do we need to store this in the container?
|
||||||
SysInitPath: sysInitPath,
|
SysInitPath: sysInitPath,
|
||||||
}
|
}
|
||||||
|
|
||||||
container.root = runtime.containerRoot(container.Id)
|
container.root = runtime.containerRoot(container.Id)
|
||||||
// Step 1: create the container directory.
|
// Step 1: create the container directory.
|
||||||
// This doubles as a barrier to avoid race conditions.
|
// 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.
|
// Commit creates a new filesystem image from the current state of a container.
|
||||||
// The image can optionally be tagged into a repository
|
// 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)
|
container := runtime.Get(id)
|
||||||
if container == nil {
|
if container == nil {
|
||||||
return nil, fmt.Errorf("No such container: %s", id)
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
// Create a new image from the container's base layers + a new layer from container changes
|
// 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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -314,13 +362,13 @@ func NewRuntime() (*Runtime, error) {
|
||||||
_, err2 := ioutil.ReadFile(path.Join(cgroupMemoryMountpoint, "memory.soft_limit_in_bytes"))
|
_, err2 := ioutil.ReadFile(path.Join(cgroupMemoryMountpoint, "memory.soft_limit_in_bytes"))
|
||||||
runtime.capabilities.MemoryLimit = err1 == nil && err2 == nil
|
runtime.capabilities.MemoryLimit = err1 == nil && err2 == nil
|
||||||
if !runtime.capabilities.MemoryLimit {
|
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"))
|
_, err = ioutil.ReadFile(path.Join(cgroupMemoryMountpoint, "memory.memsw.limit_in_bytes"))
|
||||||
runtime.capabilities.SwapLimit = err == nil
|
runtime.capabilities.SwapLimit = err == nil
|
||||||
if !runtime.capabilities.SwapLimit {
|
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
|
return runtime, nil
|
||||||
|
|
Loading…
Add table
Reference in a new issue