diff --git a/cmd/urunc/create.go b/cmd/urunc/create.go index 5a9e2f94d..aeb04b77a 100644 --- a/cmd/urunc/create.go +++ b/cmd/urunc/create.go @@ -74,7 +74,7 @@ var createCommand = &cli.Command{ return err } if !cmd.Bool("reexec") { - uruncCfg, _ := unikontainers.LoadUruncConfig(unikontainers.UruncConfigPath) // ignore the error and use default config + uruncCfg, _ := unikontainers.LoadUruncConfig(unikontainers.ResolveUruncConfigPath()) // ignore the error and use default config return createUnikontainer(cmd, uruncCfg) } diff --git a/cmd/urunc/main.go b/cmd/urunc/main.go index 7a103aacf..6b673d97d 100644 --- a/cmd/urunc/main.go +++ b/cmd/urunc/main.go @@ -135,7 +135,7 @@ func main() { return nil, err } // ignore error since ParseLogMetricsConfig will print a warning and return default values - cfg, _ := unikontainers.ParseLogMetricsConfig(unikontainers.UruncConfigPath) + cfg, _ := unikontainers.ParseLogMetricsConfig(unikontainers.ResolveUruncConfigPath()) err := configLogrus(cmd, cfg.Log) if err != nil { return nil, err diff --git a/docs/configuration.md b/docs/configuration.md index a2daa4ba4..312fb3108 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -2,7 +2,16 @@ ## Configuration File Location -`urunc` looks for its configuration file at `/etc/urunc/config.toml`. If the file doesn't exist or contains invalid configuration, `urunc` will use sensible defaults and continue to operate normally. +`urunc` looks for its configuration file at `/etc/urunc/config.toml` by default. The location can be overridden with the `URUNC_CONFIG_FILE` environment variable, for example `URUNC_CONFIG_FILE=/var/etc/urunc/config.toml`. If the file doesn't exist or contains invalid configuration, `urunc` will use sensible defaults and continue to operate normally. + +One way to set the variable is to replace the `containerd-shim-urunc-v2` binary that containerd invokes with a small wrapper script that sets it and execs the real shim. For example, move the real shim aside (e.g. to `containerd-shim-urunc-v2.real`) and save the following as `/usr/local/bin/containerd-shim-urunc-v2`: + +```bash +#!/bin/bash +URUNC_CONFIG_FILE=/some/path/config.toml exec /usr/local/bin/containerd-shim-urunc-v2.real "$@" +``` + +where `/some/path/config.toml` is the configuration file to use and `/usr/local/bin/containerd-shim-urunc-v2.real` is the actual shim binary. ## Configuration File Format diff --git a/pkg/containerd-shim/guest_rootfs.go b/pkg/containerd-shim/guest_rootfs.go index f8982ecf1..98a4b2531 100644 --- a/pkg/containerd-shim/guest_rootfs.go +++ b/pkg/containerd-shim/guest_rootfs.go @@ -59,7 +59,7 @@ func chooseGuestRootfs(r *taskAPI.CreateTaskRequest) error { } annotations := config.Map() - uruncCfg, err := unikontainers.LoadUruncConfig(unikontainers.UruncConfigPath) + uruncCfg, err := unikontainers.LoadUruncConfig(unikontainers.ResolveUruncConfigPath()) if err != nil && uruncCfg == nil { return err } diff --git a/pkg/unikontainers/urunc_config.go b/pkg/unikontainers/urunc_config.go index 22573f43c..fb071fea3 100644 --- a/pkg/unikontainers/urunc_config.go +++ b/pkg/unikontainers/urunc_config.go @@ -15,6 +15,7 @@ package unikontainers import ( + "os" "strconv" "strings" @@ -24,6 +25,20 @@ import ( const UruncConfigPath = "/etc/urunc/config.toml" +// UruncConfigFileEnv is the environment variable that overrides the default +// location of the urunc configuration file. +const UruncConfigFileEnv = "URUNC_CONFIG_FILE" + +// ResolveUruncConfigPath returns the path to the urunc configuration file. It +// uses the URUNC_CONFIG_FILE environment variable when it is set and falls back +// to UruncConfigPath (/etc/urunc/config.toml) otherwise. +func ResolveUruncConfigPath() string { + if path := os.Getenv(UruncConfigFileEnv); path != "" { + return path + } + return UruncConfigPath +} + type UruncLog struct { Level string `toml:"level"` Syslog bool `toml:"syslog"` diff --git a/pkg/unikontainers/urunc_config_test.go b/pkg/unikontainers/urunc_config_test.go index a51a3eb96..ad50c48c9 100644 --- a/pkg/unikontainers/urunc_config_test.go +++ b/pkg/unikontainers/urunc_config_test.go @@ -618,3 +618,17 @@ path = "/usr/bin/mon" assert.Equal(t, defaultMonitorsConfig(), config.Monitors) }) } + +// Note: these tests use t.Setenv and therefore must not call t.Parallel(). +func TestResolveUruncConfigPath(t *testing.T) { + t.Run("env var unset returns default path", func(t *testing.T) { + t.Setenv(UruncConfigFileEnv, "") + assert.Equal(t, UruncConfigPath, ResolveUruncConfigPath()) + }) + + t.Run("env var set overrides the path", func(t *testing.T) { + customPath := "/var/etc/urunc/config.toml" + t.Setenv(UruncConfigFileEnv, customPath) + assert.Equal(t, customPath, ResolveUruncConfigPath()) + }) +}