From 40891c5fdcb49faf0778c29eff1dc1a1220a9f63 Mon Sep 17 00:00:00 2001 From: Sunny Date: Sun, 14 Mar 2021 00:39:20 +0530 Subject: [PATCH 1/2] rm: Handle error when container not found When removing a VM with force, if the container runtime returns error when it can't find the associated VM container, the force remove fails. With this change, ignite will checks if the container runtime error is about container not found and return without any error, no-op, letting the force remove succeed. The behavior remains the same for non-forced remove. --- pkg/runtime/containerd/client.go | 10 ++++++++++ pkg/runtime/docker/client.go | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/pkg/runtime/containerd/client.go b/pkg/runtime/containerd/client.go index 3e2f7da88..bd2bf7332 100644 --- a/pkg/runtime/containerd/client.go +++ b/pkg/runtime/containerd/client.go @@ -639,11 +639,21 @@ func (cc *ctdClient) StopContainer(container string, timeout *time.Duration) (er func (cc *ctdClient) KillContainer(container, signal string) (err error) { cont, err := cc.client.LoadContainer(cc.ctx, container) if err != nil { + // If the container is not found, return nil, no-op. + if errdefs.IsNotFound(err) { + log.Warn(err) + err = nil + } return } task, err := cont.Task(cc.ctx, cio.Load) if err != nil { + // If the task is not found, return nil, no-op. + if errdefs.IsNotFound(err) { + log.Warn(err) + err = nil + } return } diff --git a/pkg/runtime/docker/client.go b/pkg/runtime/docker/client.go index ced109fe8..f401bb5cc 100644 --- a/pkg/runtime/docker/client.go +++ b/pkg/runtime/docker/client.go @@ -12,6 +12,8 @@ import ( "github.com/docker/docker/api/types/container" cont "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" + "github.com/docker/docker/errdefs" + log "github.com/sirupsen/logrus" meta "github.com/weaveworks/ignite/pkg/apis/meta/v1alpha1" "github.com/weaveworks/ignite/pkg/preflight" "github.com/weaveworks/ignite/pkg/preflight/checkers" @@ -199,6 +201,11 @@ func (dc *dockerClient) KillContainer(container, signal string) error { <-readyC // wait until removal detection has started if err := dc.client.ContainerKill(context.Background(), container, signal); err != nil { + // If the container is not found, return nil, no-op. + if errdefs.IsNotFound(err) { + log.Warn(err) + return nil + } return err } From 6de3da129b29e3442fc05afa337348d4f53596c3 Mon Sep 17 00:00:00 2001 From: Sunny Date: Sun, 14 Mar 2021 01:52:45 +0530 Subject: [PATCH 2/2] Add container not found check in stop & remove Add error checks in StopContainer() and RemoveContainer() to return nil when the container is not found. This helps avoid failure when VM stop or remove is executed and the containers don't exist anymore, resulting in no-op and a successful stop and remove execution. --- pkg/runtime/containerd/client.go | 10 ++++++++++ pkg/runtime/docker/client.go | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/pkg/runtime/containerd/client.go b/pkg/runtime/containerd/client.go index bd2bf7332..159cf26b7 100644 --- a/pkg/runtime/containerd/client.go +++ b/pkg/runtime/containerd/client.go @@ -574,6 +574,11 @@ func withDevices(devices []*runtime.Bind) oci.SpecOpts { func (cc *ctdClient) StopContainer(container string, timeout *time.Duration) (err error) { cont, err := cc.client.LoadContainer(cc.ctx, container) if err != nil { + // If the container is not found, return nil, no-op. + if errdefs.IsNotFound(err) { + log.Warn(err) + err = nil + } return } @@ -596,6 +601,11 @@ func (cc *ctdClient) StopContainer(container string, timeout *time.Duration) (er task, err := cont.Task(cc.ctx, cio.Load) if err != nil { + // If the task is not found, return nil, no-op. + if errdefs.IsNotFound(err) { + log.Warn(err) + err = nil + } return } diff --git a/pkg/runtime/docker/client.go b/pkg/runtime/docker/client.go index f401bb5cc..4f7ae2edf 100644 --- a/pkg/runtime/docker/client.go +++ b/pkg/runtime/docker/client.go @@ -185,6 +185,11 @@ func (dc *dockerClient) StopContainer(container string, timeout *time.Duration) <-readyC // wait until removal detection has started if err := dc.client.ContainerStop(context.Background(), container, timeout); err != nil { + // If the container is not found, return nil, no-op. + if errdefs.IsNotFound(err) { + log.Warn(err) + return nil + } return err } @@ -225,6 +230,11 @@ func (dc *dockerClient) RemoveContainer(container string) error { <-readyC // The ready channel is used to wait until removal detection has started if err := dc.client.ContainerRemove(context.Background(), container, types.ContainerRemoveOptions{}); err != nil { + // If the container is not found, return nil, no-op. + if errdefs.IsNotFound(err) { + log.Warn(err) + return nil + } return err }