mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #35805 from cpuguy83/fix_kill_containers_on_restart
Ensure containers are stopped on daemon startup
This commit is contained in:
commit
c3a9f5d00f
2 changed files with 134 additions and 17 deletions
|
@ -247,6 +247,11 @@ func (daemon *Daemon) restore() error {
|
|||
logrus.WithError(err).Errorf("Failed to delete container %s from containerd", c.ID)
|
||||
return
|
||||
}
|
||||
} else if !daemon.configStore.LiveRestoreEnabled {
|
||||
if err := daemon.kill(c, c.StopSignal()); err != nil && !errdefs.IsNotFound(err) {
|
||||
logrus.WithError(err).WithField("container", c.ID).Error("error shutting down container")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if c.IsRunning() || c.IsPaused() {
|
||||
|
@ -317,24 +322,24 @@ func (daemon *Daemon) restore() error {
|
|||
activeSandboxes[c.NetworkSettings.SandboxID] = options
|
||||
mapLock.Unlock()
|
||||
}
|
||||
} else {
|
||||
// get list of containers we need to restart
|
||||
}
|
||||
|
||||
// Do not autostart containers which
|
||||
// has endpoints in a swarm scope
|
||||
// network yet since the cluster is
|
||||
// not initialized yet. We will start
|
||||
// it after the cluster is
|
||||
// initialized.
|
||||
if daemon.configStore.AutoRestart && c.ShouldRestart() && !c.NetworkSettings.HasSwarmEndpoint {
|
||||
mapLock.Lock()
|
||||
restartContainers[c] = make(chan struct{})
|
||||
mapLock.Unlock()
|
||||
} else if c.HostConfig != nil && c.HostConfig.AutoRemove {
|
||||
mapLock.Lock()
|
||||
removeContainers[c.ID] = c
|
||||
mapLock.Unlock()
|
||||
}
|
||||
// get list of containers we need to restart
|
||||
|
||||
// Do not autostart containers which
|
||||
// has endpoints in a swarm scope
|
||||
// network yet since the cluster is
|
||||
// not initialized yet. We will start
|
||||
// it after the cluster is
|
||||
// initialized.
|
||||
if daemon.configStore.AutoRestart && c.ShouldRestart() && !c.NetworkSettings.HasSwarmEndpoint {
|
||||
mapLock.Lock()
|
||||
restartContainers[c] = make(chan struct{})
|
||||
mapLock.Unlock()
|
||||
} else if c.HostConfig != nil && c.HostConfig.AutoRemove {
|
||||
mapLock.Lock()
|
||||
removeContainers[c.ID] = c
|
||||
mapLock.Unlock()
|
||||
}
|
||||
|
||||
c.Lock()
|
||||
|
|
112
integration/container/restart_test.go
Normal file
112
integration/container/restart_test.go
Normal file
|
@ -0,0 +1,112 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/integration-cli/daemon"
|
||||
)
|
||||
|
||||
func TestDaemonRestartKillContainers(t *testing.T) {
|
||||
type testCase struct {
|
||||
desc string
|
||||
config *container.Config
|
||||
hostConfig *container.HostConfig
|
||||
|
||||
xRunning bool
|
||||
xRunningLiveRestore bool
|
||||
}
|
||||
|
||||
for _, c := range []testCase{
|
||||
{
|
||||
desc: "container without restart policy",
|
||||
config: &container.Config{Image: "busybox", Cmd: []string{"top"}},
|
||||
xRunningLiveRestore: true,
|
||||
},
|
||||
{
|
||||
desc: "container with restart=always",
|
||||
config: &container.Config{Image: "busybox", Cmd: []string{"top"}},
|
||||
hostConfig: &container.HostConfig{RestartPolicy: container.RestartPolicy{Name: "always"}},
|
||||
xRunning: true,
|
||||
xRunningLiveRestore: true,
|
||||
},
|
||||
} {
|
||||
for _, liveRestoreEnabled := range []bool{false, true} {
|
||||
for fnName, stopDaemon := range map[string]func(*testing.T, *daemon.Daemon){
|
||||
"kill-daemon": func(t *testing.T, d *daemon.Daemon) {
|
||||
if err := d.Kill(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
},
|
||||
"stop-daemon": func(t *testing.T, d *daemon.Daemon) {
|
||||
d.Stop(t)
|
||||
},
|
||||
} {
|
||||
t.Run(fmt.Sprintf("live-restore=%v/%s/%s", liveRestoreEnabled, c.desc, fnName), func(t *testing.T) {
|
||||
c := c
|
||||
liveRestoreEnabled := liveRestoreEnabled
|
||||
stopDaemon := stopDaemon
|
||||
|
||||
t.Parallel()
|
||||
|
||||
d := daemon.New(t, "", "dockerd", daemon.Config{})
|
||||
client, err := d.NewClient()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var args []string
|
||||
if liveRestoreEnabled {
|
||||
args = []string{"--live-restore"}
|
||||
}
|
||||
|
||||
d.StartWithBusybox(t, args...)
|
||||
defer d.Stop(t)
|
||||
ctx := context.Background()
|
||||
|
||||
resp, err := client.ContainerCreate(ctx, c.config, c.hostConfig, nil, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer client.ContainerRemove(ctx, resp.ID, types.ContainerRemoveOptions{Force: true})
|
||||
|
||||
if err := client.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
stopDaemon(t, d)
|
||||
d.Start(t, args...)
|
||||
|
||||
expected := c.xRunning
|
||||
if liveRestoreEnabled {
|
||||
expected = c.xRunningLiveRestore
|
||||
}
|
||||
|
||||
var running bool
|
||||
for i := 0; i < 30; i++ {
|
||||
inspect, err := client.ContainerInspect(ctx, resp.ID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
running = inspect.State.Running
|
||||
if running == expected {
|
||||
break
|
||||
}
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
}
|
||||
|
||||
if running != expected {
|
||||
t.Fatalf("got unexpected running state, expected %v, got: %v", expected, running)
|
||||
}
|
||||
// TODO(cpuguy83): test pause states... this seems to be rather undefined currently
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue