summaryrefslogtreecommitdiff
path: root/plugin/executor
diff options
context:
space:
mode:
authorBrian Goff <cpuguy83@gmail.com>2018-04-20 10:48:54 -0400
committerKir Kolyshkin <kolyshkin@gmail.com>2018-06-07 17:27:02 -0700
commitdbeb4329655e91dbe0e6574405937f03fabf3f2f (patch)
tree1726dd63bea30903ac8900eeff6645cea9173331 /plugin/executor
parentd47c45175b13e97475649dfe8b1ab1034c4865d0 (diff)
downloaddocker-dbeb4329655e91dbe0e6574405937f03fabf3f2f.tar.gz
Fix panic on daemon restart with running plugin
Scenario: Daemon is ungracefully shutdown and leaves plugins running (no live-restore). Daemon comes back up. The next time a container tries to use that plugin it will cause a daemon panic because the plugin client is not set. This fixes that by ensuring that the plugin does get shutdown. Note, I do not think there would be any harm in just re-attaching to the running plugin instead of shutting it down, however historically we shut down plugins and containers when live-restore is not enabled. [kir@: consolidate code to deleteTaskAndContainer, a few minor nits] Signed-off-by: Brian Goff <cpuguy83@gmail.com> Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Diffstat (limited to 'plugin/executor')
-rw-r--r--plugin/executor/containerd/containerd.go45
1 files changed, 19 insertions, 26 deletions
diff --git a/plugin/executor/containerd/containerd.go b/plugin/executor/containerd/containerd.go
index e490ef0a9e..e0267582ec 100644
--- a/plugin/executor/containerd/containerd.go
+++ b/plugin/executor/containerd/containerd.go
@@ -58,6 +58,19 @@ type Executor struct {
exitHandler ExitHandler
}
+// deleteTaskAndContainer deletes plugin task and then plugin container from containerd
+func deleteTaskAndContainer(ctx context.Context, cli Client, id string) {
+ _, _, err := cli.DeleteTask(ctx, id)
+ if err != nil && !errdefs.IsNotFound(err) {
+ logrus.WithError(err).WithField("id", id).Error("failed to delete plugin task from containerd")
+ }
+
+ err = cli.Delete(ctx, id)
+ if err != nil && !errdefs.IsNotFound(err) {
+ logrus.WithError(err).WithField("id", id).Error("failed to delete plugin container from containerd")
+ }
+}
+
// Create creates a new container
func (e *Executor) Create(id string, spec specs.Spec, stdout, stderr io.WriteCloser) error {
opts := runctypes.RuncOptions{
@@ -87,34 +100,21 @@ func (e *Executor) Create(id string, spec specs.Spec, stdout, stderr io.WriteClo
_, err = e.client.Start(ctx, id, "", false, attachStreamsFunc(stdout, stderr))
if err != nil {
- if _, _, err2 := e.client.DeleteTask(ctx, id); err2 != nil && !errdefs.IsNotFound(err2) {
- logrus.WithError(err2).WithField("id", id).Warn("Received an error while attempting to clean up containerd plugin task after failed start")
- }
- if err2 := e.client.Delete(ctx, id); err2 != nil && !errdefs.IsNotFound(err2) {
- logrus.WithError(err2).WithField("id", id).Warn("Received an error while attempting to clean up containerd plugin container after failed start")
- }
+ deleteTaskAndContainer(ctx, e.client, id)
}
return err
}
// Restore restores a container
-func (e *Executor) Restore(id string, stdout, stderr io.WriteCloser) error {
+func (e *Executor) Restore(id string, stdout, stderr io.WriteCloser) (bool, error) {
alive, _, err := e.client.Restore(context.Background(), id, attachStreamsFunc(stdout, stderr))
if err != nil && !errdefs.IsNotFound(err) {
- return err
+ return false, err
}
if !alive {
- _, _, err = e.client.DeleteTask(context.Background(), id)
- if err != nil && !errdefs.IsNotFound(err) {
- logrus.WithError(err).Errorf("failed to delete container plugin %s task from containerd", id)
- }
-
- err = e.client.Delete(context.Background(), id)
- if err != nil && !errdefs.IsNotFound(err) {
- logrus.WithError(err).Errorf("failed to delete container plugin %s from containerd", id)
- }
+ deleteTaskAndContainer(context.Background(), e.client, id)
}
- return nil
+ return alive, nil
}
// IsRunning returns if the container with the given id is running
@@ -133,14 +133,7 @@ func (e *Executor) Signal(id string, signal int) error {
func (e *Executor) ProcessEvent(id string, et libcontainerd.EventType, ei libcontainerd.EventInfo) error {
switch et {
case libcontainerd.EventExit:
- // delete task and container
- if _, _, err := e.client.DeleteTask(context.Background(), id); err != nil {
- logrus.WithError(err).Errorf("failed to delete container plugin %s task from containerd", id)
- }
-
- if err := e.client.Delete(context.Background(), id); err != nil {
- logrus.WithError(err).Errorf("failed to delete container plugin %s from containerd", id)
- }
+ deleteTaskAndContainer(context.Background(), e.client, id)
return e.exitHandler.HandleExitEvent(ei.ContainerID)
}
return nil