Add stub to build common OCI spec

Signed-off-by: Maksym Pavlenko <pavlenko.maksym@gmail.com>
This commit is contained in:
Maksym Pavlenko 2023-01-08 19:25:03 -08:00
parent f318e5630b
commit 21338d2777
7 changed files with 121 additions and 43 deletions

View File

@ -23,23 +23,24 @@ import (
"path/filepath" "path/filepath"
"time" "time"
"github.com/containerd/typeurl"
"github.com/davecgh/go-spew/spew"
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/selinux/go-selinux"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
"github.com/containerd/containerd" "github.com/containerd/containerd"
"github.com/containerd/containerd/api/types"
"github.com/containerd/containerd/containers" "github.com/containerd/containerd/containers"
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/containerd/containerd/oci" "github.com/containerd/containerd/oci"
"github.com/containerd/containerd/pkg/cri/config"
criconfig "github.com/containerd/containerd/pkg/cri/config" criconfig "github.com/containerd/containerd/pkg/cri/config"
cio "github.com/containerd/containerd/pkg/cri/io" cio "github.com/containerd/containerd/pkg/cri/io"
customopts "github.com/containerd/containerd/pkg/cri/opts" customopts "github.com/containerd/containerd/pkg/cri/opts"
containerstore "github.com/containerd/containerd/pkg/cri/store/container" containerstore "github.com/containerd/containerd/pkg/cri/store/container"
"github.com/containerd/containerd/pkg/cri/util" "github.com/containerd/containerd/pkg/cri/util"
ctrdutil "github.com/containerd/containerd/pkg/cri/util" ctrdutil "github.com/containerd/containerd/pkg/cri/util"
"github.com/containerd/typeurl"
"github.com/davecgh/go-spew/spew"
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/selinux/go-selinux"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
) )
func init() { func init() {
@ -161,8 +162,25 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta
} }
log.G(ctx).Debugf("Use OCI runtime %+v for sandbox %q and container %q", ociRuntime, sandboxID, id) log.G(ctx).Debugf("Use OCI runtime %+v for sandbox %q and container %q", ociRuntime, sandboxID, id)
spec, err := c.containerSpec(id, sandboxID, sandboxPid, sandbox.NetNSPath, containerName, containerdImage.Name(), config, sandboxConfig, platform, err := controller.Platform(ctx, sandboxID)
&image.ImageSpec.Config, append(mounts, volumeMounts...), ociRuntime) if err != nil {
return nil, fmt.Errorf("failed to query sandbox platform: %w", err)
}
spec, err := c.buildContainerSpec(
platform,
id,
sandboxID,
sandboxPid,
sandbox.NetNSPath,
containerName,
containerdImage.Name(),
config,
sandboxConfig,
&image.ImageSpec.Config,
append(mounts, volumeMounts...),
ociRuntime,
)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to generate container %q spec: %w", id, err) return nil, fmt.Errorf("failed to generate container %q spec: %w", id, err)
} }
@ -375,3 +393,57 @@ func (c *criService) runtimeSnapshotter(ctx context.Context, ociRuntime criconfi
log.G(ctx).Debugf("Set snapshotter for runtime %s to %s", ociRuntime.Type, ociRuntime.Snapshotter) log.G(ctx).Debugf("Set snapshotter for runtime %s to %s", ociRuntime.Type, ociRuntime.Snapshotter)
return ociRuntime.Snapshotter return ociRuntime.Snapshotter
} }
// buildContainerSpec build container's OCI spec depending on controller's target platform OS.
func (c *criService) buildContainerSpec(
platform *types.Platform,
id string,
sandboxID string,
sandboxPid uint32,
netNSPath string,
containerName string,
imageName string,
config *runtime.ContainerConfig,
sandboxConfig *runtime.PodSandboxConfig,
imageConfig *imagespec.ImageConfig,
extraMounts []*runtime.Mount,
ociRuntime config.Runtime,
) (_ *runtimespec.Spec, retErr error) {
var (
specOpts []oci.SpecOpts
isLinux = platform.OS == "linux"
)
if isLinux {
specOpts = append(specOpts, oci.WithoutRunMount)
// Only clear the default security settings if the runtime does not have a custom
// base runtime spec. Admins can use this functionality to define
// default ulimits, seccomp, or other default settings.
if ociRuntime.BaseRuntimeSpec == "" {
specOpts = append(specOpts, customopts.WithoutDefaultSecuritySettings)
}
}
// Get spec opts that depend on features offered by the platform containerd daemon is running on.
platformSpecOpts, err := c.platformSpec(
id,
sandboxID,
sandboxPid,
netNSPath,
containerName,
imageName,
config,
sandboxConfig,
imageConfig,
extraMounts,
ociRuntime,
)
if err != nil {
return nil, err
}
specOpts = append(specOpts, platformSpecOpts...)
return c.runtimeSpec(id, ociRuntime.BaseRuntimeSpec, specOpts...)
}

