diff --git a/pkg/cri/annotations/annotations.go b/pkg/cri/annotations/annotations.go index 68be666c8..b69f136a8 100644 --- a/pkg/cri/annotations/annotations.go +++ b/pkg/cri/annotations/annotations.go @@ -53,4 +53,6 @@ const ( // ContainerName is the name of the container in the pod ContainerName = "io.kubernetes.cri.container-name" + // ImageName is the name of the image used to create the container + ImageName = "io.kubernetes.cri.image-name" ) diff --git a/pkg/cri/server/container_create.go b/pkg/cri/server/container_create.go index 9360ba056..a3aba7a44 100644 --- a/pkg/cri/server/container_create.go +++ b/pkg/cri/server/container_create.go @@ -155,7 +155,7 @@ 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) - spec, err := c.containerSpec(id, sandboxID, sandboxPid, sandbox.NetNSPath, containerName, config, sandboxConfig, + spec, err := c.containerSpec(id, sandboxID, sandboxPid, sandbox.NetNSPath, containerName, containerdImage.Name(), config, sandboxConfig, &image.ImageSpec.Config, append(mounts, volumeMounts...), ociRuntime) if err != nil { return nil, errors.Wrapf(err, "failed to generate container %q spec", id) diff --git a/pkg/cri/server/container_create_linux.go b/pkg/cri/server/container_create_linux.go index 99998405a..26a3cd6d2 100644 --- a/pkg/cri/server/container_create_linux.go +++ b/pkg/cri/server/container_create_linux.go @@ -108,10 +108,19 @@ func (c *criService) containerMounts(sandboxID string, config *runtime.Container return mounts } -func (c *criService) containerSpec(id string, sandboxID string, sandboxPid uint32, netNSPath string, containerName string, - config *runtime.ContainerConfig, sandboxConfig *runtime.PodSandboxConfig, imageConfig *imagespec.ImageConfig, - extraMounts []*runtime.Mount, ociRuntime config.Runtime) (_ *runtimespec.Spec, retErr error) { - +func (c *criService) containerSpec( + 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) { specOpts := []oci.SpecOpts{ customopts.WithoutRunMount, } @@ -263,6 +272,7 @@ func (c *criService) containerSpec(id string, sandboxID string, sandboxPid uint3 customopts.WithAnnotation(annotations.SandboxNamespace, sandboxConfig.GetMetadata().GetNamespace()), customopts.WithAnnotation(annotations.SandboxName, sandboxConfig.GetMetadata().GetName()), customopts.WithAnnotation(annotations.ContainerName, containerName), + customopts.WithAnnotation(annotations.ImageName, imageName), ) // cgroupns is used for hiding /sys/fs/cgroup from containers. // For compatibility, cgroupns is not used when running in cgroup v1 mode or in privileged. diff --git a/pkg/cri/server/container_create_linux_test.go b/pkg/cri/server/container_create_linux_test.go index 962020ee9..b6f07a598 100644 --- a/pkg/cri/server/container_create_linux_test.go +++ b/pkg/cri/server/container_create_linux_test.go @@ -179,6 +179,9 @@ func getCreateContainerTestData() (*runtime.ContainerConfig, *runtime.PodSandbox assert.Contains(t, spec.Annotations, annotations.SandboxName) assert.EqualValues(t, spec.Annotations[annotations.SandboxName], "test-sandbox-name") + + assert.Contains(t, spec.Annotations, annotations.ImageName) + assert.EqualValues(t, spec.Annotations[annotations.ImageName], testImageName) } return config, sandboxConfig, imageConfig, specCheck } @@ -236,7 +239,7 @@ func TestContainerCapabilities(t *testing.T) { c := newTestCRIService() containerConfig.Linux.SecurityContext.Capabilities = test.capability - spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) + spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) require.NoError(t, err) if selinux.GetEnabled() { @@ -271,7 +274,7 @@ func TestContainerSpecTty(t *testing.T) { c := newTestCRIService() for _, tty := range []bool{true, false} { containerConfig.Tty = tty - spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) + spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) require.NoError(t, err) specCheck(t, testID, testSandboxID, testPid, spec) assert.Equal(t, tty, spec.Process.Terminal) @@ -298,7 +301,7 @@ func TestContainerSpecDefaultPath(t *testing.T) { imageConfig.Env = append(imageConfig.Env, pathenv) expected = pathenv } - spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) + spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) require.NoError(t, err) specCheck(t, testID, testSandboxID, testPid, spec) assert.Contains(t, spec.Process.Env, expected) @@ -315,7 +318,7 @@ func TestContainerSpecReadonlyRootfs(t *testing.T) { c := newTestCRIService() for _, readonly := range []bool{true, false} { containerConfig.Linux.SecurityContext.ReadonlyRootfs = readonly - spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) + spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) require.NoError(t, err) specCheck(t, testID, testSandboxID, testPid, spec) assert.Equal(t, readonly, spec.Root.Readonly) @@ -354,7 +357,7 @@ func TestContainerSpecWithExtraMounts(t *testing.T) { Readonly: false, }, } - spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, containerConfig, sandboxConfig, imageConfig, extraMounts, ociRuntime) + spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, extraMounts, ociRuntime) require.NoError(t, err) specCheck(t, testID, testSandboxID, testPid, spec) var mounts, sysMounts, devMounts []runtimespec.Mount @@ -422,7 +425,7 @@ func TestContainerAndSandboxPrivileged(t *testing.T) { sandboxConfig.Linux.SecurityContext = &runtime.LinuxSandboxSecurityContext{ Privileged: test.sandboxPrivileged, } - _, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) + _, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) if test.expectError { assert.Error(t, err) } else { @@ -613,7 +616,7 @@ func TestPrivilegedBindMount(t *testing.T) { containerConfig.Linux.SecurityContext.Privileged = test.privileged sandboxConfig.Linux.SecurityContext.Privileged = test.privileged - spec, err := c.containerSpec(t.Name(), testSandboxID, testPid, "", testContainerName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) + spec, err := c.containerSpec(t.Name(), testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) assert.NoError(t, err) if test.expectedSysFSRO { @@ -770,7 +773,7 @@ func TestPidNamespace(t *testing.T) { } { t.Logf("TestCase %q", desc) containerConfig.Linux.SecurityContext.NamespaceOptions = &runtime.NamespaceOption{Pid: test.pidNS} - spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) + spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) require.NoError(t, err) assert.Contains(t, spec.Linux.Namespaces, test.expected) } @@ -785,7 +788,7 @@ func TestNoDefaultRunMount(t *testing.T) { ociRuntime := config.Runtime{} c := newTestCRIService() - spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) + spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) assert.NoError(t, err) for _, mount := range spec.Mounts { assert.NotEqual(t, "/run", mount.Destination) @@ -1158,7 +1161,7 @@ func TestMaskedAndReadonlyPaths(t *testing.T) { sandboxConfig.Linux.SecurityContext = &runtime.LinuxSandboxSecurityContext{ Privileged: test.privileged, } - spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) + spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) require.NoError(t, err) if !test.privileged { // specCheck presumes an unprivileged container specCheck(t, testID, testSandboxID, testPid, spec) @@ -1205,7 +1208,7 @@ func TestHostname(t *testing.T) { sandboxConfig.Linux.SecurityContext = &runtime.LinuxSandboxSecurityContext{ NamespaceOptions: &runtime.NamespaceOption{Network: test.networkNs}, } - spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) + spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) require.NoError(t, err) specCheck(t, testID, testSandboxID, testPid, spec) assert.Contains(t, spec.Process.Env, test.expectedEnv) @@ -1217,7 +1220,7 @@ func TestDisableCgroup(t *testing.T) { ociRuntime := config.Runtime{} c := newTestCRIService() c.config.DisableCgroup = true - spec, err := c.containerSpec("test-id", "sandbox-id", 1234, "", "container-name", containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) + spec, err := c.containerSpec("test-id", "sandbox-id", 1234, "", "container-name", testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) require.NoError(t, err) t.Log("resource limit should not be set") @@ -1340,7 +1343,7 @@ func TestPrivilegedDevices(t *testing.T) { ociRuntime := config.Runtime{ PrivilegedWithoutHostDevices: test.privilegedWithoutHostDevices, } - spec, err := c.containerSpec(t.Name(), testSandboxID, testPid, "", testContainerName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) + spec, err := c.containerSpec(t.Name(), testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) assert.NoError(t, err) hostDevicesRaw, err := devices.HostDevices() @@ -1389,7 +1392,7 @@ func TestBaseOCISpec(t *testing.T) { testPid := uint32(1234) containerConfig, sandboxConfig, imageConfig, specCheck := getCreateContainerTestData() - spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) + spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) assert.NoError(t, err) specCheck(t, testID, testSandboxID, testPid, spec) diff --git a/pkg/cri/server/container_create_other.go b/pkg/cri/server/container_create_other.go index e8af1488c..c532e0e5a 100644 --- a/pkg/cri/server/container_create_other.go +++ b/pkg/cri/server/container_create_other.go @@ -33,9 +33,19 @@ func (c *criService) containerMounts(sandboxID string, config *runtime.Container return []*runtime.Mount{} } -func (c *criService) containerSpec(id string, sandboxID string, sandboxPid uint32, netNSPath string, containerName string, - config *runtime.ContainerConfig, sandboxConfig *runtime.PodSandboxConfig, imageConfig *imagespec.ImageConfig, - extraMounts []*runtime.Mount, ociRuntime config.Runtime) (_ *runtimespec.Spec, retErr error) { +func (c *criService) containerSpec( + 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) { return c.runtimeSpec(id, ociRuntime.BaseRuntimeSpec) } diff --git a/pkg/cri/server/container_create_test.go b/pkg/cri/server/container_create_test.go index ce1bfb5af..a5954c510 100644 --- a/pkg/cri/server/container_create_test.go +++ b/pkg/cri/server/container_create_test.go @@ -52,6 +52,8 @@ func checkMount(t *testing.T, mounts []runtimespec.Mount, src, dest, typ string, assert.True(t, found, "mount from %q to %q not found", src, dest) } +const testImageName = "container-image-name" + func TestGeneralContainerSpec(t *testing.T) { testID := "test-id" testPid := uint32(1234) @@ -60,7 +62,7 @@ func TestGeneralContainerSpec(t *testing.T) { c := newTestCRIService() testSandboxID := "sandbox-id" testContainerName := "container-name" - spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) + spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) require.NoError(t, err) specCheck(t, testID, testSandboxID, testPid, spec) } @@ -124,7 +126,7 @@ func TestPodAnnotationPassthroughContainerSpec(t *testing.T) { ociRuntime := config.Runtime{ PodAnnotations: test.podAnnotations, } - spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, + spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) assert.NoError(t, err) assert.NotNil(t, spec) @@ -372,7 +374,7 @@ func TestContainerAnnotationPassthroughContainerSpec(t *testing.T) { PodAnnotations: test.podAnnotations, ContainerAnnotations: test.containerAnnotations, } - spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, + spec, err := c.containerSpec(testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime) assert.NoError(t, err) assert.NotNil(t, spec) diff --git a/pkg/cri/server/container_create_windows.go b/pkg/cri/server/container_create_windows.go index 22d264fdd..99d4539bb 100644 --- a/pkg/cri/server/container_create_windows.go +++ b/pkg/cri/server/container_create_windows.go @@ -34,9 +34,19 @@ func (c *criService) containerMounts(sandboxID string, config *runtime.Container return nil } -func (c *criService) containerSpec(id string, sandboxID string, sandboxPid uint32, netNSPath string, containerName string, - config *runtime.ContainerConfig, sandboxConfig *runtime.PodSandboxConfig, imageConfig *imagespec.ImageConfig, - extraMounts []*runtime.Mount, ociRuntime config.Runtime) (*runtimespec.Spec, error) { +func (c *criService) containerSpec( + 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, error) { specOpts := []oci.SpecOpts{ customopts.WithProcessArgs(config, imageConfig), } @@ -109,6 +119,7 @@ func (c *criService) containerSpec(id string, sandboxID string, sandboxPid uint3 customopts.WithAnnotation(annotations.SandboxNamespace, sandboxConfig.GetMetadata().GetNamespace()), customopts.WithAnnotation(annotations.SandboxName, sandboxConfig.GetMetadata().GetName()), customopts.WithAnnotation(annotations.ContainerName, containerName), + customopts.WithAnnotation(annotations.ImageName, imageName), ) return c.runtimeSpec(id, ociRuntime.BaseRuntimeSpec, specOpts...) } diff --git a/pkg/cri/server/container_create_windows_test.go b/pkg/cri/server/container_create_windows_test.go index 714cd8455..312880227 100644 --- a/pkg/cri/server/container_create_windows_test.go +++ b/pkg/cri/server/container_create_windows_test.go @@ -145,7 +145,7 @@ func TestContainerWindowsNetworkNamespace(t *testing.T) { c := newTestCRIService() containerConfig, sandboxConfig, imageConfig, specCheck := getCreateContainerTestData() - spec, err := c.containerSpec(testID, testSandboxID, testPid, nsPath, testContainerName, containerConfig, sandboxConfig, imageConfig, nil, config.Runtime{}) + spec, err := c.containerSpec(testID, testSandboxID, testPid, nsPath, testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, config.Runtime{}) assert.NoError(t, err) assert.NotNil(t, spec) specCheck(t, testID, testSandboxID, testPid, spec) @@ -167,7 +167,7 @@ func TestMountCleanPath(t *testing.T) { ContainerPath: "c:/test/container-path", HostPath: "c:/test/host-path", }) - spec, err := c.containerSpec(testID, testSandboxID, testPid, nsPath, testContainerName, containerConfig, sandboxConfig, imageConfig, nil, config.Runtime{}) + spec, err := c.containerSpec(testID, testSandboxID, testPid, nsPath, testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, config.Runtime{}) assert.NoError(t, err) assert.NotNil(t, spec) specCheck(t, testID, testSandboxID, testPid, spec) @@ -187,7 +187,7 @@ func TestMountNamedPipe(t *testing.T) { ContainerPath: `\\.\pipe\foo`, HostPath: `\\.\pipe\foo`, }) - spec, err := c.containerSpec(testID, testSandboxID, testPid, nsPath, testContainerName, containerConfig, sandboxConfig, imageConfig, nil, config.Runtime{}) + spec, err := c.containerSpec(testID, testSandboxID, testPid, nsPath, testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, config.Runtime{}) assert.NoError(t, err) assert.NotNil(t, spec) specCheck(t, testID, testSandboxID, testPid, spec)