The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6520

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) ===
Re-works backup yaml file updates during backup import to simplify storage layer restoration functions.
Also improves backup yaml pool update function to also update embedded snapshots pool property. 
From 272104730cd03f8263074f14bd9cb4b94d0c571c Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Wed, 27 Nov 2019 12:25:05 +0000
Subject: [PATCH 1/5] lxd/backup/backup/instance/config: Adds instance config
 backup.yml tools

Moved from main package and cleaned up.

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/backup/backup_instance_config.go | 122 +++++++++++++++++++++++++++
 1 file changed, 122 insertions(+)
 create mode 100644 lxd/backup/backup_instance_config.go

diff --git a/lxd/backup/backup_instance_config.go 
b/lxd/backup/backup_instance_config.go
new file mode 100644
index 0000000000..a871ad0a7e
--- /dev/null
+++ b/lxd/backup/backup_instance_config.go
@@ -0,0 +1,122 @@
+package backup
+
+import (
+       "fmt"
+       "io/ioutil"
+       "os"
+
+       "gopkg.in/yaml.v2"
+
+       "github.com/lxc/lxd/lxd/db"
+       "github.com/lxc/lxd/lxd/project"
+       "github.com/lxc/lxd/shared"
+       "github.com/lxc/lxd/shared/api"
+)
+
+// InstanceConfig represents the config of an instance that can be stored in a 
backup.yaml file.
+type InstanceConfig struct {
+       Container *api.Instance           `yaml:"container"`
+       Snapshots []*api.InstanceSnapshot `yaml:"snapshots"`
+       Pool      *api.StoragePool        `yaml:"pool"`
+       Volume    *api.StorageVolume      `yaml:"volume"`
+}
+
+// ParseInstanceConfigYamlFile decodes the yaml file at path specified into an 
InstanceConfig.
+func ParseInstanceConfigYamlFile(path string) (*InstanceConfig, error) {
+       data, err := ioutil.ReadFile(path)
+       if err != nil {
+               return nil, err
+       }
+
+       backup := InstanceConfig{}
+       if err := yaml.Unmarshal(data, &backup); err != nil {
+               return nil, err
+       }
+
+       return &backup, nil
+}
+
+// updateRootDevicePool updates the root disk device in the supplied list of 
devices to the pool
+// specified. Returns true if a root disk device has been found and updated 
otherwise false.
+func updateRootDevicePool(devices map[string]map[string]string, poolName 
string) bool {
+       if devices != nil {
+               devName, _, err := shared.GetRootDiskDevice(devices)
+               if err == nil {
+                       devices[devName]["pool"] = poolName
+                       return true
+               }
+       }
+
+       return false
+}
+
+// UpdateInstanceConfigStoragePool changes the pool information in the 
backup.yaml to the pool
+// specified in b.Pool.
+func UpdateInstanceConfigStoragePool(c *db.Cluster, b Info) error {
+       // Load the storage pool.
+       _, pool, err := c.StoragePoolGet(b.Pool)
+       if err != nil {
+               return err
+       }
+
+       f := func(path string) error {
+               // Read in the backup.yaml file.
+               backup, err := ParseInstanceConfigYamlFile(path)
+               if err != nil {
+                       return err
+               }
+
+               rootDiskDeviceFound := false
+
+               // Change the pool in the backup.yaml.
+               backup.Pool = pool
+
+               if updateRootDevicePool(backup.Container.Devices, pool.Name) {
+                       rootDiskDeviceFound = true
+               }
+
+               if updateRootDevicePool(backup.Container.ExpandedDevices, 
pool.Name) {
+                       rootDiskDeviceFound = true
+               }
+
+               for _, snapshot := range backup.Snapshots {
+                       updateRootDevicePool(snapshot.Devices, pool.Name)
+                       updateRootDevicePool(snapshot.ExpandedDevices, 
pool.Name)
+               }
+
+               if !rootDiskDeviceFound {
+                       return fmt.Errorf("No root device could be found")
+               }
+
+               file, err := os.Create(path)
+               if err != nil {
+                       return err
+               }
+               defer file.Close()
+
+               data, err := yaml.Marshal(&backup)
+               if err != nil {
+                       return err
+               }
+
+               _, err = file.Write(data)
+               if err != nil {
+                       return err
+               }
+
+               return nil
+       }
+
+       err = f(shared.VarPath("storage-pools", pool.Name, "containers", 
project.Prefix(b.Project, b.Name), "backup.yaml"))
+       if err != nil {
+               return err
+       }
+
+       for _, snap := range b.Snapshots {
+               err = f(shared.VarPath("storage-pools", pool.Name, 
"containers-snapshots", project.Prefix(b.Project, b.Name), snap, "backup.yaml"))
+               if err != nil {
+                       return err
+               }
+       }
+       return nil
+}

