[lxc-devel] [lxd/master] Move backup to separate package
monstermunchkin on Github
lxc-bot at linuxcontainers.org
Mon Oct 7 12:35:08 UTC 2019
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20191007/2f7cdea2/attachment-0001.bin>
-------------- next part --------------
From aa2ec7b359ae05d86711f145c97e29d3030dd642 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Mon, 7 Oct 2019 14:33:37 +0200
Subject: [PATCH 1/2] lxd: Move backup to separate package
This moves relevant backup code into its own package.
Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
lxd/backup.go | 237 +++++---------------------------------
lxd/backup/backup.go | 233 +++++++++++++++++++++++++++++++++++++
lxd/container.go | 3 +-
lxd/container_backup.go | 8 +-
lxd/container_lxc.go | 7 +-
lxd/containers_post.go | 5 +-
lxd/instance_interface.go | 3 +-
lxd/storage.go | 5 +-
lxd/storage_btrfs.go | 45 +++-----
lxd/storage_ceph.go | 38 +-----
lxd/storage_ceph_utils.go | 3 +-
lxd/storage_cephfs.go | 5 +-
lxd/storage_dir.go | 40 ++-----
lxd/storage_lvm.go | 36 ++----
lxd/storage_mock.go | 5 +-
lxd/storage_zfs.go | 51 +++-----
16 files changed, 338 insertions(+), 386 deletions(-)
create mode 100644 lxd/backup/backup.go
diff --git a/lxd/backup.go b/lxd/backup.go
index 4ebd4240a4..ce235b9989 100644
--- a/lxd/backup.go
+++ b/lxd/backup.go
@@ -1,33 +1,30 @@
package main
import (
- "archive/tar"
"fmt"
- "io"
+ "io/ioutil"
"os"
- "os/exec"
"path/filepath"
- "strings"
"time"
"context"
"gopkg.in/yaml.v2"
+ "github.com/lxc/lxd/lxd/backup"
"github.com/lxc/lxd/lxd/cluster"
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/state"
"github.com/lxc/lxd/lxd/task"
"github.com/lxc/lxd/shared"
- "github.com/lxc/lxd/shared/api"
log "github.com/lxc/lxd/shared/log15"
"github.com/lxc/lxd/shared/logger"
"github.com/pkg/errors"
)
// Load a backup from the database
-func backupLoadByName(s *state.State, project, name string) (*backup, error) {
+func backupLoadByName(s *state.State, project, name string) (*backup.Backup, error) {
// Get the backup database record
args, err := s.Cluster.ContainerGetBackup(project, name)
if err != nil {
@@ -40,17 +37,7 @@ func backupLoadByName(s *state.State, project, name string) (*backup, error) {
return nil, errors.Wrap(err, "Load container from database")
}
- // Return the backup struct
- return &backup{
- state: s,
- instance: instance,
- id: args.ID,
- name: name,
- creationDate: args.CreationDate,
- expiryDate: args.ExpiryDate,
- instanceOnly: args.InstanceOnly,
- optimizedStorage: args.OptimizedStorage,
- }, nil
+ return backup.NewBackup(s, instance, name, args), nil
}
// Create a new backup
@@ -71,168 +58,36 @@ func backupCreate(s *state.State, args db.InstanceBackupArgs, sourceContainer In
return errors.Wrap(err, "Load backup object")
}
- // Now create the empty snapshot
- err = sourceContainer.Storage().ContainerBackupCreate(*b, sourceContainer)
- if err != nil {
- s.Cluster.ContainerBackupRemove(args.Name)
- return errors.Wrap(err, "Backup storage")
- }
-
- return nil
-}
-
-// backup represents a container backup
-type backup struct {
- state *state.State
- instance Instance
-
- // Properties
- id int
- name string
- creationDate time.Time
- expiryDate time.Time
- instanceOnly bool
- optimizedStorage bool
-}
-
-type backupInfo struct {
- Project string `json:"project" yaml:"project"`
- Name string `json:"name" yaml:"name"`
- Backend string `json:"backend" yaml:"backend"`
- Privileged bool `json:"privileged" yaml:"privileged"`
- Pool string `json:"pool" yaml:"pool"`
- Snapshots []string `json:"snapshots,omitempty" yaml:"snapshots,omitempty"`
- HasBinaryFormat bool `json:"-" yaml:"-"`
-}
-
-// Rename renames a container backup
-func (b *backup) Rename(newName string) error {
- oldBackupPath := shared.VarPath("backups", b.name)
- newBackupPath := shared.VarPath("backups", newName)
-
- // Create the new backup path
- backupsPath := shared.VarPath("backups", b.instance.Name())
- if !shared.PathExists(backupsPath) {
- err := os.MkdirAll(backupsPath, 0700)
- if err != nil {
- return err
- }
- }
-
- // Rename the backup directory
- err := os.Rename(oldBackupPath, newBackupPath)
+ ourStart, err := sourceContainer.StorageStart()
if err != nil {
return err
}
-
- // Check if we can remove the container directory
- empty, _ := shared.PathIsEmpty(backupsPath)
- if empty {
- err := os.Remove(backupsPath)
- if err != nil {
- return err
- }
+ if ourStart {
+ defer sourceContainer.StorageStop()
}
- // Rename the database record
- err = b.state.Cluster.ContainerBackupRename(b.name, newName)
+ // Create a temporary path for the backup
+ tmpPath, err := ioutil.TempDir(shared.VarPath("backups"), "lxd_backup_")
if err != nil {
return err
}
+ defer os.RemoveAll(tmpPath)
- return nil
-}
-
-// Delete removes an instance backup
-func (b *backup) Delete() error {
- return doBackupDelete(b.state, b.name, b.instance.Name())
-}
-
-func (b *backup) Render() *api.InstanceBackup {
- return &api.InstanceBackup{
- Name: strings.SplitN(b.name, "/", 2)[1],
- CreatedAt: b.creationDate,
- ExpiresAt: b.expiryDate,
- InstanceOnly: b.instanceOnly,
- ContainerOnly: b.instanceOnly,
- OptimizedStorage: b.optimizedStorage,
- }
-}
-
-func backupGetInfo(r io.ReadSeeker) (*backupInfo, error) {
- var tr *tar.Reader
- result := backupInfo{}
- hasBinaryFormat := false
- hasIndexFile := false
-
- // Extract
- r.Seek(0, 0)
- _, _, unpacker, err := shared.DetectCompressionFile(r)
+ // Now create the empty snapshot
+ err = sourceContainer.Storage().ContainerBackupCreate(tmpPath, *b, sourceContainer)
if err != nil {
- return nil, err
- }
- r.Seek(0, 0)
-
- if unpacker == nil {
- return nil, fmt.Errorf("Unsupported backup compression")
- }
-
- if len(unpacker) > 0 {
- cmd := exec.Command(unpacker[0], unpacker[1:]...)
- cmd.Stdin = r
-
- stdout, err := cmd.StdoutPipe()
- if err != nil {
- return nil, err
- }
- defer stdout.Close()
-
- err = cmd.Start()
- if err != nil {
- return nil, err
- }
- defer cmd.Wait()
-
- tr = tar.NewReader(stdout)
- } else {
- tr = tar.NewReader(r)
- }
-
- for {
- hdr, err := tr.Next()
- if err == io.EOF {
- break // End of archive
- }
- if err != nil {
- return nil, err
- }
-
- if hdr.Name == "backup/index.yaml" {
- err = yaml.NewDecoder(tr).Decode(&result)
- if err != nil {
- return nil, err
- }
-
- hasIndexFile = true
- }
-
- if hdr.Name == "backup/container.bin" {
- hasBinaryFormat = true
- }
- }
-
- if !hasIndexFile {
- return nil, fmt.Errorf("Backup is missing index.yaml")
+ s.Cluster.ContainerBackupRemove(args.Name)
+ return errors.Wrap(err, "Backup storage")
}
- result.HasBinaryFormat = hasBinaryFormat
- return &result, nil
+ // Pack the backup
+ return backupCreateTarball(s, tmpPath, *b, sourceContainer)
}
// 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 backupInfo, useDefaultPool bool) error {
+func backupFixStoragePool(c *db.Cluster, b backup.Info, useDefaultPool bool) error {
var poolName string
if useDefaultPool {
@@ -323,23 +178,23 @@ func backupFixStoragePool(c *db.Cluster, b backupInfo, useDefaultPool bool) erro
return nil
}
-func backupCreateTarball(s *state.State, path string, backup backup) error {
+func backupCreateTarball(s *state.State, path string, b backup.Backup, c Instance) error {
// Create the index
- pool, err := backup.instance.StoragePool()
+ pool, err := c.StoragePool()
if err != nil {
return err
}
- indexFile := backupInfo{
- Name: backup.instance.Name(),
- Backend: backup.instance.Storage().GetStorageTypeName(),
- Privileged: backup.instance.IsPrivileged(),
+ indexFile := backup.Info{
+ Name: c.Name(),
+ Backend: c.Storage().GetStorageTypeName(),
+ Privileged: c.IsPrivileged(),
Pool: pool,
Snapshots: []string{},
}
- if !backup.instanceOnly {
- snaps, err := backup.instance.Snapshots()
+ if !b.InstanceOnly() {
+ snaps, err := c.Snapshots()
if err != nil {
return err
}
@@ -367,7 +222,7 @@ func backupCreateTarball(s *state.State, path string, backup backup) error {
}
// Create the target path if needed
- backupsPath := shared.VarPath("backups", backup.instance.Name())
+ backupsPath := shared.VarPath("backups", c.Name())
if !shared.PathExists(backupsPath) {
err := os.MkdirAll(backupsPath, 0700)
if err != nil {
@@ -376,7 +231,7 @@ func backupCreateTarball(s *state.State, path string, backup backup) error {
}
// Create the tarball
- backupPath := shared.VarPath("backups", backup.name)
+ backupPath := shared.VarPath("backups", b.Name())
success := false
defer func() {
if success {
@@ -489,43 +344,13 @@ func pruneExpiredContainerBackups(ctx context.Context, d *Daemon) error {
return errors.Wrap(err, "Unable to retrieve the list of expired container backups")
}
- for _, backup := range backups {
- containerName, _, _ := shared.ContainerGetParentAndSnapshotName(backup)
- err := doBackupDelete(d.State(), backup, containerName)
- if err != nil {
- return errors.Wrapf(err, "Error deleting container backup %s", backup)
- }
- }
-
- return nil
-}
-
-func doBackupDelete(s *state.State, backupName, containerName string) error {
- backupPath := shared.VarPath("backups", backupName)
-
- // Delete the on-disk data
- if shared.PathExists(backupPath) {
- err := os.RemoveAll(backupPath)
- if err != nil {
- return err
- }
- }
-
- // Check if we can remove the container directory
- backupsPath := shared.VarPath("backups", containerName)
- empty, _ := shared.PathIsEmpty(backupsPath)
- if empty {
- err := os.Remove(backupsPath)
+ for _, b := range backups {
+ containerName, _, _ := shared.ContainerGetParentAndSnapshotName(b)
+ err := backup.DoBackupDelete(d.State(), b, containerName)
if err != nil {
- return err
+ return errors.Wrapf(err, "Error deleting container backup %s", b)
}
}
- // Remove the database record
- err := s.Cluster.ContainerBackupRemove(backupName)
- if err != nil {
- return err
- }
-
return nil
}
diff --git a/lxd/backup/backup.go b/lxd/backup/backup.go
new file mode 100644
index 0000000000..1e694f2f4d
--- /dev/null
+++ b/lxd/backup/backup.go
@@ -0,0 +1,233 @@
+package backup
+
+import (
+ "archive/tar"
+ "fmt"
+ "io"
+ "os"
+ "os/exec"
+ "strings"
+ "time"
+
+ "github.com/lxc/lxd/lxd/db"
+ "github.com/lxc/lxd/lxd/state"
+ "github.com/lxc/lxd/shared"
+ "github.com/lxc/lxd/shared/api"
+ "gopkg.in/yaml.v2"
+)
+
+// Info represents exported backup information.
+type Info struct {
+ Project string `json:"project" yaml:"project"`
+ Name string `json:"name" yaml:"name"`
+ Backend string `json:"backend" yaml:"backend"`
+ Privileged bool `json:"privileged" yaml:"privileged"`
+ Pool string `json:"pool" yaml:"pool"`
+ Snapshots []string `json:"snapshots,omitempty" yaml:"snapshots,omitempty"`
+ HasBinaryFormat bool `json:"-" yaml:"-"`
+}
+
+// GetInfo extracts backup information from a given ReadSeeker.
+func GetInfo(r io.ReadSeeker) (*Info, error) {
+ var tr *tar.Reader
+ result := Info{}
+ hasBinaryFormat := false
+ hasIndexFile := false
+
+ // Extract
+ r.Seek(0, 0)
+ _, _, unpacker, err := shared.DetectCompressionFile(r)
+ if err != nil {
+ return nil, err
+ }
+ r.Seek(0, 0)
+
+ if unpacker == nil {
+ return nil, fmt.Errorf("Unsupported backup compression")
+ }
+
+ if len(unpacker) > 0 {
+ cmd := exec.Command(unpacker[0], unpacker[1:]...)
+ cmd.Stdin = r
+
+ stdout, err := cmd.StdoutPipe()
+ if err != nil {
+ return nil, err
+ }
+ defer stdout.Close()
+
+ err = cmd.Start()
+ if err != nil {
+ return nil, err
+ }
+ defer cmd.Wait()
+
+ tr = tar.NewReader(stdout)
+ } else {
+ tr = tar.NewReader(r)
+ }
+
+ for {
+ hdr, err := tr.Next()
+ if err == io.EOF {
+ break // End of archive
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ if hdr.Name == "backup/index.yaml" {
+ err = yaml.NewDecoder(tr).Decode(&result)
+ if err != nil {
+ return nil, err
+ }
+
+ hasIndexFile = true
+ }
+
+ if hdr.Name == "backup/container.bin" {
+ hasBinaryFormat = true
+ }
+ }
+
+ if !hasIndexFile {
+ return nil, fmt.Errorf("Backup is missing index.yaml")
+ }
+
+ result.HasBinaryFormat = hasBinaryFormat
+ return &result, nil
+}
+
+type instance interface {
+ Name() string
+}
+
+// Backup represents a container backup
+type Backup struct {
+ state *state.State
+ instance instance
+
+ // Properties
+ id int
+ name string
+ creationDate time.Time
+ expiryDate time.Time
+ instanceOnly bool
+ optimizedStorage bool
+}
+
+// NewBackup returns a new Backup struct.
+func NewBackup(s *state.State, instance instance, name string, args db.InstanceBackupArgs) *Backup {
+ return &Backup{
+ state: s,
+ instance: instance,
+ id: args.ID,
+ name: name,
+ creationDate: args.CreationDate,
+ expiryDate: args.ExpiryDate,
+ instanceOnly: args.InstanceOnly,
+ optimizedStorage: args.OptimizedStorage,
+ }
+}
+
+// InstanceOnly returns whether only the instance itself is to be backed up.
+func (b *Backup) InstanceOnly() bool {
+ return b.instanceOnly
+}
+
+// Name returns the name of the backup.
+func (b *Backup) Name() string {
+ return b.name
+}
+
+// OptimizedStorage returns whether the backup is to be performed using
+// optimization supported by the storage driver.
+func (b *Backup) OptimizedStorage() bool {
+ return b.optimizedStorage
+}
+
+// Rename renames a container backup
+func (b *Backup) Rename(newName string) error {
+ oldBackupPath := shared.VarPath("backups", b.name)
+ newBackupPath := shared.VarPath("backups", newName)
+
+ // Create the new backup path
+ backupsPath := shared.VarPath("backups", b.instance.Name())
+ if !shared.PathExists(backupsPath) {
+ err := os.MkdirAll(backupsPath, 0700)
+ if err != nil {
+ return err
+ }
+ }
+
+ // Rename the backup directory
+ err := os.Rename(oldBackupPath, newBackupPath)
+ if err != nil {
+ return err
+ }
+
+ // Check if we can remove the container directory
+ empty, _ := shared.PathIsEmpty(backupsPath)
+ if empty {
+ err := os.Remove(backupsPath)
+ if err != nil {
+ return err
+ }
+ }
+
+ // Rename the database record
+ err = b.state.Cluster.ContainerBackupRename(b.name, newName)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// Delete removes an instance backup
+func (b *Backup) Delete() error {
+ return DoBackupDelete(b.state, b.name, b.instance.Name())
+}
+
+// Render returns an InstanceBackup struct of the backup.
+func (b *Backup) Render() *api.InstanceBackup {
+ return &api.InstanceBackup{
+ Name: strings.SplitN(b.name, "/", 2)[1],
+ CreatedAt: b.creationDate,
+ ExpiresAt: b.expiryDate,
+ InstanceOnly: b.instanceOnly,
+ ContainerOnly: b.instanceOnly,
+ OptimizedStorage: b.optimizedStorage,
+ }
+}
+
+// DoBackupDelete deletes a backup.
+func DoBackupDelete(s *state.State, backupName, containerName string) error {
+ backupPath := shared.VarPath("backups", backupName)
+
+ // Delete the on-disk data
+ if shared.PathExists(backupPath) {
+ err := os.RemoveAll(backupPath)
+ if err != nil {
+ return err
+ }
+ }
+
+ // Check if we can remove the container directory
+ backupsPath := shared.VarPath("backups", containerName)
+ empty, _ := shared.PathIsEmpty(backupsPath)
+ if empty {
+ err := os.Remove(backupsPath)
+ if err != nil {
+ return err
+ }
+ }
+
+ // Remove the database record
+ err := s.Cluster.ContainerBackupRemove(backupName)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/lxd/container.go b/lxd/container.go
index dce1e8f191..6162e1a67c 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -16,6 +16,7 @@ import (
cron "gopkg.in/robfig/cron.v2"
"github.com/flosch/pongo2"
+ "github.com/lxc/lxd/lxd/backup"
"github.com/lxc/lxd/lxd/cluster"
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/device"
@@ -264,7 +265,7 @@ func containerCreateAsEmpty(d *Daemon, args db.InstanceArgs) (container, error)
return c, nil
}
-func containerCreateFromBackup(s *state.State, info backupInfo, data io.ReadSeeker,
+func containerCreateFromBackup(s *state.State, info backup.Info, data io.ReadSeeker,
customPool bool) (storage, error) {
var pool storage
var fixBackupFile = false
diff --git a/lxd/container_backup.go b/lxd/container_backup.go
index 4e016d7af0..064eac09ba 100644
--- a/lxd/container_backup.go
+++ b/lxd/container_backup.go
@@ -55,7 +55,7 @@ func containerBackupsGet(d *Daemon, r *http.Request) response.Response {
for _, backup := range backups {
if !recursion {
url := fmt.Sprintf("/%s/containers/%s/backups/%s",
- version.APIVersion, cname, strings.Split(backup.name, "/")[1])
+ version.APIVersion, cname, strings.Split(backup.Name(), "/")[1])
resultString = append(resultString, url)
} else {
render := backup.Render()
@@ -131,11 +131,11 @@ func containerBackupsPost(d *Daemon, r *http.Request) response.Response {
for _, backup := range backups {
// Ignore backups not containing base
- if !strings.HasPrefix(backup.name, base) {
+ if !strings.HasPrefix(backup.Name(), base) {
continue
}
- substr := backup.name[length:]
+ substr := backup.Name()[length:]
var num int
count, err := fmt.Sscanf(substr, "%d", &num)
if err != nil || count != 1 {
@@ -347,7 +347,7 @@ func containerBackupExportGet(d *Daemon, r *http.Request) response.Response {
}
ent := response.FileResponseEntry{
- Path: shared.VarPath("backups", backup.name),
+ Path: shared.VarPath("backups", backup.Name()),
}
return response.FileResponse(r, []response.FileResponseEntry{ent}, nil, false)
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index f2c7195b69..9dc090281d 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -26,6 +26,7 @@ import (
yaml "gopkg.in/yaml.v2"
"github.com/lxc/lxd/lxd/apparmor"
+ "github.com/lxc/lxd/lxd/backup"
"github.com/lxc/lxd/lxd/cluster"
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/db/query"
@@ -3287,7 +3288,7 @@ func (c *containerLXC) Snapshots() ([]Instance, error) {
return instances, nil
}
-func (c *containerLXC) Backups() ([]backup, error) {
+func (c *containerLXC) Backups() ([]backup.Backup, error) {
// Get all the backups
backupNames, err := c.state.Cluster.ContainerGetBackups(c.project, c.name)
if err != nil {
@@ -3295,7 +3296,7 @@ func (c *containerLXC) Backups() ([]backup, error) {
}
// Build the backup list
- backups := []backup{}
+ backups := []backup.Backup{}
for _, backupName := range backupNames {
backup, err := backupLoadByName(c.state, c.project, backupName)
if err != nil {
@@ -3709,7 +3710,7 @@ func (c *containerLXC) Rename(newName string) error {
}
for _, backup := range backups {
- backupName := strings.Split(backup.name, "/")[1]
+ backupName := strings.Split(backup.Name(), "/")[1]
newName := fmt.Sprintf("%s/%s", newName, backupName)
err = backup.Rename(newName)
diff --git a/lxd/containers_post.go b/lxd/containers_post.go
index 5c79e675d2..a19d53aa0c 100644
--- a/lxd/containers_post.go
+++ b/lxd/containers_post.go
@@ -13,10 +13,11 @@ import (
"os"
"strings"
- "github.com/dustinkirkland/golang-petname"
+ petname "github.com/dustinkirkland/golang-petname"
"github.com/gorilla/websocket"
"github.com/pkg/errors"
+ "github.com/lxc/lxd/lxd/backup"
"github.com/lxc/lxd/lxd/cluster"
"github.com/lxc/lxd/lxd/db"
deviceConfig "github.com/lxc/lxd/lxd/device/config"
@@ -634,7 +635,7 @@ func createFromBackup(d *Daemon, project string, data io.Reader, pool string) re
// Parse the backup information
f.Seek(0, 0)
- bInfo, err := backupGetInfo(f)
+ bInfo, err := backup.GetInfo(f)
if err != nil {
f.Close()
return response.BadRequest(err)
diff --git a/lxd/instance_interface.go b/lxd/instance_interface.go
index 80af10ce13..b6dbaa3022 100644
--- a/lxd/instance_interface.go
+++ b/lxd/instance_interface.go
@@ -6,6 +6,7 @@ import (
"os/exec"
"time"
+ "github.com/lxc/lxd/lxd/backup"
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/device"
deviceConfig "github.com/lxc/lxd/lxd/device/config"
@@ -29,7 +30,7 @@ type Instance interface {
// Snapshots & migration & backups
Restore(source Instance, stateful bool) error
Snapshots() ([]Instance, error)
- Backups() ([]backup, error)
+ Backups() ([]backup.Backup, error)
// Config handling
Rename(newName string) error
diff --git a/lxd/storage.go b/lxd/storage.go
index ece8dc2812..4f5a1d6289 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -11,6 +11,7 @@ import (
"github.com/gorilla/websocket"
"github.com/pkg/errors"
+ "github.com/lxc/lxd/lxd/backup"
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/device"
"github.com/lxc/lxd/lxd/instance/instancetype"
@@ -212,8 +213,8 @@ type storage interface {
ContainerSnapshotStart(c Instance) (bool, error)
ContainerSnapshotStop(c Instance) (bool, error)
- ContainerBackupCreate(backup backup, sourceContainer Instance) error
- ContainerBackupLoad(info backupInfo, data io.ReadSeeker, tarArgs []string) error
+ ContainerBackupCreate(path string, backup backup.Backup, sourceContainer Instance) error
+ ContainerBackupLoad(info backup.Info, data io.ReadSeeker, tarArgs []string) error
// For use in migrating snapshots.
ContainerSnapshotCreateEmpty(c Instance) error
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 3220b10af2..daa64b6138 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -16,6 +16,7 @@ import (
"github.com/pkg/errors"
"golang.org/x/sys/unix"
+ "github.com/lxc/lxd/lxd/backup"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/project"
@@ -1616,10 +1617,10 @@ func (s *storageBtrfs) doBtrfsBackup(cur string, prev string, target string) err
return err
}
-func (s *storageBtrfs) doContainerBackupCreateOptimized(tmpPath string, backup backup, source Instance) error {
+func (s *storageBtrfs) doContainerBackupCreateOptimized(tmpPath string, backup backup.Backup, source Instance) error {
// Handle snapshots
finalParent := ""
- if !backup.instanceOnly {
+ if !backup.InstanceOnly() {
snapshotsPath := fmt.Sprintf("%s/snapshots", tmpPath)
// Retrieve the snapshots
@@ -1689,7 +1690,7 @@ func (s *storageBtrfs) doContainerBackupCreateOptimized(tmpPath string, backup b
return nil
}
-func (s *storageBtrfs) doContainerBackupCreateVanilla(tmpPath string, backup backup, source Instance) error {
+func (s *storageBtrfs) doContainerBackupCreateVanilla(tmpPath string, backup backup.Backup, source Instance) error {
// Prepare for rsync
rsync := func(oldPath string, newPath string, bwlimit string) error {
output, err := rsyncLocalCopy(oldPath, newPath, bwlimit, true)
@@ -1703,7 +1704,7 @@ func (s *storageBtrfs) doContainerBackupCreateVanilla(tmpPath string, backup bac
bwlimit := s.pool.Config["rsync.bwlimit"]
// Handle snapshots
- if !backup.instanceOnly {
+ if !backup.InstanceOnly() {
snapshotsPath := fmt.Sprintf("%s/snapshots", tmpPath)
// Retrieve the snapshots
@@ -1772,46 +1773,26 @@ func (s *storageBtrfs) doContainerBackupCreateVanilla(tmpPath string, backup bac
return nil
}
-func (s *storageBtrfs) ContainerBackupCreate(backup backup, source Instance) error {
- // Start storage
- ourStart, err := source.StorageStart()
- if err != nil {
- return err
- }
- if ourStart {
- defer source.StorageStop()
- }
-
- // Create a temporary path for the backup
- tmpPath, err := ioutil.TempDir(shared.VarPath("backups"), "lxd_backup_")
- if err != nil {
- return err
- }
- defer os.RemoveAll(tmpPath)
+func (s *storageBtrfs) ContainerBackupCreate(path string, backup backup.Backup, source Instance) error {
+ var err error
// Generate the actual backup
- if backup.optimizedStorage {
- err = s.doContainerBackupCreateOptimized(tmpPath, backup, source)
+ if backup.OptimizedStorage() {
+ err = s.doContainerBackupCreateOptimized(path, backup, source)
if err != nil {
return err
}
} else {
- err := s.doContainerBackupCreateVanilla(tmpPath, backup, source)
+ err := s.doContainerBackupCreateVanilla(path, backup, source)
if err != nil {
return err
}
}
- // Pack the backup
- err = backupCreateTarball(s.s, tmpPath, backup)
- if err != nil {
- return err
- }
-
return nil
}
-func (s *storageBtrfs) doContainerBackupLoadOptimized(info backupInfo, data io.ReadSeeker, tarArgs []string) error {
+func (s *storageBtrfs) doContainerBackupLoadOptimized(info backup.Info, data io.ReadSeeker, tarArgs []string) error {
containerName, _, _ := shared.ContainerGetParentAndSnapshotName(info.Name)
containerMntPoint := driver.GetContainerMountPoint("default", s.pool.Name, "")
@@ -1909,7 +1890,7 @@ func (s *storageBtrfs) doContainerBackupLoadOptimized(info backupInfo, data io.R
return nil
}
-func (s *storageBtrfs) doContainerBackupLoadVanilla(info backupInfo, data io.ReadSeeker, tarArgs []string) error {
+func (s *storageBtrfs) doContainerBackupLoadVanilla(info backup.Info, data io.ReadSeeker, tarArgs []string) error {
// create the main container
err := s.doContainerCreate(info.Project, info.Name, info.Privileged)
if err != nil {
@@ -1964,7 +1945,7 @@ func (s *storageBtrfs) doContainerBackupLoadVanilla(info backupInfo, data io.Rea
return nil
}
-func (s *storageBtrfs) ContainerBackupLoad(info backupInfo, data io.ReadSeeker, tarArgs []string) error {
+func (s *storageBtrfs) ContainerBackupLoad(info backup.Info, data io.ReadSeeker, tarArgs []string) error {
logger.Debugf("Loading BTRFS storage volume for backup \"%s\" on storage pool \"%s\"", info.Name, s.pool.Name)
if info.HasBinaryFormat {
diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index bede743bd3..61c032a8ad 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -14,6 +14,7 @@ import (
"github.com/pkg/errors"
"golang.org/x/sys/unix"
+ "github.com/lxc/lxd/lxd/backup"
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
@@ -1890,50 +1891,23 @@ func (s *storageCeph) ContainerSnapshotCreateEmpty(c Instance) error {
return nil
}
-func (s *storageCeph) ContainerBackupCreate(backup backup, source Instance) error {
- // Start storage
- ourStart, err := source.StorageStart()
- if err != nil {
- return err
- }
- if ourStart {
- defer source.StorageStop()
- }
-
- // Create a temporary path for the backup
- tmpPath, err := ioutil.TempDir(shared.VarPath("backups"), "lxd_backup_")
- if err != nil {
- return err
- }
- defer os.RemoveAll(tmpPath)
-
+func (s *storageCeph) ContainerBackupCreate(path string, backup backup.Backup, source Instance) error {
// Generate the actual backup
- if !backup.instanceOnly {
+ if !backup.InstanceOnly() {
snapshots, err := source.Snapshots()
if err != nil {
return err
}
for _, snap := range snapshots {
- err := s.cephRBDVolumeBackupCreate(tmpPath, backup, snap)
+ err := s.cephRBDVolumeBackupCreate(path, backup, snap)
if err != nil {
return err
}
}
}
- err = s.cephRBDVolumeBackupCreate(tmpPath, backup, source)
- if err != nil {
- return err
- }
-
- // Pack the backup
- err = backupCreateTarball(s.s, tmpPath, backup)
- if err != nil {
- return err
- }
-
- return nil
+ return s.cephRBDVolumeBackupCreate(path, backup, source)
}
// This function recreates an rbd container including its snapshots. It
@@ -1942,7 +1916,7 @@ func (s *storageCeph) ContainerBackupCreate(backup backup, source Instance) erro
// - for each snapshot dump the contents into the empty storage volume and
// after each dump take a snapshot of the rbd storage volume
// - dump the container contents into the rbd storage volume.
-func (s *storageCeph) ContainerBackupLoad(info backupInfo, data io.ReadSeeker, tarArgs []string) error {
+func (s *storageCeph) ContainerBackupLoad(info backup.Info, data io.ReadSeeker, tarArgs []string) error {
// create the main container
err := s.doContainerCreate(info.Project, info.Name, info.Privileged)
if err != nil {
diff --git a/lxd/storage_ceph_utils.go b/lxd/storage_ceph_utils.go
index 4d5c20222e..174a62315c 100644
--- a/lxd/storage_ceph_utils.go
+++ b/lxd/storage_ceph_utils.go
@@ -14,6 +14,7 @@ import (
"github.com/pborman/uuid"
"golang.org/x/sys/unix"
+ "github.com/lxc/lxd/lxd/backup"
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/project"
driver "github.com/lxc/lxd/lxd/storage"
@@ -1584,7 +1585,7 @@ func (s *storageCeph) cephRBDVolumeDumpToFile(sourceVolumeName string, file stri
}
// cephRBDVolumeBackupCreate creates a backup of a container or snapshot.
-func (s *storageCeph) cephRBDVolumeBackupCreate(tmpPath string, backup backup, source Instance) error {
+func (s *storageCeph) cephRBDVolumeBackupCreate(tmpPath string, backup backup.Backup, source Instance) error {
sourceIsSnapshot := source.IsSnapshot()
sourceContainerName := source.Name()
sourceContainerOnlyName := project.Prefix(source.Project(), sourceContainerName)
diff --git a/lxd/storage_cephfs.go b/lxd/storage_cephfs.go
index ed3f219ece..89810318b4 100644
--- a/lxd/storage_cephfs.go
+++ b/lxd/storage_cephfs.go
@@ -13,6 +13,7 @@ import (
"github.com/gorilla/websocket"
"github.com/pkg/errors"
+ "github.com/lxc/lxd/lxd/backup"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/state"
@@ -693,11 +694,11 @@ func (s *storageCephFs) ContainerSnapshotStop(container Instance) (bool, error)
return false, fmt.Errorf("CEPHFS cannot be used for containers")
}
-func (s *storageCephFs) ContainerBackupCreate(backup backup, source Instance) error {
+func (s *storageCephFs) ContainerBackupCreate(path string, backup backup.Backup, source Instance) error {
return fmt.Errorf("CEPHFS cannot be used for containers")
}
-func (s *storageCephFs) ContainerBackupLoad(info backupInfo, data io.ReadSeeker, tarArgs []string) error {
+func (s *storageCephFs) ContainerBackupLoad(info backup.Info, data io.ReadSeeker, tarArgs []string) error {
return fmt.Errorf("CEPHFS cannot be used for containers")
}
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index c24eecaae4..825485eedf 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -3,7 +3,6 @@ package main
import (
"fmt"
"io"
- "io/ioutil"
"os"
"path/filepath"
"strings"
@@ -12,6 +11,7 @@ import (
"github.com/pkg/errors"
"golang.org/x/sys/unix"
+ "github.com/lxc/lxd/lxd/backup"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/project"
@@ -1122,23 +1122,7 @@ func (s *storageDir) ContainerSnapshotStop(container Instance) (bool, error) {
return true, nil
}
-func (s *storageDir) ContainerBackupCreate(backup backup, source Instance) error {
- // Start storage
- ourStart, err := source.StorageStart()
- if err != nil {
- return err
- }
- if ourStart {
- defer source.StorageStop()
- }
-
- // Create a temporary path for the backup
- tmpPath, err := ioutil.TempDir(shared.VarPath("backups"), "lxd_backup_")
- if err != nil {
- return err
- }
- defer os.RemoveAll(tmpPath)
-
+func (s *storageDir) ContainerBackupCreate(path string, backup backup.Backup, source Instance) error {
// Prepare for rsync
rsync := func(oldPath string, newPath string, bwlimit string) error {
output, err := rsyncLocalCopy(oldPath, newPath, bwlimit, true)
@@ -1152,8 +1136,8 @@ func (s *storageDir) ContainerBackupCreate(backup backup, source Instance) error
bwlimit := s.pool.Config["rsync.bwlimit"]
// Handle snapshots
- if !backup.instanceOnly {
- snapshotsPath := fmt.Sprintf("%s/snapshots", tmpPath)
+ if !backup.InstanceOnly() {
+ snapshotsPath := fmt.Sprintf("%s/snapshots", path)
// Retrieve the snapshots
snapshots, err := source.Snapshots()
@@ -1195,22 +1179,12 @@ func (s *storageDir) ContainerBackupCreate(backup backup, source Instance) error
}
// Copy the container
- containerPath := fmt.Sprintf("%s/container", tmpPath)
- err = rsync(source.Path(), containerPath, bwlimit)
- if err != nil {
- return err
- }
+ containerPath := fmt.Sprintf("%s/container", path)
- // Pack the backup
- err = backupCreateTarball(s.s, tmpPath, backup)
- if err != nil {
- return err
- }
-
- return nil
+ return rsync(source.Path(), containerPath, bwlimit)
}
-func (s *storageDir) ContainerBackupLoad(info backupInfo, data io.ReadSeeker, tarArgs []string) error {
+func (s *storageDir) ContainerBackupLoad(info backup.Info, data io.ReadSeeker, tarArgs []string) error {
_, err := s.StoragePoolMount()
if err != nil {
return err
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index d41704a8bf..bdb211368e 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -3,7 +3,6 @@ package main
import (
"fmt"
"io"
- "io/ioutil"
"os"
"path/filepath"
"strconv"
@@ -13,6 +12,7 @@ import (
"github.com/pborman/uuid"
"github.com/pkg/errors"
+ "github.com/lxc/lxd/lxd/backup"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/project"
@@ -1662,25 +1662,9 @@ func (s *storageLvm) ContainerSnapshotCreateEmpty(snapshotContainer Instance) er
return nil
}
-func (s *storageLvm) ContainerBackupCreate(backup backup, source Instance) error {
+func (s *storageLvm) ContainerBackupCreate(path string, backup backup.Backup, source Instance) error {
poolName := s.getOnDiskPoolName()
- // Start storage
- ourStart, err := source.StorageStart()
- if err != nil {
- return err
- }
- if ourStart {
- defer source.StorageStop()
- }
-
- // Create a temporary path for the backup
- tmpPath, err := ioutil.TempDir(shared.VarPath("backups"), "lxd_backup_")
- if err != nil {
- return err
- }
- defer os.RemoveAll(tmpPath)
-
// Prepare for rsync
rsync := func(oldPath string, newPath string, bwlimit string) error {
output, err := rsyncLocalCopy(oldPath, newPath, bwlimit, true)
@@ -1694,8 +1678,8 @@ func (s *storageLvm) ContainerBackupCreate(backup backup, source Instance) error
bwlimit := s.pool.Config["rsync.bwlimit"]
// Handle snapshots
- if !backup.instanceOnly {
- snapshotsPath := fmt.Sprintf("%s/snapshots", tmpPath)
+ if !backup.InstanceOnly() {
+ snapshotsPath := fmt.Sprintf("%s/snapshots", path)
// Retrieve the snapshots
snapshots, err := source.Snapshots()
@@ -1734,7 +1718,7 @@ func (s *storageLvm) ContainerBackupCreate(backup backup, source Instance) error
// Make a temporary snapshot of the container
sourceLvmDatasetSnapshot := fmt.Sprintf("snapshot-%s", uuid.NewRandom().String())
tmpContainerMntPoint := driver.GetContainerMountPoint(source.Project(), s.pool.Name, sourceLvmDatasetSnapshot)
- err = os.MkdirAll(tmpContainerMntPoint, 0700)
+ err := os.MkdirAll(tmpContainerMntPoint, 0700)
if err != nil {
return err
}
@@ -1756,23 +1740,17 @@ func (s *storageLvm) ContainerBackupCreate(backup backup, source Instance) error
}
// Copy the container
- containerPath := fmt.Sprintf("%s/container", tmpPath)
+ containerPath := fmt.Sprintf("%s/container", path)
err = rsync(tmpContainerMntPoint, containerPath, bwlimit)
s.umount(source.Project(), sourceLvmDatasetSnapshot, "")
if err != nil {
return err
}
- // Pack the backup
- err = backupCreateTarball(s.s, tmpPath, backup)
- if err != nil {
- return err
- }
-
return nil
}
-func (s *storageLvm) ContainerBackupLoad(info backupInfo, data io.ReadSeeker, tarArgs []string) error {
+func (s *storageLvm) ContainerBackupLoad(info backup.Info, data io.ReadSeeker, tarArgs []string) error {
containerPath, err := s.doContainerBackupLoad(info.Project, info.Name, info.Privileged, false)
if err != nil {
return err
diff --git a/lxd/storage_mock.go b/lxd/storage_mock.go
index d3ab28b093..7b9c2d1d80 100644
--- a/lxd/storage_mock.go
+++ b/lxd/storage_mock.go
@@ -5,6 +5,7 @@ import (
"github.com/gorilla/websocket"
+ "github.com/lxc/lxd/lxd/backup"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/state"
@@ -176,11 +177,11 @@ func (s *storageMock) ContainerSnapshotCreateEmpty(snapshotContainer Instance) e
return nil
}
-func (s *storageMock) ContainerBackupCreate(backup backup, sourceContainer Instance) error {
+func (s *storageMock) ContainerBackupCreate(path string, backup backup.Backup, sourceContainer Instance) error {
return nil
}
-func (s *storageMock) ContainerBackupLoad(info backupInfo, data io.ReadSeeker, tarArgs []string) error {
+func (s *storageMock) ContainerBackupLoad(info backup.Info, data io.ReadSeeker, tarArgs []string) error {
return nil
}
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index b0bf9c9df9..03bcd510d7 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -14,6 +14,7 @@ import (
"github.com/pkg/errors"
"golang.org/x/sys/unix"
+ "github.com/lxc/lxd/lxd/backup"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/project"
@@ -1839,7 +1840,7 @@ func (s *storageZfs) ContainerSnapshotCreateEmpty(snapshotContainer Instance) er
return nil
}
-func (s *storageZfs) doContainerOnlyBackup(tmpPath string, backup backup, source Instance) error {
+func (s *storageZfs) doContainerOnlyBackup(tmpPath string, backup backup.Backup, source Instance) error {
sourceIsSnapshot := source.IsSnapshot()
poolName := s.getOnDiskPoolName()
@@ -1887,7 +1888,7 @@ func (s *storageZfs) doContainerOnlyBackup(tmpPath string, backup backup, source
return nil
}
-func (s *storageZfs) doSnapshotBackup(tmpPath string, backup backup, source Instance, parentSnapshot string) error {
+func (s *storageZfs) doSnapshotBackup(tmpPath string, backup backup.Backup, source Instance, parentSnapshot string) error {
sourceName := source.Name()
snapshotsPath := fmt.Sprintf("%s/snapshots", tmpPath)
@@ -1919,14 +1920,14 @@ func (s *storageZfs) doSnapshotBackup(tmpPath string, backup backup, source Inst
return zfsSendCmd.Run()
}
-func (s *storageZfs) doContainerBackupCreateOptimized(tmpPath string, backup backup, source Instance) error {
+func (s *storageZfs) doContainerBackupCreateOptimized(tmpPath string, backup backup.Backup, source Instance) error {
// Handle snapshots
snapshots, err := source.Snapshots()
if err != nil {
return err
}
- if backup.instanceOnly || len(snapshots) == 0 {
+ if backup.InstanceOnly() || len(snapshots) == 0 {
err = s.doContainerOnlyBackup(tmpPath, backup, source)
} else {
prev := ""
@@ -1988,7 +1989,7 @@ func (s *storageZfs) doContainerBackupCreateOptimized(tmpPath string, backup bac
return nil
}
-func (s *storageZfs) doContainerBackupCreateVanilla(tmpPath string, backup backup, source Instance) error {
+func (s *storageZfs) doContainerBackupCreateVanilla(tmpPath string, backup backup.Backup, source Instance) error {
// Prepare for rsync
rsync := func(oldPath string, newPath string, bwlimit string) error {
output, err := rsyncLocalCopy(oldPath, newPath, bwlimit, true)
@@ -2000,10 +2001,10 @@ func (s *storageZfs) doContainerBackupCreateVanilla(tmpPath string, backup backu
}
bwlimit := s.pool.Config["rsync.bwlimit"]
- projectName := backup.instance.Project()
+ projectName := source.Project()
// Handle snapshots
- if !backup.instanceOnly {
+ if !backup.InstanceOnly() {
snapshotsPath := fmt.Sprintf("%s/snapshots", tmpPath)
// Retrieve the snapshots
@@ -2091,46 +2092,24 @@ func (s *storageZfs) doContainerBackupCreateVanilla(tmpPath string, backup backu
return nil
}
-func (s *storageZfs) ContainerBackupCreate(backup backup, source Instance) error {
- // Start storage
- ourStart, err := source.StorageStart()
- if err != nil {
- return err
- }
- if ourStart {
- defer source.StorageStop()
- }
-
- // Create a temporary path for the backup
- tmpPath, err := ioutil.TempDir(shared.VarPath("backups"), "lxd_backup_")
- if err != nil {
- return err
- }
- defer os.RemoveAll(tmpPath)
-
+func (s *storageZfs) ContainerBackupCreate(path string, backup backup.Backup, source Instance) error {
// Generate the actual backup
- if backup.optimizedStorage {
- err = s.doContainerBackupCreateOptimized(tmpPath, backup, source)
+ if backup.OptimizedStorage() {
+ err := s.doContainerBackupCreateOptimized(path, backup, source)
if err != nil {
return errors.Wrap(err, "Optimized backup")
}
} else {
- err = s.doContainerBackupCreateVanilla(tmpPath, backup, source)
+ err := s.doContainerBackupCreateVanilla(path, backup, source)
if err != nil {
return errors.Wrap(err, "Vanilla backup")
}
}
- // Pack the backup
- err = backupCreateTarball(s.s, tmpPath, backup)
- if err != nil {
- return err
- }
-
return nil
}
-func (s *storageZfs) doContainerBackupLoadOptimized(info backupInfo, data io.ReadSeeker, tarArgs []string) error {
+func (s *storageZfs) doContainerBackupLoadOptimized(info backup.Info, data io.ReadSeeker, tarArgs []string) error {
containerName, _, _ := shared.ContainerGetParentAndSnapshotName(info.Name)
containerMntPoint := driver.GetContainerMountPoint(info.Project, s.pool.Name, containerName)
err := driver.CreateContainerMountpoint(containerMntPoint, driver.ContainerPath(info.Name, false), info.Privileged)
@@ -2240,7 +2219,7 @@ func (s *storageZfs) doContainerBackupLoadOptimized(info backupInfo, data io.Rea
return nil
}
-func (s *storageZfs) doContainerBackupLoadVanilla(info backupInfo, data io.ReadSeeker, tarArgs []string) error {
+func (s *storageZfs) doContainerBackupLoadVanilla(info backup.Info, data io.ReadSeeker, tarArgs []string) error {
// create the main container
err := s.doContainerCreate(info.Project, info.Name, info.Privileged)
if err != nil {
@@ -2302,7 +2281,7 @@ func (s *storageZfs) doContainerBackupLoadVanilla(info backupInfo, data io.ReadS
return nil
}
-func (s *storageZfs) ContainerBackupLoad(info backupInfo, data io.ReadSeeker, tarArgs []string) error {
+func (s *storageZfs) ContainerBackupLoad(info backup.Info, data io.ReadSeeker, tarArgs []string) error {
logger.Debugf("Loading ZFS storage volume for backup \"%s\" on storage pool \"%s\"", info.Name, s.pool.Name)
if info.HasBinaryFormat {
From a9fa1f6bab102f294916c30d419883c24868c424 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Mon, 7 Oct 2019 14:33:51 +0200
Subject: [PATCH 2/2] test: Add backup package to static analysis
Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
test/suites/static_analysis.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/test/suites/static_analysis.sh b/test/suites/static_analysis.sh
index 44786668d3..79b41810e0 100644
--- a/test/suites/static_analysis.sh
+++ b/test/suites/static_analysis.sh
@@ -72,6 +72,7 @@ test_static_analysis() {
golint -set_exit_status lxd-p2c
+ golint -set_exit_status lxd/backup
golint -set_exit_status lxd/config
golint -set_exit_status lxd/db
golint -set_exit_status lxd/db/node
More information about the lxc-devel
mailing list