2021-01-19 10:15:58 +08:00
|
|
|
From 5ba30cd1dc6000ee53b34f628cbff91d7f6d7231 Mon Sep 17 00:00:00 2001
|
|
|
|
|
From: Brian Goff <cpuguy83@gmail.com>
|
|
|
|
|
Date: Wed, 12 Dec 2018 12:04:09 -0800
|
|
|
|
|
Subject: [PATCH] Delete stale containerd object on start failure
|
2020-03-17 10:42:12 +08:00
|
|
|
|
|
|
|
|
containerd has two objects with regard to containers.
|
2021-01-19 10:15:58 +08:00
|
|
|
There is a "container" object which is metadata and a "task" which is
|
2020-03-17 10:42:12 +08:00
|
|
|
manging the actual runtime state.
|
|
|
|
|
|
2021-01-19 10:15:58 +08:00
|
|
|
When docker starts a container, it creartes both the container metadata
|
|
|
|
|
and the task at the same time. So when a container exits, docker deletes
|
2020-03-17 10:42:12 +08:00
|
|
|
both of these objects as well.
|
|
|
|
|
|
|
|
|
|
This ensures that if, on start, when we go to create the container metadata object
|
2021-01-19 10:15:58 +08:00
|
|
|
in containerd, if there is an error due to a name conflict that we go
|
2020-03-17 10:42:12 +08:00
|
|
|
ahead and clean that up and try again.
|
|
|
|
|
|
2021-01-19 10:15:58 +08:00
|
|
|
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
|
2020-03-17 10:42:12 +08:00
|
|
|
---
|
|
|
|
|
components/engine/daemon/start.go | 17 +++++++++++++++--
|
|
|
|
|
1 file changed, 15 insertions(+), 2 deletions(-)
|
|
|
|
|
|
|
|
|
|
diff --git a/components/engine/daemon/start.go b/components/engine/daemon/start.go
|
2021-01-19 10:15:58 +08:00
|
|
|
index 393e00b..57a7267 100644
|
2020-03-17 10:42:12 +08:00
|
|
|
--- a/components/engine/daemon/start.go
|
|
|
|
|
+++ b/components/engine/daemon/start.go
|
2021-01-19 10:15:58 +08:00
|
|
|
@@ -177,9 +177,22 @@ func (daemon *Daemon) containerStart(container *container.Container, checkpoint
|
2020-03-17 10:42:12 +08:00
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- err = daemon.containerd.Create(context.Background(), container.ID, spec, createOptions)
|
|
|
|
|
+ ctx := context.TODO()
|
|
|
|
|
+
|
|
|
|
|
+ err = daemon.containerd.Create(ctx, container.ID, spec, createOptions)
|
|
|
|
|
if err != nil {
|
|
|
|
|
- return translateContainerdStartErr(container.Path, container.SetExitCode, err)
|
|
|
|
|
+ if errdefs.IsConflict(err) {
|
|
|
|
|
+ logrus.WithError(err).WithField("container", container.ID).Error("Container not cleaned up from containerd from previous run")
|
|
|
|
|
+ // best effort to clean up old container object
|
|
|
|
|
+ daemon.containerd.DeleteTask(ctx, container.ID)
|
|
|
|
|
+ if err := daemon.containerd.Delete(ctx, container.ID); err != nil && !errdefs.IsNotFound(err) {
|
|
|
|
|
+ logrus.WithError(err).WithField("container", container.ID).Error("Error cleaning up stale containerd container object")
|
|
|
|
|
+ }
|
|
|
|
|
+ err = daemon.containerd.Create(ctx, container.ID, spec, createOptions)
|
|
|
|
|
+ }
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return translateContainerdStartErr(container.Path, container.SetExitCode, err)
|
|
|
|
|
+ }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO(mlaventure): we need to specify checkpoint options here
|
|
|
|
|
--
|
|
|
|
|
1.8.3.1
|
|
|
|
|
|