
Revert PR 9713, as it appeared to break the compatibility too much
https://github.com/kubernetes/enhancements/pull/3858#issuecomment-1925441072
This reverts commit b2f254fff0
.
> Conflicts:
> internal/cri/opts/spec_linux_opts.go
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
310 lines
8.3 KiB
Go
310 lines
8.3 KiB
Go
/*
|
|
Copyright The containerd Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package config
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
|
|
|
|
"github.com/containerd/containerd/v2/pkg/deprecation"
|
|
)
|
|
|
|
func TestValidateConfig(t *testing.T) {
|
|
for desc, test := range map[string]struct {
|
|
runtimeConfig *RuntimeConfig
|
|
runtimeExpectedErr string
|
|
runtimeExpected *RuntimeConfig
|
|
imageConfig *ImageConfig
|
|
imageExpectedErr string
|
|
imageExpected *ImageConfig
|
|
serverConfig *ServerConfig
|
|
serverExpectedErr string
|
|
serverExpected *ServerConfig
|
|
warnings []deprecation.Warning
|
|
}{
|
|
"no default_runtime_name": {
|
|
runtimeConfig: &RuntimeConfig{},
|
|
runtimeExpectedErr: "`default_runtime_name` is empty",
|
|
},
|
|
"no runtime[default_runtime_name]": {
|
|
runtimeConfig: &RuntimeConfig{
|
|
ContainerdConfig: ContainerdConfig{
|
|
DefaultRuntimeName: RuntimeDefault,
|
|
},
|
|
},
|
|
runtimeExpectedErr: "no corresponding runtime configured in `containerd.runtimes` for `containerd` `default_runtime_name = \"default\"",
|
|
},
|
|
|
|
"deprecated auths": {
|
|
runtimeConfig: &RuntimeConfig{
|
|
ContainerdConfig: ContainerdConfig{
|
|
DefaultRuntimeName: RuntimeDefault,
|
|
Runtimes: map[string]Runtime{
|
|
RuntimeDefault: {},
|
|
},
|
|
},
|
|
},
|
|
runtimeExpected: &RuntimeConfig{
|
|
ContainerdConfig: ContainerdConfig{
|
|
DefaultRuntimeName: RuntimeDefault,
|
|
Runtimes: map[string]Runtime{
|
|
RuntimeDefault: {
|
|
Sandboxer: string(ModePodSandbox),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
imageConfig: &ImageConfig{
|
|
Registry: Registry{
|
|
Auths: map[string]AuthConfig{
|
|
"https://gcr.io": {Username: "test"},
|
|
},
|
|
},
|
|
},
|
|
imageExpected: &ImageConfig{
|
|
Registry: Registry{
|
|
Configs: map[string]RegistryConfig{
|
|
"gcr.io": {
|
|
Auth: &AuthConfig{
|
|
Username: "test",
|
|
},
|
|
},
|
|
},
|
|
Auths: map[string]AuthConfig{
|
|
"https://gcr.io": {Username: "test"},
|
|
},
|
|
},
|
|
},
|
|
warnings: []deprecation.Warning{deprecation.CRIRegistryAuths},
|
|
},
|
|
"invalid stream_idle_timeout": {
|
|
serverConfig: &ServerConfig{
|
|
StreamIdleTimeout: "invalid",
|
|
},
|
|
serverExpectedErr: "invalid stream idle timeout",
|
|
},
|
|
"conflicting mirror registry config": {
|
|
imageConfig: &ImageConfig{
|
|
Registry: Registry{
|
|
ConfigPath: "/etc/containerd/conf.d",
|
|
Mirrors: map[string]Mirror{
|
|
"something.io": {},
|
|
},
|
|
},
|
|
},
|
|
imageExpectedErr: "`mirrors` cannot be set when `config_path` is provided",
|
|
},
|
|
"deprecated mirrors": {
|
|
runtimeConfig: &RuntimeConfig{
|
|
ContainerdConfig: ContainerdConfig{
|
|
DefaultRuntimeName: RuntimeDefault,
|
|
Runtimes: map[string]Runtime{
|
|
RuntimeDefault: {},
|
|
},
|
|
},
|
|
},
|
|
imageConfig: &ImageConfig{
|
|
Registry: Registry{
|
|
Mirrors: map[string]Mirror{
|
|
"example.com": {},
|
|
},
|
|
},
|
|
},
|
|
runtimeExpected: &RuntimeConfig{
|
|
ContainerdConfig: ContainerdConfig{
|
|
DefaultRuntimeName: RuntimeDefault,
|
|
Runtimes: map[string]Runtime{
|
|
RuntimeDefault: {
|
|
Sandboxer: string(ModePodSandbox),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
imageExpected: &ImageConfig{
|
|
Registry: Registry{
|
|
Mirrors: map[string]Mirror{
|
|
"example.com": {},
|
|
},
|
|
},
|
|
},
|
|
warnings: []deprecation.Warning{deprecation.CRIRegistryMirrors},
|
|
},
|
|
"deprecated configs": {
|
|
runtimeConfig: &RuntimeConfig{
|
|
ContainerdConfig: ContainerdConfig{
|
|
DefaultRuntimeName: RuntimeDefault,
|
|
Runtimes: map[string]Runtime{
|
|
RuntimeDefault: {},
|
|
},
|
|
},
|
|
},
|
|
imageConfig: &ImageConfig{
|
|
Registry: Registry{
|
|
Configs: map[string]RegistryConfig{
|
|
"gcr.io": {
|
|
Auth: &AuthConfig{
|
|
Username: "test",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
runtimeExpected: &RuntimeConfig{
|
|
ContainerdConfig: ContainerdConfig{
|
|
DefaultRuntimeName: RuntimeDefault,
|
|
Runtimes: map[string]Runtime{
|
|
RuntimeDefault: {
|
|
Sandboxer: string(ModePodSandbox),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
imageExpected: &ImageConfig{
|
|
Registry: Registry{
|
|
Configs: map[string]RegistryConfig{
|
|
"gcr.io": {
|
|
Auth: &AuthConfig{
|
|
Username: "test",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
warnings: []deprecation.Warning{deprecation.CRIRegistryConfigs},
|
|
},
|
|
"privileged_without_host_devices_all_devices_allowed without privileged_without_host_devices": {
|
|
runtimeConfig: &RuntimeConfig{
|
|
ContainerdConfig: ContainerdConfig{
|
|
DefaultRuntimeName: RuntimeDefault,
|
|
Runtimes: map[string]Runtime{
|
|
RuntimeDefault: {
|
|
PrivilegedWithoutHostDevices: false,
|
|
PrivilegedWithoutHostDevicesAllDevicesAllowed: true,
|
|
Type: "default",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
runtimeExpectedErr: "`privileged_without_host_devices_all_devices_allowed` requires `privileged_without_host_devices` to be enabled",
|
|
},
|
|
"invalid drain_exec_sync_io_timeout input": {
|
|
runtimeConfig: &RuntimeConfig{
|
|
ContainerdConfig: ContainerdConfig{
|
|
DefaultRuntimeName: RuntimeDefault,
|
|
Runtimes: map[string]Runtime{
|
|
RuntimeDefault: {
|
|
Type: "default",
|
|
},
|
|
},
|
|
},
|
|
DrainExecSyncIOTimeout: "10",
|
|
},
|
|
runtimeExpectedErr: "invalid `drain_exec_sync_io_timeout`",
|
|
},
|
|
} {
|
|
t.Run(desc, func(t *testing.T) {
|
|
var warnings []deprecation.Warning
|
|
if test.runtimeConfig != nil {
|
|
w, err := ValidateRuntimeConfig(context.Background(), test.runtimeConfig)
|
|
if test.runtimeExpectedErr != "" {
|
|
assert.Contains(t, err.Error(), test.runtimeExpectedErr)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, test.runtimeExpected, test.runtimeConfig)
|
|
}
|
|
warnings = append(warnings, w...)
|
|
}
|
|
if test.imageConfig != nil {
|
|
w, err := ValidateImageConfig(context.Background(), test.imageConfig)
|
|
if test.imageExpectedErr != "" {
|
|
assert.Contains(t, err.Error(), test.imageExpectedErr)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, test.imageExpected, test.imageConfig)
|
|
}
|
|
warnings = append(warnings, w...)
|
|
}
|
|
if test.serverConfig != nil {
|
|
w, err := ValidateServerConfig(context.Background(), test.serverConfig)
|
|
if test.serverExpectedErr != "" {
|
|
assert.Contains(t, err.Error(), test.serverExpectedErr)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, test.serverExpected, test.serverConfig)
|
|
}
|
|
warnings = append(warnings, w...)
|
|
}
|
|
|
|
if len(test.warnings) > 0 {
|
|
assert.ElementsMatch(t, test.warnings, warnings)
|
|
} else {
|
|
assert.Len(t, warnings, 0)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHostAccessingSandbox(t *testing.T) {
|
|
privilegedContext := &runtime.PodSandboxConfig{
|
|
Linux: &runtime.LinuxPodSandboxConfig{
|
|
SecurityContext: &runtime.LinuxSandboxSecurityContext{
|
|
Privileged: true,
|
|
},
|
|
},
|
|
}
|
|
nonPrivilegedContext := &runtime.PodSandboxConfig{
|
|
Linux: &runtime.LinuxPodSandboxConfig{
|
|
SecurityContext: &runtime.LinuxSandboxSecurityContext{
|
|
Privileged: false,
|
|
},
|
|
},
|
|
}
|
|
hostNamespace := &runtime.PodSandboxConfig{
|
|
Linux: &runtime.LinuxPodSandboxConfig{
|
|
SecurityContext: &runtime.LinuxSandboxSecurityContext{
|
|
Privileged: false,
|
|
NamespaceOptions: &runtime.NamespaceOption{
|
|
Network: runtime.NamespaceMode_NODE,
|
|
Pid: runtime.NamespaceMode_NODE,
|
|
Ipc: runtime.NamespaceMode_NODE,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
config *runtime.PodSandboxConfig
|
|
want bool
|
|
}{
|
|
{"Security Context is nil", nil, false},
|
|
{"Security Context is privileged", privilegedContext, false},
|
|
{"Security Context is not privileged", nonPrivilegedContext, false},
|
|
{"Security Context namespace host access", hostNamespace, true},
|
|
}
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := hostAccessingSandbox(tt.config); got != tt.want {
|
|
t.Errorf("hostAccessingSandbox() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|