diff --git a/cmd/containerd/command/config.go b/cmd/containerd/command/config.go index 0e08f5afa..84e418e95 100644 --- a/cmd/containerd/command/config.go +++ b/cmd/containerd/command/config.go @@ -123,6 +123,28 @@ var configCommand = cli.Command{ } } + plugins, err := server.LoadPlugins(ctx, config) + if err != nil { + return err + } + if len(plugins) != 0 { + if config.Plugins == nil { + config.Plugins = make(map[string]interface{}) + } + for _, p := range plugins { + if p.Config == nil { + continue + } + + pc, err := config.Decode(ctx, p.URI(), p.Config) + if err != nil { + return err + } + + config.Plugins[p.URI()] = pc + } + } + config.Version = srvconfig.CurrentConfigVersion return toml.NewEncoder(os.Stdout).SetIndentTables(true).Encode(config) diff --git a/cmd/containerd/server/config/config.go b/cmd/containerd/server/config/config.go index 3962cd9f4..ac0a6e8a5 100644 --- a/cmd/containerd/server/config/config.go +++ b/cmd/containerd/server/config/config.go @@ -30,6 +30,7 @@ import ( "io" "os" "path/filepath" + "reflect" "strings" "dario.cat/mergo" @@ -310,12 +311,6 @@ func LoadConfig(ctx context.Context, path string, out *Config) error { pending = append(pending, imports...) } - // Fix up the list of config files loaded - out.Imports = []string{} - for path := range loaded { - out.Imports = append(out.Imports, path) - } - err := out.ValidateVersion() if err != nil { return fmt.Errorf("failed to load TOML from %s: %w", path, err) @@ -408,9 +403,11 @@ func resolveImports(parent string, imports []string) ([]string, error) { // 0 1 1 // []{"1"} []{"2"} []{"1","2"} // []{"1"} []{} []{"1"} +// []{"1", "2"} []{"1"} []{"1","2"} +// []{} []{"2"} []{"2"} // Maps merged by keys, but values are replaced entirely. func mergeConfig(to, from *Config) error { - err := mergo.Merge(to, from, mergo.WithOverride, mergo.WithAppendSlice) + err := mergo.Merge(to, from, mergo.WithOverride, mergo.WithTransformers(sliceTransformer{})) if err != nil { return err } @@ -435,6 +432,43 @@ func mergeConfig(to, from *Config) error { return nil } +type sliceTransformer struct{} + +func (sliceTransformer) Transformer(t reflect.Type) func(dst, src reflect.Value) error { + if t.Kind() != reflect.Slice { + return nil + } + return func(dst, src reflect.Value) error { + if !dst.CanSet() { + return nil + } + if src.Type() != dst.Type() { + return fmt.Errorf("cannot append two slice with different type (%s, %s)", src.Type(), dst.Type()) + } + for i := 0; i < src.Len(); i++ { + found := false + for j := 0; j < dst.Len(); j++ { + srcv := src.Index(i) + dstv := dst.Index(j) + if !srcv.CanInterface() || !dstv.CanInterface() { + if srcv.Equal(dstv) { + found = true + break + } + } else if reflect.DeepEqual(srcv.Interface(), dstv.Interface()) { + found = true + break + } + } + if !found { + dst.Set(reflect.Append(dst, src.Index(i))) + } + } + + return nil + } +} + // V2DisabledFilter matches based on URI func V2DisabledFilter(list []string) plugin.DisableFilter { set := make(map[string]struct{}, len(list)) diff --git a/cmd/containerd/server/config/config_test.go b/cmd/containerd/server/config/config_test.go index 39d3a6616..817e82028 100644 --- a/cmd/containerd/server/config/config_test.go +++ b/cmd/containerd/server/config/config_test.go @@ -50,6 +50,7 @@ func TestMergeConfigs(t *testing.T) { Version: 2, Root: "new_root", RequiredPlugins: []string{"io.containerd.new_plugin1.v1", "io.containerd.new_plugin2.v1"}, + DisabledPlugins: []string{"io.containerd.old_plugin.v1"}, OOMScore: 2, Timeouts: map[string]string{"b": "2"}, StreamProcessors: map[string]StreamProcessor{"1": {Path: "3"}}, @@ -191,8 +192,8 @@ imports = ["data1.toml", "data2.toml"] sort.Strings(out.Imports) assert.Equal(t, []string{ - filepath.Join(tempDir, "data1.toml"), - filepath.Join(tempDir, "data2.toml"), + "data1.toml", + "data2.toml", }, out.Imports) } diff --git a/integration/client/migration_test.go b/integration/client/migration_test.go new file mode 100644 index 000000000..c50626e8d --- /dev/null +++ b/integration/client/migration_test.go @@ -0,0 +1,92 @@ +/* + 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 client + +import ( + "bytes" + "os" + "os/exec" + "path/filepath" + "runtime" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestMigration(t *testing.T) { + currentDefault := filepath.Join(t.TempDir(), "default.toml") + defaultContent, err := currentDefaultConfig() + require.NoError(t, err) + require.NoError(t, os.WriteFile(currentDefault, []byte(defaultContent), 0644)) + + type migrationTest struct { + Name string + File string + Migrated string + } + migrationTests := []migrationTest{ + { + Name: "CurrentDefault", + File: currentDefault, + Migrated: defaultContent, + }, + } + + // Only run the old version migration tests for the same platform + // and build settings the default config was generated for. + if runtime.GOOS == "linux" && runtime.GOARCH == "amd64" && strings.Contains(defaultContent, "btrfs") && strings.Contains(defaultContent, "devmapper") { + migrationTests = append(migrationTests, []migrationTest{ + { + Name: "1.6-Default", + File: "testdata/default-1.6.toml", + Migrated: defaultContent, + }, + { + Name: "1.7-Default", + File: "testdata/default-1.7.toml", + Migrated: defaultContent, + }, + }...) + } + + for _, tc := range migrationTests { + tc := tc + t.Run(tc.Name, func(t *testing.T) { + buf := bytes.NewBuffer(nil) + cmd := exec.Command("containerd", "-c", tc.File, "config", "migrate") + cmd.Stdout = buf + cmd.Stderr = os.Stderr + require.NoError(t, cmd.Run()) + actual := buf.String() + assert.Equal(t, tc.Migrated, actual) + }) + } + +} + +func currentDefaultConfig() (string, error) { + cmd := exec.Command("containerd", "config", "default") + buf := bytes.NewBuffer(nil) + cmd.Stdout = buf + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + return "", err + } + return buf.String(), nil +} diff --git a/integration/client/testdata/default-1.6.toml b/integration/client/testdata/default-1.6.toml new file mode 100644 index 000000000..810b78925 --- /dev/null +++ b/integration/client/testdata/default-1.6.toml @@ -0,0 +1,263 @@ +disabled_plugins = [] +imports = [] +oom_score = 0 +plugin_dir = "" +required_plugins = [] +root = "/var/lib/containerd" +state = "/run/containerd" +temp = "" +version = 2 + +[cgroup] + path = "" + +[debug] + address = "" + format = "" + gid = 0 + level = "" + uid = 0 + +[grpc] + address = "/run/containerd/containerd.sock" + gid = 0 + max_recv_message_size = 16777216 + max_send_message_size = 16777216 + tcp_address = "" + tcp_tls_ca = "" + tcp_tls_cert = "" + tcp_tls_key = "" + uid = 0 + +[metrics] + address = "" + grpc_histogram = false + +[plugins] + + [plugins."io.containerd.gc.v1.scheduler"] + deletion_threshold = 0 + mutation_threshold = 100 + pause_threshold = 0.02 + schedule_delay = "0s" + startup_delay = "100ms" + + [plugins."io.containerd.grpc.v1.cri"] + device_ownership_from_security_context = false + disable_apparmor = false + disable_cgroup = false + disable_hugetlb_controller = true + disable_proc_mount = false + disable_tcp_service = true + enable_selinux = false + enable_tls_streaming = false + # Defaults change to true in latest + #enable_unprivileged_icmp = false + #enable_unprivileged_ports = false + enable_unprivileged_icmp = true + enable_unprivileged_ports = true + ignore_image_defined_volumes = false + max_concurrent_downloads = 3 + max_container_log_line_size = 16384 + netns_mounts_under_state_dir = false + restrict_oom_score_adj = false + # Default image update in latest + #sandbox_image = "registry.k8s.io/pause:3.6" + sandbox_image = "registry.k8s.io/pause:3.9" + selinux_category_range = 1024 + stats_collect_period = 10 + stream_idle_timeout = "4h0m0s" + stream_server_address = "127.0.0.1" + stream_server_port = "0" + systemd_cgroup = false + tolerate_missing_hugetlb_controller = true + unset_seccomp_profile = "" + + [plugins."io.containerd.grpc.v1.cri".cni] + bin_dir = "/opt/cni/bin" + conf_dir = "/etc/cni/net.d" + conf_template = "" + ip_pref = "" + max_conf_num = 1 + + [plugins."io.containerd.grpc.v1.cri".containerd] + default_runtime_name = "runc" + disable_snapshot_annotations = true + discard_unpacked_layers = false + ignore_rdt_not_enabled_errors = false + no_pivot = false + snapshotter = "overlayfs" + + [plugins."io.containerd.grpc.v1.cri".containerd.default_runtime] + base_runtime_spec = "" + cni_conf_dir = "" + cni_max_conf_num = 0 + container_annotations = [] + pod_annotations = [] + privileged_without_host_devices = false + runtime_engine = "" + runtime_path = "" + runtime_root = "" + runtime_type = "" + + [plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options] + + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] + + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] + base_runtime_spec = "" + cni_conf_dir = "" + cni_max_conf_num = 0 + container_annotations = [] + pod_annotations = [] + privileged_without_host_devices = false + runtime_engine = "" + runtime_path = "" + runtime_root = "" + runtime_type = "io.containerd.runc.v2" + + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] + BinaryName = "" + CriuImagePath = "" + CriuWorkPath = "" + IoGid = 0 + IoUid = 0 + NoNewKeyring = false + Root = "" + ShimCgroup = "" + # Removed in latest + #CriuPath = "" + #NoPivotRoot = false + #SystemdCgroup = false + + [plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime] + base_runtime_spec = "" + cni_conf_dir = "" + cni_max_conf_num = 0 + container_annotations = [] + pod_annotations = [] + privileged_without_host_devices = false + runtime_engine = "" + runtime_path = "" + runtime_root = "" + runtime_type = "" + + [plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime.options] + + [plugins."io.containerd.grpc.v1.cri".image_decryption] + key_model = "node" + + [plugins."io.containerd.grpc.v1.cri".registry] + config_path = "" + + [plugins."io.containerd.grpc.v1.cri".registry.auths] + + [plugins."io.containerd.grpc.v1.cri".registry.configs] + + [plugins."io.containerd.grpc.v1.cri".registry.headers] + + [plugins."io.containerd.grpc.v1.cri".registry.mirrors] + + [plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming] + tls_cert_file = "" + tls_key_file = "" + + [plugins."io.containerd.internal.v1.opt"] + path = "/opt/containerd" + + [plugins."io.containerd.internal.v1.restart"] + interval = "10s" + + [plugins."io.containerd.internal.v1.tracing"] + sampling_ratio = 1.0 + service_name = "containerd" + + [plugins."io.containerd.metadata.v1.bolt"] + content_sharing_policy = "shared" + + [plugins."io.containerd.monitor.v1.cgroups"] + no_prometheus = false + + # Removed in latest + #[plugins."io.containerd.runtime.v1.linux"] + # no_shim = false + # runtime = "runc" + # runtime_root = "" + # shim = "containerd-shim" + # shim_debug = false + + [plugins."io.containerd.runtime.v2.task"] + platforms = ["linux/amd64"] + sched_core = false + + [plugins."io.containerd.service.v1.diff-service"] + default = ["walking"] + + [plugins."io.containerd.service.v1.tasks-service"] + rdt_config_file = "" + + # Removed in latest + #[plugins."io.containerd.snapshotter.v1.aufs"] + # root_path = "" + + [plugins."io.containerd.snapshotter.v1.btrfs"] + root_path = "" + + [plugins."io.containerd.snapshotter.v1.devmapper"] + async_remove = false + base_image_size = "" + discard_blocks = false + fs_options = "" + fs_type = "" + pool_name = "" + root_path = "" + + [plugins."io.containerd.snapshotter.v1.native"] + root_path = "" + + [plugins."io.containerd.snapshotter.v1.overlayfs"] + mount_options = [] + root_path = "" + sync_remove = false + upperdir_label = false + + # Removed in latest + #[plugins."io.containerd.snapshotter.v1.zfs"] + # root_path = "" + + [plugins."io.containerd.tracing.processor.v1.otlp"] + endpoint = "" + insecure = false + protocol = "" + +[proxy_plugins] + +[stream_processors] + + [stream_processors."io.containerd.ocicrypt.decoder.v1.tar"] + accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"] + args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"] + env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"] + path = "ctd-decoder" + returns = "application/vnd.oci.image.layer.v1.tar" + + [stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"] + accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"] + args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"] + env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"] + path = "ctd-decoder" + returns = "application/vnd.oci.image.layer.v1.tar+gzip" + +[timeouts] + "io.containerd.timeout.bolt.open" = "0s" + "io.containerd.timeout.shim.cleanup" = "5s" + "io.containerd.timeout.shim.load" = "5s" + "io.containerd.timeout.shim.shutdown" = "3s" + "io.containerd.timeout.task.state" = "2s" + # Added in latest + "io.containerd.timeout.metrics.shimstats" = "2s" + +[ttrpc] + address = "" + gid = 0 + uid = 0 diff --git a/integration/client/testdata/default-1.7.toml b/integration/client/testdata/default-1.7.toml new file mode 100644 index 000000000..ede46d9c7 --- /dev/null +++ b/integration/client/testdata/default-1.7.toml @@ -0,0 +1,306 @@ +disabled_plugins = [] +imports = [] +oom_score = 0 +plugin_dir = "" +required_plugins = [] +root = "/var/lib/containerd" +state = "/run/containerd" +temp = "" +version = 2 + +[cgroup] + path = "" + +[debug] + address = "" + format = "" + gid = 0 + level = "" + uid = 0 + +[grpc] + address = "/run/containerd/containerd.sock" + gid = 0 + max_recv_message_size = 16777216 + max_send_message_size = 16777216 + tcp_address = "" + tcp_tls_ca = "" + tcp_tls_cert = "" + tcp_tls_key = "" + uid = 0 + +[metrics] + address = "" + grpc_histogram = false + +[plugins] + + [plugins."io.containerd.gc.v1.scheduler"] + deletion_threshold = 0 + mutation_threshold = 100 + pause_threshold = 0.02 + schedule_delay = "0s" + startup_delay = "100ms" + + [plugins."io.containerd.grpc.v1.cri"] + cdi_spec_dirs = ["/etc/cdi", "/var/run/cdi"] + device_ownership_from_security_context = false + disable_apparmor = false + disable_cgroup = false + disable_hugetlb_controller = true + disable_proc_mount = false + disable_tcp_service = true + drain_exec_sync_io_timeout = "0s" + # Updated in latest release + #enable_cdi = false + enable_cdi = true + enable_selinux = false + enable_tls_streaming = false + # Updated in latest release + #enable_unprivileged_icmp = false + #enable_unprivileged_ports = false + enable_unprivileged_icmp = true + enable_unprivileged_ports = true + ignore_image_defined_volumes = false + image_pull_progress_timeout = "5m0s" + max_concurrent_downloads = 3 + max_container_log_line_size = 16384 + netns_mounts_under_state_dir = false + restrict_oom_score_adj = false + # Updated in latest + #sandbox_image = "registry.k8s.io/pause:3.8" + sandbox_image = "registry.k8s.io/pause:3.9" + selinux_category_range = 1024 + stats_collect_period = 10 + stream_idle_timeout = "4h0m0s" + stream_server_address = "127.0.0.1" + stream_server_port = "0" + systemd_cgroup = false + tolerate_missing_hugetlb_controller = true + unset_seccomp_profile = "" + + [plugins."io.containerd.grpc.v1.cri".cni] + bin_dir = "/opt/cni/bin" + conf_dir = "/etc/cni/net.d" + conf_template = "" + ip_pref = "" + max_conf_num = 1 + setup_serially = false + + [plugins."io.containerd.grpc.v1.cri".containerd] + default_runtime_name = "runc" + disable_snapshot_annotations = true + discard_unpacked_layers = false + ignore_blockio_not_enabled_errors = false + ignore_rdt_not_enabled_errors = false + no_pivot = false + snapshotter = "overlayfs" + + [plugins."io.containerd.grpc.v1.cri".containerd.default_runtime] + base_runtime_spec = "" + cni_conf_dir = "" + cni_max_conf_num = 0 + container_annotations = [] + pod_annotations = [] + privileged_without_host_devices = false + privileged_without_host_devices_all_devices_allowed = false + runtime_engine = "" + runtime_path = "" + runtime_root = "" + runtime_type = "" + sandbox_mode = "" + snapshotter = "" + + [plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options] + + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] + + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] + base_runtime_spec = "" + cni_conf_dir = "" + cni_max_conf_num = 0 + container_annotations = [] + pod_annotations = [] + privileged_without_host_devices = false + privileged_without_host_devices_all_devices_allowed = false + runtime_engine = "" + runtime_path = "" + runtime_root = "" + runtime_type = "io.containerd.runc.v2" + sandbox_mode = "podsandbox" + snapshotter = "" + + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] + BinaryName = "" + CriuImagePath = "" + CriuWorkPath = "" + IoGid = 0 + IoUid = 0 + NoNewKeyring = false + Root = "" + ShimCgroup = "" + # Removed in latest + #CriuPath = "" + #NoPivotRoot = false + #SystemdCgroup = false + + [plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime] + base_runtime_spec = "" + cni_conf_dir = "" + cni_max_conf_num = 0 + container_annotations = [] + pod_annotations = [] + privileged_without_host_devices = false + privileged_without_host_devices_all_devices_allowed = false + runtime_engine = "" + runtime_path = "" + runtime_root = "" + runtime_type = "" + sandbox_mode = "" + snapshotter = "" + + [plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime.options] + + [plugins."io.containerd.grpc.v1.cri".image_decryption] + key_model = "node" + + [plugins."io.containerd.grpc.v1.cri".registry] + config_path = "" + + [plugins."io.containerd.grpc.v1.cri".registry.auths] + + [plugins."io.containerd.grpc.v1.cri".registry.configs] + + [plugins."io.containerd.grpc.v1.cri".registry.headers] + + [plugins."io.containerd.grpc.v1.cri".registry.mirrors] + + [plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming] + tls_cert_file = "" + tls_key_file = "" + + [plugins."io.containerd.internal.v1.opt"] + path = "/opt/containerd" + + [plugins."io.containerd.internal.v1.restart"] + interval = "10s" + + [plugins."io.containerd.internal.v1.tracing"] + sampling_ratio = 1.0 + service_name = "containerd" + + [plugins."io.containerd.metadata.v1.bolt"] + content_sharing_policy = "shared" + + [plugins."io.containerd.monitor.v1.cgroups"] + no_prometheus = false + + [plugins."io.containerd.nri.v1.nri"] + disable = true + disable_connections = false + plugin_config_path = "/etc/nri/conf.d" + plugin_path = "/opt/nri/plugins" + plugin_registration_timeout = "5s" + plugin_request_timeout = "2s" + socket_path = "/var/run/nri/nri.sock" + + # Removed in latest + #[plugins."io.containerd.runtime.v1.linux"] + # no_shim = false + # runtime = "runc" + # runtime_root = "" + # shim = "containerd-shim" + # shim_debug = false + + [plugins."io.containerd.runtime.v2.task"] + platforms = ["linux/amd64"] + sched_core = false + + [plugins."io.containerd.service.v1.diff-service"] + default = ["walking"] + + [plugins."io.containerd.service.v1.tasks-service"] + blockio_config_file = "" + rdt_config_file = "" + + # Removed in latest + #[plugins."io.containerd.snapshotter.v1.aufs"] + # root_path = "" + + [plugins."io.containerd.snapshotter.v1.blockfile"] + fs_type = "" + mount_options = [] + root_path = "" + scratch_file = "" + + [plugins."io.containerd.snapshotter.v1.btrfs"] + root_path = "" + + [plugins."io.containerd.snapshotter.v1.devmapper"] + async_remove = false + base_image_size = "" + discard_blocks = false + fs_options = "" + fs_type = "" + pool_name = "" + root_path = "" + + [plugins."io.containerd.snapshotter.v1.native"] + root_path = "" + + [plugins."io.containerd.snapshotter.v1.overlayfs"] + mount_options = [] + root_path = "" + sync_remove = false + upperdir_label = false + + # Removed in latest + #[plugins."io.containerd.snapshotter.v1.zfs"] + # root_path = "" + + [plugins."io.containerd.tracing.processor.v1.otlp"] + endpoint = "" + insecure = false + protocol = "" + + [plugins."io.containerd.transfer.v1.local"] + config_path = "" + max_concurrent_downloads = 3 + max_concurrent_uploaded_layers = 3 + + # In 2.0, the default unpack config is applied when not specified + #[[plugins."io.containerd.transfer.v1.local".unpack_config]] + # differ = "" + # platform = "linux/amd64" + # snapshotter = "overlayfs" + +[proxy_plugins] + +[stream_processors] + + [stream_processors."io.containerd.ocicrypt.decoder.v1.tar"] + accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"] + args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"] + env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"] + path = "ctd-decoder" + returns = "application/vnd.oci.image.layer.v1.tar" + + [stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"] + accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"] + args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"] + env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"] + path = "ctd-decoder" + returns = "application/vnd.oci.image.layer.v1.tar+gzip" + +[timeouts] + "io.containerd.timeout.bolt.open" = "0s" + "io.containerd.timeout.metrics.shimstats" = "2s" + "io.containerd.timeout.shim.cleanup" = "5s" + "io.containerd.timeout.shim.load" = "5s" + "io.containerd.timeout.shim.shutdown" = "3s" + "io.containerd.timeout.task.state" = "2s" + +[ttrpc] + address = "" + gid = 0 + uid = 0 diff --git a/pkg/cri/server/base/cri_base.go b/pkg/cri/server/base/cri_base.go index a719e21e4..f5eaa23cb 100644 --- a/pkg/cri/server/base/cri_base.go +++ b/pkg/cri/server/base/cri_base.go @@ -69,6 +69,7 @@ func init() { conf := c.(map[string]interface{}) migrateConfig(conf) plugins["io.containerd.internal.v1.cri"] = conf + delete(plugins, "io.containerd.grpc.v1.cri") return nil }, InitFn: initCRIBase, diff --git a/plugins/transfer/plugin.go b/plugins/transfer/plugin.go index 38972b29a..90185e78b 100644 --- a/plugins/transfer/plugin.go +++ b/plugins/transfer/plugin.go @@ -77,6 +77,17 @@ func init() { var lc local.TransferConfig lc.MaxConcurrentDownloads = config.MaxConcurrentDownloads lc.MaxConcurrentUploadedLayers = config.MaxConcurrentUploadedLayers + + // If UnpackConfiguration is not defined, set the default. + // If UnpackConfiguration is defined and empty, ignore. + if config.UnpackConfiguration == nil { + config.UnpackConfiguration = []unpackConfiguration{ + { + Platform: platforms.Format(platforms.DefaultSpec()), + Snapshotter: defaults.DefaultSnapshotter, + }, + } + } for _, uc := range config.UnpackConfiguration { p, err := platforms.Parse(uc.Platform) if err != nil { @@ -148,7 +159,7 @@ type transferConfig struct { MaxConcurrentUploadedLayers int `toml:"max_concurrent_uploaded_layers"` // UnpackConfiguration is used to read config from toml - UnpackConfiguration []unpackConfiguration `toml:"unpack_config"` + UnpackConfiguration []unpackConfiguration `toml:"unpack_config,omitempty"` // RegistryConfigPath is a path to the root directory containing registry-specific configurations RegistryConfigPath string `toml:"config_path"` @@ -169,11 +180,5 @@ func defaultConfig() *transferConfig { return &transferConfig{ MaxConcurrentDownloads: 3, MaxConcurrentUploadedLayers: 3, - UnpackConfiguration: []unpackConfiguration{ - { - Platform: platforms.Format(platforms.DefaultSpec()), - Snapshotter: defaults.DefaultSnapshotter, - }, - }, } }