From 76049febee22f676304c99948e5b609eb6f99596 Mon Sep 17 00:00:00 2001 From: Martin Sivak Date: Tue, 12 Nov 2024 13:35:31 +0100 Subject: [PATCH] RuntimeHandler inheritance This allows defining a RuntimeHandler with custom annotations or other fields while inheriting the runtime type from the default runtime. This behavior is useful for layered projects that are not in control of the runtime selection but need to tweak the specific behavior while inheriting the node global runtime. Signed-off-by: Martin Sivak --- docs/crio.conf.5.md | 3 +++ pkg/config/config.go | 4 ++++ pkg/config/config_test.go | 14 ++++++++++++++ pkg/config/reload.go | 10 ++++++++++ pkg/config/reload_test.go | 24 ++++++++++++++++++++++++ pkg/config/template.go | 5 +++++ 6 files changed, 60 insertions(+) diff --git a/docs/crio.conf.5.md b/docs/crio.conf.5.md index 068e5be6e92..b758404c427 100644 --- a/docs/crio.conf.5.md +++ b/docs/crio.conf.5.md @@ -345,6 +345,9 @@ Root directory used to store runtime data **runtime_type**="oci" Type of the runtime used for this runtime handler. "oci", "vm" +**inherit_default_runtime**=false +Override the runtime path, runtime config path, runtime root and runtime type from the default runtime on load. + **runtime_config_path**="" Path to the runtime configuration file, should only be used with VM runtime types diff --git a/pkg/config/config.go b/pkg/config/config.go index 199176f784e..e234bcb2a2d 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -264,6 +264,10 @@ type RuntimeHandler struct { // Output of the "features" subcommand. // This is populated dynamically and not read from config. features runtimeHandlerFeatures + + // Inheritance request + // Fill in the Runtime information (paths and type) from the default runtime + InheritDefaultRuntime bool `toml:"inherit_default_runtime,omitempty"` } // Multiple runtime Handlers in a map. diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 540da450358..fef630dd517 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -1458,6 +1458,20 @@ var _ = t.Describe("Config", func() { // Then Expect(err).ToNot(HaveOccurred()) }) + + It("should succeed with empty runtime type and runtime_config_path when inheriting from default", func() { + // Given + sut.Runtimes["inherited"] = &config.RuntimeHandler{ + RuntimeConfigPath: invalidPath, RuntimeType: "invalid", InheritDefaultRuntime: true, + } + err := sut.ReloadRuntimes(sut) + Expect(err).ToNot(HaveOccurred()) + + // When + err = sut.Validate(false) + // Then + Expect(err).ToNot(HaveOccurred()) + }) }) t.Describe("RuntimeHandlerFeatures", func() { diff --git a/pkg/config/reload.go b/pkg/config/reload.go index 0fef2bf987e..004cd629bd1 100644 --- a/pkg/config/reload.go +++ b/pkg/config/reload.go @@ -285,6 +285,16 @@ func (c *Config) ReloadRuntimes(newConfig *Config) error { return nil } + // Update the default runtime paths in all runtimes that are asking for inheritance + for _, runtime := range c.Runtimes { + if runtime.InheritDefaultRuntime { + runtime.RuntimePath = c.Runtimes[c.DefaultRuntime].RuntimePath + runtime.RuntimeType = c.Runtimes[c.DefaultRuntime].RuntimeType + runtime.RuntimeConfigPath = c.Runtimes[c.DefaultRuntime].RuntimeConfigPath + runtime.RuntimeRoot = c.Runtimes[c.DefaultRuntime].RuntimeRoot + } + } + if err := c.ValidateRuntimes(); err != nil { return fmt.Errorf("unabled to reload runtimes: %w", err) } diff --git a/pkg/config/reload_test.go b/pkg/config/reload_test.go index 2bbb495d3aa..d401369c1f9 100644 --- a/pkg/config/reload_test.go +++ b/pkg/config/reload_test.go @@ -428,6 +428,30 @@ var _ = t.Describe("Config", func() { Expect(sut.Runtimes).To(HaveKeyWithValue("existing", newRuntime)) Expect(sut.Runtimes["existing"].PrivilegedWithoutHostDevices).To(BeTrue()) }) + + It("should inherit runtime config", func() { + // Given + newRuntime := &config.RuntimeHandler{ + RuntimePath: invalidPath, + InheritDefaultRuntime: true, + } + defaultRuntime := &config.RuntimeHandler{ + RuntimePath: existingRuntimePath, + } + newConfig := &config.Config{} + newConfig.DefaultRuntime = "default" + newConfig.Runtimes = make(config.Runtimes) + newConfig.Runtimes["default"] = defaultRuntime + newConfig.Runtimes["new"] = newRuntime + + // When + err := sut.ReloadRuntimes(newConfig) + + // Then + Expect(err).ToNot(HaveOccurred()) + Expect(sut.Runtimes).To(HaveKeyWithValue("new", newRuntime)) + Expect(sut.Runtimes["new"].RuntimePath).To(Equal(existingRuntimePath)) + }) }) t.Describe("ReloadPinnedImages", func() { diff --git a/pkg/config/template.go b/pkg/config/template.go index 7826bf52e02..63123b6665a 100644 --- a/pkg/config/template.go +++ b/pkg/config/template.go @@ -1231,6 +1231,7 @@ const templateStringCrioRuntimeRuntimesRuntimeHandler = `# The "crio.runtime.run # runtime_path = "/path/to/the/executable" # runtime_type = "oci" # runtime_root = "/path/to/the/root" +# inherit_default_runtime = false # monitor_path = "/path/to/container/monitor" # monitor_cgroup = "/cgroup/path" # monitor_exec_cgroup = "/cgroup/path" @@ -1251,6 +1252,9 @@ const templateStringCrioRuntimeRuntimesRuntimeHandler = `# The "crio.runtime.run # state. # - runtime_config_path (optional, string): the path for the runtime configuration # file. This can only be used with when using the VM runtime_type. +# - inherit_default_runtime (optional, bool): when true the runtime_path, +# runtime_type, runtime_root and runtime_config_path will be replaced by +# the values from the default runtime on load time. # - privileged_without_host_devices (optional, bool): an option for restricting # host devices from being passed to privileged containers. # - allowed_annotations (optional, array of strings): an option for specifying @@ -1321,6 +1325,7 @@ const templateStringCrioRuntimeRuntimesRuntimeHandler = `# The "crio.runtime.run {{ $.Comment }}runtime_path = "{{ $runtime_handler.RuntimePath }}" {{ $.Comment }}runtime_type = "{{ $runtime_handler.RuntimeType }}" {{ $.Comment }}runtime_root = "{{ $runtime_handler.RuntimeRoot }}" +{{ $.Comment }}inherit_default_runtime = {{ $runtime_handler.InheritDefaultRuntime }} {{ $.Comment }}runtime_config_path = "{{ $runtime_handler.RuntimeConfigPath }}" {{ $.Comment }}container_min_memory = "{{ $runtime_handler.ContainerMinMemory }}" {{ $.Comment }}monitor_path = "{{ $runtime_handler.MonitorPath }}"