diff --git a/vendor.conf b/vendor.conf index 3a1025f02..dbc3eecd9 100644 --- a/vendor.conf +++ b/vendor.conf @@ -43,8 +43,8 @@ github.com/google/go-cmp v0.1.0 go.etcd.io/bbolt v1.3.1-etcd.8 # cri dependencies -github.com/containerd/cri 8506fe836677cc3bb23a16b68145128243d843b5 # release/1.2 branch -github.com/containerd/go-cni 6d7b509a054a3cb1c35ed1865d4fde2f0cb547cd +github.com/containerd/cri f913714917d2456d7e65a0be84962b1ce8acb487 # release/1.2 branch +github.com/containerd/go-cni 40bcf8ec8acd7372be1d77031d585d5d8e561c90 github.com/blang/semver v3.1.0 github.com/containernetworking/cni v0.6.0 github.com/containernetworking/plugins v0.7.0 diff --git a/vendor/github.com/containerd/cri/pkg/config/config.go b/vendor/github.com/containerd/cri/pkg/config/config.go index 7fa993c85..7d53a7b53 100644 --- a/vendor/github.com/containerd/cri/pkg/config/config.go +++ b/vendor/github.com/containerd/cri/pkg/config/config.go @@ -16,7 +16,10 @@ limitations under the License. package config -import "github.com/containerd/containerd" +import ( + "github.com/BurntSushi/toml" + "github.com/containerd/containerd" +) // Runtime struct to contain the type(ID), engine, and root variables for a default runtime // and a runtime for untrusted worload. @@ -24,9 +27,16 @@ type Runtime struct { // Type is the runtime type to use in containerd e.g. io.containerd.runtime.v1.linux Type string `toml:"runtime_type" json:"runtimeType"` // Engine is the name of the runtime engine used by containerd. + // This only works for runtime type "io.containerd.runtime.v1.linux". + // DEPRECATED: use Options instead. Remove when shim v1 is deprecated. Engine string `toml:"runtime_engine" json:"runtimeEngine"` // Root is the directory used by containerd for runtime state. + // DEPRECATED: use Options instead. Remove when shim v1 is deprecated. + // This only works for runtime type "io.containerd.runtime.v1.linux". Root string `toml:"runtime_root" json:"runtimeRoot"` + // Options are config options for the runtime. If options is loaded + // from toml config, it will be toml.Primitive. + Options *toml.Primitive `toml:"options" json:"options"` } // ContainerdConfig contains toml config related to containerd @@ -46,6 +56,8 @@ type ContainerdConfig struct { // configurations, to the matching configurations. Runtimes map[string]Runtime `toml:"runtimes" json:"runtimes"` // NoPivot disables pivot-root (linux only), required when running a container in a RamDisk with runc + // This only works for runtime type "io.containerd.runtime.v1.linux". + // DEPRECATED: use Runtime.Options instead. Remove when shim v1 is deprecated. NoPivot bool `toml:"no_pivot" json:"noPivot"` } @@ -119,6 +131,8 @@ type PluginConfig struct { // StatsCollectPeriod is the period (in seconds) of snapshots stats collection. StatsCollectPeriod int `toml:"stats_collect_period" json:"statsCollectPeriod"` // SystemdCgroup enables systemd cgroup support. + // This only works for runtime type "io.containerd.runtime.v1.linux". + // DEPRECATED: config runc runtime handler instead. Remove when shim v1 is deprecated. SystemdCgroup bool `toml:"systemd_cgroup" json:"systemdCgroup"` // EnableTLSStreaming indicates to enable the TLS streaming support. EnableTLSStreaming bool `toml:"enable_tls_streaming" json:"enableTLSStreaming"` diff --git a/vendor/github.com/containerd/cri/pkg/server/container_create.go b/vendor/github.com/containerd/cri/pkg/server/container_create.go index 5911c9075..e29cb40f8 100644 --- a/vendor/github.com/containerd/cri/pkg/server/container_create.go +++ b/vendor/github.com/containerd/cri/pkg/server/container_create.go @@ -30,7 +30,6 @@ import ( "github.com/containerd/containerd/contrib/seccomp" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/oci" - "github.com/containerd/containerd/runtime/linux/runctypes" "github.com/containerd/typeurl" "github.com/davecgh/go-spew/spew" imagespec "github.com/opencontainers/image-spec/specs-go/v1" @@ -125,11 +124,6 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta if err != nil { return nil, errors.Wrapf(err, "failed to get sandbox %q info", sandboxID) } - ociRuntime, err := getRuntimeConfigFromContainerInfo(sandboxInfo) - if err != nil { - return nil, errors.Wrap(err, "failed to get OCI runtime") - } - logrus.Debugf("Use OCI %+v for container %q", ociRuntime, id) // Create container root directory. containerRootDir := c.getContainerRootDir(id) @@ -261,14 +255,13 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta } containerLabels := buildLabels(config.Labels, containerKindContainer) + runtimeOptions, err := getRuntimeOptions(sandboxInfo) + if err != nil { + return nil, errors.Wrap(err, "failed to get runtime options") + } opts = append(opts, containerd.WithSpec(spec, specOpts...), - containerd.WithRuntime( - ociRuntime.Type, - &runctypes.RuncOptions{ - Runtime: ociRuntime.Engine, - RuntimeRoot: ociRuntime.Root, - SystemdCgroup: c.config.SystemdCgroup}), // TODO (mikebrow): add CriuPath when we add support for pause + containerd.WithRuntime(sandboxInfo.Runtime.Name, runtimeOptions), containerd.WithContainerLabels(containerLabels), containerd.WithContainerExtension(containerMetadataExtension, &meta)) var cntr containerd.Container diff --git a/vendor/github.com/containerd/cri/pkg/server/container_start.go b/vendor/github.com/containerd/cri/pkg/server/container_start.go index a4467c4bd..59fa5ed69 100644 --- a/vendor/github.com/containerd/cri/pkg/server/container_start.go +++ b/vendor/github.com/containerd/cri/pkg/server/container_start.go @@ -108,8 +108,14 @@ func (c *criService) startContainer(ctx context.Context, return cntr.IO, nil } + ctrInfo, err := container.Info(ctx) + if err != nil { + return errors.Wrap(err, "failed to get container info") + } + var taskOpts []containerd.NewTaskOpts - if c.config.NoPivot { + // TODO(random-liu): Remove this after shim v1 is deprecated. + if c.config.NoPivot && ctrInfo.Runtime.Name == linuxRuntime { taskOpts = append(taskOpts, containerd.WithNoPivotRoot) } task, err := container.NewTask(ctx, ioCreation, taskOpts...) diff --git a/vendor/github.com/containerd/cri/pkg/server/container_status.go b/vendor/github.com/containerd/cri/pkg/server/container_status.go index bacf02132..a02454690 100644 --- a/vendor/github.com/containerd/cri/pkg/server/container_status.go +++ b/vendor/github.com/containerd/cri/pkg/server/container_status.go @@ -24,7 +24,6 @@ import ( "golang.org/x/net/context" runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" - criconfig "github.com/containerd/cri/pkg/config" containerstore "github.com/containerd/cri/pkg/store/container" ) @@ -100,16 +99,18 @@ func toCRIContainerStatus(container containerstore.Container, spec *runtime.Imag } } -type containerInfo struct { +// ContainerInfo is extra information for a container. +type ContainerInfo struct { // TODO(random-liu): Add sandboxID in CRI container status. - SandboxID string `json:"sandboxID"` - Pid uint32 `json:"pid"` - Removing bool `json:"removing"` - SnapshotKey string `json:"snapshotKey"` - Snapshotter string `json:"snapshotter"` - Runtime *criconfig.Runtime `json:"runtime"` - Config *runtime.ContainerConfig `json:"config"` - RuntimeSpec *runtimespec.Spec `json:"runtimeSpec"` + SandboxID string `json:"sandboxID"` + Pid uint32 `json:"pid"` + Removing bool `json:"removing"` + SnapshotKey string `json:"snapshotKey"` + Snapshotter string `json:"snapshotter"` + RuntimeType string `json:"runtimeType"` + RuntimeOptions interface{} `json:"runtimeOptions"` + Config *runtime.ContainerConfig `json:"config"` + RuntimeSpec *runtimespec.Spec `json:"runtimeSpec"` } // toCRIContainerInfo converts internal container object information to CRI container status response info map. @@ -122,7 +123,7 @@ func toCRIContainerInfo(ctx context.Context, container containerstore.Container, status := container.Status.Get() // TODO(random-liu): Change CRI status info to use array instead of map. - ci := &containerInfo{ + ci := &ContainerInfo{ SandboxID: container.SandboxID, Pid: status.Pid, Removing: status.Removing, @@ -142,11 +143,12 @@ func toCRIContainerInfo(ctx context.Context, container containerstore.Container, ci.SnapshotKey = ctrInfo.SnapshotKey ci.Snapshotter = ctrInfo.Snapshotter - ociRuntime, err := getRuntimeConfigFromContainerInfo(ctrInfo) + runtimeOptions, err := getRuntimeOptions(ctrInfo) if err != nil { - return nil, errors.Wrap(err, "failed to get container runtime config") + return nil, errors.Wrap(err, "failed to get runtime options") } - ci.Runtime = &ociRuntime + ci.RuntimeType = ctrInfo.Runtime.Name + ci.RuntimeOptions = runtimeOptions infoBytes, err := json.Marshal(ci) if err != nil { diff --git a/vendor/github.com/containerd/cri/pkg/server/helpers.go b/vendor/github.com/containerd/cri/pkg/server/helpers.go index d11918685..9b2744c94 100644 --- a/vendor/github.com/containerd/cri/pkg/server/helpers.go +++ b/vendor/github.com/containerd/cri/pkg/server/helpers.go @@ -25,8 +25,10 @@ import ( "strconv" "strings" + "github.com/BurntSushi/toml" "github.com/containerd/containerd/containers" "github.com/containerd/containerd/runtime/linux/runctypes" + runcoptions "github.com/containerd/containerd/runtime/v2/runc/options" "github.com/containerd/typeurl" "github.com/docker/distribution/reference" imagedigest "github.com/opencontainers/go-digest" @@ -123,6 +125,14 @@ const ( networkAttachCount = 2 ) +// Runtime type strings for various runtimes. +const ( + // linuxRuntime is the legacy linux runtime for shim v1. + linuxRuntime = "io.containerd.runtime.v1.linux" + // runcRuntime is the runc runtime for shim v2. + runcRuntime = "io.containerd.runc.v1" +) + // makeSandboxName generates sandbox name from sandbox metadata. The name // generated is unique as long as sandbox metadata is unique. func makeSandboxName(s *runtime.PodSandboxMetadata) string { @@ -390,26 +400,6 @@ func getPodCNILabels(id string, config *runtime.PodSandboxConfig) map[string]str } } -// getRuntimeConfigFromContainerInfo gets runtime configuration from containerd -// container info. -func getRuntimeConfigFromContainerInfo(c containers.Container) (criconfig.Runtime, error) { - r := criconfig.Runtime{ - Type: c.Runtime.Name, - } - if c.Runtime.Options == nil { - // CRI plugin makes sure that runtime option is always set. - return criconfig.Runtime{}, errors.New("runtime options is nil") - } - data, err := typeurl.UnmarshalAny(c.Runtime.Options) - if err != nil { - return criconfig.Runtime{}, errors.Wrap(err, "failed to unmarshal runtime options") - } - runtimeOpts := data.(*runctypes.RuncOptions) - r.Engine = runtimeOpts.Runtime - r.Root = runtimeOpts.RuntimeRoot - return r, nil -} - // toRuntimeAuthConfig converts cri plugin auth config to runtime auth config. func toRuntimeAuthConfig(a criconfig.AuthConfig) *runtime.AuthConfig { return &runtime.AuthConfig{ @@ -464,3 +454,45 @@ func parseImageReferences(refs []string) ([]string, []string) { } return tags, digests } + +// generateRuntimeOptions generates runtime options from cri plugin config. +func generateRuntimeOptions(r criconfig.Runtime, c criconfig.Config) (interface{}, error) { + if r.Options == nil { + if r.Type != linuxRuntime { + return nil, nil + } + // This is a legacy config, generate runctypes.RuncOptions. + return &runctypes.RuncOptions{ + Runtime: r.Engine, + RuntimeRoot: r.Root, + SystemdCgroup: c.SystemdCgroup, + }, nil + } + options := getRuntimeOptionsType(r.Type) + if err := toml.PrimitiveDecode(*r.Options, options); err != nil { + return nil, err + } + return options, nil +} + +// getRuntimeOptionsType gets empty runtime options by the runtime type name. +func getRuntimeOptionsType(t string) interface{} { + switch t { + case runcRuntime: + return &runcoptions.Options{} + default: + return &runctypes.RuncOptions{} + } +} + +// getRuntimeOptions get runtime options from container metadata. +func getRuntimeOptions(c containers.Container) (interface{}, error) { + if c.Runtime.Options == nil { + return nil, nil + } + opts, err := typeurl.UnmarshalAny(c.Runtime.Options) + if err != nil { + return nil, err + } + return opts, nil +} diff --git a/vendor/github.com/containerd/cri/pkg/server/image_pull.go b/vendor/github.com/containerd/cri/pkg/server/image_pull.go index cb66f138a..3461b493a 100644 --- a/vendor/github.com/containerd/cri/pkg/server/image_pull.go +++ b/vendor/github.com/containerd/cri/pkg/server/image_pull.go @@ -261,9 +261,9 @@ func (c *criService) getResolver(ctx context.Context, ref string, cred func(stri return nil, imagespec.Descriptor{}, errors.Wrapf(err, "parse registry endpoint %q", e) } resolver := docker.NewResolver(docker.ResolverOptions{ - Credentials: cred, - Client: http.DefaultClient, - Host: func(string) (string, error) { return u.Host, nil }, + Authorizer: docker.NewAuthorizer(http.DefaultClient, cred), + Client: http.DefaultClient, + Host: func(string) (string, error) { return u.Host, nil }, // By default use "https". PlainHTTP: u.Scheme == "http", }) diff --git a/vendor/github.com/containerd/cri/pkg/server/sandbox_run.go b/vendor/github.com/containerd/cri/pkg/server/sandbox_run.go index f4a8dd630..959a51898 100644 --- a/vendor/github.com/containerd/cri/pkg/server/sandbox_run.go +++ b/vendor/github.com/containerd/cri/pkg/server/sandbox_run.go @@ -25,7 +25,6 @@ import ( containerdio "github.com/containerd/containerd/cio" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/oci" - "github.com/containerd/containerd/runtime/linux/runctypes" cni "github.com/containerd/go-cni" "github.com/containerd/typeurl" imagespec "github.com/opencontainers/image-spec/specs-go/v1" @@ -171,18 +170,17 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox sandboxLabels := buildLabels(config.Labels, containerKindSandbox) + runtimeOpts, err := generateRuntimeOptions(ociRuntime, c.config) + if err != nil { + return nil, errors.Wrap(err, "failed to generate runtime options") + } opts := []containerd.NewContainerOpts{ containerd.WithSnapshotter(c.config.ContainerdConfig.Snapshotter), customopts.WithNewSnapshot(id, image.Image), containerd.WithSpec(spec, specOpts...), containerd.WithContainerLabels(sandboxLabels), containerd.WithContainerExtension(sandboxMetadataExtension, &sandbox.Metadata), - containerd.WithRuntime( - ociRuntime.Type, - &runctypes.RuncOptions{ - Runtime: ociRuntime.Engine, - RuntimeRoot: ociRuntime.Root, - SystemdCgroup: c.config.SystemdCgroup})} // TODO (mikebrow): add CriuPath when we add support for pause + containerd.WithRuntime(ociRuntime.Type, runtimeOpts)} container, err := c.client.NewContainer(ctx, id, opts...) if err != nil { @@ -296,7 +294,8 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox id, name) var taskOpts []containerd.NewTaskOpts - if c.config.NoPivot { + // TODO(random-liu): Remove this after shim v1 is deprecated. + if c.config.NoPivot && ociRuntime.Type == linuxRuntime { taskOpts = append(taskOpts, containerd.WithNoPivotRoot) } // We don't need stdio for sandbox container. diff --git a/vendor/github.com/containerd/cri/pkg/server/sandbox_status.go b/vendor/github.com/containerd/cri/pkg/server/sandbox_status.go index 8c3ab3f05..7965a1a3f 100644 --- a/vendor/github.com/containerd/cri/pkg/server/sandbox_status.go +++ b/vendor/github.com/containerd/cri/pkg/server/sandbox_status.go @@ -26,7 +26,6 @@ import ( "golang.org/x/net/context" runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" - criconfig "github.com/containerd/cri/pkg/config" sandboxstore "github.com/containerd/cri/pkg/store/sandbox" ) @@ -100,8 +99,9 @@ func toCRISandboxStatus(meta sandboxstore.Metadata, status sandboxstore.Status, } } +// SandboxInfo is extra information for sandbox. // TODO (mikebrow): discuss predefining constants structures for some or all of these field names in CRI -type sandboxInfo struct { +type SandboxInfo struct { Pid uint32 `json:"pid"` Status string `json:"processStatus"` NetNSClosed bool `json:"netNamespaceClosed"` @@ -109,7 +109,8 @@ type sandboxInfo struct { SnapshotKey string `json:"snapshotKey"` Snapshotter string `json:"snapshotter"` RuntimeHandler string `json:"runtimeHandler"` - Runtime *criconfig.Runtime `json:"runtime"` + RuntimeType string `json:"runtimeType"` + RuntimeOptions interface{} `json:"runtimeOptions"` Config *runtime.PodSandboxConfig `json:"config"` RuntimeSpec *runtimespec.Spec `json:"runtimeSpec"` } @@ -132,7 +133,7 @@ func toCRISandboxInfo(ctx context.Context, sandbox sandboxstore.Sandbox) (map[st processStatus = taskStatus.Status } - si := &sandboxInfo{ + si := &SandboxInfo{ Pid: sandbox.Status.Get().Pid, RuntimeHandler: sandbox.RuntimeHandler, Status: string(processStatus), @@ -167,11 +168,12 @@ func toCRISandboxInfo(ctx context.Context, sandbox sandboxstore.Sandbox) (map[st si.SnapshotKey = ctrInfo.SnapshotKey si.Snapshotter = ctrInfo.Snapshotter - ociRuntime, err := getRuntimeConfigFromContainerInfo(ctrInfo) + runtimeOptions, err := getRuntimeOptions(ctrInfo) if err != nil { - return nil, errors.Wrap(err, "failed to get sandbox container runtime config") + return nil, errors.Wrap(err, "failed to get runtime options") } - si.Runtime = &ociRuntime + si.RuntimeType = ctrInfo.Runtime.Name + si.RuntimeOptions = runtimeOptions infoBytes, err := json.Marshal(si) if err != nil { diff --git a/vendor/github.com/containerd/cri/pkg/server/sandbox_stop.go b/vendor/github.com/containerd/cri/pkg/server/sandbox_stop.go index 2d5b3ca33..e0f203309 100644 --- a/vendor/github.com/containerd/cri/pkg/server/sandbox_stop.go +++ b/vendor/github.com/containerd/cri/pkg/server/sandbox_stop.go @@ -17,7 +17,6 @@ limitations under the License. package server import ( - "os" "time" "github.com/containerd/containerd" @@ -60,23 +59,21 @@ func (c *criService) StopPodSandbox(ctx context.Context, r *runtime.StopPodSandb } // Teardown network for sandbox. - if sandbox.NetNSPath != "" && sandbox.NetNS != nil { - if _, err := os.Stat(sandbox.NetNSPath); err != nil { - if !os.IsNotExist(err) { - return nil, errors.Wrapf(err, "failed to stat network namespace path %s", sandbox.NetNSPath) - } - } else { - if teardownErr := c.teardownPod(id, sandbox.NetNSPath, sandbox.Config); teardownErr != nil { - return nil, errors.Wrapf(teardownErr, "failed to destroy network for sandbox %q", id) - } + if sandbox.NetNSPath != "" { + netNSPath := sandbox.NetNSPath + if sandbox.NetNS == nil || sandbox.NetNS.Closed() { + // Use empty netns path if netns is not available. This is defined in: + // https://github.com/containernetworking/cni/blob/v0.7.0-alpha1/SPEC.md + netNSPath = "" } - /*TODO:It is still possible that containerd crashes after we teardown the network, but before we remove the network namespace. - In that case, we'll not be able to remove the sandbox anymore. The chance is slim, but we should be aware of that. - In the future, once TearDownPod is idempotent, this will be fixed.*/ - - //Close the sandbox network namespace if it was created - if err = sandbox.NetNS.Remove(); err != nil { - return nil, errors.Wrapf(err, "failed to remove network namespace for sandbox %q", id) + if err := c.teardownPod(id, netNSPath, sandbox.Config); err != nil { + return nil, errors.Wrapf(err, "failed to destroy network for sandbox %q", id) + } + // Close the sandbox network namespace if it was created + if sandbox.NetNS != nil { + if err = sandbox.NetNS.Remove(); err != nil { + return nil, errors.Wrapf(err, "failed to remove network namespace for sandbox %q", id) + } } } diff --git a/vendor/github.com/containerd/cri/pkg/store/sandbox/netns.go b/vendor/github.com/containerd/cri/pkg/store/sandbox/netns.go index a96eb6aad..8a08194cb 100644 --- a/vendor/github.com/containerd/cri/pkg/store/sandbox/netns.go +++ b/vendor/github.com/containerd/cri/pkg/store/sandbox/netns.go @@ -27,6 +27,13 @@ import ( osinterface "github.com/containerd/cri/pkg/os" ) +// The NetNS library assumes only containerd manages the lifecycle of the +// network namespace mount. The only case that netns will be unmounted by +// someone else is node reboot. +// If this assumption is broken, NetNS won't be aware of the external +// unmount, and there will be a state mismatch. +// TODO(random-liu): Don't cache state, always load from the system. + // ErrClosedNetNS is the error returned when network namespace is closed. var ErrClosedNetNS = errors.New("network namespace is closed") diff --git a/vendor/github.com/containerd/cri/vendor.conf b/vendor/github.com/containerd/cri/vendor.conf index fc73f38b6..c81758046 100644 --- a/vendor/github.com/containerd/cri/vendor.conf +++ b/vendor/github.com/containerd/cri/vendor.conf @@ -3,10 +3,10 @@ github.com/blang/semver v3.1.0 github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895 github.com/containerd/cgroups 5e610833b72089b37d0e615de9a92dfc043757c2 github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23 -github.com/containerd/containerd f88d3e5d6dfe9b7d7941ac5241649ad8240b9282 -github.com/containerd/continuity 7f53d412b9eb1cbf744c2063185d703a0ee34700 +github.com/containerd/containerd 15f19d7a67fa322e6de0ef4c6a1bf9da0f056554 +github.com/containerd/continuity bd77b46c8352f74eb12c85bdc01f4b90f69d66b4 github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c -github.com/containerd/go-cni 6d7b509a054a3cb1c35ed1865d4fde2f0cb547cd +github.com/containerd/go-cni 40bcf8ec8acd7372be1d77031d585d5d8e561c90 github.com/containerd/go-runc 5a6d9f37cfa36b15efba46dc7ea349fa9b7143c3 github.com/containerd/ttrpc 2a805f71863501300ae1976d29f0454ae003e85a github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40 @@ -34,7 +34,7 @@ github.com/hashicorp/go-multierror ed905158d87462226a13fe39ddf685ea65f1c11f github.com/json-iterator/go 1.1.5 github.com/matttproud/golang_protobuf_extensions v1.0.0 github.com/Microsoft/go-winio v0.4.10 -github.com/Microsoft/hcsshim v0.7.4 +github.com/Microsoft/hcsshim v0.7.6 github.com/modern-go/concurrent 1.0.3 github.com/modern-go/reflect2 1.0.1 github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7 diff --git a/vendor/github.com/containerd/go-cni/cni.go b/vendor/github.com/containerd/go-cni/cni.go index 3993395fc..31350e304 100644 --- a/vendor/github.com/containerd/go-cni/cni.go +++ b/vendor/github.com/containerd/go-cni/cni.go @@ -18,6 +18,7 @@ package cni import ( "fmt" + "strings" "sync" cnilibrary "github.com/containernetworking/cni/libcni" @@ -127,6 +128,15 @@ func (c *libcni) Remove(id string, path string, opts ...NamespaceOpts) error { } for _, network := range c.networks { if err := network.Remove(ns); err != nil { + // Based on CNI spec v0.7.0, empty network namespace is allowed to + // do best effort cleanup. However, it is not handled consistently + // right now: + // https://github.com/containernetworking/plugins/issues/210 + // TODO(random-liu): Remove the error handling when the issue is + // fixed and the CNI spec v0.6.0 support is deprecated. + if path == "" && strings.Contains(err.Error(), "no such file or directory") { + continue + } return err } }