The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/4464
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === As per #4390, this renames $LXD_DIR/lxd.db to $LXD_DIR/database/local.db and $LXD_DIR/raft to $LXD_DIR/database/global. Signed-off-by: Free Ekanayaka <free.ekanay...@canonical.com>
From 5503db2205c5100e23d8adc5a9e624ade022e2f8 Mon Sep 17 00:00:00 2001 From: Free Ekanayaka <free.ekanay...@canonical.com> Date: Tue, 17 Apr 2018 06:15:55 +0000 Subject: [PATCH] Rename database files Signed-off-by: Free Ekanayaka <free.ekanay...@canonical.com> --- lxd/cluster/gateway.go | 2 +- lxd/cluster/gateway_test.go | 2 +- lxd/cluster/membership.go | 4 ++-- lxd/cluster/raft.go | 23 ++++++++++++++++----- lxd/daemon.go | 26 +++++++++++++++++------- lxd/db/migration.go | 4 ++-- lxd/db/node/open.go | 6 +++--- lxd/main_activateifneeded.go | 24 ++++++++++++++-------- lxd/sys/fs.go | 32 +++++++++++++++++++++++++++-- test/includes/lxd.sh | 46 +++++++++++++++++++++--------------------- test/suites/database_update.sh | 3 ++- 11 files changed, 117 insertions(+), 55 deletions(-) diff --git a/lxd/cluster/gateway.go b/lxd/cluster/gateway.go index 07546c170..b37b6db1f 100644 --- a/lxd/cluster/gateway.go +++ b/lxd/cluster/gateway.go @@ -296,7 +296,7 @@ func (g *Gateway) Reset(cert *shared.CertInfo) error { if err != nil { return err } - err = os.RemoveAll(filepath.Join(g.db.Dir(), "raft")) + err = os.RemoveAll(filepath.Join(g.db.Dir(), "global")) if err != nil { return err } diff --git a/lxd/cluster/gateway_test.go b/lxd/cluster/gateway_test.go index bfefaf29a..71ed46913 100644 --- a/lxd/cluster/gateway_test.go +++ b/lxd/cluster/gateway_test.go @@ -146,7 +146,7 @@ func TestGateway_RaftNodesNotLeader(t *testing.T) { // happens. func newGateway(t *testing.T, db *db.Node, certInfo *shared.CertInfo) *cluster.Gateway { logging.Testing(t) - require.NoError(t, os.Mkdir(filepath.Join(db.Dir(), "raft"), 0755)) + require.NoError(t, os.Mkdir(filepath.Join(db.Dir(), "global"), 0755)) gateway, err := cluster.NewGateway( db, certInfo, cluster.Latency(0.2), cluster.LogLevel("TRACE")) require.NoError(t, err) diff --git a/lxd/cluster/membership.go b/lxd/cluster/membership.go index 8bea809ad..865e909e2 100644 --- a/lxd/cluster/membership.go +++ b/lxd/cluster/membership.go @@ -286,7 +286,7 @@ func Join(state *state.State, gateway *Gateway, cert *shared.CertInfo, name stri if err != nil { return errors.Wrap(err, "failed to shutdown gRPC SQL gateway") } - err = os.RemoveAll(filepath.Join(state.OS.VarDir, "raft")) + err = os.RemoveAll(state.OS.GlobalDatabaseDir()) if err != nil { return errors.Wrap(err, "failed to remove existing raft data") } @@ -582,7 +582,7 @@ func Promote(state *state.State, gateway *Gateway, nodes []db.RaftNode) error { // Wipe all existing raft data, for good measure (perhaps they were // somehow leftover). - err = os.RemoveAll(filepath.Join(state.OS.VarDir, "raft")) + err = os.RemoveAll(state.OS.GlobalDatabaseDir()) if err != nil { return errors.Wrap(err, "failed to remove existing raft data") } diff --git a/lxd/cluster/raft.go b/lxd/cluster/raft.go index 72ce4c437..fa540ce35 100644 --- a/lxd/cluster/raft.go +++ b/lxd/cluster/raft.go @@ -95,11 +95,11 @@ func raftInstanceInit( // FIXME: should be a parameter timeout := 5 * time.Second - logger := raftLogger() + raftLogger := raftLogger() // Raft config. config := raftConfig(latency) - config.Logger = logger + config.Logger = raftLogger config.LocalID = raft.ServerID(strconv.Itoa(int(node.ID))) // Raft transport @@ -122,7 +122,7 @@ func raftInstanceInit( return nil, err } - transport, handler, layer, err = raftNetworkTransport(db, addr, logger, timeout, dial) + transport, handler, layer, err = raftNetworkTransport(db, addr, raftLogger, timeout, dial) if err != nil { return nil, err } @@ -136,8 +136,21 @@ func raftInstanceInit( return nil, errors.Wrap(err, "invalid raft configuration") } + // Rename legacy data directory if needed. + dir := filepath.Join(db.Dir(), "global") + legacyDir := filepath.Join(db.Dir(), "..", "raft") + if shared.PathExists(legacyDir) { + if shared.PathExists(dir) { + return nil, fmt.Errorf("both legacy and new global database directories exist") + } + logger.Info("Renaming global database directory from raft/ to database/global/") + err := os.Rename(legacyDir, dir) + if err != nil { + return nil, errors.Wrap(err, "failed to rename legacy global database directory") + } + } + // Data directory - dir := filepath.Join(db.Dir(), "raft") if !shared.PathExists(dir) { err := os.Mkdir(dir, 0750) if err != nil { @@ -155,7 +168,7 @@ func raftInstanceInit( } // Raft snapshot store - snaps, err := raft.NewFileSnapshotStoreWithLogger(dir, 2, logger) + snaps, err := raft.NewFileSnapshotStoreWithLogger(dir, 2, raftLogger) if err != nil { return nil, errors.Wrap(err, "failed to create file snapshot store") } diff --git a/lxd/daemon.go b/lxd/daemon.go index 8c8ef3bfc..2b76ab2ec 100644 --- a/lxd/daemon.go +++ b/lxd/daemon.go @@ -497,24 +497,24 @@ func (d *Daemon) init() error { /* Migrate the node local data to the cluster database, if needed */ if dump != nil { - logger.Infof("Migrating data from lxd.db to db.bin") + logger.Infof("Migrating data from local to global database") err = d.cluster.ImportPreClusteringData(dump) if err != nil { // Restore the local sqlite3 backup and wipe the raft // directory, so users can fix problems and retry. - path := filepath.Join(d.os.VarDir, "lxd.db") + path := d.os.LocalDatabasePath() copyErr := shared.FileCopy(path+".bak", path) if copyErr != nil { // Ignore errors here, there's not much we can do - logger.Errorf("Failed to restore lxd.db: %v", copyErr) + logger.Errorf("Failed to restore local database: %v", copyErr) } - rmErr := os.RemoveAll(filepath.Join(d.os.VarDir, "raft")) + rmErr := os.RemoveAll(d.os.GlobalDatabaseDir()) if rmErr != nil { // Ignore errors here, there's not much we can do - logger.Errorf("Failed to cleanup raft db: %v", rmErr) + logger.Errorf("Failed to cleanup global database: %v", rmErr) } - return fmt.Errorf("Failed to migrate data to db.bin: %v", err) + return fmt.Errorf("Failed to migrate data to global database: %v", err) } } @@ -859,6 +859,18 @@ func (d *Daemon) setupMAASController(server string, key string, machine string) // Create a database connection and perform any updates needed. func initializeDbObject(d *Daemon) (*db.Dump, error) { + // Rename the old database name if needed. + if shared.PathExists(d.os.LegacyLocalDatabasePath()) { + if shared.PathExists(d.os.LocalDatabasePath()) { + return nil, fmt.Errorf("Both legacy and new local database files exists") + } + logger.Info("Renaming local database file from lxd.db to database/local.db") + err := os.Rename(d.os.LegacyLocalDatabasePath(), d.os.LocalDatabasePath()) + if err != nil { + return nil, errors.Wrap(err, "Failed to rename legacy local database file") + } + } + // NOTE: we use the legacyPatches parameter to run a few // legacy non-db updates that were in place before the // patches mechanism was introduced in lxd/patches.go. The @@ -898,7 +910,7 @@ func initializeDbObject(d *Daemon) (*db.Dump, error) { } var err error var dump *db.Dump - d.db, dump, err = db.OpenNode(d.os.VarDir, freshHook, legacy) + d.db, dump, err = db.OpenNode(filepath.Join(d.os.VarDir, "database"), freshHook, legacy) if err != nil { return nil, fmt.Errorf("Error creating database: %s", err) } diff --git a/lxd/db/migration.go b/lxd/db/migration.go index d2116ceb9..8f320deea 100644 --- a/lxd/db/migration.go +++ b/lxd/db/migration.go @@ -237,8 +237,8 @@ func importNodeAssociation(entity string, columns []string, row []interface{}, t return nil } -// Dump is a dump of all the user data in lxd.db prior the migration to the -// cluster db. +// Dump is a dump of all the user data in the local db prior the migration to +// the cluster db. type Dump struct { // Map table names to the names or their columns. Schema map[string][]string diff --git a/lxd/db/node/open.go b/lxd/db/node/open.go index 9d77f0c2d..23048820f 100644 --- a/lxd/db/node/open.go +++ b/lxd/db/node/open.go @@ -12,7 +12,7 @@ import ( // Open the node-local database object. func Open(dir string) (*sql.DB, error) { - path := filepath.Join(dir, "lxd.db") + path := filepath.Join(dir, "local.db") db, err := sqliteOpen(path) if err != nil { return nil, fmt.Errorf("cannot open node database: %v", err) @@ -32,8 +32,8 @@ func EnsureSchema(db *sql.DB, dir string, hook schema.Hook) (int, error) { schema := Schema() schema.Hook(func(version int, tx *sql.Tx) error { if !backupDone { - logger.Infof("Updating the LXD database schema. Backup made as \"lxd.db.bak\"") - path := filepath.Join(dir, "lxd.db") + logger.Infof("Updating the LXD database schema. Backup made as \"local.db.bak\"") + path := filepath.Join(dir, "local.db") err := shared.FileCopy(path, path+".bak") if err != nil { return err diff --git a/lxd/main_activateifneeded.go b/lxd/main_activateifneeded.go index a3c9e282d..760478f0a 100644 --- a/lxd/main_activateifneeded.go +++ b/lxd/main_activateifneeded.go @@ -4,7 +4,6 @@ import ( "database/sql" "fmt" "os" - "path/filepath" "github.com/CanonicalLtd/go-sqlite3" "github.com/spf13/cobra" @@ -53,14 +52,20 @@ func (c *cmdActivateifneeded) Run(cmd *cobra.Command, args []string) error { // Don't start a full daemon, we just need DB access d := DefaultDaemon() - if !shared.PathExists(shared.VarPath("lxd.db")) { - logger.Debugf("No DB, so no need to start the daemon now.") - return nil + // Check if either the local database or the legacy local database + // files exists. + path := d.os.LocalDatabasePath() + if !shared.PathExists(d.os.LocalDatabasePath()) { + path = d.os.LegacyLocalDatabasePath() + if !shared.PathExists(path) { + logger.Debugf("No DB, so no need to start the daemon now.") + return nil + } } // Open the database directly to avoid triggering any initialization // code, in particular the data migration from node to cluster db. - sqldb, err := sql.Open("sqlite3", filepath.Join(d.os.VarDir, "lxd.db")) + sqldb, err := sql.Open("sqlite3", path) if err != nil { return err } @@ -86,10 +91,13 @@ func (c *cmdActivateifneeded) Run(cmd *cobra.Command, args []string) error { } // Look for auto-started or previously started containers - path := filepath.Join(d.os.VarDir, "raft", "db.bin") + path = d.os.GlobalDatabasePath() if !shared.PathExists(path) { - logger.Debugf("No DB, so no need to start the daemon now.") - return nil + path = d.os.LegacyGlobalDatabasePath() + if !shared.PathExists(path) { + logger.Debugf("No DB, so no need to start the daemon now.") + return nil + } } sqldb, err = sql.Open("dqlite_direct_access", path+"?mode=ro") if err != nil { diff --git a/lxd/sys/fs.go b/lxd/sys/fs.go index 8370838eb..0f4e948e5 100644 --- a/lxd/sys/fs.go +++ b/lxd/sys/fs.go @@ -3,8 +3,36 @@ package sys import ( "os" "path/filepath" + + "github.com/pkg/errors" ) +// LocalDatabasePath returns the path of the local database file. +func (s *OS) LocalDatabasePath() string { + return filepath.Join(s.VarDir, "database", "local.db") +} + +// LegacyLocalDatabasePath returns the path of legacy local database file. +func (s *OS) LegacyLocalDatabasePath() string { + return filepath.Join(s.VarDir, "lxd.db") +} + +// GlobalDatabaseDir returns the path of the global database directory. +func (s *OS) GlobalDatabaseDir() string { + return filepath.Join(s.VarDir, "database", "global") +} + +// GlobalDatabasePath returns the path of the global database SQLite file +// managed by dqlite. +func (s *OS) GlobalDatabasePath() string { + return filepath.Join(s.GlobalDatabaseDir(), "db.bin") +} + +// LegacyGlobalDatabasePath returns the path of legacy global database file. +func (s *OS) LegacyGlobalDatabasePath() string { + return filepath.Join(s.VarDir, "raft", "db.bin") +} + // Make sure all our directories are available. func (s *OS) initDirs() error { dirs := []struct { @@ -13,7 +41,7 @@ func (s *OS) initDirs() error { }{ {s.VarDir, 0711}, {s.CacheDir, 0700}, - {filepath.Join(s.VarDir, "raft"), 0700}, + {filepath.Join(s.VarDir, "database"), 0700}, {filepath.Join(s.VarDir, "containers"), 0711}, {filepath.Join(s.VarDir, "devices"), 0711}, {filepath.Join(s.VarDir, "devlxd"), 0755}, @@ -30,7 +58,7 @@ func (s *OS) initDirs() error { for _, dir := range dirs { err := os.Mkdir(dir.path, dir.mode) if err != nil && !os.IsExist(err) { - return err + return errors.Wrapf(err, "failed to init dir %s", dir.path) } } diff --git a/test/includes/lxd.sh b/test/includes/lxd.sh index ca7384ab5..58bfb9178 100644 --- a/test/includes/lxd.sh +++ b/test/includes/lxd.sh @@ -164,8 +164,8 @@ kill_lxd() { done echo "==> Checking for locked DB tables" - for table in $(echo .tables | sqlite3 "${daemon_dir}/lxd.db"); do - echo "SELECT * FROM ${table};" | sqlite3 "${daemon_dir}/lxd.db" >/dev/null + for table in $(echo .tables | sqlite3 "${daemon_dir}/local.db"); do + echo "SELECT * FROM ${table};" | sqlite3 "${daemon_dir}/local.db" >/dev/null done # Kill the daemon @@ -203,27 +203,27 @@ kill_lxd() { echo "==> Checking for leftover cluster DB entries" # FIXME: we should not use the command line sqlite client, since it's # not compatible with dqlite - check_empty_table "${daemon_dir}/raft/db.bin" "containers" - check_empty_table "${daemon_dir}/raft/db.bin" "containers_config" - check_empty_table "${daemon_dir}/raft/db.bin" "containers_devices" - check_empty_table "${daemon_dir}/raft/db.bin" "containers_devices_config" - check_empty_table "${daemon_dir}/raft/db.bin" "containers_profiles" - check_empty_table "${daemon_dir}/raft/db.bin" "images" - check_empty_table "${daemon_dir}/raft/db.bin" "images_aliases" - check_empty_table "${daemon_dir}/raft/db.bin" "images_properties" - check_empty_table "${daemon_dir}/raft/db.bin" "images_source" - check_empty_table "${daemon_dir}/raft/db.bin" "images_nodes" - check_empty_table "${daemon_dir}/raft/db.bin" "networks" - check_empty_table "${daemon_dir}/raft/db.bin" "networks_config" - check_empty_table "${daemon_dir}/raft/db.bin" "profiles" - check_empty_table "${daemon_dir}/raft/db.bin" "profiles_config" - check_empty_table "${daemon_dir}/raft/db.bin" "profiles_devices" - check_empty_table "${daemon_dir}/raft/db.bin" "profiles_devices_config" - check_empty_table "${daemon_dir}/raft/db.bin" "storage_pools" - check_empty_table "${daemon_dir}/raft/db.bin" "storage_pools_nodes" - check_empty_table "${daemon_dir}/raft/db.bin" "storage_pools_config" - check_empty_table "${daemon_dir}/raft/db.bin" "storage_volumes" - check_empty_table "${daemon_dir}/raft/db.bin" "storage_volumes_config" + check_empty_table "${daemon_dir}/database/global/db.bin" "containers" + check_empty_table "${daemon_dir}/database/global/db.bin" "containers_config" + check_empty_table "${daemon_dir}/database/global/db.bin" "containers_devices" + check_empty_table "${daemon_dir}/database/global/db.bin" "containers_devices_config" + check_empty_table "${daemon_dir}/database/global/db.bin" "containers_profiles" + check_empty_table "${daemon_dir}/database/global/db.bin" "images" + check_empty_table "${daemon_dir}/database/global/db.bin" "images_aliases" + check_empty_table "${daemon_dir}/database/global/db.bin" "images_properties" + check_empty_table "${daemon_dir}/database/global/db.bin" "images_source" + check_empty_table "${daemon_dir}/database/global/db.bin" "images_nodes" + check_empty_table "${daemon_dir}/database/global/db.bin" "networks" + check_empty_table "${daemon_dir}/database/global/db.bin" "networks_config" + check_empty_table "${daemon_dir}/database/global/db.bin" "profiles" + check_empty_table "${daemon_dir}/database/global/db.bin" "profiles_config" + check_empty_table "${daemon_dir}/database/global/db.bin" "profiles_devices" + check_empty_table "${daemon_dir}/database/global/db.bin" "profiles_devices_config" + check_empty_table "${daemon_dir}/database/global/db.bin" "storage_pools" + check_empty_table "${daemon_dir}/database/global/db.bin" "storage_pools_nodes" + check_empty_table "${daemon_dir}/database/global/db.bin" "storage_pools_config" + check_empty_table "${daemon_dir}/database/global/db.bin" "storage_volumes" + check_empty_table "${daemon_dir}/database/global/db.bin" "storage_volumes_config" fi # teardown storage diff --git a/test/suites/database_update.sh b/test/suites/database_update.sh index 4987802a0..6259d5c34 100644 --- a/test/suites/database_update.sh +++ b/test/suites/database_update.sh @@ -1,6 +1,7 @@ test_database_update(){ LXD_MIGRATE_DIR=$(mktemp -d -p "${TEST_DIR}" XXX) - MIGRATE_DB=${LXD_MIGRATE_DIR}/lxd.db + mkdir -p "${LXD_MIGRATE_DIR}/database" + MIGRATE_DB=${LXD_MIGRATE_DIR}/database/local.db # Create the version 1 schema as the database sqlite3 "${MIGRATE_DB}" > /dev/null < deps/schema1.sql
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel