From d342d555787d99cd8c58a6e3686fb53faefdafe0 Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Mon, 9 Dec 2019 17:12:23 -0500 Subject: [PATCH 1/2] Remove merge code and optional handling Fix handling of toml files No longer need merge, since we can specify a default conf for each toml file. The toml code will retain the previous defaults and only use the newly specified values. This greatly simplifies the code. Signed-off-by: Daniel J Walsh --- pkg/config/config.go | 292 ++++++++++---------------------- pkg/config/config_suite_test.go | 9 +- pkg/config/config_test.go | 123 +++++++------- pkg/config/default.go | 48 ++++-- pkg/config/merge.go | 139 --------------- pkg/config/merge_test.go | 175 ------------------- 6 files changed, 186 insertions(+), 600 deletions(-) delete mode 100644 pkg/config/merge.go delete mode 100644 pkg/config/merge_test.go diff --git a/pkg/config/config.go b/pkg/config/config.go index 7593734fb..489a1d040 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -2,11 +2,9 @@ package config import ( "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" - "strconv" "strings" "syscall" @@ -46,59 +44,14 @@ const ( BoltDBStateStore RuntimeStateStore = iota ) -// optionalBool is a boolean with an additional undefined value, which is meant -// to be used in the context of user input to distinguish between a -// user-specified value and a default value. -type optionalBool byte - -const ( - // optionalBoolUndefined indicates that the OptionalBoolean hasn't been written. - optionalBoolUndefined optionalBool = iota - // optionalBoolTrue represents the boolean true. - optionalBoolTrue - // optionalBoolFalse represents the boolean false. - optionalBoolFalse -) - -// newOptionalBool converts the input bool into either optionalBoolTrue or -// optionalBoolFalse. The function is meant to avoid boilerplate code of users. -func newOptionalBool(b bool) optionalBool { - o := optionalBoolFalse - if b { - o = optionalBoolTrue - } - return o -} - -// UnmarshalText customs marshaling rules for OptionalBool type -func (o *optionalBool) UnmarshalText(text []byte) error { - b, err := strconv.ParseBool(string(text)) - if err != nil { - *o = optionalBoolUndefined - return err - } - if b { - *o = optionalBoolTrue - } else { - *o = optionalBoolFalse - } - return err -} - -// tomlConfig is another way of looking at a Config, which is -// TOML-friendly (it has all of the explicit tables). It's just used for -// conversions. -type tomlConfig struct { - Containers struct{ ContainersConfig } `toml:"containers"` - Libpod struct{ LibpodConfig } `toml:"libpod"` - Network struct{ NetworkConfig } `toml:"network"` -} - // Config contains configuration options for container tools type Config struct { - ContainersConfig - LibpodConfig - NetworkConfig + // Containers specify settings that configure how containers will run ont the system + Containers ContainersConfig `toml:"containers"` + // Libpod specifies how the container engine based on Libpod will run + Libpod LibpodConfig `toml:"libpod"` + // Network section defines the configuration of CNI Plugins + Network NetworkConfig `toml:"network"` } // ContainersConfig represents the "containers" TOML config table @@ -129,7 +82,9 @@ type ContainersConfig struct { // DefaultUlimits specifies the default ulimits to apply to containers DefaultUlimits []string `toml:"default_ulimits"` - optionalEnableLabeling optionalBool `toml:"label"` + // EnableLabeling tells the container engines whether to use MAC + // Labeling to separate containers (SELinux) + EnableLabeling bool `toml:"label"` // Env is the environment variable list for container process. Env []string `toml:"env"` @@ -141,7 +96,7 @@ type ContainersConfig struct { HooksDir []string `toml:"hooks_dir"` // Run an init inside the container that forwards signals and reaps processes. - optionalInit optionalBool `toml:"init"` + Init bool `toml:"init"` // HTTPProxy is the proxy environment variable list to apply to container process HTTPProxy []string `toml:"http_proxy"` @@ -191,7 +146,7 @@ type LibpodConfig struct { // programs on the host. However, this can cause significant memory usage if // a container has many ports forwarded to it. Disabling this can save // memory. - optionalEnablePortReservation optionalBool `toml:"enable_port_reservation"` + EnablePortReservation bool `toml:"enable_port_reservation"` // EventsLogFilePath is where the events log is stored. EventsLogFilePath string `toml:"events_logfile_path"` @@ -228,7 +183,7 @@ type LibpodConfig struct { NetworkCmdPath string `toml:"network_cmd_path"` // NoPivotRoot sets whether to set no-pivot-root in the OCI runtime. - optionalNoPivotRoot optionalBool `toml:"no_pivot_root"` + NoPivotRoot bool `toml:"no_pivot_root"` // NumLocks is the number of locks to make available for containers and // pods. @@ -263,7 +218,7 @@ type LibpodConfig struct { // SDNotify tells container engine to allow containers to notify the host systemd of // readiness using the SD_NOTIFY mechanism. - optionalSDNotify optionalBool + SDNotify bool // StateType is the type of the backing state store. Avoid using multiple // values for this with the same containers/storage configuration on the @@ -347,26 +302,6 @@ type NetworkConfig struct { NetworkConfigDir string `toml:"network_config_dir"` } -// DefaultCapabilities for the default_capabilities option in the containers.conf file -var DefaultCapabilities = []string{ - "CAP_AUDIT_WRITE", - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FOWNER", - "CAP_FSETID", - "CAP_KILL", - "CAP_MKNOD", - "CAP_NET_BIND_SERVICE", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETPCAP", - "CAP_SETUID", - "CAP_SYS_CHROOT", -} - -// DefaultHooksDirs defines the default hooks directory -var DefaultHooksDirs = []string{"/usr/share/containers/oci/hooks.d"} - // NewConfig creates a new Config. It starts with an empty config and, if // specified, merges the config at `userConfigPath` path. Depending if we're // running as root or rootless, we then merge the system configuration followed @@ -376,46 +311,40 @@ var DefaultHooksDirs = []string{"/usr/share/containers/oci/hooks.d"} // might change in the future. func NewConfig(userConfigPath string) (*Config, error) { - config := &Config{} // start with an empty config + // Genereate the default config for the system + config, err := DefaultConfig() + if err != nil { + return nil, err + } - // First, try to read the user-specified config + // If the caller specified a config path to use, then we read this + // rather then using the system defaults. if userConfigPath != "" { var err error - config, err = ReadConfigFromFile(userConfigPath) + // ReadConfigFromFile reads in container config in the specified + // file and then merge changes with the current defauls. + config, err = ReadConfigFromFile(userConfigPath, config) if err != nil { return nil, errors.Wrapf(err, "error reading user config %q", userConfigPath) } } - // Now, check if the user can access system configs and merge them if needed. + // Now, gather the system configs and merge them as needed. configs, err := systemConfigs() if err != nil { return nil, errors.Wrapf(err, "error finding config on system") } for _, path := range configs { - systemConfig, err := ReadConfigFromFile(path) + // Merge changes in later configs with the previous configs. + // Each config file that specified fields, will override the + // previous fields. + config, err := ReadConfigFromFile(path, config) if err != nil { return nil, errors.Wrapf(err, "error reading system config %q", path) } - // Merge the it into the config. Any unset field in config will be - // over-written by the systemConfig. - if err := config.mergeConfig(systemConfig); err != nil { - return nil, errors.Wrapf(err, "error merging system config") - } logrus.Debugf("Merged system config %q: %v", path, config) } - // Finally, create a default config from memory and forcefully merge it into - // the config. This way we try to make sure that all fields are properly set - // and that user AND system config can partially set. - defaultConfig, err := DefaultConfig() - if err != nil { - return nil, errors.Wrapf(err, "error generating default config from memory") - } - if err := config.mergeConfig(defaultConfig); err != nil { - return nil, errors.Wrapf(err, "error merging default config from memory") - } - config.checkCgroupsAndAdjustConfig() config.addCAPPrefix() @@ -426,54 +355,32 @@ func NewConfig(userConfigPath string) (*Config, error) { return config, nil } -func (t *tomlConfig) toConfig(c *Config) { - c.ContainersConfig = t.Containers.ContainersConfig - c.LibpodConfig = t.Libpod.LibpodConfig - c.NetworkConfig = t.Network.NetworkConfig -} - -func (t *tomlConfig) fromConfig(c *Config) { - t.Containers.ContainersConfig = c.ContainersConfig - t.Libpod.LibpodConfig = c.LibpodConfig - t.Network.NetworkConfig = c.NetworkConfig -} - // ReadConfigFromFile reads the specified config file at `path` and attempts to -// unmarshal its content into a Config. -func ReadConfigFromFile(path string) (*Config, error) { - var config Config - t := new(tomlConfig) - t.fromConfig(&config) - - configBytes, err := ioutil.ReadFile(path) - if err != nil { - return nil, err - } - +// unmarshal its content into a Config. The config param specifies the previos +// default config. If the path, only specifies a few fields in the Toml file +// the defaults from the config paramater will be used for all other fields. +func ReadConfigFromFile(path string, config *Config) (*Config, error) { logrus.Debugf("Reading configuration file %q", path) - _, err = toml.Decode(string(configBytes), t) + _, err := toml.DecodeFile(path, config) if err != nil { return nil, fmt.Errorf("unable to decode configuration %v: %v", path, err) } - t.toConfig(&config) - - // For the sake of backwards compat we need to check if the config fields - // with *Set suffix are set in the config. Note that the storage-related - // fields are NOT set in the config here but in the storage.conf OR directly - // by the user. - if config.VolumePath != "" { - config.VolumePathSet = true + if config.Libpod.VolumePath != "" { + config.Libpod.VolumePathSet = true } - if config.StaticDir != "" { - config.StaticDirSet = true + if config.Libpod.StaticDir != "" { + config.Libpod.StaticDirSet = true } - if config.TmpDir != "" { - config.TmpDirSet = true + if config.Libpod.TmpDir != "" { + config.Libpod.TmpDirSet = true } - return &config, err + return config, err } +// Returns the list of configuration files, if they exist in order of hierarchy. +// The files are read in order and each new file can/will override previous +// file settings. func systemConfigs() ([]string, error) { configs := []string{} path := os.Getenv("CONTAINERS_CONF") @@ -483,6 +390,12 @@ func systemConfigs() ([]string, error) { } return append(configs, path), nil } + if _, err := os.Stat(DefaultContainersConfig); err == nil { + configs = append(configs, DefaultContainersConfig) + } + if _, err := os.Stat(OverrideContainersConfig); err == nil { + configs = append(configs, OverrideContainersConfig) + } if unshare.IsRootless() { path, err := rootlessConfigPath() if err != nil { @@ -492,12 +405,6 @@ func systemConfigs() ([]string, error) { configs = append(configs, path) } } - if _, err := os.Stat(OverrideContainersConfig); err == nil { - configs = append(configs, OverrideContainersConfig) - } - if _, err := os.Stat(DefaultContainersConfig); err == nil { - configs = append(configs, DefaultContainersConfig) - } return configs, nil } @@ -505,7 +412,7 @@ func systemConfigs() ([]string, error) { // cgroup manager. In case the user session isn't available, we're switching the // cgroup manager to cgroupfs. Note, this only applies to rootless. func (c *Config) checkCgroupsAndAdjustConfig() { - if !unshare.IsRootless() || c.CgroupManager != SystemdCgroupsManager { + if !unshare.IsRootless() || c.Containers.CgroupManager != SystemdCgroupsManager { return } @@ -521,7 +428,7 @@ func (c *Config) checkCgroupsAndAdjustConfig() { logrus.Warningf("For using systemd, you may need to login using an user session") logrus.Warningf("Alternatively, you can enable lingering with: `loginctl enable-linger %d` (possibly as root)", unshare.GetRootlessUID()) logrus.Warningf("Falling back to --cgroup-manager=cgroupfs") - c.CgroupManager = CgroupfsCgroupsManager + c.Containers.CgroupManager = CgroupfsCgroupsManager } } @@ -532,8 +439,8 @@ func (c *Config) addCAPPrefix() { } return cap } - for i, cap := range c.ContainersConfig.DefaultCapabilities { - c.ContainersConfig.DefaultCapabilities[i] = toCAPPrefixed(cap) + for i, cap := range c.Containers.DefaultCapabilities { + c.Containers.DefaultCapabilities[i] = toCAPPrefixed(cap) } } @@ -543,16 +450,16 @@ func (c *Config) addCAPPrefix() { // `nil`. func (c *Config) Validate(onExecution bool) error { - if err := c.ContainersConfig.Validate(); err != nil { + if err := c.Containers.Validate(); err != nil { return errors.Wrapf(err, "containers config") } if !unshare.IsRootless() { - if err := c.NetworkConfig.Validate(onExecution); err != nil { + if err := c.Network.Validate(onExecution); err != nil { return errors.Wrapf(err, "network config") } } - if c.EnableLabeling() { + if c.Containers.EnableLabeling { selinux.SetDisabled() } @@ -652,90 +559,63 @@ type DBConfig struct { // MergeDBConfig merges the configuration from the database. func (c *Config) MergeDBConfig(dbConfig *DBConfig) error { - if !c.StorageConfigRunRootSet && dbConfig.StorageTmp != "" { - if c.StorageConfig.RunRoot != dbConfig.StorageTmp && - c.StorageConfig.RunRoot != "" { + if !c.Libpod.StorageConfigRunRootSet && dbConfig.StorageTmp != "" { + if c.Libpod.StorageConfig.RunRoot != dbConfig.StorageTmp && + c.Libpod.StorageConfig.RunRoot != "" { logrus.Debugf("Overriding run root %q with %q from database", - c.StorageConfig.RunRoot, dbConfig.StorageTmp) + c.Libpod.StorageConfig.RunRoot, dbConfig.StorageTmp) } - c.StorageConfig.RunRoot = dbConfig.StorageTmp + c.Libpod.StorageConfig.RunRoot = dbConfig.StorageTmp } - if !c.StorageConfigGraphRootSet && dbConfig.StorageRoot != "" { - if c.StorageConfig.GraphRoot != dbConfig.StorageRoot && - c.StorageConfig.GraphRoot != "" { + if !c.Libpod.StorageConfigGraphRootSet && dbConfig.StorageRoot != "" { + if c.Libpod.StorageConfig.GraphRoot != dbConfig.StorageRoot && + c.Libpod.StorageConfig.GraphRoot != "" { logrus.Debugf("Overriding graph root %q with %q from database", - c.StorageConfig.GraphRoot, dbConfig.StorageRoot) + c.Libpod.StorageConfig.GraphRoot, dbConfig.StorageRoot) } - c.StorageConfig.GraphRoot = dbConfig.StorageRoot + c.Libpod.StorageConfig.GraphRoot = dbConfig.StorageRoot } - if !c.StorageConfigGraphDriverNameSet && dbConfig.GraphDriver != "" { - if c.StorageConfig.GraphDriverName != dbConfig.GraphDriver && - c.StorageConfig.GraphDriverName != "" { + if !c.Libpod.StorageConfigGraphDriverNameSet && dbConfig.GraphDriver != "" { + if c.Libpod.StorageConfig.GraphDriverName != dbConfig.GraphDriver && + c.Libpod.StorageConfig.GraphDriverName != "" { logrus.Errorf("User-selected graph driver %q overwritten by graph driver %q from database - delete libpod local files to resolve", - c.StorageConfig.GraphDriverName, dbConfig.GraphDriver) + c.Libpod.StorageConfig.GraphDriverName, dbConfig.GraphDriver) } - c.StorageConfig.GraphDriverName = dbConfig.GraphDriver + c.Libpod.StorageConfig.GraphDriverName = dbConfig.GraphDriver } - if !c.StaticDirSet && dbConfig.LibpodRoot != "" { - if c.StaticDir != dbConfig.LibpodRoot && c.StaticDir != "" { - logrus.Debugf("Overriding static dir %q with %q from database", c.StaticDir, dbConfig.LibpodRoot) + if !c.Libpod.StaticDirSet && dbConfig.LibpodRoot != "" { + if c.Libpod.StaticDir != dbConfig.LibpodRoot && c.Libpod.StaticDir != "" { + logrus.Debugf("Overriding static dir %q with %q from database", c.Libpod.StaticDir, dbConfig.LibpodRoot) } - c.StaticDir = dbConfig.LibpodRoot + c.Libpod.StaticDir = dbConfig.LibpodRoot } - if !c.TmpDirSet && dbConfig.LibpodTmp != "" { - if c.TmpDir != dbConfig.LibpodTmp && c.TmpDir != "" { - logrus.Debugf("Overriding tmp dir %q with %q from database", c.TmpDir, dbConfig.LibpodTmp) + if !c.Libpod.TmpDirSet && dbConfig.LibpodTmp != "" { + if c.Libpod.TmpDir != dbConfig.LibpodTmp && c.Libpod.TmpDir != "" { + logrus.Debugf("Overriding tmp dir %q with %q from database", c.Libpod.TmpDir, dbConfig.LibpodTmp) } - c.TmpDir = dbConfig.LibpodTmp - c.EventsLogFilePath = filepath.Join(dbConfig.LibpodTmp, "events", "events.log") + c.Libpod.TmpDir = dbConfig.LibpodTmp + c.Libpod.EventsLogFilePath = filepath.Join(dbConfig.LibpodTmp, "events", "events.log") } - if !c.VolumePathSet && dbConfig.VolumePath != "" { - if c.VolumePath != dbConfig.VolumePath && c.VolumePath != "" { - logrus.Debugf("Overriding volume path %q with %q from database", c.VolumePath, dbConfig.VolumePath) + if !c.Libpod.VolumePathSet && dbConfig.VolumePath != "" { + if c.Libpod.VolumePath != dbConfig.VolumePath && c.Libpod.VolumePath != "" { + logrus.Debugf("Overriding volume path %q with %q from database", c.Libpod.VolumePath, dbConfig.VolumePath) } - c.VolumePath = dbConfig.VolumePath + c.Libpod.VolumePath = dbConfig.VolumePath } return nil } -// EnableLabeling indicates whether or not labeling is enabled -func (c *Config) EnableLabeling() bool { - return c.optionalEnableLabeling == optionalBoolTrue -} - -// NoPivotRoot sets whether to set no-pivot-root in the OCI runtime. -func (c *Config) NoPivotRoot() bool { - return c.optionalNoPivotRoot == optionalBoolTrue -} - -// SDNotify tells container engine to allow containers to notify the host systemd of -// readiness using the SD_NOTIFY mechanism. -func (c *Config) SDNotify() bool { - return c.optionalSDNotify == optionalBoolTrue -} - -// EnablePortReservation determines whether libpod will reserve ports on the -// host when they are forwarded to containers. -func (c *Config) EnablePortReservation() bool { - return c.optionalEnablePortReservation == optionalBoolTrue -} - -// EnableInit run an init inside the container that forwards signals and reaps processes. -func (c *Config) Init() bool { - return c.optionalInit == optionalBoolTrue -} - // FindConmon iterates over (*Config).ConmonPath and returns the path to first // (version) matching conmon binary. If non is found, we try to do a path lookup // of "conmon". func (c *Config) FindConmon() (string, error) { foundOutdatedConmon := false - for _, path := range c.ConmonPath { + for _, path := range c.Libpod.ConmonPath { stat, err := os.Stat(path) if err != nil { continue @@ -771,7 +651,7 @@ func (c *Config) FindConmon() (string, error) { return "", errors.Wrapf(ErrInvalidArg, "could not find a working conmon binary (configured options: %v)", - c.ConmonPath) + c.Libpod.ConmonPath) } // Device parses device mapping string to a src, dest & permissions string diff --git a/pkg/config/config_suite_test.go b/pkg/config/config_suite_test.go index 1ba5cd45e..ffbcf2f54 100644 --- a/pkg/config/config_suite_test.go +++ b/pkg/config/config_suite_test.go @@ -1,9 +1,8 @@ -package config_test +package config import ( "testing" - "github.com/containers/common/pkg/config" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) @@ -18,15 +17,15 @@ const ( ) var ( - sut *config.Config + sut *Config ) func beforeEach() { sut = defaultConfig() } -func defaultConfig() *config.Config { - c, err := config.DefaultConfig() +func defaultConfig() *Config { + c, err := DefaultConfig() Expect(err).To(BeNil()) Expect(c).NotTo(BeNil()) return c diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index f7943d598..2fa3fd6fc 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -1,11 +1,10 @@ -package config_test +package config import ( "io/ioutil" "os" "path" - "github.com/containers/common/pkg/config" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) @@ -17,24 +16,24 @@ var _ = Describe("Config", func() { It("should succeed with default config", func() { // Given // When - defaultConfig, err := config.NewConfig("") + defaultConfig, err := NewConfig("") // Then Expect(err).To(BeNil()) - Expect(defaultConfig.ApparmorProfile).To(Equal("container-default")) - Expect(defaultConfig.PidsLimit).To(BeEquivalentTo(2048)) + Expect(defaultConfig.Containers.ApparmorProfile).To(Equal("container-default")) + Expect(defaultConfig.Containers.PidsLimit).To(BeEquivalentTo(2048)) }) It("should succeed with additional devices", func() { // Given - sut.AdditionalDevices = []string{"/dev/null:/dev/null:rw", + sut.Containers.AdditionalDevices = []string{"/dev/null:/dev/null:rw", "/dev/sdc/", "/dev/sdc:/dev/xvdc", "/dev/sdc:rm", } // When - err := sut.ContainersConfig.Validate() + err := sut.Containers.Validate() // Then Expect(err).To(BeNil()) @@ -42,10 +41,10 @@ var _ = Describe("Config", func() { It("should fail on wrong DefaultUlimits", func() { // Given - sut.DefaultUlimits = []string{invalidPath} + sut.Containers.DefaultUlimits = []string{invalidPath} // When - err := sut.ContainersConfig.Validate() + err := sut.Containers.Validate() // Then Expect(err).NotTo(BeNil()) @@ -53,10 +52,10 @@ var _ = Describe("Config", func() { It("should fail on wrong invalid device specification", func() { // Given - sut.AdditionalDevices = []string{"::::"} + sut.Containers.AdditionalDevices = []string{"::::"} // When - err := sut.ContainersConfig.Validate() + err := sut.Containers.Validate() // Then Expect(err).NotTo(BeNil()) @@ -64,10 +63,10 @@ var _ = Describe("Config", func() { It("should fail on invalid device", func() { // Given - sut.AdditionalDevices = []string{invalidPath} + sut.Containers.AdditionalDevices = []string{invalidPath} // When - err := sut.ContainersConfig.Validate() + err := sut.Containers.Validate() // Then Expect(err).NotTo(BeNil()) @@ -75,10 +74,10 @@ var _ = Describe("Config", func() { It("should fail on invalid device mode", func() { // Given - sut.AdditionalDevices = []string{"/dev/null:/dev/null:abc"} + sut.Containers.AdditionalDevices = []string{"/dev/null:/dev/null:abc"} // When - err := sut.ContainersConfig.Validate() + err := sut.Containers.Validate() // Then Expect(err).NotTo(BeNil()) @@ -86,10 +85,10 @@ var _ = Describe("Config", func() { It("should fail on invalid first device", func() { // Given - sut.AdditionalDevices = []string{"wrong:/dev/null:rw"} + sut.Containers.AdditionalDevices = []string{"wrong:/dev/null:rw"} // When - err := sut.ContainersConfig.Validate() + err := sut.Containers.Validate() // Then Expect(err).NotTo(BeNil()) @@ -97,10 +96,10 @@ var _ = Describe("Config", func() { It("should fail on invalid second device", func() { // Given - sut.AdditionalDevices = []string{"/dev/null:wrong:rw"} + sut.Containers.AdditionalDevices = []string{"/dev/null:wrong:rw"} // When - err := sut.ContainersConfig.Validate() + err := sut.Containers.Validate() // Then Expect(err).NotTo(BeNil()) @@ -108,7 +107,7 @@ var _ = Describe("Config", func() { It("should fail wrong max log size", func() { // Given - sut.LogSizeMax = 1 + sut.Containers.LogSizeMax = 1 // When err := sut.Validate(true) @@ -119,7 +118,7 @@ var _ = Describe("Config", func() { It("should succeed with valid shm size", func() { // Given - sut.ShmSize = "1024" + sut.Containers.ShmSize = "1024" // When err := sut.Validate(true) @@ -128,7 +127,7 @@ var _ = Describe("Config", func() { Expect(err).To(BeNil()) // Given - sut.ShmSize = "64m" + sut.Containers.ShmSize = "64m" // When err = sut.Validate(true) @@ -139,7 +138,7 @@ var _ = Describe("Config", func() { It("should fail wrong shm size", func() { // Given - sut.ShmSize = "-2" + sut.Containers.ShmSize = "-2" // When err := sut.Validate(true) @@ -154,7 +153,7 @@ var _ = Describe("Config", func() { It("should succeed with default config", func() { // Given // When - err := sut.NetworkConfig.Validate(false) + err := sut.Network.Validate(false) // Then Expect(err).To(BeNil()) @@ -167,13 +166,13 @@ var _ = Describe("Config", func() { } defer os.RemoveAll(validDirPath) // Given - sut.NetworkConfig.NetworkConfigDir = validDirPath + sut.Network.NetworkConfigDir = validDirPath tmpDir := path.Join(os.TempDir(), "cni-test") - sut.NetworkConfig.CNIPluginDirs = []string{tmpDir} + sut.Network.CNIPluginDirs = []string{tmpDir} defer os.RemoveAll(tmpDir) // When - err = sut.NetworkConfig.Validate(true) + err = sut.Network.Validate(true) // Then Expect(err).To(BeNil()) @@ -187,11 +186,11 @@ var _ = Describe("Config", func() { defer os.RemoveAll(validDirPath) // Given tmpDir := path.Join(os.TempDir(), invalidPath) - sut.NetworkConfig.NetworkConfigDir = tmpDir - sut.NetworkConfig.CNIPluginDirs = []string{validDirPath} + sut.Network.NetworkConfigDir = tmpDir + sut.Network.CNIPluginDirs = []string{validDirPath} // When - err = sut.NetworkConfig.Validate(true) + err = sut.Network.Validate(true) // Then Expect(err).To(BeNil()) @@ -205,11 +204,11 @@ var _ = Describe("Config", func() { Expect(err).To(BeNil()) file.Close() defer os.Remove(tmpfile) - sut.NetworkConfig.NetworkConfigDir = tmpfile - sut.NetworkConfig.CNIPluginDirs = []string{} + sut.Network.NetworkConfigDir = tmpfile + sut.Network.CNIPluginDirs = []string{} // When - err = sut.NetworkConfig.Validate(true) + err = sut.Network.Validate(true) // Then Expect(err).NotTo(BeNil()) @@ -222,11 +221,11 @@ var _ = Describe("Config", func() { } defer os.RemoveAll(validDirPath) // Given - sut.NetworkConfig.NetworkConfigDir = validDirPath - sut.NetworkConfig.CNIPluginDirs = []string{invalidPath} + sut.Network.NetworkConfigDir = validDirPath + sut.Network.CNIPluginDirs = []string{invalidPath} // When - err = sut.NetworkConfig.Validate(true) + err = sut.Network.Validate(true) // Then Expect(err).NotTo(BeNil()) @@ -239,11 +238,11 @@ var _ = Describe("Config", func() { } defer os.RemoveAll(validDirPath) // Given - sut.NetworkConfig.NetworkConfigDir = validDirPath - sut.NetworkConfig.CNIPluginDirs = []string{invalidPath} + sut.Network.NetworkConfigDir = validDirPath + sut.Network.CNIPluginDirs = []string{invalidPath} // When - err = sut.NetworkConfig.Validate(true) + err = sut.Network.Validate(true) // Then Expect(err).ToNot(BeNil()) @@ -255,7 +254,8 @@ var _ = Describe("Config", func() { It("should succeed with default config", func() { // Given // When - defaultConfig, err := config.ReadConfigFromFile("testdata/containers_default.conf") + conf, _ := DefaultConfig() + defaultConfig, err := ReadConfigFromFile("testdata/containers_default.conf", conf) OCIRuntimeMap := map[string][]string{ "runc": []string{ @@ -286,18 +286,19 @@ var _ = Describe("Config", func() { // Then Expect(err).To(BeNil()) - Expect(defaultConfig.CgroupManager).To(Equal("systemd")) - Expect(defaultConfig.Env).To(BeEquivalentTo(envs)) - Expect(defaultConfig.PidsLimit).To(BeEquivalentTo(2048)) - Expect(defaultConfig.CNIPluginDirs).To(Equal(pluginDirs)) - Expect(defaultConfig.NumLocks).To(BeEquivalentTo(2048)) - Expect(defaultConfig.OCIRuntimes).To(Equal(OCIRuntimeMap)) + Expect(defaultConfig.Containers.CgroupManager).To(Equal("systemd")) + Expect(defaultConfig.Containers.Env).To(BeEquivalentTo(envs)) + Expect(defaultConfig.Containers.PidsLimit).To(BeEquivalentTo(2048)) + Expect(defaultConfig.Network.CNIPluginDirs).To(Equal(pluginDirs)) + Expect(defaultConfig.Libpod.NumLocks).To(BeEquivalentTo(2048)) + Expect(defaultConfig.Libpod.OCIRuntimes).To(Equal(OCIRuntimeMap)) }) It("should succeed with commented out configuration", func() { // Given // When - _, err := config.ReadConfigFromFile("testdata/containers_comment.conf") + conf := Config{} + _, err := ReadConfigFromFile("testdata/containers_comment.conf", &conf) // Then Expect(err).To(BeNil()) @@ -306,7 +307,8 @@ var _ = Describe("Config", func() { It("should fail when file does not exist", func() { // Given // When - _, err := config.ReadConfigFromFile("/invalid/file") + conf := Config{} + _, err := ReadConfigFromFile("/invalid/file", &conf) // Then Expect(err).NotTo(BeNil()) @@ -315,7 +317,8 @@ var _ = Describe("Config", func() { It("should fail when toml decode fails", func() { // Given // When - _, err := config.ReadConfigFromFile("config.go") + conf := Config{} + _, err := ReadConfigFromFile("config.go", &conf) // Then Expect(err).NotTo(BeNil()) @@ -359,31 +362,31 @@ var _ = Describe("Config", func() { } // When - config, err := config.NewConfig("") + config, err := NewConfig("") // Then Expect(err).To(BeNil()) - Expect(config.ApparmorProfile).To(Equal("container-default")) - Expect(config.PidsLimit).To(BeEquivalentTo(2048)) - Expect(config.Env).To(BeEquivalentTo(envs)) - Expect(config.CNIPluginDirs).To(Equal(pluginDirs)) - Expect(config.NumLocks).To(BeEquivalentTo(2048)) - Expect(config.OCIRuntimes["runc"]).To(Equal(OCIRuntimeMap["runc"])) + Expect(config.Containers.ApparmorProfile).To(Equal("container-default")) + Expect(config.Containers.PidsLimit).To(BeEquivalentTo(2048)) + Expect(config.Containers.Env).To(BeEquivalentTo(envs)) + Expect(config.Network.CNIPluginDirs).To(Equal(pluginDirs)) + Expect(config.Libpod.NumLocks).To(BeEquivalentTo(2048)) + Expect(config.Libpod.OCIRuntimes["runc"]).To(Equal(OCIRuntimeMap["runc"])) }) It("should success with valid user file path", func() { // Given // When - config, err := config.NewConfig("testdata/containers_default.conf") + config, err := NewConfig("testdata/containers_default.conf") // Then Expect(err).To(BeNil()) - Expect(config.ApparmorProfile).To(Equal("container-default")) - Expect(config.PidsLimit).To(BeEquivalentTo(2048)) + Expect(config.Containers.ApparmorProfile).To(Equal("container-default")) + Expect(config.Containers.PidsLimit).To(BeEquivalentTo(2048)) }) It("should fail with invalid value", func() { // Given // When - config, err := config.NewConfig("testdata/containers_invalid.conf") + config, err := NewConfig("testdata/containers_invalid.conf") // Then Expect(err).ToNot(BeNil()) Expect(config).To(BeNil()) diff --git a/pkg/config/default.go b/pkg/config/default.go index 1a6f339a1..d74b2daf0 100644 --- a/pkg/config/default.go +++ b/pkg/config/default.go @@ -58,6 +58,24 @@ var ( ErrConmonOutdated = errors.New("outdated conmon version") // ErrInvalidArg indicates that an invalid argument was passed ErrInvalidArg = errors.New("invalid argument") + // DefaultHooksDirs defines the default hooks directory + DefaultHooksDirs = []string{"/usr/share/containers/oci/hooks.d"} + // DefaultCapabilities for the default_capabilities option in the containers.conf file + DefaultCapabilities = []string{ + "CAP_AUDIT_WRITE", + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_KILL", + "CAP_MKNOD", + "CAP_NET_BIND_SERVICE", + "CAP_NET_RAW", + "CAP_SETGID", + "CAP_SETPCAP", + "CAP_SETUID", + "CAP_SYS_CHROOT", + } ) const ( @@ -113,32 +131,32 @@ func DefaultConfig() (*Config, error) { } return &Config{ - ContainersConfig: ContainersConfig{ - AdditionalDevices: []string{}, - ApparmorProfile: DefaultApparmorProfile, - CgroupManager: SystemdCgroupsManager, - DefaultCapabilities: DefaultCapabilities, - DefaultSysctls: []string{}, - DefaultUlimits: []string{}, - optionalEnableLabeling: newOptionalBool(selinuxEnabled()), + Containers: ContainersConfig{ + AdditionalDevices: []string{}, + ApparmorProfile: DefaultApparmorProfile, + CgroupManager: SystemdCgroupsManager, + DefaultCapabilities: DefaultCapabilities, + DefaultSysctls: []string{}, + DefaultUlimits: []string{}, + EnableLabeling: selinuxEnabled(), Env: []string{ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", }, HooksDir: DefaultHooksDirs, HTTPProxy: []string{}, - optionalInit: newOptionalBool(false), + Init: false, LogSizeMax: DefaultLogSizeMax, PidsLimit: DefaultPidsLimit, SeccompProfile: SeccompDefaultPath, ShmSize: DefaultShmSize, SignaturePolicyPath: signaturePolicyPath, }, - NetworkConfig: NetworkConfig{ + Network: NetworkConfig{ DefaultNetwork: "podman", NetworkConfigDir: cniConfigDir, CNIPluginDirs: cniBinDir, }, - LibpodConfig: *defaultLibpodConfig, + Libpod: *defaultLibpodConfig, }, nil } @@ -215,15 +233,15 @@ func defaultConfigFromMemory() (*LibpodConfig, error) { } c.RuntimeSupportsNoCgroups = []string{"crun"} c.InitPath = DefaultInitPath - c.optionalNoPivotRoot = newOptionalBool(false) + c.NoPivotRoot = false c.InfraCommand = DefaultInfraCommand c.InfraImage = DefaultInfraImage - c.optionalEnablePortReservation = newOptionalBool(true) + c.EnablePortReservation = true c.NumLocks = 2048 - c.EventsLogger = "file" + c.EventsLogger = "journald" c.DetachKeys = DefaultDetachKeys - c.optionalSDNotify = newOptionalBool(false) + c.SDNotify = false // TODO - ideally we should expose a `type LockType string` along with // constants. c.LockType = "shm" diff --git a/pkg/config/merge.go b/pkg/config/merge.go deleted file mode 100644 index 792fcefe5..000000000 --- a/pkg/config/merge.go +++ /dev/null @@ -1,139 +0,0 @@ -package config - -// Merge merges the other config into the current one. Note that a field of the -// other config is only merged when it's not already set in the current one. -// -// Note that the StateType and the StorageConfig will NOT be changed. -func (c *Config) mergeConfig(other *Config) error { - // strings - c.ApparmorProfile = mergeStrings(c.ApparmorProfile, other.ApparmorProfile) - c.CgroupManager = mergeStrings(c.CgroupManager, other.CgroupManager) - c.NetworkConfigDir = mergeStrings(c.NetworkConfigDir, other.NetworkConfigDir) - c.DefaultNetwork = mergeStrings(c.DefaultNetwork, other.DefaultNetwork) - c.DefaultMountsFile = mergeStrings(c.DefaultMountsFile, other.DefaultMountsFile) - c.DetachKeys = mergeStrings(c.DetachKeys, other.DetachKeys) - c.EventsLogFilePath = mergeStrings(c.EventsLogFilePath, other.EventsLogFilePath) - c.EventsLogger = mergeStrings(c.EventsLogger, other.EventsLogger) - c.ImageDefaultTransport = mergeStrings(c.ImageDefaultTransport, other.ImageDefaultTransport) - c.InfraCommand = mergeStrings(c.InfraCommand, other.InfraCommand) - c.InfraImage = mergeStrings(c.InfraImage, other.InfraImage) - c.InitPath = mergeStrings(c.InitPath, other.InitPath) - c.LockType = mergeStrings(c.LockType, other.LockType) - c.Namespace = mergeStrings(c.Namespace, other.Namespace) - c.NetworkCmdPath = mergeStrings(c.NetworkCmdPath, other.NetworkCmdPath) - c.OCIRuntime = mergeStrings(c.OCIRuntime, other.OCIRuntime) - c.SeccompProfile = mergeStrings(c.SeccompProfile, other.SeccompProfile) - c.ShmSize = mergeStrings(c.ShmSize, other.ShmSize) - c.SignaturePolicyPath = mergeStrings(c.SignaturePolicyPath, other.SignaturePolicyPath) - c.StaticDir = mergeStrings(c.StaticDir, other.StaticDir) - c.TmpDir = mergeStrings(c.TmpDir, other.TmpDir) - c.VolumePath = mergeStrings(c.VolumePath, other.VolumePath) - - // string map of slices - c.OCIRuntimes = mergeStringMaps(c.OCIRuntimes, other.OCIRuntimes) - - // string slices - c.AdditionalDevices = mergeStringSlices(c.AdditionalDevices, other.AdditionalDevices) - c.DefaultCapabilities = mergeStringSlices(c.DefaultCapabilities, other.DefaultCapabilities) - c.DefaultSysctls = mergeStringSlices(c.DefaultSysctls, other.DefaultSysctls) - c.DefaultUlimits = mergeStringSlices(c.DefaultUlimits, other.DefaultUlimits) - c.CNIPluginDirs = mergeStringSlices(c.CNIPluginDirs, other.CNIPluginDirs) - c.Env = mergeStringSlices(c.Env, other.Env) - c.ConmonPath = mergeStringSlices(c.ConmonPath, other.ConmonPath) - c.HooksDir = mergeStringSlices(c.HooksDir, other.HooksDir) - c.HTTPProxy = mergeStringSlices(c.HTTPProxy, other.HTTPProxy) - c.RuntimePath = mergeStringSlices(c.RuntimePath, other.RuntimePath) - c.RuntimeSupportsJSON = mergeStringSlices(c.RuntimeSupportsJSON, other.RuntimeSupportsJSON) - c.RuntimeSupportsNoCgroups = mergeStringSlices(c.RuntimeSupportsNoCgroups, other.RuntimeSupportsNoCgroups) - - // int64s - c.LogSizeMax = mergeInt64s(c.LogSizeMax, other.LogSizeMax) - c.PidsLimit = mergeInt64s(c.PidsLimit, other.PidsLimit) - - // uint32s - c.NumLocks = mergeUint32s(c.NumLocks, other.NumLocks) - - // bools - c.optionalEnableLabeling = mergeOptionalBools(c.optionalEnableLabeling, other.optionalEnableLabeling) - c.optionalEnablePortReservation = mergeOptionalBools(c.optionalEnablePortReservation, other.optionalEnablePortReservation) - c.optionalInit = mergeOptionalBools(c.optionalInit, other.optionalInit) - c.optionalNoPivotRoot = mergeOptionalBools(c.optionalNoPivotRoot, other.optionalNoPivotRoot) - c.optionalSDNotify = mergeOptionalBools(c.optionalSDNotify, other.optionalSDNotify) - - // state type - if c.StateType == InvalidStateStore { - c.StateType = other.StateType - } - - // store options - need to check all fields since some configs might only - // set it partially - c.StorageConfig.RunRoot = mergeStrings(c.StorageConfig.RunRoot, other.StorageConfig.RunRoot) - c.StorageConfig.GraphRoot = mergeStrings(c.StorageConfig.GraphRoot, other.StorageConfig.GraphRoot) - c.StorageConfig.GraphDriverName = mergeStrings(c.StorageConfig.GraphDriverName, other.StorageConfig.GraphDriverName) - c.StorageConfig.GraphDriverOptions = mergeStringSlices(c.StorageConfig.GraphDriverOptions, other.StorageConfig.GraphDriverOptions) - if c.StorageConfig.UIDMap == nil { - c.StorageConfig.UIDMap = other.StorageConfig.UIDMap - } - if c.StorageConfig.GIDMap == nil { - c.StorageConfig.GIDMap = other.StorageConfig.GIDMap - } - - // backwards compat *Set fields - c.StorageConfigRunRootSet = mergeBools(c.StorageConfigRunRootSet, other.StorageConfigRunRootSet) - c.StorageConfigGraphRootSet = mergeBools(c.StorageConfigGraphRootSet, other.StorageConfigGraphRootSet) - c.StorageConfigGraphDriverNameSet = mergeBools(c.StorageConfigGraphDriverNameSet, other.StorageConfigGraphDriverNameSet) - c.VolumePathSet = mergeBools(c.VolumePathSet, other.VolumePathSet) - c.StaticDirSet = mergeBools(c.StaticDirSet, other.StaticDirSet) - c.TmpDirSet = mergeBools(c.TmpDirSet, other.TmpDirSet) - - return nil -} - -func mergeStrings(a, b string) string { - if a == "" { - return b - } - return a -} - -func mergeStringSlices(a, b []string) []string { - if len(a) == 0 && b != nil { - return b - } - return a -} - -func mergeStringMaps(a, b map[string][]string) map[string][]string { - if len(a) == 0 && b != nil { - return b - } - return a -} - -func mergeInt64s(a, b int64) int64 { - if a == 0 { - return b - } - return a -} - -func mergeUint32s(a, b uint32) uint32 { - if a == 0 { - return b - } - return a -} - -func mergeBools(a, b bool) bool { - if !a { - return b - } - return a -} - -func mergeOptionalBools(a, b optionalBool) optionalBool { - if a == optionalBoolUndefined { - return b - } - return a -} diff --git a/pkg/config/merge_test.go b/pkg/config/merge_test.go deleted file mode 100644 index beb98d606..000000000 --- a/pkg/config/merge_test.go +++ /dev/null @@ -1,175 +0,0 @@ -package config - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestMergeStrings(t *testing.T) { - testData := []struct { - a string - b string - res string - }{ - {"", "", ""}, - {"a", "", "a"}, - {"a", "b", "a"}, - {"", "b", "b"}, - } - for _, data := range testData { - res := mergeStrings(data.a, data.b) - assert.Equal(t, data.res, res) - } -} - -func TestMergeStringSlices(t *testing.T) { - testData := []struct { - a []string - b []string - res []string - }{ - { - nil, nil, nil, - }, - { - nil, - []string{}, - []string{}, - }, - { - []string{}, - nil, - []string{}, - }, - { - []string{}, - []string{}, - []string{}, - }, - { - []string{"a"}, - []string{}, - []string{"a"}, - }, - { - []string{"a"}, - []string{"b"}, - []string{"a"}, - }, - { - []string{}, - []string{"b"}, - []string{"b"}, - }, - } - for _, data := range testData { - res := mergeStringSlices(data.a, data.b) - assert.Equal(t, data.res, res) - } -} - -func TestMergeStringMaps(t *testing.T) { - testData := []struct { - a map[string][]string - b map[string][]string - res map[string][]string - }{ - { - nil, nil, nil, - }, - { - nil, - map[string][]string{}, - map[string][]string{}, - }, - { - map[string][]string{"a": {"a"}}, - nil, - map[string][]string{"a": {"a"}}, - }, - { - nil, - map[string][]string{"b": {"b"}}, - map[string][]string{"b": {"b"}}, - }, - { - map[string][]string{"a": {"a"}}, - map[string][]string{"b": {"b"}}, - map[string][]string{"a": {"a"}}, - }, - } - for _, data := range testData { - res := mergeStringMaps(data.a, data.b) - assert.Equal(t, data.res, res) - } -} - -func TestMergeInts64(t *testing.T) { - testData := []struct { - a int64 - b int64 - res int64 - }{ - {int64(0), int64(0), int64(0)}, - {int64(1), int64(0), int64(1)}, - {int64(0), int64(1), int64(1)}, - {int64(2), int64(1), int64(2)}, - {int64(-1), int64(1), int64(-1)}, - {int64(0), int64(-1), int64(-1)}, - } - for _, data := range testData { - res := mergeInt64s(data.a, data.b) - assert.Equal(t, data.res, res) - } -} -func TestMergeUint32(t *testing.T) { - testData := []struct { - a uint32 - b uint32 - res uint32 - }{ - {uint32(0), uint32(0), uint32(0)}, - {uint32(1), uint32(0), uint32(1)}, - {uint32(0), uint32(1), uint32(1)}, - {uint32(2), uint32(1), uint32(2)}, - } - for _, data := range testData { - res := mergeUint32s(data.a, data.b) - assert.Equal(t, data.res, res) - } -} - -func TestMergeBools(t *testing.T) { - testData := []struct { - a bool - b bool - res bool - }{ - {false, false, false}, - {true, false, true}, - {false, true, true}, - {true, true, true}, - } - for _, data := range testData { - res := mergeBools(data.a, data.b) - assert.Equal(t, data.res, res) - } -} - -func TestMergeOptionalBools(t *testing.T) { - testData := []struct { - a optionalBool - b optionalBool - res optionalBool - }{ - {optionalBoolUndefined, optionalBoolTrue, optionalBoolTrue}, - {optionalBoolFalse, optionalBoolTrue, optionalBoolFalse}, - {optionalBoolTrue, optionalBoolFalse, optionalBoolTrue}, - {optionalBoolUndefined, optionalBoolUndefined, optionalBoolUndefined}, - } - for _, data := range testData { - res := mergeOptionalBools(data.a, data.b) - assert.Equal(t, data.res, res) - } -} From a8244f7dfa46d5268b917906a3cbdee4ccca8bbc Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Wed, 11 Dec 2019 08:24:46 -0500 Subject: [PATCH 2/2] Comment out all fields in containers.conf by default Signed-off-by: Daniel J Walsh --- pkg/config/containers.conf | 162 +++++++++++++++++++------------------ 1 file changed, 82 insertions(+), 80 deletions(-) diff --git a/pkg/config/containers.conf b/pkg/config/containers.conf index be845b64e..d7a0afbf1 100644 --- a/pkg/config/containers.conf +++ b/pkg/config/containers.conf @@ -10,78 +10,77 @@ # "::", for example: "--device=/dev/sdc:/dev/xvdc:rwm". #If it is empty or commented out, only the devices # defined in the container json file by the user/kube will be added. -additional_devices = [ -] +# additional_devices = [ +# ] # Used to change the name of the default AppArmor profile of container engines. The default # profile name is "container-default". -apparmor_profile = "container-default" +# apparmor_profile = "container-default" # Cgroup management implementation used for the runtime. -cgroup_manager = "systemd" +# cgroup_manager = "systemd" # List of default capabilities for containers. If it is empty or commented out, # only the capabilities defined in the containers json file by the user/kube # will be added. -default_capabilities = [ - "AUDIT_WRITE", - "CHOWN", - "DAC_OVERRIDE", - "FOWNER", - "FSETID", - "KILL", - "MKNOD", - "NET_BIND_SERVICE", - "NET_RAW", - "SETGID", - "SETPCAP", - "SETUID", - "SYS_CHROOT", -] +# default_capabilities = [ +# "AUDIT_WRITE", +# "CHOWN", +# "DAC_OVERRIDE", +# "FOWNER", +# "FSETID", +# "KILL", +# "MKNOD", +# "NET_BIND_SERVICE", +# "NET_RAW", +# "SETGID", +# "SETPCAP", +# "SETUID", +# "SYS_CHROOT", +# ] # A list of ulimits to be set in containers by default, specified as # "=:", for example: # "nofile=1024:2048" # See setrlimit(2) for a list of resource names. # Any limit not specified here will be inherited from the process launching the container engine -default_ulimits = [ -] - +# default_ulimits = [ +# ] # List of default sysctls. If it is empty or commented out, only the sysctls # defined in the container json file by the user/kube will be added. -default_sysctls = [ -] +# default_sysctls = [ +# ] # Environment variable list for the conmon process, used for passing necessary # environment variables to conmon or the runtime. -env = [ - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", -] +# env = [ +# "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", +# ] # Path to OCI hooks directories for automatically executed hooks. -hooks_dir = [ -] +# hooks_dir = [ +# ] # Run an init inside the container that forwards signals and reaps processes. -init = false +# init = false # proxy environment variables are passed into the container -http_proxy = [ -] +# http_proxy = [ +# ] # whether the container tool will support container labeling. -label = true +# label = true # Maximum size allowed for the container log file. Negative numbers indicate # that no size limit is imposed. If it is positive, it must be >= 8192 to # match/exceed conmon's read buffer. The file is truncated and re-opened so the # limit is never exceeded. -log_size_max = -1 +# log_size_max = -1 # Maximum number of processes allowed in a container. -pids_limit = 2048 +# pids_limit = 2048 # Path to the seccomp.json profile which is used as the default seccomp profile # for the runtime. @@ -89,54 +88,53 @@ pids_limit = 2048 # Size of /dev/shm. Specified as . # Unit is optional and can be b (bytes), k (kilobytes), m (megabytes), or g (gigabytes). If the unit is omitted, the system uses bytes. -shm_size = "65536k" +# shm_size = "65536k" # The network table containers settings pertaining to the management of # CNI plugins. [network] # Path to directory where CNI plugin binaries are located. -cni_plugin_dirs = ["/usr/libexec/cni"] +# cni_plugin_dirs = ["/usr/libexec/cni"] # Path to the directory where CNI configuration files are located. -network_config_dir = "/etc/cni/net.d/" +# network_config_dir = "/etc/cni/net.d/" [libpod] # Default transport method for pulling and pushing for images -image_default_transport = "docker://" +# image_default_transport = "docker://" # Environment variables to pass into conmon -conmon_env_vars = [ - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" -] +# conmon_env_vars = [ +# "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" +# ] # Paths to look for the Conmon container manager binary -conmon_path = [ - "/usr/libexec/podman/conmon", - "/usr/local/libexec/podman/conmon", - "/usr/local/lib/podman/conmon", - "/usr/bin/conmon", - "/usr/sbin/conmon", - "/usr/local/bin/conmon", - "/usr/local/sbin/conmon" -] +# conmon_path = [ +# "/usr/libexec/podman/conmon", +# "/usr/local/libexec/podman/conmon", +# "/usr/local/lib/podman/conmon", +# "/usr/bin/conmon", +# "/usr/sbin/conmon", +# "/usr/local/bin/conmon", +# "/usr/local/sbin/conmon" +# ] # Container init binary -#init_path = "/usr/libexec/podman/catatonit" +# init_path = "/usr/libexec/podman/catatonit" # Directory for persistent libpod files (database, etc) # By default, this will be configured relative to where containers/storage # stores containers # Uncomment to change location from this default -#static_dir = "/var/lib/containers/storage/libpod" +# static_dir = "/var/lib/containers/storage/libpod" # Directory for temporary files. Must be tmpfs (wiped after reboot) -tmp_dir = "/var/run/libpod" - +# tmp_dir = "/var/run/libpod" # Whether to use chroot instead of pivot_root in the runtime -no_pivot_root = false +# no_pivot_root = false # Default libpod namespace # If libpod is joined to a namespace, it will see only containers and pods @@ -144,13 +142,13 @@ no_pivot_root = false # pods in that namespace. # The default namespace is "", which corresponds to no namespace. When no # namespace is set, all containers and pods are visible. -#namespace = "" +# namespace = "" # Default infra (pause) image name for pod infra containers -infra_image = "k8s.gcr.io/pause:3.1" +# infra_image = "k8s.gcr.io/pause:3.1" # Default command to run the infra container -infra_command = "/pause" +# infra_command = "/pause" # Determines whether libpod will reserve ports on the host when they are # forwarded to containers. When enabled, when ports are forwarded to containers, @@ -158,7 +156,7 @@ infra_command = "/pause" # they cannot be reused by other programs on the host. However, this can cause # significant memory usage if a container has many ports forwarded to it. # Disabling this can save memory. -#enable_port_reservation = true +# enable_port_reservation = true # Default libpod support for container labeling # label=true @@ -166,17 +164,17 @@ infra_command = "/pause" # Number of locks available for containers and pods. # If this is changed, a lock renumber must be performed (e.g. with the # 'podman system renumber' command). -num_locks = 2048 +# num_locks = 2048 # Directory for libpod named volumes. # By default, this will be configured relative to where containers/storage # stores containers. # Uncomment to change location from this default. -#volume_path = "/var/lib/containers/storage/volumes" +# volume_path = "/var/lib/containers/storage/volumes" # Selects which logging mechanism to use for Podman events. Valid values # are `journald` or `file`. -# events_logger = "journald" +# events_logger = "file" # Specify the keys sequence used to detach a container. # Format is a single character [a-Z] or a comma separated sequence of @@ -186,32 +184,36 @@ num_locks = 2048 # detach_keys = "ctrl-p,ctrl-q" # Default OCI runtime -runtime = "runc" +# runtime = "runc" # List of the OCI runtimes that support --format=json. When json is supported # libpod will use it for reporting nicer errors. -runtime_supports_json = ["runc"] +# runtime_supports_json = ["crun", "runc"] # Paths to look for a valid OCI runtime (runc, runv, etc) [libpod.runtimes] -runc = [ - "/usr/bin/runc", - "/usr/sbin/runc", - "/usr/local/bin/runc", - "/usr/local/sbin/runc", - "/sbin/runc", - "/bin/runc", - "/usr/lib/cri-o-runc/sbin/runc", -] - -crun = [ - "/usr/bin/crun", - "/usr/local/bin/crun", -] +# runc = [ +# "/usr/bin/runc", +# "/usr/sbin/runc", +# "/usr/local/bin/runc", +# "/usr/local/sbin/runc", +# "/sbin/runc", +# "/bin/runc", +# "/usr/lib/cri-o-runc/sbin/runc", +# ] + +# crun = [ +# "/usr/bin/crun", +# "/usr/sbin/crun", +# "/usr/local/bin/crun", +# "/usr/local/sbin/crun", +# "/sbin/crun", +# "/bin/crun", +# "/run/current-system/sw/bin/crun", +# ] # The [libpod.runtimes] table MUST be the last thing in this file. # (Unless another table is added) # TOML does not provide a way to end a table other than a further table being # defined, so every key hereafter will be part of [runtimes] and not the main # config. -