Skip to content

Commit

Permalink
Deprecate BoltDB, preventing creation of new databases.
Browse files Browse the repository at this point in the history
This is one of the breaking changes in Podman 5.0: removing the
ability to create new instances of the old Bolt database. This
does not remove support for the database entirely, as existing
Bolt databases will still be usable, but all new installs will
use SQLite after this point - if Bolt is forced by config, we'll
just error.

We don't have plans to outright remove the Bolt code. If that
were to happen, it'd be Podman 6.0 at least, and a significant
enough change it'd warrant a lot of discussion and planning. We
do intend to start winding down support of BoltDB, though, and
new features may be added only to SQLite from here on.

I have added an escape hatch via an undocumented environment
variable that allows us to continue testing BoltDB in CI (and, if
necessary, locally) but I don't want this to be used for any
purpose except continued testing of the old DB to ensure we don't
break it.

Signed-off-by: Matt Heon <mheon@redhat.com>
  • Loading branch information
mheon committed Jan 22, 2024
1 parent 34e9146 commit 0972c6b
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 3 deletions.
15 changes: 15 additions & 0 deletions libpod/boltdb_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (
"bytes"
"errors"
"fmt"
"io/fs"
"net"
"os"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -78,6 +80,19 @@ func NewBoltState(path string, runtime *Runtime) (State, error) {

logrus.Debugf("Initializing boltdb state at %s", path)

// BoltDB is deprecated and, as of Podman 5.0, we no longer allow the
// creation of new Bolt states.
// If the DB does not already exist, error out.
// To continue testing in CI, allow creation iff an undocumented env
// var is set.
if os.Getenv("CI_DESIRED_DATABASE") != "boltdb" {
if _, err := os.Stat(path); err != nil && errors.Is(err, fs.ErrNotExist) {
return nil, fmt.Errorf("the BoltDB backend has been deprecated, no new BoltDB databases can be created: %w", define.ErrInvalidArg)
}
} else {
logrus.Debugf("Allowing deprecated database backend due to CI_DESIRED_DATABASE.")
}

db, err := bolt.Open(path, 0600, nil)
if err != nil {
return nil, fmt.Errorf("opening database %s: %w", path, err)
Expand Down
4 changes: 4 additions & 0 deletions libpod/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ func getEmptyBoltState() (_ State, _ string, _ lock.Manager, retErr error) {
}
}()

if err := os.Setenv("CI_DESIRED_DATABASE", "boltdb"); err != nil {
return nil, "", nil, err
}

dbPath := filepath.Join(tmpDir, "db.sql")

lockManager, err := lock.NewInMemoryManager(16)
Expand Down
20 changes: 19 additions & 1 deletion test/e2e/info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,11 @@ var _ = Describe("Podman Info", func() {
Expect(session.OutputToString()).To(Equal(want))
})

It("podman --db-backend info basic check", func() {
It("podman --db-backend info basic check", Serial, func() {
SkipIfRemote("--db-backend only supported on the local client")

const desiredDB = "CI_DESIRED_DATABASE"

type argWant struct {
arg string
want string
Expand All @@ -199,14 +202,29 @@ var _ = Describe("Podman Info", func() {
// now because a boltdb exists it should use boltdb when default is requested
{arg: "", want: "boltdb"},
{arg: "sqlite", want: "sqlite"},
// just because we requested sqlite doesn't mean it stays that way.
// once a boltdb exists, podman will forevermore stick with it
{arg: "", want: "boltdb"},
}

for _, tt := range backends {
oldDesiredDB := os.Getenv(desiredDB)
if tt.arg == "boltdb" {
err := os.Setenv(desiredDB, "boltdb")
Expect(err).To(Not(HaveOccurred()))
defer os.Setenv(desiredDB, oldDesiredDB)
}

session := podmanTest.Podman([]string{"--db-backend", tt.arg, "--log-level=info", "info", "--format", "{{.Host.DatabaseBackend}}"})
session.WaitWithDefaultTimeout()
Expect(session).To(Exit(0))
Expect(session.OutputToString()).To(Equal(tt.want))
Expect(session.ErrorToString()).To(ContainSubstring("Using %s as database backend", tt.want))

if tt.arg == "boltdb" {
err := os.Setenv(desiredDB, oldDesiredDB)
Expect(err).To(Not(HaveOccurred()))
}
}

// make sure we get an error for bogus values
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/systemd_activate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ var _ = Describe("Systemd activate", func() {
systemdArgs := []string{
"-E", "http_proxy", "-E", "https_proxy", "-E", "no_proxy",
"-E", "HTTP_PROXY", "-E", "HTTPS_PROXY", "-E", "NO_PROXY",
"-E", "XDG_RUNTIME_DIR",
"-E", "XDG_RUNTIME_DIR", "-E", "CI_DESIRED_DATABASE",
"--listen", addr,
podmanTest.PodmanBinary}
systemdArgs = append(systemdArgs, podmanOptions...)
Expand Down Expand Up @@ -114,7 +114,7 @@ var _ = Describe("Systemd activate", func() {

// start systemd activation with datagram socket
activateSession := testUtils.StartSystemExec(activate, []string{
"--datagram", "--listen", addr,
"--datagram", "--listen", addr, "-E", "CI_DESIRED_DATABASE",
podmanTest.PodmanBinary,
"--root=" + filepath.Join(tempdir, "server_root"),
"system", "service",
Expand Down
16 changes: 16 additions & 0 deletions test/system/005-info.bats
Original file line number Diff line number Diff line change
Expand Up @@ -255,4 +255,20 @@ EOF

}

@test "podman - BoltDB cannot create new databases" {
skip_if_remote "DB checks only work for local Podman"

safe_opts=$(podman_isolation_opts ${PODMAN_TMPDIR})

CI_DESIRED_DATABASE= run_podman 125 $safe_opts --db-backend=boltdb info
assert "$output" =~ "deprecated, no new BoltDB databases can be created" \
"without CI_DESIRED_DATABASE"

CI_DESIRED_DATABASE=boltdb run_podman $safe_opts --log-level=debug --db-backend=boltdb info
assert "$output" =~ "Allowing deprecated database backend" \
"with CI_DESIRED_DATABASE"

run_podman $safe_opts system reset --force
}

# vim: filetype=sh

0 comments on commit 0972c6b

Please sign in to comment.