diff --git a/pkg/config/config.go b/pkg/config/config.go index 6514df6fc..c857f5d45 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -251,6 +251,9 @@ type EngineConfig struct { // in containers-registries.conf(5). CompatAPIEnforceDockerHub bool `toml:"compat_api_enforce_docker_hub,omitempty"` + // DBBackend is the database backend to be used by Podman. + DBBackend string `toml:"database_backend,omitempty"` + // DetachKeys is the sequence of keys used to detach a container. DetachKeys string `toml:"detach_keys,omitempty"` @@ -898,6 +901,11 @@ func (c *EngineConfig) Validate() error { if _, err := ValidatePullPolicy(pullPolicy); err != nil { return fmt.Errorf("invalid pull type from containers.conf %q: %w", c.PullPolicy, err) } + + if _, err := ParseDBBackend(c.DBBackend); err != nil { + return err + } + return nil } diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index fcdaa1583..372e2f059 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -37,6 +37,11 @@ var _ = Describe("Config", func() { gomega.Expect(defaultConfig.Engine.ImageVolumeMode).To(gomega.BeEquivalentTo("bind")) gomega.Expect(defaultConfig.Engine.SSHConfig).To(gomega.ContainSubstring("/.ssh/config")) gomega.Expect(defaultConfig.Engine.EventsContainerCreateInspectData).To(gomega.BeFalse()) + gomega.Expect(defaultConfig.Engine.DBBackend).To(gomega.BeEquivalentTo(stringBoltDB)) + + dbBackend, err := defaultConfig.DBBackend() + gomega.Expect(dbBackend).To(gomega.BeEquivalentTo(DBBackendBoltDB)) + gomega.Expect(err).To(gomega.BeNil()) path, err := defaultConfig.ImageCopyTmpDir() gomega.Expect(err).To(gomega.BeNil()) gomega.Expect(path).To(gomega.BeEquivalentTo("/var/tmp")) @@ -410,6 +415,11 @@ image_copy_tmp_dir="storage"` gomega.Expect(config.Containers.HostContainersInternalIP).To(gomega.BeEquivalentTo("1.2.3.4")) gomega.Expect(config.Engine.ImageVolumeMode).To(gomega.BeEquivalentTo("tmpfs")) gomega.Expect(config.Engine.SSHConfig).To(gomega.Equal("/foo/bar/.ssh/config")) + + gomega.Expect(config.Engine.DBBackend).To(gomega.Equal(stringSQLite)) + dbBackend, err := config.DBBackend() + gomega.Expect(err).To(gomega.BeNil()) + gomega.Expect(dbBackend).To(gomega.BeEquivalentTo(DBBackendSQLite)) }) It("contents of passed-in file should override others", func() { @@ -553,6 +563,12 @@ image_copy_tmp_dir="storage"` err := sut.Engine.Validate() gomega.Expect(err).ToNot(gomega.BeNil()) }) + + It("should fail with invalid database_backend", func() { + sut.Engine.DBBackend = "" + err := sut.Engine.Validate() + gomega.Expect(err).ToNot(gomega.BeNil()) + }) }) Describe("Service Destinations", func() { diff --git a/pkg/config/db_backend.go b/pkg/config/db_backend.go new file mode 100644 index 000000000..8fd78165b --- /dev/null +++ b/pkg/config/db_backend.go @@ -0,0 +1,60 @@ +package config + +import "fmt" + +// DBBackend determines which supported database backend Podman should use. +type DBBackend int + +const ( + // Unsupported database backend. Used as a sane base value for the type. + DBBackendUnsupported DBBackend = iota + // BoltDB backend. + DBBackendBoltDB + // SQLite backend. + DBBackendSQLite + + stringBoltDB = "boltdb" + stringSQLite = "sqlite" +) + +// String returns the DBBackend's string representation. +func (d DBBackend) String() string { + switch d { + case DBBackendBoltDB: + return stringBoltDB + case DBBackendSQLite: + return stringSQLite + default: + return fmt.Sprintf("unsupported database backend: %d", d) + } +} + +// Validate returns whether the DBBackend is supported. +func (d DBBackend) Validate() error { + switch d { + case DBBackendBoltDB, DBBackendSQLite: + return nil + default: + return fmt.Errorf("unsupported database backend: %d", d) + } +} + +// ParseDBBackend parses the specified string into a DBBackend. +// An error is return for unsupported backends. +func ParseDBBackend(raw string) (DBBackend, error) { + // NOTE: this function should be used for parsing the user-specified + // values on Podman's CLI. + switch raw { + case stringBoltDB: + return DBBackendBoltDB, nil + case stringSQLite: + return DBBackendSQLite, nil + default: + return DBBackendUnsupported, fmt.Errorf("unsupported database backend: %q", raw) + } +} + +// DBBackend returns the configured database backend. +func (c *Config) DBBackend() (DBBackend, error) { + return ParseDBBackend(c.Engine.DBBackend) +} diff --git a/pkg/config/db_backend_test.go b/pkg/config/db_backend_test.go new file mode 100644 index 000000000..e3ca50038 --- /dev/null +++ b/pkg/config/db_backend_test.go @@ -0,0 +1,33 @@ +package config + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestDBBackend(t *testing.T) { + tests := []struct { + input string + valid bool + expected DBBackend + }{ + {stringBoltDB, true, DBBackendBoltDB}, + {stringSQLite, true, DBBackendSQLite}, + {"", false, DBBackendUnsupported}, + {stringSQLite + " ", false, DBBackendUnsupported}, + } + + for _, test := range tests { + result, err := ParseDBBackend(test.input) + if test.valid { + require.NoError(t, err, "should parse %v", test) + require.NoError(t, result.Validate(), "should validate %v", test) + require.Equal(t, test.expected, result) + } else { + require.Error(t, err, "should NOT parse %v", test) + require.Error(t, result.Validate(), "should NOT validate %v", test) + require.Equal(t, test.expected, result) + } + } +} diff --git a/pkg/config/default.go b/pkg/config/default.go index e27f63064..a811d0183 100644 --- a/pkg/config/default.go +++ b/pkg/config/default.go @@ -104,6 +104,8 @@ const ( CgroupfsCgroupsManager = "cgroupfs" // DefaultApparmorProfile specifies the default apparmor profile for the container. DefaultApparmorProfile = apparmor.Profile + // DefaultDBBackend specifies the default database backend to be used by Podman. + DefaultDBBackend = DBBackendBoltDB // DefaultHostsFile is the default path to the hosts file. DefaultHostsFile = "/etc/hosts" // SystemdCgroupsManager represents systemd native cgroup manager. @@ -387,6 +389,7 @@ func defaultConfigFromMemory() (*EngineConfig, error) { "/run/current-system/sw/bin/conmonrs", } c.PullPolicy = DefaultPullPolicy + c.DBBackend = stringBoltDB c.RuntimeSupportsJSON = []string{ "crun", "runc", diff --git a/pkg/config/testdata/containers_default.conf b/pkg/config/testdata/containers_default.conf index c84811845..32e7949f3 100644 --- a/pkg/config/testdata/containers_default.conf +++ b/pkg/config/testdata/containers_default.conf @@ -117,6 +117,8 @@ dns_bind_port = 1153 # Cgroup management implementation used for the runtime. cgroup_manager = "systemd" +database_backend = "sqlite" + # Default transport method for pulling and pushing for images image_default_transport = "docker://"