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

Reply via email to