From d8a2ef2d0523113ef24d741162ebb0f4bdef5a97 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Wed, 27 Nov 2019 12:26:08 +0000
Subject: [PATCH 2/5] lxd/api/internal: Removes slurpBackupFile and switches to
 backup.ParseInstanceConfigYamlFile

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/api_internal.go | 20 ++------------------
 1 file changed, 2 insertions(+), 18 deletions(-)

diff --git a/lxd/api_internal.go b/lxd/api_internal.go
index 957b0107b7..38ee0da172 100644
--- a/lxd/api_internal.go
+++ b/lxd/api_internal.go
@@ -4,7 +4,6 @@ import (
        "database/sql"
        "encoding/json"
        "fmt"
-       "io/ioutil"
        "net/http"
        "os"
        "path/filepath"
@@ -15,8 +14,8 @@ import (
 
        "github.com/gorilla/mux"
        "github.com/pkg/errors"
-       "gopkg.in/yaml.v2"
 
+       "github.com/lxc/lxd/lxd/backup"
        "github.com/lxc/lxd/lxd/db"
        "github.com/lxc/lxd/lxd/db/cluster"
        "github.com/lxc/lxd/lxd/db/node"
@@ -390,21 +389,6 @@ func internalSQLExec(tx *sql.Tx, query string, result 
*internalSQLResult) error
        return nil
 }
 
-func slurpBackupFile(path string) (*backupFile, error) {
-       data, err := ioutil.ReadFile(path)
-       if err != nil {
-               return nil, err
-       }
-
-       backup := backupFile{}
-
-       if err := yaml.Unmarshal(data, &backup); err != nil {
-               return nil, err
-       }
-
-       return &backup, nil
-}
-
 type internalImportPost struct {
        Name  string `json:"name" yaml:"name"`
        Force bool   `json:"force" yaml:"force"`
@@ -476,7 +460,7 @@ func internalImport(d *Daemon, r *http.Request) 
response.Response {
 
        // Read in the backup.yaml file.
        backupYamlPath := filepath.Join(containerMntPoint, "backup.yaml")
-       backup, err := slurpBackupFile(backupYamlPath)
+       backup, err := backup.ParseInstanceConfigYamlFile(backupYamlPath)
        if err != nil {
                return response.SmartError(err)
        }

From 50837149c75edcc9fa90f5a86e50d2fe5dada67a Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Wed, 27 Nov 2019 12:26:38 +0000
Subject: [PATCH 3/5] lxd/backup: Removes backupFixStoragePool

Replaced by backup.UpdateInstanceConfigStoragePool

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/backup.go | 94 ---------------------------------------------------
 1 file changed, 94 deletions(-)

diff --git a/lxd/backup.go b/lxd/backup.go
index be3b24511b..15189bffd7 100644
--- a/lxd/backup.go
+++ b/lxd/backup.go
@@ -101,100 +101,6 @@ func backupCreate(s *state.State, args 
db.InstanceBackupArgs, sourceInst instanc
        return nil
 }
 
-// fixBackupStoragePool changes the pool information in the backup.yaml. This
-// is done only if the provided pool doesn't exist. In this case, the pool of
-// the default profile will be used.
-func backupFixStoragePool(c *db.Cluster, b backup.Info, useDefaultPool bool) 
error {
-       var poolName string
-
-       if useDefaultPool {
-               // Get the default profile
-               _, profile, err := c.ProfileGet("default", "default")
-               if err != nil {
-                       return err
-               }
-
-               _, v, err := shared.GetRootDiskDevice(profile.Devices)
-               if err != nil {
-                       return err
-               }
-
-               poolName = v["pool"]
-       } else {
-               poolName = b.Pool
-       }
-
-       // Get the default's profile pool
-       _, pool, err := c.StoragePoolGet(poolName)
-       if err != nil {
-               return err
-       }
-
-       f := func(path string) error {
-               // Read in the backup.yaml file.
-               backup, err := slurpBackupFile(path)
-               if err != nil {
-                       return err
-               }
-
-               rootDiskDeviceFound := false
-
-               // Change the pool in the backup.yaml
-               backup.Pool = pool
-               if backup.Container.Devices != nil {
-                       devName, _, err := 
shared.GetRootDiskDevice(backup.Container.Devices)
-                       if err == nil {
-                               backup.Container.Devices[devName]["pool"] = 
poolName
-                               rootDiskDeviceFound = true
-                       }
-               }
-
-               if backup.Container.ExpandedDevices != nil {
-                       devName, _, err := 
shared.GetRootDiskDevice(backup.Container.ExpandedDevices)
-                       if err == nil {
-                               
backup.Container.ExpandedDevices[devName]["pool"] = poolName
-                               rootDiskDeviceFound = true
-                       }
-               }
-
-               if !rootDiskDeviceFound {
-                       return fmt.Errorf("No root device could be found")
-               }
-
-               file, err := os.Create(path)
-               if err != nil {
-                       return err
-               }
-               defer file.Close()
-
-               data, err := yaml.Marshal(&backup)
-               if err != nil {
-                       return err
-               }
-
-               _, err = file.Write(data)
-               if err != nil {
-                       return err
-               }
-
-               return nil
-       }
-
-       err = f(shared.VarPath("storage-pools", pool.Name, "containers", 
project.Prefix(b.Project, b.Name), "backup.yaml"))
-       if err != nil {
-               return err
-       }
-
-       for _, snap := range b.Snapshots {
-               err = f(shared.VarPath("storage-pools", pool.Name, 
"containers-snapshots", project.Prefix(b.Project, b.Name), snap,
-                       "backup.yaml"))
-               if err != nil {
-                       return err
-               }
-       }
-       return nil
-}
-
 func backupCreateTarball(s *state.State, path string, b backup.Backup, c 
instance.Instance) error {
        // Create the index
        pool, err := c.StoragePool()

From cfc105ae56a054510a2ead417cf71f46314e58ed Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Wed, 27 Nov 2019 12:28:25 +0000
Subject: [PATCH 4/5] lxd/containers/post: Updates instanceCreateFromBackup
 usage

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/containers_post.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/containers_post.go b/lxd/containers_post.go
index eae96c5597..c3440ce4fb 100644
--- a/lxd/containers_post.go
+++ b/lxd/containers_post.go
@@ -657,7 +657,7 @@ func createFromBackup(d *Daemon, project string, data 
io.Reader, pool string) re
 
                // Dump tarball to storage.
                f.Seek(0, 0)
-               revertFunc, err := instanceCreateFromBackup(d.State(), *bInfo, 
f, pool != "")
+               revertFunc, err := instanceCreateFromBackup(d.State(), *bInfo, 
f)
                if err != nil {
                        return errors.Wrap(err, "Create instance from backup")
                }

From ed788bd0682a20aa1710b1358ad76fce614a33d9 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Wed, 27 Nov 2019 15:43:27 +0000
Subject: [PATCH 5/5] lxd/container: Updates instanceCreateFromBackup signature

- Removes need for customBool variable and instead will just always update 
backup.yaml file to use current storage pool.
- This simplifies the function signature needed later for 
pool.CreateInstanceFromBackup().

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/container.go | 27 ++++++++++-----------------
 1 file changed, 10 insertions(+), 17 deletions(-)

diff --git a/lxd/container.go b/lxd/container.go
index 125e5c4b8e..625c57ffd4 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -307,13 +307,10 @@ func instanceCreateAsEmpty(d *Daemon, args 
db.InstanceArgs) (instance.Instance,
 
 // instanceCreateFromBackup imports a backup file to restore an instance. 
Returns a revert function
 // that can be called to delete the files created during import if subsequent 
steps fail.
-func instanceCreateFromBackup(s *state.State, info backup.Info, srcData 
io.ReadSeeker, customPool bool) (func(), error) {
-       var fixBackupFile = false
-       poolName := info.Pool
-
+func instanceCreateFromBackup(s *state.State, info backup.Info, srcData 
io.ReadSeeker) (func(), error) {
        // Check storage pool from index.yaml exists. If the storage pool in 
the index.yaml doesn't
-       // exist, try and use the default profile's storage pool.
-       _, _, err := s.Cluster.StoragePoolGet(poolName)
+       // exist, try and use the project's default profile storage pool.
+       _, _, err := s.Cluster.StoragePoolGet(info.Pool)
        if errors.Cause(err) == db.ErrNoSuchObject {
                // The backup is in binary format so we cannot alter the 
backup.yaml.
                if info.HasBinaryFormat {
@@ -332,10 +329,7 @@ func instanceCreateFromBackup(s *state.State, info 
backup.Info, srcData io.ReadS
                }
 
                // Use the default-profile's root pool.
-               poolName = v["pool"]
-
-               // Mark requirement to change the pool information in the 
backup.yaml file.
-               fixBackupFile = true
+               info.Pool = v["pool"]
        } else if err != nil {
                return nil, err
        }
@@ -385,7 +379,7 @@ func instanceCreateFromBackup(s *state.State, info 
backup.Info, srcData io.ReadS
                srcData = tarData
        }
 
-       pool, err := storagePoolInit(s, poolName)
+       pool, err := storagePoolInit(s, info.Pool)
        if err != nil {
                return nil, err
        }
@@ -396,12 +390,11 @@ func instanceCreateFromBackup(s *state.State, info 
backup.Info, srcData io.ReadS
                return nil, err
        }
 
-       if fixBackupFile || customPool {
-               // Update pool information in the backup.yaml file.
-               err = backupFixStoragePool(s.Cluster, info, !customPool)
-               if err != nil {
-                       return nil, err
-               }
+       // Update pool information in the backup.yaml file.
+       // Requires the volume and snapshots be mounted from 
pool.ContainerBackupLoad().
+       err = backup.UpdateInstanceConfigStoragePool(s.Cluster, info)
+       if err != nil {
+               return nil, err
        }
 
        // Create revert function to remove the files created so far.
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to