View File

@ -113,7 +113,7 @@ func (c *criService) containerMounts(sandboxID string, config *runtime.Container
return mounts return mounts
} }
func (c *criService) containerSpec( func (c *criService) platformSpec(
id string, id string,
sandboxID string, sandboxID string,
sandboxPid uint32, sandboxPid uint32,
@ -125,7 +125,7 @@ func (c *criService) containerSpec(
imageConfig *imagespec.ImageConfig, imageConfig *imagespec.ImageConfig,
extraMounts []*runtime.Mount, extraMounts []*runtime.Mount,
ociRuntime config.Runtime, ociRuntime config.Runtime,
) (_ *runtimespec.Spec, retErr error) { ) (_ []oci.SpecOpts, retErr error) {
specOpts := []oci.SpecOpts{ specOpts := []oci.SpecOpts{
oci.WithoutRunMount, oci.WithoutRunMount,
} }
@ -334,7 +334,8 @@ func (c *criService) containerSpec(
Type: runtimespec.CgroupNamespace, Type: runtimespec.CgroupNamespace,
})) }))
} }
return c.runtimeSpec(id, ociRuntime.BaseRuntimeSpec, specOpts...)
return specOpts, nil
} }
func (c *criService) containerSpecOpts(config *runtime.ContainerConfig, imageConfig *imagespec.ImageConfig) ([]oci.SpecOpts, error) { func (c *criService) containerSpecOpts(config *runtime.ContainerConfig, imageConfig *imagespec.ImageConfig) ([]oci.SpecOpts, error) {

View File

@ -248,7 +248,7 @@ func TestContainerCapabilities(t *testing.T) {
c.allCaps = allCaps c.allCaps = allCaps
containerConfig.Linux.SecurityContext.Capabilities = test.capability containerConfig.Linux.SecurityContext.Capabilities = test.capability
spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) spec, err := c.buildContainerSpec(linuxPlatform, testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
require.NoError(t, err) require.NoError(t, err)
if selinux.GetEnabled() { if selinux.GetEnabled() {
@ -283,7 +283,7 @@ func TestContainerSpecTty(t *testing.T) {
c := newTestCRIService() c := newTestCRIService()
for _, tty := range []bool{true, false} { for _, tty := range []bool{true, false} {
containerConfig.Tty = tty containerConfig.Tty = tty
spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) spec, err := c.buildContainerSpec(linuxPlatform, testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
require.NoError(t, err) require.NoError(t, err)
specCheck(t, testID, testSandboxID, testPid, spec) specCheck(t, testID, testSandboxID, testPid, spec)
assert.Equal(t, tty, spec.Process.Terminal) assert.Equal(t, tty, spec.Process.Terminal)
@ -310,7 +310,7 @@ func TestContainerSpecDefaultPath(t *testing.T) {
imageConfig.Env = append(imageConfig.Env, pathenv) imageConfig.Env = append(imageConfig.Env, pathenv)
expected = pathenv expected = pathenv
} }
spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) spec, err := c.buildContainerSpec(linuxPlatform, testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
require.NoError(t, err) require.NoError(t, err)
specCheck(t, testID, testSandboxID, testPid, spec) specCheck(t, testID, testSandboxID, testPid, spec)
assert.Contains(t, spec.Process.Env, expected) assert.Contains(t, spec.Process.Env, expected)
@ -327,7 +327,7 @@ func TestContainerSpecReadonlyRootfs(t *testing.T) {
c := newTestCRIService() c := newTestCRIService()
for _, readonly := range []bool{true, false} { for _, readonly := range []bool{true, false} {
containerConfig.Linux.SecurityContext.ReadonlyRootfs = readonly containerConfig.Linux.SecurityContext.ReadonlyRootfs = readonly
spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) spec, err := c.buildContainerSpec(linuxPlatform, testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
require.NoError(t, err) require.NoError(t, err)
specCheck(t, testID, testSandboxID, testPid, spec) specCheck(t, testID, testSandboxID, testPid, spec)
assert.Equal(t, readonly, spec.Root.Readonly) assert.Equal(t, readonly, spec.Root.Readonly)
@ -366,7 +366,7 @@ func TestContainerSpecWithExtraMounts(t *testing.T) {
Readonly: false, Readonly: false,
}, },
} }
spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, extraMounts, ociRuntime) spec, err := c.buildContainerSpec(linuxPlatform, testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, extraMounts, ociRuntime)
require.NoError(t, err) require.NoError(t, err)
specCheck(t, testID, testSandboxID, testPid, spec) specCheck(t, testID, testSandboxID, testPid, spec)
var mounts, sysMounts, devMounts []runtimespec.Mount var mounts, sysMounts, devMounts []runtimespec.Mount
@ -434,7 +434,7 @@ func TestContainerAndSandboxPrivileged(t *testing.T) {
sandboxConfig.Linux.SecurityContext = &runtime.LinuxSandboxSecurityContext{ sandboxConfig.Linux.SecurityContext = &runtime.LinuxSandboxSecurityContext{
Privileged: test.sandboxPrivileged, Privileged: test.sandboxPrivileged,
} }
_, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) _, err := c.platformSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
if test.expectError { if test.expectError {
assert.Error(t, err) assert.Error(t, err)
} else { } else {
@ -638,7 +638,7 @@ func TestPrivilegedBindMount(t *testing.T) {
containerConfig.Linux.SecurityContext.Privileged = test.privileged containerConfig.Linux.SecurityContext.Privileged = test.privileged
sandboxConfig.Linux.SecurityContext.Privileged = test.privileged sandboxConfig.Linux.SecurityContext.Privileged = test.privileged
spec, err := c.containerSpec(t.Name(), testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) spec, err := c.buildContainerSpec(linuxPlatform, t.Name(), testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
assert.NoError(t, err) assert.NoError(t, err)
if test.expectedSysFSRO { if test.expectedSysFSRO {
@ -797,7 +797,7 @@ func TestPidNamespace(t *testing.T) {
} { } {
t.Run(desc, func(t *testing.T) { t.Run(desc, func(t *testing.T) {
containerConfig.Linux.SecurityContext.NamespaceOptions = &runtime.NamespaceOption{Pid: test.pidNS} containerConfig.Linux.SecurityContext.NamespaceOptions = &runtime.NamespaceOption{Pid: test.pidNS}
spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) spec, err := c.buildContainerSpec(linuxPlatform, testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
require.NoError(t, err) require.NoError(t, err)
assert.Contains(t, spec.Linux.Namespaces, test.expected) assert.Contains(t, spec.Linux.Namespaces, test.expected)
}) })
@ -813,7 +813,7 @@ func TestNoDefaultRunMount(t *testing.T) {
ociRuntime := config.Runtime{} ociRuntime := config.Runtime{}
c := newTestCRIService() c := newTestCRIService()
spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) spec, err := c.buildContainerSpec(linuxPlatform, testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
assert.NoError(t, err) assert.NoError(t, err)
for _, mount := range spec.Mounts { for _, mount := range spec.Mounts {
assert.NotEqual(t, "/run", mount.Destination) assert.NotEqual(t, "/run", mount.Destination)
@ -1187,7 +1187,7 @@ func TestMaskedAndReadonlyPaths(t *testing.T) {
sandboxConfig.Linux.SecurityContext = &runtime.LinuxSandboxSecurityContext{ sandboxConfig.Linux.SecurityContext = &runtime.LinuxSandboxSecurityContext{
Privileged: test.privileged, Privileged: test.privileged,
} }
spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) spec, err := c.buildContainerSpec(linuxPlatform, testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
require.NoError(t, err) require.NoError(t, err)
if !test.privileged { // specCheck presumes an unprivileged container if !test.privileged { // specCheck presumes an unprivileged container
specCheck(t, testID, testSandboxID, testPid, spec) specCheck(t, testID, testSandboxID, testPid, spec)
@ -1235,7 +1235,7 @@ func TestHostname(t *testing.T) {
sandboxConfig.Linux.SecurityContext = &runtime.LinuxSandboxSecurityContext{ sandboxConfig.Linux.SecurityContext = &runtime.LinuxSandboxSecurityContext{
NamespaceOptions: &runtime.NamespaceOption{Network: test.networkNs}, NamespaceOptions: &runtime.NamespaceOption{Network: test.networkNs},
} }
spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) spec, err := c.buildContainerSpec(linuxPlatform, testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
require.NoError(t, err) require.NoError(t, err)
specCheck(t, testID, testSandboxID, testPid, spec) specCheck(t, testID, testSandboxID, testPid, spec)
assert.Contains(t, spec.Process.Env, test.expectedEnv) assert.Contains(t, spec.Process.Env, test.expectedEnv)
@ -1248,7 +1248,7 @@ func TestDisableCgroup(t *testing.T) {
ociRuntime := config.Runtime{} ociRuntime := config.Runtime{}
c := newTestCRIService() c := newTestCRIService()
c.config.DisableCgroup = true c.config.DisableCgroup = true
spec, err := c.containerSpec("test-id", "sandbox-id", 1234, "", "container-name", testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) spec, err := c.buildContainerSpec(linuxPlatform, "test-id", "sandbox-id", 1234, "", "container-name", testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
require.NoError(t, err) require.NoError(t, err)
t.Log("resource limit should not be set") t.Log("resource limit should not be set")
@ -1387,7 +1387,7 @@ func TestNonRootUserAndDevices(t *testing.T) {
}, },
} }
spec, err := c.containerSpec(t.Name(), testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, config.Runtime{}) spec, err := c.buildContainerSpec(linuxPlatform, t.Name(), testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, config.Runtime{})
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, test.expectedDeviceUID, *spec.Linux.Devices[0].UID) assert.Equal(t, test.expectedDeviceUID, *spec.Linux.Devices[0].UID)
@ -1454,7 +1454,7 @@ func TestPrivilegedDevices(t *testing.T) {
PrivilegedWithoutHostDevices: test.privilegedWithoutHostDevices, PrivilegedWithoutHostDevices: test.privilegedWithoutHostDevices,
PrivilegedWithoutHostDevicesAllDevicesAllowed: test.privilegedWithoutHostDevicesAllDevicesAllowed, PrivilegedWithoutHostDevicesAllDevicesAllowed: test.privilegedWithoutHostDevicesAllDevicesAllowed,
} }
spec, err := c.containerSpec(t.Name(), testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) spec, err := c.buildContainerSpec(linuxPlatform, t.Name(), testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
assert.NoError(t, err) assert.NoError(t, err)
hostDevicesRaw, err := oci.HostDevices() hostDevicesRaw, err := oci.HostDevices()
@ -1508,7 +1508,7 @@ func TestBaseOCISpec(t *testing.T) {
testPid := uint32(1234) testPid := uint32(1234)
containerConfig, sandboxConfig, imageConfig, specCheck := getCreateContainerTestData() containerConfig, sandboxConfig, imageConfig, specCheck := getCreateContainerTestData()
spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) spec, err := c.buildContainerSpec(linuxPlatform, testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
assert.NoError(t, err) assert.NoError(t, err)
specCheck(t, testID, testSandboxID, testPid, spec) specCheck(t, testID, testSandboxID, testPid, spec)
@ -1642,7 +1642,7 @@ containerEdits:
}, },
} { } {
t.Run(test.description, func(t *testing.T) { t.Run(test.description, func(t *testing.T) {
spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) spec, err := c.buildContainerSpec(linuxPlatform, testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
require.NoError(t, err) require.NoError(t, err)
specCheck(t, testID, testSandboxID, testPid, spec) specCheck(t, testID, testSandboxID, testPid, spec)

View File

@ -22,7 +22,6 @@ import (
"github.com/containerd/containerd/oci" "github.com/containerd/containerd/oci"
"github.com/containerd/containerd/snapshots" "github.com/containerd/containerd/snapshots"
imagespec "github.com/opencontainers/image-spec/specs-go/v1" imagespec "github.com/opencontainers/image-spec/specs-go/v1"
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1" runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
"github.com/containerd/containerd/pkg/cri/config" "github.com/containerd/containerd/pkg/cri/config"
@ -34,7 +33,7 @@ func (c *criService) containerMounts(sandboxID string, config *runtime.Container
return []*runtime.Mount{} return []*runtime.Mount{}
} }
func (c *criService) containerSpec( func (c *criService) platformSpec(
id string, id string,
sandboxID string, sandboxID string,
sandboxPid uint32, sandboxPid uint32,
@ -46,8 +45,8 @@ func (c *criService) containerSpec(
imageConfig *imagespec.ImageConfig, imageConfig *imagespec.ImageConfig,
extraMounts []*runtime.Mount, extraMounts []*runtime.Mount,
ociRuntime config.Runtime, ociRuntime config.Runtime,
) (_ *runtimespec.Spec, retErr error) { ) ([]oci.SpecOpts, error) {
return c.runtimeSpec(id, ociRuntime.BaseRuntimeSpec) return []oci.SpecOpts{}, nil
} }
func (c *criService) containerSpecOpts(config *runtime.ContainerConfig, imageConfig *imagespec.ImageConfig) ([]oci.SpecOpts, error) { func (c *criService) containerSpecOpts(config *runtime.ContainerConfig, imageConfig *imagespec.ImageConfig) ([]oci.SpecOpts, error) {

View File

@ -22,6 +22,7 @@ import (
goruntime "runtime" goruntime "runtime"
"testing" "testing"
"github.com/containerd/containerd/api/types"
imagespec "github.com/opencontainers/image-spec/specs-go/v1" imagespec "github.com/opencontainers/image-spec/specs-go/v1"
runtimespec "github.com/opencontainers/runtime-spec/specs-go" runtimespec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -34,6 +35,8 @@ import (
"github.com/containerd/containerd/pkg/cri/opts" "github.com/containerd/containerd/pkg/cri/opts"
) )
var linuxPlatform = &types.Platform{OS: "linux"}
func checkMount(t *testing.T, mounts []runtimespec.Mount, src, dest, typ string, func checkMount(t *testing.T, mounts []runtimespec.Mount, src, dest, typ string,
contains, notcontains []string) { contains, notcontains []string) {
found := false found := false
@ -63,7 +66,7 @@ func TestGeneralContainerSpec(t *testing.T) {
c := newTestCRIService() c := newTestCRIService()
testSandboxID := "sandbox-id" testSandboxID := "sandbox-id"
testContainerName := "container-name" testContainerName := "container-name"
spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) spec, err := c.buildContainerSpec(linuxPlatform, testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
require.NoError(t, err) require.NoError(t, err)
specCheck(t, testID, testSandboxID, testPid, spec) specCheck(t, testID, testSandboxID, testPid, spec)
} }
@ -134,7 +137,7 @@ func TestPodAnnotationPassthroughContainerSpec(t *testing.T) {
ociRuntime := config.Runtime{ ociRuntime := config.Runtime{
PodAnnotations: test.podAnnotations, PodAnnotations: test.podAnnotations,
} }
spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, spec, err := c.buildContainerSpec(linuxPlatform, testID, testSandboxID, testPid, "", testContainerName, testImageName,
containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, spec) assert.NotNil(t, spec)
@ -391,7 +394,7 @@ func TestContainerAnnotationPassthroughContainerSpec(t *testing.T) {
PodAnnotations: test.podAnnotations, PodAnnotations: test.podAnnotations,
ContainerAnnotations: test.containerAnnotations, ContainerAnnotations: test.containerAnnotations,
} }
spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, spec, err := c.buildContainerSpec(linuxPlatform, testID, testSandboxID, testPid, "", testContainerName, testImageName,
containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, spec) assert.NotNil(t, spec)

View File

@ -24,7 +24,6 @@ import (
"github.com/containerd/containerd/oci" "github.com/containerd/containerd/oci"
"github.com/containerd/containerd/snapshots" "github.com/containerd/containerd/snapshots"
imagespec "github.com/opencontainers/image-spec/specs-go/v1" imagespec "github.com/opencontainers/image-spec/specs-go/v1"
runtimespec "github.com/opencontainers/runtime-spec/specs-go"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1" runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
"github.com/containerd/containerd/pkg/cri/annotations" "github.com/containerd/containerd/pkg/cri/annotations"
@ -37,7 +36,7 @@ func (c *criService) containerMounts(sandboxID string, config *runtime.Container
return nil return nil
} }
func (c *criService) containerSpec( func (c *criService) platformSpec(
id string, id string,
sandboxID string, sandboxID string,
sandboxPid uint32, sandboxPid uint32,
@ -49,7 +48,7 @@ func (c *criService) containerSpec(
imageConfig *imagespec.ImageConfig, imageConfig *imagespec.ImageConfig,
extraMounts []*runtime.Mount, extraMounts []*runtime.Mount,
ociRuntime config.Runtime, ociRuntime config.Runtime,
) (*runtimespec.Spec, error) { ) ([]oci.SpecOpts, error) {
specOpts := []oci.SpecOpts{ specOpts := []oci.SpecOpts{
customopts.WithProcessArgs(config, imageConfig), customopts.WithProcessArgs(config, imageConfig),
} }
@ -136,7 +135,8 @@ func (c *criService) containerSpec(
customopts.WithAnnotation(annotations.ImageName, imageName), customopts.WithAnnotation(annotations.ImageName, imageName),
customopts.WithAnnotation(annotations.WindowsHostProcess, strconv.FormatBool(sandboxHpc)), customopts.WithAnnotation(annotations.WindowsHostProcess, strconv.FormatBool(sandboxHpc)),
) )
return c.runtimeSpec(id, ociRuntime.BaseRuntimeSpec, specOpts...)
return specOpts, nil
} }
// No extra spec options needed for windows. // No extra spec options needed for windows.

View File

@ -19,6 +19,7 @@ package sbserver
import ( import (
"testing" "testing"
"github.com/containerd/containerd/api/types"
imagespec "github.com/opencontainers/image-spec/specs-go/v1" imagespec "github.com/opencontainers/image-spec/specs-go/v1"
runtimespec "github.com/opencontainers/runtime-spec/specs-go" runtimespec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -142,6 +143,8 @@ func getCreateContainerTestData() (*runtime.ContainerConfig, *runtime.PodSandbox
return config, sandboxConfig, imageConfig, specCheck return config, sandboxConfig, imageConfig, specCheck
} }
var windowsPlatform = &types.Platform{OS: "windows"}
func TestContainerWindowsNetworkNamespace(t *testing.T) { func TestContainerWindowsNetworkNamespace(t *testing.T) {
testID := "test-id" testID := "test-id"
testSandboxID := "sandbox-id" testSandboxID := "sandbox-id"
@ -151,7 +154,7 @@ func TestContainerWindowsNetworkNamespace(t *testing.T) {
c := newTestCRIService() c := newTestCRIService()
containerConfig, sandboxConfig, imageConfig, specCheck := getCreateContainerTestData() containerConfig, sandboxConfig, imageConfig, specCheck := getCreateContainerTestData()
spec, err := c.containerSpec(testID, testSandboxID, testPid, nsPath, testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, config.Runtime{}) spec, err := c.buildContainerSpec(windowsPlatform, testID, testSandboxID, testPid, nsPath, testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, config.Runtime{})
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, spec) assert.NotNil(t, spec)
specCheck(t, testID, testSandboxID, testPid, spec) specCheck(t, testID, testSandboxID, testPid, spec)
@ -173,7 +176,7 @@ func TestMountCleanPath(t *testing.T) {
ContainerPath: "c:/test/container-path", ContainerPath: "c:/test/container-path",
HostPath: "c:/test/host-path", HostPath: "c:/test/host-path",
}) })
spec, err := c.containerSpec(testID, testSandboxID, testPid, nsPath, testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, config.Runtime{}) spec, err := c.buildContainerSpec(windowsPlatform, testID, testSandboxID, testPid, nsPath, testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, config.Runtime{})
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, spec) assert.NotNil(t, spec)
specCheck(t, testID, testSandboxID, testPid, spec) specCheck(t, testID, testSandboxID, testPid, spec)
@ -193,7 +196,7 @@ func TestMountNamedPipe(t *testing.T) {
ContainerPath: `\\.\pipe\foo`, ContainerPath: `\\.\pipe\foo`,
HostPath: `\\.\pipe\foo`, HostPath: `\\.\pipe\foo`,
}) })
spec, err := c.containerSpec(testID, testSandboxID, testPid, nsPath, testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, config.Runtime{}) spec, err := c.buildContainerSpec(windowsPlatform, testID, testSandboxID, testPid, nsPath, testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, config.Runtime{})
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, spec) assert.NotNil(t, spec)
specCheck(t, testID, testSandboxID, testPid, spec) specCheck(t, testID, testSandboxID, testPid, spec)
@ -239,7 +242,7 @@ func TestHostProcessRequirements(t *testing.T) {
sandboxConfig.Windows.SecurityContext = &runtime.WindowsSandboxSecurityContext{ sandboxConfig.Windows.SecurityContext = &runtime.WindowsSandboxSecurityContext{
HostProcess: test.sandboxHostProcess, HostProcess: test.sandboxHostProcess,
} }
_, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) _, err := c.platformSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
if test.expectError { if test.expectError {
assert.Error(t, err) assert.Error(t, err)
} else { } else {