mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
automatically remove container via -rm
add AutoRemove to HostConfig add -rm flag to docker run add TestRunAutoRemove to test -rm docs: add -rm to commandline/command/run add hostConfig to container monitor make monitor destroy the container via -rm This adds support for automatically removing a container after it exits. The removal of the container is handled on the server side.
This commit is contained in:
parent
7447867edd
commit
22e7e107ad
4 changed files with 54 additions and 3 deletions
|
@ -542,3 +542,40 @@ func TestAttachDisconnect(t *testing.T) {
|
||||||
cStdin.Close()
|
cStdin.Close()
|
||||||
container.Wait()
|
container.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Expected behaviour: container gets deleted automatically after exit
|
||||||
|
func TestRunAutoRemove(t *testing.T) {
|
||||||
|
stdout, stdoutPipe := io.Pipe()
|
||||||
|
cli := NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||||
|
defer cleanup(globalRuntime)
|
||||||
|
|
||||||
|
c := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
defer close(c)
|
||||||
|
if err := cli.CmdRun("-rm", unitTestImageID, "hostname"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
var temporaryContainerID string
|
||||||
|
setTimeout(t, "Reading command output time out", 2*time.Second, func() {
|
||||||
|
cmdOutput, err := bufio.NewReader(stdout).ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
temporaryContainerID = cmdOutput
|
||||||
|
if err := closeWrap(stdout, stdoutPipe); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
setTimeout(t, "CmdRun timed out", 5*time.Second, func() {
|
||||||
|
<-c
|
||||||
|
})
|
||||||
|
|
||||||
|
time.Sleep(500 * time.Millisecond)
|
||||||
|
|
||||||
|
if len(globalRuntime.List()) > 0 {
|
||||||
|
t.Fatalf("failed to remove container automatically: container %s still exists", temporaryContainerID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
16
container.go
16
container.go
|
@ -90,6 +90,7 @@ type HostConfig struct {
|
||||||
Binds []string
|
Binds []string
|
||||||
ContainerIDFile string
|
ContainerIDFile string
|
||||||
LxcConf []KeyValuePair
|
LxcConf []KeyValuePair
|
||||||
|
AutoRemove bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type BindMap struct {
|
type BindMap struct {
|
||||||
|
@ -126,6 +127,7 @@ func ParseRun(args []string, capabilities *Capabilities) (*Config, *HostConfig,
|
||||||
flContainerIDFile := cmd.String("cidfile", "", "Write the container ID to the file")
|
flContainerIDFile := cmd.String("cidfile", "", "Write the container ID to the file")
|
||||||
flNetwork := cmd.Bool("n", true, "Enable networking for this container")
|
flNetwork := cmd.Bool("n", true, "Enable networking for this container")
|
||||||
flPrivileged := cmd.Bool("privileged", false, "Give extended privileges to this container")
|
flPrivileged := cmd.Bool("privileged", false, "Give extended privileges to this container")
|
||||||
|
flAutoRemove := cmd.Bool("rm", false, "Automatically remove the container when it exits (incompatible with -d)")
|
||||||
|
|
||||||
if capabilities != nil && *flMemory > 0 && !capabilities.MemoryLimit {
|
if capabilities != nil && *flMemory > 0 && !capabilities.MemoryLimit {
|
||||||
//fmt.Fprintf(stdout, "WARNING: Your kernel does not support memory limit capabilities. Limitation discarded.\n")
|
//fmt.Fprintf(stdout, "WARNING: Your kernel does not support memory limit capabilities. Limitation discarded.\n")
|
||||||
|
@ -174,6 +176,10 @@ func ParseRun(args []string, capabilities *Capabilities) (*Config, *HostConfig,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if *flDetach && *flAutoRemove {
|
||||||
|
return nil, nil, cmd, fmt.Errorf("Conflicting options: -rm and -d")
|
||||||
|
}
|
||||||
|
|
||||||
var binds []string
|
var binds []string
|
||||||
|
|
||||||
// add any bind targets to the list of container volumes
|
// add any bind targets to the list of container volumes
|
||||||
|
@ -242,6 +248,7 @@ func ParseRun(args []string, capabilities *Capabilities) (*Config, *HostConfig,
|
||||||
Binds: binds,
|
Binds: binds,
|
||||||
ContainerIDFile: *flContainerIDFile,
|
ContainerIDFile: *flContainerIDFile,
|
||||||
LxcConf: lxcConf,
|
LxcConf: lxcConf,
|
||||||
|
AutoRemove: *flAutoRemove,
|
||||||
}
|
}
|
||||||
|
|
||||||
if capabilities != nil && *flMemory > 0 && !capabilities.SwapLimit {
|
if capabilities != nil && *flMemory > 0 && !capabilities.SwapLimit {
|
||||||
|
@ -818,7 +825,7 @@ func (container *Container) Start(hostConfig *HostConfig) error {
|
||||||
|
|
||||||
container.ToDisk()
|
container.ToDisk()
|
||||||
container.SaveHostConfig(hostConfig)
|
container.SaveHostConfig(hostConfig)
|
||||||
go container.monitor()
|
go container.monitor(hostConfig)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -948,7 +955,7 @@ func (container *Container) waitLxc() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (container *Container) monitor() {
|
func (container *Container) monitor(hostConfig *HostConfig) {
|
||||||
// Wait for the program to exit
|
// Wait for the program to exit
|
||||||
utils.Debugf("Waiting for process")
|
utils.Debugf("Waiting for process")
|
||||||
|
|
||||||
|
@ -1018,6 +1025,11 @@ func (container *Container) monitor() {
|
||||||
// FIXME: why are we serializing running state to disk in the first place?
|
// FIXME: why are we serializing running state to disk in the first place?
|
||||||
//log.Printf("%s: Failed to dump configuration to the disk: %s", container.ID, err)
|
//log.Printf("%s: Failed to dump configuration to the disk: %s", container.ID, err)
|
||||||
}
|
}
|
||||||
|
if hostConfig != nil {
|
||||||
|
if hostConfig.AutoRemove {
|
||||||
|
container.runtime.Destroy(container)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (container *Container) kill() error {
|
func (container *Container) kill() error {
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
-m=0: Memory limit (in bytes)
|
-m=0: Memory limit (in bytes)
|
||||||
-n=true: Enable networking for this container
|
-n=true: Enable networking for this container
|
||||||
-p=[]: Map a network port to the container
|
-p=[]: Map a network port to the container
|
||||||
|
-rm=false: Automatically remove the container when it exits (incompatible with -d)
|
||||||
-t=false: Allocate a pseudo-tty
|
-t=false: Allocate a pseudo-tty
|
||||||
-u="": Username or UID
|
-u="": Username or UID
|
||||||
-dns=[]: Set custom dns servers for the container
|
-dns=[]: Set custom dns servers for the container
|
||||||
|
|
|
@ -174,7 +174,8 @@ func (runtime *Runtime) Register(container *Container) error {
|
||||||
close(container.waitLock)
|
close(container.waitLock)
|
||||||
} else if !nomonitor {
|
} else if !nomonitor {
|
||||||
container.allocateNetwork()
|
container.allocateNetwork()
|
||||||
go container.monitor()
|
// hostConfig isn't needed here and can be nil
|
||||||
|
go container.monitor(nil)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue