diff --git a/pkg/storage/runtime.go b/pkg/storage/runtime.go index 1074e717..c2e173a5 100644 --- a/pkg/storage/runtime.go +++ b/pkg/storage/runtime.go @@ -345,11 +345,11 @@ func (r *runtimeService) RemovePodSandbox(idOrName string) error { } func (r *runtimeService) DeleteContainer(idOrName string) error { + if idOrName == "" { + return ErrInvalidContainerID + } container, err := r.storageImageServer.GetStore().Container(idOrName) if err != nil { - if err == storage.ErrContainerUnknown { - return ErrInvalidContainerID - } return err } err = r.storageImageServer.GetStore().DeleteContainer(container.ID) @@ -403,11 +403,11 @@ func (r *runtimeService) StartContainer(idOrName string) (string, error) { } func (r *runtimeService) StopContainer(idOrName string) error { + if idOrName == "" { + return ErrInvalidContainerID + } container, err := r.storageImageServer.GetStore().Container(idOrName) if err != nil { - if err == storage.ErrContainerUnknown { - return ErrInvalidContainerID - } return err } err = r.storageImageServer.GetStore().Unmount(container.ID) diff --git a/server/sandbox_remove.go b/server/sandbox_remove.go index 6f23b9ed..09f2d054 100644 --- a/server/sandbox_remove.go +++ b/server/sandbox_remove.go @@ -5,6 +5,8 @@ import ( "syscall" "github.com/Sirupsen/logrus" + "github.com/containers/storage" + "github.com/docker/docker/pkg/mount" "github.com/kubernetes-incubator/cri-o/oci" "github.com/opencontainers/selinux/go-selinux/label" "golang.org/x/net/context" @@ -56,10 +58,11 @@ func (s *Server) RemovePodSandbox(ctx context.Context, req *pb.RemovePodSandboxR continue } - if err := s.storageRuntimeServer.StopContainer(c.ID()); err != nil { - return nil, fmt.Errorf("failed to delete container %s in pod sandbox %s: %v", c.Name(), sb.id, err) + if err := s.storageRuntimeServer.StopContainer(c.ID()); err != nil && err != storage.ErrContainerUnknown { + // assume container already umounted + logrus.Warnf("failed to stop container %s in pod sandbox %s: %v", c.Name(), sb.id, err) } - if err := s.storageRuntimeServer.DeleteContainer(c.ID()); err != nil { + if err := s.storageRuntimeServer.DeleteContainer(c.ID()); err != nil && err != storage.ErrContainerUnknown { return nil, fmt.Errorf("failed to delete container %s in pod sandbox %s: %v", c.Name(), sb.id, err) } @@ -76,8 +79,10 @@ func (s *Server) RemovePodSandbox(ctx context.Context, req *pb.RemovePodSandboxR // unmount the shm for the pod if sb.shmPath != "/dev/shm" { - if err := syscall.Unmount(sb.shmPath, syscall.MNT_DETACH); err != nil { - return nil, err + if mounted, err := mount.Mounted(sb.shmPath); err == nil && mounted { + if err := syscall.Unmount(sb.shmPath, syscall.MNT_DETACH); err != nil { + return nil, err + } } } @@ -89,7 +94,7 @@ func (s *Server) RemovePodSandbox(ctx context.Context, req *pb.RemovePodSandboxR // Remove the files related to the sandbox if err := s.storageRuntimeServer.StopContainer(sb.id); err != nil { - return nil, fmt.Errorf("failed to delete sandbox container in pod sandbox %s: %v", sb.id, err) + logrus.Warnf("failed to stop sandbox container in pod sandbox %s: %v", sb.id, err) } if err := s.storageRuntimeServer.RemovePodSandbox(sb.id); err != nil { return nil, fmt.Errorf("failed to remove pod sandbox %s: %v", sb.id, err) diff --git a/server/sandbox_run.go b/server/sandbox_run.go index 0f20b408..3320c54a 100644 --- a/server/sandbox_run.go +++ b/server/sandbox_run.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "path/filepath" + "regexp" "strconv" "strings" "syscall" @@ -66,6 +67,10 @@ func (s *Server) runContainer(container *oci.Container, cgroupParent string) err return nil } +var ( + conflictRE = regexp.MustCompile(`already reserved for pod "([0-9a-z]+)"`) +) + // RunPodSandbox creates and runs a pod-level sandbox. func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest) (resp *pb.RunPodSandboxResponse, err error) { s.updateLock.RLock() @@ -84,7 +89,22 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest id, name, err := s.generatePodIDandName(kubeName, namespace, attempt) if err != nil { - return nil, err + if strings.Contains(err.Error(), "already reserved for pod") { + matches := conflictRE.FindStringSubmatch(err.Error()) + if len(matches) != 2 { + return nil, err + } + dupID := matches[1] + if _, err := s.RemovePodSandbox(ctx, &pb.RemovePodSandboxRequest{PodSandboxId: dupID}); err != nil { + return nil, err + } + id, name, err = s.generatePodIDandName(kubeName, namespace, attempt) + if err != nil { + return nil, err + } + } else { + return nil, err + } } _, containerName, err := s.generateContainerIDandName(name, "infra", attempt) if err != nil {