diff --git a/vendor.conf b/vendor.conf index 69a28e113..792aa1ee8 100644 --- a/vendor.conf +++ b/vendor.conf @@ -56,7 +56,7 @@ gotest.tools/v3 v3.0.2 github.com/cilium/ebpf 4032b1d8aae306b7bb94a2a11002932caf88c644 # cri dependencies -github.com/containerd/cri c744b66a3b655f140426f846cf64ef50ea8419c8 # master +github.com/containerd/cri 8898550e348932e406049e937d98fb7564ac4e7a # master github.com/davecgh/go-spew v1.1.1 github.com/docker/docker 4634ce647cf2ce2c6031129ccd109e557244986f github.com/docker/spdystream 449fdfce4d962303d702fec724ef0ad181c92528 diff --git a/vendor/github.com/containerd/cri/pkg/config/config.go b/vendor/github.com/containerd/cri/pkg/config/config.go index d2e10f192..3e3e59105 100644 --- a/vendor/github.com/containerd/cri/pkg/config/config.go +++ b/vendor/github.com/containerd/cri/pkg/config/config.go @@ -52,6 +52,8 @@ type Runtime struct { // PrivilegedWithoutHostDevices overloads the default behaviour for adding host devices to the // runtime spec when the container is privileged. Defaults to false. PrivilegedWithoutHostDevices bool `toml:"privileged_without_host_devices" json:"privileged_without_host_devices"` + // BaseRuntimeSpec is a json file with OCI spec to use as base spec that all container's will be created from. + BaseRuntimeSpec string `toml:"base_runtime_spec" json:"baseRuntimeSpec"` } // ContainerdConfig contains toml config related to containerd 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 833501de0..cbed9e236 100644 --- a/vendor/github.com/containerd/cri/pkg/server/container_create.go +++ b/vendor/github.com/containerd/cri/pkg/server/container_create.go @@ -297,12 +297,36 @@ func (c *criService) volumeMounts(containerRootDir string, criMounts []*runtime. } // runtimeSpec returns a default runtime spec used in cri-containerd. -func runtimeSpec(id string, opts ...oci.SpecOpts) (*runtimespec.Spec, error) { +func (c *criService) runtimeSpec(id string, baseSpecFile string, opts ...oci.SpecOpts) (*runtimespec.Spec, error) { // GenerateSpec needs namespace. ctx := ctrdutil.NamespacedContext() - spec, err := oci.GenerateSpec(ctx, nil, &containers.Container{ID: id}, opts...) - if err != nil { - return nil, err + container := &containers.Container{ID: id} + + if baseSpecFile != "" { + baseSpec, ok := c.baseOCISpecs[baseSpecFile] + if !ok { + return nil, errors.Errorf("can't find base OCI spec %q", baseSpecFile) + } + + spec := oci.Spec{} + if err := util.DeepCopy(&spec, &baseSpec); err != nil { + return nil, errors.Wrap(err, "failed to clone OCI spec") + } + + // Fix up cgroups path + applyOpts := append([]oci.SpecOpts{oci.WithNamespacedCgroup()}, opts...) + + if err := oci.ApplyOpts(ctx, nil, container, &spec, applyOpts...); err != nil { + return nil, errors.Wrap(err, "failed to apply OCI options") + } + + return &spec, nil } + + spec, err := oci.GenerateSpec(ctx, nil, container, opts...) + if err != nil { + return nil, errors.Wrap(err, "failed to generate spec") + } + return spec, nil } diff --git a/vendor/github.com/containerd/cri/pkg/server/container_create_unix.go b/vendor/github.com/containerd/cri/pkg/server/container_create_unix.go index d5f0bc955..d0ff20e3f 100644 --- a/vendor/github.com/containerd/cri/pkg/server/container_create_unix.go +++ b/vendor/github.com/containerd/cri/pkg/server/container_create_unix.go @@ -262,7 +262,7 @@ func (c *criService) containerSpec(id string, sandboxID string, sandboxPid uint3 Type: runtimespec.CgroupNamespace, })) } - return runtimeSpec(id, specOpts...) + return c.runtimeSpec(id, ociRuntime.BaseRuntimeSpec, specOpts...) } func (c *criService) containerSpecOpts(config *runtime.ContainerConfig, imageConfig *imagespec.ImageConfig) ([]oci.SpecOpts, error) { diff --git a/vendor/github.com/containerd/cri/pkg/server/container_create_windows.go b/vendor/github.com/containerd/cri/pkg/server/container_create_windows.go index 2211008eb..e8c81808d 100644 --- a/vendor/github.com/containerd/cri/pkg/server/container_create_windows.go +++ b/vendor/github.com/containerd/cri/pkg/server/container_create_windows.go @@ -91,8 +91,7 @@ func (c *criService) containerSpec(id string, sandboxID string, sandboxPid uint3 customopts.WithAnnotation(annotations.SandboxID, sandboxID), customopts.WithAnnotation(annotations.ContainerName, containerName), ) - - return runtimeSpec(id, specOpts...) + return c.runtimeSpec(id, ociRuntime.BaseRuntimeSpec, specOpts...) } // No extra spec options needed for windows. diff --git a/vendor/github.com/containerd/cri/pkg/server/sandbox_run_unix.go b/vendor/github.com/containerd/cri/pkg/server/sandbox_run_unix.go index 8391872c4..ad0b85254 100644 --- a/vendor/github.com/containerd/cri/pkg/server/sandbox_run_unix.go +++ b/vendor/github.com/containerd/cri/pkg/server/sandbox_run_unix.go @@ -156,7 +156,7 @@ func (c *criService) sandboxContainerSpec(id string, config *runtime.PodSandboxC customopts.WithAnnotation(annotations.SandboxLogDir, config.GetLogDirectory()), ) - return runtimeSpec(id, specOpts...) + return c.runtimeSpec(id, "", specOpts...) } // sandboxContainerSpecOpts generates OCI spec options for diff --git a/vendor/github.com/containerd/cri/pkg/server/sandbox_run_windows.go b/vendor/github.com/containerd/cri/pkg/server/sandbox_run_windows.go index 4f8f054a9..85105c299 100644 --- a/vendor/github.com/containerd/cri/pkg/server/sandbox_run_windows.go +++ b/vendor/github.com/containerd/cri/pkg/server/sandbox_run_windows.go @@ -67,7 +67,7 @@ func (c *criService) sandboxContainerSpec(id string, config *runtime.PodSandboxC customopts.WithAnnotation(annotations.SandboxLogDir, config.GetLogDirectory()), ) - return runtimeSpec(id, specOpts...) + return c.runtimeSpec(id, "", specOpts...) } // No sandbox container spec options for windows yet. diff --git a/vendor/github.com/containerd/cri/pkg/server/service.go b/vendor/github.com/containerd/cri/pkg/server/service.go index d4a0d2817..43512ff97 100644 --- a/vendor/github.com/containerd/cri/pkg/server/service.go +++ b/vendor/github.com/containerd/cri/pkg/server/service.go @@ -17,15 +17,17 @@ package server import ( + "encoding/json" "fmt" "io" "net/http" + "os" "path/filepath" "time" "github.com/containerd/containerd" + "github.com/containerd/containerd/oci" "github.com/containerd/containerd/plugin" - "github.com/containerd/cri/pkg/store/label" cni "github.com/containerd/go-cni" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -33,6 +35,8 @@ import ( runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" "k8s.io/kubernetes/pkg/kubelet/server/streaming" + "github.com/containerd/cri/pkg/store/label" + "github.com/containerd/cri/pkg/atomic" criconfig "github.com/containerd/cri/pkg/config" ctrdutil "github.com/containerd/cri/pkg/containerd/util" @@ -95,6 +99,8 @@ type criService struct { // cniNetConfMonitor is used to reload cni network conf if there is // any valid fs change events from cni network conf dir. cniNetConfMonitor *cniNetConfSyncer + // baseOCISpecs contains cached OCI specs loaded via `Runtime.BaseRuntimeSpec` + baseOCISpecs map[string]*oci.Spec } // NewCRIService returns a new instance of CRIService @@ -138,6 +144,12 @@ func NewCRIService(config criconfig.Config, client *containerd.Client) (CRIServi return nil, errors.Wrap(err, "failed to create cni conf monitor") } + // Preload base OCI specs + c.baseOCISpecs, err = loadBaseOCISpecs(&config) + if err != nil { + return nil, err + } + return c, nil } @@ -273,3 +285,41 @@ func (c *criService) register(s *grpc.Server) error { func imageFSPath(rootDir, snapshotter string) string { return filepath.Join(rootDir, fmt.Sprintf("%s.%s", plugin.SnapshotPlugin, snapshotter)) } + +func loadOCISpec(filename string) (*oci.Spec, error) { + file, err := os.Open(filename) + if err != nil { + return nil, errors.Wrapf(err, "failed to open base OCI spec: %s", filename) + } + defer file.Close() + + spec := oci.Spec{} + if err := json.NewDecoder(file).Decode(&spec); err != nil { + return nil, errors.Wrap(err, "failed to parse base OCI spec file") + } + + return &spec, nil +} + +func loadBaseOCISpecs(config *criconfig.Config) (map[string]*oci.Spec, error) { + specs := map[string]*oci.Spec{} + for _, cfg := range config.Runtimes { + if cfg.BaseRuntimeSpec == "" { + continue + } + + // Don't load same file twice + if _, ok := specs[cfg.BaseRuntimeSpec]; ok { + continue + } + + spec, err := loadOCISpec(cfg.BaseRuntimeSpec) + if err != nil { + return nil, errors.Wrapf(err, "failed to load base OCI spec from file: %s", cfg.BaseRuntimeSpec) + } + + specs[cfg.BaseRuntimeSpec] = spec + } + + return specs, nil +}