[lxc-devel] [lxd/master] storage: implement local {copy, move} custom storage volumes
brauner on Github
lxc-bot at linuxcontainers.org
Tue Jan 16 13:06:43 UTC 2018
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 520 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180116/9356a25d/attachment.bin>
-------------- next part --------------
From d3d3a0f573dfcc98a809f787eac60fe889a1d012 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 15 Jan 2018 12:39:40 +0100
Subject: [PATCH 01/10] doc: s/zfs/ceph/
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
doc/storage.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/storage.md b/doc/storage.md
index fe68d8984..2a8eaf422 100644
--- a/doc/storage.md
+++ b/doc/storage.md
@@ -186,7 +186,7 @@ lxc storage create pool2 dir source=/data/lxd
storage entities is not recommended by Ceph upstream. You may see unexpected
and erratic failures which are unrelated to LXD itself.
-#### The following commands can be used to create ZFS storage pools
+#### The following commands can be used to create Ceph storage pools
- Create a osd storage pool named "pool1" in the CEPH cluster "ceph".
From e00b1117d44c1ec1d2db5b67dd22667d52c3094e Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 15 Jan 2018 13:14:30 +0100
Subject: [PATCH 02/10] shared/api: add StorageVolumeSource struct
Closes #3984.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
shared/api/storage_pool_volume.go | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/shared/api/storage_pool_volume.go b/shared/api/storage_pool_volume.go
index 61e6b8732..2ad98ea4c 100644
--- a/shared/api/storage_pool_volume.go
+++ b/shared/api/storage_pool_volume.go
@@ -8,6 +8,9 @@ type StorageVolumesPost struct {
Name string `json:"name" yaml:"name"`
Type string `json:"type" yaml:"type"`
+
+ // API extension: storage_local_volume_copy
+ Source StorageVolumeSource `json:"source" yaml:"source"`
}
// StorageVolumePost represents the fields required to rename a LXD storage pool volume
@@ -37,6 +40,15 @@ type StorageVolumePut struct {
Description string `json:"description" yaml:"description"`
}
+// StoragePoolVolumeSource represents the creation source for a new storage volume.
+//
+// API extension: storage_local_volume_copy
+type StorageVolumeSource struct {
+ Name string `json:"name" yaml:"name"`
+ Type string `json:"type" yaml:"type"`
+ Pool string `json:"pool" yaml:"pool"`
+}
+
// Writable converts a full StorageVolume struct into a StorageVolumePut struct
// (filters read-only fields).
func (storageVolume *StorageVolume) Writable() StorageVolumePut {
From 964ed393ede22e095574415dac5e3e28f0b9fd0d Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 15 Jan 2018 17:33:58 +0100
Subject: [PATCH 03/10] client: add CopyStoragePoolVolume()
This also adds a new struct StoragePoolVolumeCopyArgs which is currently empty.
This will likely prove helpful when we need to start passing additional
arguments. We have done similar things for images and containers.
Closes #3984.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
client/interfaces.go | 6 ++++++
client/lxd_storage_volumes.go | 13 +++++++++++++
2 files changed, 19 insertions(+)
diff --git a/client/interfaces.go b/client/interfaces.go
index b88fbef2d..94f2058fe 100644
--- a/client/interfaces.go
+++ b/client/interfaces.go
@@ -159,6 +159,7 @@ type ContainerServer interface {
UpdateStoragePoolVolume(pool string, volType string, name string, volume api.StorageVolumePut, ETag string) (err error)
DeleteStoragePoolVolume(pool string, volType string, name string) (err error)
RenameStoragePoolVolume(pool string, volType string, name string, volume api.StorageVolumePost) (err error)
+ CopyStoragePoolVolume(source ContainerServer, pool string, volume api.StorageVolumesPost, args *StoragePoolVolumeCopyArgs) (err error)
// Internal functions (for internal use)
RawQuery(method string, path string, data interface{}, queryETag string) (resp *api.Response, ETag string, err error)
@@ -254,6 +255,11 @@ type ImageCopyArgs struct {
Public bool
}
+// The StoragePoolVolumeCopyArgs struct is used to pass additional options
+// during storage volume copy
+type StoragePoolVolumeCopyArgs struct {
+}
+
// The ContainerCopyArgs struct is used to pass additional options during container copy
type ContainerCopyArgs struct {
// If set, the container will be renamed on copy
diff --git a/client/lxd_storage_volumes.go b/client/lxd_storage_volumes.go
index 1aa576e7f..78d8e5d05 100644
--- a/client/lxd_storage_volumes.go
+++ b/client/lxd_storage_volumes.go
@@ -71,6 +71,19 @@ func (r *ProtocolLXD) CreateStoragePoolVolume(pool string, volume api.StorageVol
return nil
}
+// CopyStoragePoolVolume copies an existing storage volume
+func (r *ProtocolLXD) CopyStoragePoolVolume(source ContainerServer, pool string, volume api.StorageVolumesPost, args *StoragePoolVolumeCopyArgs) error {
+ if !r.HasExtension("storage_api_local_volume_handling") {
+ return fmt.Errorf("The server is missing the required \"storage_api_local_volume_handling\" API extension")
+ }
+
+ if r != source {
+ return fmt.Errorf("Copying storage volumes between remotes is not implemented\n")
+ }
+
+ return r.CreateStoragePoolVolume(pool, volume)
+}
+
// UpdateStoragePoolVolume updates the volume to match the provided StoragePoolVolume struct
func (r *ProtocolLXD) UpdateStoragePoolVolume(pool string, volType string, name string, volume api.StorageVolumePut, ETag string) error {
// Send the request
From 7f10f3042363db85a3902b628f3414c9afddbac7 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 15 Jan 2018 17:39:57 +0100
Subject: [PATCH 04/10] storage volumes: non-functional changes
Closes #3984.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/storage_volumes.go | 2 +-
lxd/storage_volumes_utils.go | 8 +++++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go
index 480029c41..2601bfdb9 100644
--- a/lxd/storage_volumes.go
+++ b/lxd/storage_volumes.go
@@ -177,7 +177,7 @@ func storagePoolVolumesTypePost(d *Daemon, r *http.Request) Response {
`storage volumes of type %s`, req.Type))
}
- err = storagePoolVolumeCreateInternal(d.State(), poolName, req.Name, req.Description, req.Type, req.Config)
+ err = storagePoolVolumeCreateInternal(d.State(), poolName, &req)
if err != nil {
return InternalError(err)
}
diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go
index 7e690e60b..0916ae35b 100644
--- a/lxd/storage_volumes_utils.go
+++ b/lxd/storage_volumes_utils.go
@@ -8,6 +8,7 @@ import (
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/state"
"github.com/lxc/lxd/shared"
+ "github.com/lxc/lxd/shared/api"
"github.com/lxc/lxd/shared/version"
)
@@ -339,7 +340,12 @@ func storagePoolVolumeDBCreate(s *state.State, poolName string, volumeName, volu
return nil
}
-func storagePoolVolumeCreateInternal(state *state.State, poolName string, volumeName, volumeDescription string, volumeTypeName string, volumeConfig map[string]string) error {
+func storagePoolVolumeCreateInternal(state *state.State, poolName string, vol *api.StorageVolumesPost) error {
+ volumeName := vol.Name
+ volumeDescription := vol.Description
+ volumeTypeName := vol.Type
+ volumeConfig := vol.Config
+
err := storagePoolVolumeDBCreate(state, poolName, volumeName, volumeDescription, volumeTypeName, volumeConfig)
if err != nil {
return err
From ae13a9133cc73f2944f281867d13543eba4822d0 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 15 Jan 2018 17:41:00 +0100
Subject: [PATCH 05/10] storage: local storage volume {move,copy}
Closes #3984.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/storage.go | 1 +
lxd/storage_btrfs.go | 62 +++++++++++++++++++++++
lxd/storage_ceph.go | 101 ++++++++++++++++++++++++++++++++++---
lxd/storage_dir.go | 42 ++++++++++++++++
lxd/storage_lvm.go | 76 ++++++++++++++++++++++++++++
lxd/storage_mock.go | 4 ++
lxd/storage_zfs.go | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++-
7 files changed, 415 insertions(+), 8 deletions(-)
diff --git a/lxd/storage.go b/lxd/storage.go
index 4a651d70e..fd16649d6 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -155,6 +155,7 @@ type storage interface {
StoragePoolVolumeUmount() (bool, error)
StoragePoolVolumeUpdate(writable *api.StorageVolumePut, changedConfig []string) error
StoragePoolVolumeRename(newName string) error
+ StoragePoolVolumeCopy(source *api.StorageVolumeSource) error
GetStoragePoolVolumeWritable() api.StorageVolumePut
SetStoragePoolVolumeWritable(writable *api.StorageVolumePut)
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 1218ee271..ee95ecdbc 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -2289,3 +2289,65 @@ func (s *storageBtrfs) StoragePoolResources() (*api.ResourcesStoragePool, error)
return storageResource(poolMntPoint)
}
+
+func (s *storageBtrfs) StoragePoolVolumeCopy(source *api.StorageVolumeSource) error {
+ logger.Infof("Copying BTRFS storage volume \"%s\" on storage pool \"%s\" as \"%s\" to storage pool \"%s\"", source.Name, source.Pool, s.volume.Name, s.pool.Name)
+ successMsg := fmt.Sprintf("Copied BTRFS storage volume \"%s\" on storage pool \"%s\" as \"%s\" to storage pool \"%s\"", source.Name, source.Pool, s.volume.Name, s.pool.Name)
+
+ srcMountPoint := getStoragePoolVolumeMountPoint(source.Pool, source.Name)
+ dstMountPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+
+ if s.pool.Name == source.Pool {
+ // Ensure that the directories immediately preceding the subvolume directory exist.
+ customDir := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+ if !shared.PathExists(customDir) {
+ err := os.MkdirAll(customDir, 0700)
+ if err != nil {
+ logger.Errorf("Failed to create directory \"%s\" for storage volume \"%s\" on storage pool \"%s\": %s", customDir, s.volume.Name, s.pool.Name, err)
+ return err
+ }
+ }
+
+ err := s.btrfsPoolVolumesSnapshot(srcMountPoint, dstMountPoint, false)
+ if err != nil {
+ logger.Errorf("Failed to create BTRFS snapshot for storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ logger.Infof(successMsg)
+ return nil
+ }
+
+ // setup storage for the source volume
+ srcStorage, err := storagePoolVolumeInit(s.s, source.Pool, source.Name, storagePoolVolumeTypeCustom)
+ if err != nil {
+ logger.Errorf("Failed to initialize storage for BTRFS storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ ourMount, err := srcStorage.StoragePoolVolumeMount()
+ if err != nil {
+ logger.Errorf("Failed to mount BTRFS storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+ if ourMount {
+ defer srcStorage.StoragePoolVolumeUmount()
+ }
+
+ err = s.StoragePoolVolumeCreate()
+ if err != nil {
+ logger.Errorf("Failed to create BTRFS storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ bwlimit := s.pool.Config["rsync.bwlimit"]
+ _, err = rsyncLocalCopy(srcMountPoint, dstMountPoint, bwlimit)
+ if err != nil {
+ s.StoragePoolVolumeDelete()
+ logger.Errorf("Failed to rsync into BTRFS storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ logger.Infof(successMsg)
+ return nil
+}
diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index 1af3cc410..60cdac47a 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -10,6 +10,8 @@ import (
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/api"
"github.com/lxc/lxd/shared/logger"
+
+ "github.com/pborman/uuid"
)
type storageCeph struct {
@@ -509,15 +511,14 @@ func (s *storageCeph) StoragePoolVolumeDelete() error {
// delete
if rbdVolumeExists {
- err := cephRBDVolumeDelete(s.ClusterName, s.OSDPoolName, s.volume.Name,
+ ret := cephContainerDelete(s.ClusterName, s.OSDPoolName, s.volume.Name,
storagePoolVolumeTypeNameCustom, s.UserName)
- if err != nil {
- logger.Errorf(`Failed to delete RBD storage volume "%s" on `+
- `storage pool "%s": %s`, s.volume.Name, s.pool.Name, err)
- return err
+ if ret < 0 {
+ msg := fmt.Sprintf(`Failed to delete RBD storage volume "%s" on storage pool "%s"`, s.volume.Name, s.pool.Name)
+ logger.Errorf(msg)
+ return fmt.Errorf(msg)
}
- logger.Debugf(`Deleted RBD storage volume "%s" on storage pool "%s"`,
- s.volume.Name, s.pool.Name)
+ logger.Debugf(`Deleted RBD storage volume "%s" on storage pool "%s"`, s.volume.Name, s.pool.Name)
}
err = s.db.StoragePoolVolumeDelete(
@@ -2835,3 +2836,89 @@ func (s *storageCeph) StoragePoolResources() (*api.ResourcesStoragePool, error)
return &res, nil
}
+
+func (s *storageCeph) StoragePoolVolumeCopy(source *api.StorageVolumeSource) error {
+ logger.Infof("Copying RBD storage volume \"%s\" on storage pool \"%s\" as \"%s\" to storage pool \"%s\"", source.Name, source.Pool, s.volume.Name, s.pool.Name)
+ successMsg := fmt.Sprintf("Copied RBD storage volume \"%s\" on storage pool \"%s\" as \"%s\" to storage pool \"%s\"", source.Name, source.Pool, s.volume.Name, s.pool.Name)
+
+ srcMountPoint := getStoragePoolVolumeMountPoint(source.Pool, source.Name)
+ dstMountPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+ if s.pool.Name == source.Pool {
+ oldVolumeName := fmt.Sprintf("%s/custom_%s", s.OSDPoolName, source.Name)
+ newVolumeName := fmt.Sprintf("%s/custom_%s", s.OSDPoolName, s.volume.Name)
+
+ if s.pool.Config["ceph.rbd.clone_copy"] != "" && !shared.IsTrue(s.pool.Config["ceph.rbd.clone_copy"]) {
+ // create full copy
+ err := cephRBDVolumeCopy(s.ClusterName, oldVolumeName, newVolumeName, s.UserName)
+ if err != nil {
+ logger.Errorf("Failed to create non-sparse copy of RBD storage volume \"%s\" on storage pool \"%s\": %s", source.Name, source.Pool, err)
+ return err
+ }
+ } else {
+ // create sparse copy
+ snapshotName := uuid.NewRandom().String()
+
+ // create snapshot of original volume
+ err := cephRBDSnapshotCreate(s.ClusterName, s.OSDPoolName, source.Name, storagePoolVolumeTypeNameCustom, snapshotName, s.UserName)
+ if err != nil {
+ logger.Errorf("Failed to create snapshot of RBD storage volume \"%s\" on storage pool \"%s\": %s", source.Name, source.Pool, err)
+ return err
+ }
+
+ // protect volume so we can create clones of it
+ err = cephRBDSnapshotProtect(s.ClusterName, s.OSDPoolName, source.Name, storagePoolVolumeTypeNameCustom, snapshotName, s.UserName)
+ if err != nil {
+ logger.Errorf("Failed to protect snapshot for RBD storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ // create new clone
+ err = cephRBDCloneCreate(s.ClusterName, s.OSDPoolName, source.Name, storagePoolVolumeTypeNameCustom, snapshotName, s.OSDPoolName, s.volume.Name, storagePoolVolumeTypeNameCustom, s.UserName)
+ if err != nil {
+ logger.Errorf("Failed to clone RBD storage volume \"%s\" on storage pool \"%s\": %s", source.Name, source.Pool, err)
+ return err
+ }
+ }
+
+ RBDDevPath, err := cephRBDVolumeMap(s.ClusterName, s.OSDPoolName, s.volume.Name, storagePoolVolumeTypeNameCustom, s.UserName)
+ if err != nil {
+ logger.Errorf("Failed to map RBD storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ // Generate a new xfs's UUID
+ RBDFilesystem := s.getRBDFilesystem()
+ msg, err := fsGenerateNewUUID(RBDFilesystem, RBDDevPath)
+ if err != nil {
+ logger.Errorf("Failed to create new UUID for filesystem \"%s\" for RBD storage volume \"%s\" on storage pool \"%s\": %s: %s", RBDFilesystem, s.volume.Name, s.pool.Name, msg, err)
+ return err
+ }
+
+ volumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+ err = os.MkdirAll(volumeMntPoint, 0711)
+ if err != nil {
+ logger.Errorf("Failed to create mountpoint \"%s\" for RBD storage volume \"%s\" on storage pool \"%s\": %s", volumeMntPoint, s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ logger.Infof(successMsg)
+ return nil
+ }
+
+ err := s.StoragePoolVolumeCreate()
+ if err != nil {
+ logger.Errorf("Failed to create RBD storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ bwlimit := s.pool.Config["rsync.bwlimit"]
+ _, err = rsyncLocalCopy(srcMountPoint, dstMountPoint, bwlimit)
+ if err != nil {
+ os.RemoveAll(dstMountPoint)
+ logger.Errorf("Failed to rsync into RBD storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ logger.Infof(successMsg)
+ return nil
+}
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index 78e562fa7..771153d70 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -1060,3 +1060,45 @@ func (s *storageDir) StoragePoolResources() (*api.ResourcesStoragePool, error) {
return storageResource(poolMntPoint)
}
+
+func (s *storageDir) StoragePoolVolumeCopy(source *api.StorageVolumeSource) error {
+ logger.Infof("Copying DIR storage volume \"%s\" on storage pool \"%s\" as \"%s\" to storage pool \"%s\"", source.Name, source.Pool, s.volume.Name, s.pool.Name)
+ successMsg := fmt.Sprintf("Copied DIR storage volume \"%s\" on storage pool \"%s\" as \"%s\" to storage pool \"%s\"", source.Name, source.Pool, s.volume.Name, s.pool.Name)
+
+ if s.pool.Name != source.Pool {
+ // setup storage for the source volume
+ srcStorage, err := storagePoolVolumeInit(s.s, source.Pool, source.Name, storagePoolVolumeTypeCustom)
+ if err != nil {
+ logger.Errorf("Failed to initialize DIR storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ ourMount, err := srcStorage.StoragePoolVolumeMount()
+ if err != nil {
+ logger.Errorf("Failed to mount DIR storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+ if ourMount {
+ defer srcStorage.StoragePoolVolumeUmount()
+ }
+ }
+
+ err := s.StoragePoolVolumeCreate()
+ if err != nil {
+ logger.Errorf("Failed to create DIR storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ srcMountPoint := getStoragePoolVolumeMountPoint(source.Pool, source.Name)
+ dstMountPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+ bwlimit := s.pool.Config["rsync.bwlimit"]
+ _, err = rsyncLocalCopy(srcMountPoint, dstMountPoint, bwlimit)
+ if err != nil {
+ os.RemoveAll(dstMountPoint)
+ logger.Errorf("Failed to rsync into DIR storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ logger.Infof(successMsg)
+ return nil
+}
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index 95c596b1c..d74b24d2f 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -1845,3 +1845,79 @@ func (s *storageLvm) StoragePoolResources() (*api.ResourcesStoragePool, error) {
return &res, nil
}
+
+func (s *storageLvm) StoragePoolVolumeCopy(source *api.StorageVolumeSource) error {
+ logger.Infof("Copying LVM storage volume \"%s\" on storage pool \"%s\" as \"%s\" to storage pool \"%s\"", source.Name, source.Pool, s.volume.Name, s.pool.Name)
+ successMsg := fmt.Sprintf("Copied LVM storage volume \"%s\" on storage pool \"%s\" as \"%s\" to storage pool \"%s\"", source.Name, source.Pool, s.volume.Name, s.pool.Name)
+
+ srcMountPoint := getStoragePoolVolumeMountPoint(source.Pool, source.Name)
+ dstMountPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+
+ if s.pool.Name == source.Pool && s.useThinpool {
+ err := os.MkdirAll(dstMountPoint, 0711)
+ if err != nil {
+ logger.Errorf("Failed to create mountpoint \"%s\" for LVM storage volume \"%s\" on storage pool \"%s\": %s", dstMountPoint, s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ poolName := s.getOnDiskPoolName()
+ lvFsType := s.getLvmFilesystem()
+ lvSize, err := s.getLvmVolumeSize()
+ if lvSize == "" {
+ logger.Errorf("Failed to get size for LVM storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ _, err = s.createSnapshotLV(poolName, source.Name, storagePoolVolumeAPIEndpointCustom, s.volume.Name, storagePoolVolumeAPIEndpointCustom, false, s.useThinpool)
+ if err != nil {
+ logger.Errorf("Failed to create snapshot for LVM storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ lvDevPath := getLvmDevPath(poolName, storagePoolVolumeAPIEndpointCustom, s.volume.Name)
+ msg, err := fsGenerateNewUUID(lvFsType, lvDevPath)
+ if err != nil {
+ logger.Errorf("Failed to create new UUID for filesystem \"%s\" for RBD storage volume \"%s\" on storage pool \"%s\": %s: %s", lvFsType, s.volume.Name, s.pool.Name, msg, err)
+ return err
+ }
+
+ logger.Infof(successMsg)
+ return nil
+ }
+
+ if s.pool.Name != source.Pool {
+ // setup storage for the source volume
+ srcStorage, err := storagePoolVolumeInit(s.s, source.Pool, source.Name, storagePoolVolumeTypeCustom)
+ if err != nil {
+ logger.Errorf("Failed to initialize LVM storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ ourMount, err := srcStorage.StoragePoolVolumeMount()
+ if err != nil {
+ logger.Errorf("Failed to mount LVM storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ if ourMount {
+ defer srcStorage.StoragePoolVolumeUmount()
+ }
+ }
+
+ err := s.StoragePoolVolumeCreate()
+ if err != nil {
+ logger.Errorf("Failed to create LVM storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ bwlimit := s.pool.Config["rsync.bwlimit"]
+ _, err = rsyncLocalCopy(srcMountPoint, dstMountPoint, bwlimit)
+ if err != nil {
+ os.RemoveAll(dstMountPoint)
+ logger.Errorf("Failed to rsync into LVM storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ logger.Infof(successMsg)
+ return nil
+}
diff --git a/lxd/storage_mock.go b/lxd/storage_mock.go
index aacf7cdc0..5019237f7 100644
--- a/lxd/storage_mock.go
+++ b/lxd/storage_mock.go
@@ -226,3 +226,7 @@ func (s *storageMock) StorageEntitySetQuota(volumeType int, size int64, data int
func (s *storageMock) StoragePoolResources() (*api.ResourcesStoragePool, error) {
return &api.ResourcesStoragePool{}, nil
}
+
+func (s *storageMock) StoragePoolVolumeCopy(source *api.StorageVolumeSource) error {
+ return nil
+}
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index 30a616b93..cd39b8bd9 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -423,10 +423,52 @@ func (s *storageZfs) StoragePoolVolumeDelete() error {
poolName := s.getOnDiskPoolName()
if zfsFilesystemEntityExists(poolName, fs) {
- err := zfsPoolVolumeDestroy(s.getOnDiskPoolName(), fs)
+ removable := true
+ snaps, err := zfsPoolListSnapshots(poolName, fs)
if err != nil {
return err
}
+
+ for _, snap := range snaps {
+ var err error
+ removable, err = zfsPoolVolumeSnapshotRemovable(poolName, fs, snap)
+ if err != nil {
+ return err
+ }
+
+ if !removable {
+ break
+ }
+ }
+
+ if removable {
+ origin, err := zfsFilesystemEntityPropertyGet(poolName, fs, "origin")
+ if err != nil {
+ return err
+ }
+ poolName := s.getOnDiskPoolName()
+ origin = strings.TrimPrefix(origin, fmt.Sprintf("%s/", poolName))
+
+ err = zfsPoolVolumeDestroy(poolName, fs)
+ if err != nil {
+ return err
+ }
+
+ err = zfsPoolVolumeCleanup(poolName, origin)
+ if err != nil {
+ return err
+ }
+ } else {
+ err := zfsPoolVolumeSet(poolName, fs, "mountpoint", "none")
+ if err != nil {
+ return err
+ }
+
+ err = zfsPoolVolumeRename(poolName, fs, fmt.Sprintf("deleted/custom/%s", uuid.NewRandom().String()))
+ if err != nil {
+ return err
+ }
+ }
}
if shared.PathExists(customPoolVolumeMntPoint) {
@@ -2414,3 +2456,96 @@ func (s *storageZfs) StoragePoolResources() (*api.ResourcesStoragePool, error) {
return &res, nil
}
+
+func (s *storageZfs) StoragePoolVolumeCopy(source *api.StorageVolumeSource) error {
+ logger.Infof("Copying ZFS storage volume \"%s\" on storage pool \"%s\" as \"%s\" to storage pool \"%s\"", source.Name, source.Pool, s.volume.Name, s.pool.Name)
+ successMsg := fmt.Sprintf("Copied ZFS storage volume \"%s\" on storage pool \"%s\" as \"%s\" to storage pool \"%s\"", source.Name, source.Pool, s.volume.Name, s.pool.Name)
+
+ srcMountPoint := getStoragePoolVolumeMountPoint(source.Pool, source.Name)
+ dstMountPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+
+ if s.pool.Name == source.Pool && (s.pool.Config["zfs.clone_copy"] == "" || shared.IsTrue(s.pool.Config["zfs.clone_copy"])) {
+ poolName := s.getOnDiskPoolName()
+ snapUUID := fmt.Sprintf("copy-%s", uuid.NewRandom().String())
+
+ // create snapshot for zfs to clone from
+ err := zfsPoolVolumeSnapshotCreate(poolName, storagePoolVolumeTypeNameCustom, snapUUID)
+ if err != nil {
+ logger.Errorf("Failed to create snapshot for ZFS storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ srcDataset := fmt.Sprintf("custom/%s", source.Name)
+ dstDataset := fmt.Sprintf("custom/%s", s.volume.Name)
+
+ // clone snapshot
+ err = zfsPoolVolumeClone(poolName, srcDataset, snapUUID, dstDataset, dstMountPoint)
+ if err != nil {
+ logger.Errorf("Failed to create clone for ZFS storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ err = zfsPoolVolumeSet(poolName, dstDataset, "mountpoint", dstMountPoint)
+ if err != nil {
+ logger.Errorf("Failed to set mountpoint \"%s\" for ZFS storage volume \"%s\" on storage pool \"%s\": %s", dstMountPoint, s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ if !shared.IsMountPoint(dstMountPoint) {
+ zfsMount(poolName, dstDataset)
+ }
+
+ // apply quota
+ if s.volume.Config["size"] != "" {
+ size, err := shared.ParseByteSizeString(s.volume.Config["size"])
+ if err != nil {
+ logger.Errorf("Failed to parse size for ZFS storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ err = s.StorageEntitySetQuota(storagePoolVolumeTypeCustom, size, nil)
+ if err != nil {
+ logger.Errorf("Failed to set quota for ZFS storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+ }
+
+ logger.Infof(successMsg)
+ return nil
+ }
+
+ if s.pool.Name != source.Pool {
+ // setup storage for the source volume
+ srcStorage, err := storagePoolVolumeInit(s.s, source.Pool, source.Name, storagePoolVolumeTypeCustom)
+ if err != nil {
+ logger.Errorf("Failed to initialize ZFS storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ ourMount, err := srcStorage.StoragePoolVolumeMount()
+ if err != nil {
+ logger.Errorf("Failed to mount ZFS storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+ if ourMount {
+ defer srcStorage.StoragePoolVolumeUmount()
+ }
+ }
+
+ err := s.StoragePoolVolumeCreate()
+ if err != nil {
+ logger.Errorf("Failed to create ZFS storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ bwlimit := s.pool.Config["rsync.bwlimit"]
+ _, err = rsyncLocalCopy(srcMountPoint, dstMountPoint, bwlimit)
+ if err != nil {
+ os.RemoveAll(dstMountPoint)
+ logger.Errorf("Failed to rsync into ZFS storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
+ return err
+ }
+
+ logger.Infof(successMsg)
+ return nil
+}
From 3bdbf71f26b758b5eb73db525bd42ae8ab8b5939 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 15 Jan 2018 17:41:17 +0100
Subject: [PATCH 06/10] storage volumes: local storage volume {move,copy}
Closes #3984.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/storage_btrfs.go | 2 +-
lxd/storage_volumes_utils.go | 9 +++++++--
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index ee95ecdbc..2eca2c6a8 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -2299,7 +2299,7 @@ func (s *storageBtrfs) StoragePoolVolumeCopy(source *api.StorageVolumeSource) er
if s.pool.Name == source.Pool {
// Ensure that the directories immediately preceding the subvolume directory exist.
- customDir := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+ customDir := getStoragePoolVolumeMountPoint(s.pool.Name, "")
if !shared.PathExists(customDir) {
err := os.MkdirAll(customDir, 0700)
if err != nil {
diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go
index 0916ae35b..40da0fb78 100644
--- a/lxd/storage_volumes_utils.go
+++ b/lxd/storage_volumes_utils.go
@@ -364,8 +364,13 @@ func storagePoolVolumeCreateInternal(state *state.State, poolName string, vol *a
poolID, _, _ := s.GetContainerPoolInfo()
- // Create storage volume.
- err = s.StoragePoolVolumeCreate()
+ if vol.Source.Name == "" {
+ // Create storage volume.
+ err = s.StoragePoolVolumeCreate()
+ } else {
+ // Copy storage volume.
+ err = s.StoragePoolVolumeCopy(&vol.Source)
+ }
if err != nil {
state.DB.StoragePoolVolumeDelete(volumeName, volumeType, poolID)
return err
From 6cc466dba34cb4556ce905e52ed570af9f85e2b5 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 16 Jan 2018 13:01:13 +0100
Subject: [PATCH 07/10] storage volumes: translate volume properties
Closes #3984.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/storage_pools_utils.go | 2 ++
lxd/storage_volumes_config.go | 84 ++++++++++++++++++++++++++++++++++++-------
lxd/storage_volumes_utils.go | 17 ++++++++-
3 files changed, 90 insertions(+), 13 deletions(-)
diff --git a/lxd/storage_pools_utils.go b/lxd/storage_pools_utils.go
index 6df16c870..34efd0ecd 100644
--- a/lxd/storage_pools_utils.go
+++ b/lxd/storage_pools_utils.go
@@ -10,6 +10,8 @@ import (
"github.com/lxc/lxd/shared/version"
)
+var supportedPoolTypes = []string{"btrfs", "ceph", "dir", "lvm", "zfs"}
+
func storagePoolUpdate(state *state.State, name, newDescription string, newConfig map[string]string) error {
s, err := storagePoolInit(state, name)
if err != nil {
diff --git a/lxd/storage_volumes_config.go b/lxd/storage_volumes_config.go
index 8e64f9454..5d59404d4 100644
--- a/lxd/storage_volumes_config.go
+++ b/lxd/storage_volumes_config.go
@@ -8,6 +8,36 @@ import (
"github.com/lxc/lxd/shared/api"
)
+func storageVolumePropertiesTranslate(targetConfig map[string]string, targetParentPoolDriver string) (map[string]string, error) {
+ newConfig := make(map[string]string, len(targetConfig))
+ for key, val := range targetConfig {
+ // User keys are not validated.
+ if strings.HasPrefix(key, "user.") {
+ continue
+ }
+
+ // Validate storage volume config keys.
+ validator, ok := storageVolumeConfigKeys[key]
+ if !ok {
+ return nil, fmt.Errorf("Invalid storage volume configuration key: %s", key)
+ }
+
+ validStorageDrivers, err := validator(val)
+ if err != nil {
+ return nil, err
+ }
+
+ // Drop invalid keys.
+ if !shared.StringInSlice(targetParentPoolDriver, validStorageDrivers) {
+ continue
+ }
+
+ newConfig[key] = val
+ }
+
+ return newConfig, nil
+}
+
func updateStoragePoolVolumeError(unchangeable []string, driverName string) error {
return fmt.Errorf(`The %v properties cannot be changed for "%s" `+
`storage volumes`, unchangeable, driverName)
@@ -37,23 +67,53 @@ var changeableStoragePoolVolumeProperties = map[string][]string{
"zfs.use_refquota"},
}
-var storageVolumeConfigKeys = map[string]func(value string) error{
- "block.filesystem": func(value string) error {
- return shared.IsOneOf(value, []string{"btrfs", "ext4", "xfs"})
+// btrfs, ceph, dir, lvm, zfs
+var storageVolumeConfigKeys = map[string]func(value string) ([]string, error){
+ "block.filesystem": func(value string) ([]string, error) {
+ err := shared.IsOneOf(value, []string{"btrfs", "ext4", "xfs"})
+ if err != nil {
+ return nil, err
+ }
+
+ return []string{"ceph", "lvm"}, nil
+ },
+ "block.mount_options": func(value string) ([]string, error) {
+ return []string{"ceph", "lvm"}, shared.IsAny(value)
},
- "block.mount_options": shared.IsAny,
- "size": func(value string) error {
+ "size": func(value string) ([]string, error) {
if value == "" {
- return nil
+ return []string{"btrfs", "ceph", "lvm", "zfs"}, nil
}
_, err := shared.ParseByteSizeString(value)
- return err
+ if err != nil {
+ return nil, err
+ }
+
+ return []string{"btrfs", "ceph", "lvm", "zfs"}, nil
+ },
+ "volatile.idmap.last": func(value string) ([]string, error) {
+ return supportedPoolTypes, shared.IsAny(value)
+ },
+ "volatile.idmap.next": func(value string) ([]string, error) {
+ return supportedPoolTypes, shared.IsAny(value)
+ },
+ "zfs.remove_snapshots": func(value string) ([]string, error) {
+ err := shared.IsBool(value)
+ if err != nil {
+ return nil, err
+ }
+
+ return []string{"zfs"}, nil
+ },
+ "zfs.use_refquota": func(value string) ([]string, error) {
+ err := shared.IsBool(value)
+ if err != nil {
+ return nil, err
+ }
+
+ return []string{"zfs"}, nil
},
- "volatile.idmap.last": shared.IsAny,
- "volatile.idmap.next": shared.IsAny,
- "zfs.remove_snapshots": shared.IsBool,
- "zfs.use_refquota": shared.IsBool,
}
func storageVolumeValidateConfig(name string, config map[string]string, parentPool *api.StoragePool) error {
@@ -69,7 +129,7 @@ func storageVolumeValidateConfig(name string, config map[string]string, parentPo
return fmt.Errorf("Invalid storage volume configuration key: %s", key)
}
- err := validator(val)
+ _, err := validator(val)
if err != nil {
return err
}
diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go
index 40da0fb78..7f068715e 100644
--- a/lxd/storage_volumes_utils.go
+++ b/lxd/storage_volumes_utils.go
@@ -346,6 +346,22 @@ func storagePoolVolumeCreateInternal(state *state.State, poolName string, vol *a
volumeTypeName := vol.Type
volumeConfig := vol.Config
+ if vol.Source.Name != "" {
+ s, err := storagePoolInit(state, poolName)
+ if err != nil {
+ return err
+ }
+
+ driver := s.GetStorageTypeName()
+ newConfig, err := storageVolumePropertiesTranslate(vol.Config, driver)
+ if err != nil {
+ return err
+ }
+
+ vol.Config = newConfig
+ volumeConfig = newConfig
+ }
+
err := storagePoolVolumeDBCreate(state, poolName, volumeName, volumeDescription, volumeTypeName, volumeConfig)
if err != nil {
return err
@@ -363,7 +379,6 @@ func storagePoolVolumeCreateInternal(state *state.State, poolName string, vol *a
}
poolID, _, _ := s.GetContainerPoolInfo()
-
if vol.Source.Name == "" {
// Create storage volume.
err = s.StoragePoolVolumeCreate()
From 5efce19e505583545bf81f74712ad1345af900cf Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 15 Jan 2018 17:47:07 +0100
Subject: [PATCH 08/10] lxc: implement local storage {move,copy}
Closes #3984.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxc/storage.go | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++------
po/de.po | 60 +++++++++++++++++-----------
po/el.po | 59 ++++++++++++++++-----------
po/es.po | 59 ++++++++++++++++-----------
po/fi.po | 59 ++++++++++++++++-----------
po/fr.po | 60 +++++++++++++++++-----------
po/id.po | 59 ++++++++++++++++-----------
po/it.po | 59 ++++++++++++++++-----------
po/ja.po | 60 +++++++++++++++++-----------
po/lxd.pot | 58 ++++++++++++++++-----------
po/nb_NO.po | 59 ++++++++++++++++-----------
po/nl.po | 59 ++++++++++++++++-----------
po/pl.po | 59 ++++++++++++++++-----------
po/pt_BR.po | 59 ++++++++++++++++-----------
po/ru.po | 59 ++++++++++++++++-----------
po/sr.po | 59 ++++++++++++++++-----------
po/sv.po | 59 ++++++++++++++++-----------
po/tr.po | 59 ++++++++++++++++-----------
po/zh.po | 59 ++++++++++++++++-----------
po/zh_Hans.po | 59 ++++++++++++++++-----------
20 files changed, 777 insertions(+), 469 deletions(-)
diff --git a/lxc/storage.go b/lxc/storage.go
index 5f294761a..24ddaf0a8 100644
--- a/lxc/storage.go
+++ b/lxc/storage.go
@@ -23,6 +23,7 @@ import (
type storageCmd struct {
resources bool
+ confArgs configList
}
func (c *storageCmd) showByDefault() bool {
@@ -129,7 +130,13 @@ lxc storage volume detach [<remote>:]<pool> <volume> <container> [device name]
Detach a storage volume from the specified container.
lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> [device name]
- Detach a storage volume from the specified profile.
+ Detach a storage volume from the specified profile.
+
+lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c <key=value>...]
+ Copy an existing volume to a new volume at the specified pool.
+
+lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>
+ Move an existing volume to the specified pool.
Unless specified through a prefix, all volume operations affect "custom" (user created) volumes.
@@ -148,6 +155,7 @@ lxc storage volume show default container/data
}
func (c *storageCmd) flags() {
+ gnuflag.Var(&c.confArgs, "config", i18n.G("Config key/value to apply to the new storage volume"))
gnuflag.BoolVar(&c.resources, "resources", false, i18n.G("Show the resources available to the storage pool"))
}
@@ -270,6 +278,22 @@ func (c *storageCmd) run(conf *config.Config, args []string) error {
pool := sub
volume := args[3]
return c.doStoragePoolVolumeShow(client, pool, volume)
+ case "copy":
+ // only support non remote for now
+ if len(args) != 4 {
+ return errArgs
+ }
+ src := sub
+ dst := args[3]
+ return c.doStoragePoolVolumeCopy(client, src, dst, false)
+ case "move":
+ // only support non remote for now
+ if len(args) != 4 {
+ return errArgs
+ }
+ src := sub
+ dst := args[3]
+ return c.doStoragePoolVolumeCopy(client, src, dst, true)
default:
return errArgs
}
@@ -322,9 +346,7 @@ func (c *storageCmd) run(conf *config.Config, args []string) error {
}
}
-func (c *storageCmd) parseVolume(name string) (string, string) {
- defaultType := "custom"
-
+func (c *storageCmd) parseVolume(defaultType string, name string) (string, string) {
fields := strings.SplitN(name, "/", 2)
if len(fields) == 1 {
return fields[0], defaultType
@@ -350,7 +372,7 @@ func (c *storageCmd) doStoragePoolVolumeAttach(client lxd.ContainerServer, pool
devPath = args[2]
}
- volName, volType := c.parseVolume(volume)
+ volName, volType := c.parseVolume("custom", volume)
if volType != "custom" {
return fmt.Errorf(i18n.G("Only \"custom\" volumes can be attached to containers."))
}
@@ -443,7 +465,7 @@ func (c *storageCmd) doStoragePoolVolumeAttachProfile(client lxd.ContainerServer
devPath = args[2]
}
- volName, volType := c.parseVolume(volume)
+ volName, volType := c.parseVolume("custom", volume)
if volType != "custom" {
return fmt.Errorf(i18n.G("Only \"custom\" volumes can be attached to containers."))
}
@@ -805,7 +827,7 @@ func (c *storageCmd) doStoragePoolVolumesList(conf *config.Config, remote string
func (c *storageCmd) doStoragePoolVolumeCreate(client lxd.ContainerServer, pool string, volume string, args []string) error {
// Parse the input
- volName, volType := c.parseVolume(volume)
+ volName, volType := c.parseVolume("custom", volume)
// Create the storage volume entry
vol := api.StorageVolumesPost{}
@@ -834,7 +856,7 @@ func (c *storageCmd) doStoragePoolVolumeCreate(client lxd.ContainerServer, pool
func (c *storageCmd) doStoragePoolVolumeDelete(client lxd.ContainerServer, pool string, volume string) error {
// Parse the input
- volName, volType := c.parseVolume(volume)
+ volName, volType := c.parseVolume("custom", volume)
// Delete the volume
err := client.DeleteStoragePoolVolume(pool, volType, volName)
@@ -853,7 +875,7 @@ func (c *storageCmd) doStoragePoolVolumeGet(client lxd.ContainerServer, pool str
}
// Parse input
- volName, volType := c.parseVolume(volume)
+ volName, volType := c.parseVolume("custom", volume)
// Get the storage volume entry
resp, _, err := client.GetStoragePoolVolume(pool, volType, volName)
@@ -876,7 +898,7 @@ func (c *storageCmd) doStoragePoolVolumeSet(client lxd.ContainerServer, pool str
}
// Parse the input
- volName, volType := c.parseVolume(volume)
+ volName, volType := c.parseVolume("custom", volume)
// Get the storage volume entry
vol, etag, err := client.GetStoragePoolVolume(pool, volType, volName)
@@ -913,7 +935,7 @@ func (c *storageCmd) doStoragePoolVolumeSet(client lxd.ContainerServer, pool str
func (c *storageCmd) doStoragePoolVolumeShow(client lxd.ContainerServer, pool string, volume string) error {
// Parse the input
- volName, volType := c.parseVolume(volume)
+ volName, volType := c.parseVolume("custom", volume)
// Get the storage volume entry
vol, _, err := client.GetStoragePoolVolume(pool, volType, volName)
@@ -933,9 +955,84 @@ func (c *storageCmd) doStoragePoolVolumeShow(client lxd.ContainerServer, pool st
return nil
}
+func (c *storageCmd) doStoragePoolVolumeCopy(client lxd.ContainerServer, src string, dst string, rm bool) error {
+ // validate both src and dst string
+ dstVolName, dstVolPool := c.parseVolume("", dst)
+ srcVolName, srcVolPool := c.parseVolume("", src)
+ if dstVolPool == "" || srcVolPool == "" {
+ defaultProfile, _, err := client.GetProfile("default")
+ if err != nil {
+ return fmt.Errorf("No storage pool for source or target volume specified")
+ }
+
+ rootDiskDevice := defaultProfile.Devices["root"]
+ if rootDiskDevice != nil &&
+ rootDiskDevice["pool"] != "" &&
+ rootDiskDevice["type"] == "disk" &&
+ rootDiskDevice["source"] == "" &&
+ rootDiskDevice["path"] == "/" {
+
+ if srcVolPool == "" {
+ srcVolPool = rootDiskDevice["pool"]
+ }
+
+ if dstVolPool == "" {
+ dstVolPool = rootDiskDevice["pool"]
+ }
+ } else {
+ return fmt.Errorf("No storage pool for source or target volume specified")
+ }
+ }
+
+ // Check if the requested storage volume actually exists
+ srcVol, _, err := client.GetStoragePoolVolume(srcVolPool, "custom", srcVolName)
+ if err != nil {
+ return err
+ }
+ client.GetProfile("default")
+
+ if rm && len(srcVol.UsedBy) > 0 {
+ return fmt.Errorf("Storage volume \"%s\" is still in use by profile or containers", srcVol.Name)
+ }
+
+ // Create the storage volume entry
+ dstVol := api.StorageVolumesPost{}
+ dstVol.Name = dstVolName
+ dstVol.Type = "custom"
+ dstVol.Config = srcVol.Config
+ dstVol.Source = api.StorageVolumeSource{
+ Name: srcVol.Name,
+ Type: "custom",
+ Pool: srcVolPool,
+ }
+
+ // Allow setting additional config keys
+ if configMap != nil {
+ for key, value := range configMap {
+ dstVol.Config[key] = value
+ }
+ }
+
+ // copy is a special case of create
+ err = client.CreateStoragePoolVolume(dstVolPool, dstVol)
+ if err != nil {
+ return err
+ }
+
+ if rm {
+ err = client.DeleteStoragePoolVolume(srcVolPool, "custom", srcVolName)
+ if err != nil {
+ return err
+ }
+ }
+
+ fmt.Printf("Successfully copied %s to %s \n", src, dst)
+ return nil
+}
+
func (c *storageCmd) doStoragePoolVolumeEdit(client lxd.ContainerServer, pool string, volume string) error {
// Parse the input
- volName, volType := c.parseVolume(volume)
+ volName, volType := c.parseVolume("custom", volume)
// If stdin isn't a terminal, read text from it
if !termios.IsTerminal(int(syscall.Stdin)) {
@@ -1001,7 +1098,7 @@ func (c *storageCmd) doStoragePoolVolumeEdit(client lxd.ContainerServer, pool st
func (c *storageCmd) doStoragePoolVolumeRename(client lxd.ContainerServer, pool string, volume string, args []string) error {
// Parse the input
- volName, volType := c.parseVolume(volume)
+ volName, volType := c.parseVolume("custom", volume)
// Create the storage volume entry
vol := api.StorageVolumePost{}
diff --git a/po/de.po b/po/de.po
index 1dd7fd420..fc926d175 100644
--- a/po/de.po
+++ b/po/de.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: LXD\n"
"Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-01-11 17:16-0500\n"
+"POT-Creation-Date: 2018-01-16 11:17+0100\n"
"PO-Revision-Date: 2017-02-14 17:11+0000\n"
"Last-Translator: Tim Rose <tim at netlope.de>\n"
"Language-Team: German <https://hosted.weblate.org/projects/linux-containers/"
@@ -19,7 +19,7 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 2.14-dev\n"
-#: lxc/storage.go:33
+#: lxc/storage.go:34
#, fuzzy
msgid ""
"### This is a yaml representation of a storage pool.\n"
@@ -54,7 +54,7 @@ msgstr ""
"###\n"
"### Der Name wird zwar angezeigt, lässt sich jedoch nicht ändern.\n"
-#: lxc/storage.go:50
+#: lxc/storage.go:51
#, fuzzy
msgid ""
"### This is a yaml representation of a storage volume.\n"
@@ -402,7 +402,7 @@ msgstr ""
msgid "Can't unset key '%s', it's not currently set."
msgstr ""
-#: lxc/profile.go:546 lxc/storage.go:653
+#: lxc/profile.go:546 lxc/storage.go:675
msgid "Cannot provide container name to list"
msgstr ""
@@ -428,8 +428,13 @@ msgstr ""
msgid "Config key/value to apply to the new container"
msgstr "kann nicht zum selben Container Namen kopieren"
+#: lxc/storage.go:158
+#, fuzzy
+msgid "Config key/value to apply to the new storage volume"
+msgstr "kann nicht zum selben Container Namen kopieren"
+
#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190
-#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:604 lxc/storage.go:979
+#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:626 lxc/storage.go:1058
#, fuzzy, c-format
msgid "Config parsing error: %s"
msgstr "YAML Analyse Fehler %v\n"
@@ -498,11 +503,11 @@ msgid "Creating the container"
msgstr "kann nicht zum selben Container Namen kopieren"
#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525
-#: lxc/storage.go:682 lxc/storage.go:793
+#: lxc/storage.go:704 lxc/storage.go:819
msgid "DESCRIPTION"
msgstr ""
-#: lxc/storage.go:683
+#: lxc/storage.go:705
msgid "DRIVER"
msgstr ""
@@ -827,7 +832,7 @@ msgstr ""
msgid "Missing summary."
msgstr "Fehlende Zusammenfassung."
-#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:402 lxc/storage.go:522
+#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:424 lxc/storage.go:544
msgid "More than one device matches, specify the device name."
msgstr ""
@@ -851,7 +856,7 @@ msgid "Must supply container name for: "
msgstr "der Name des Ursprung Containers muss angegeben werden"
#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409
-#: lxc/storage.go:681 lxc/storage.go:792
+#: lxc/storage.go:703 lxc/storage.go:818
msgid "NAME"
msgstr ""
@@ -902,7 +907,7 @@ msgstr "Kein Zertifikat zum hinzufügen bereitgestellt"
msgid "No device found for this network"
msgstr "Kein Zertifikat für diese Verbindung"
-#: lxc/storage.go:411 lxc/storage.go:531
+#: lxc/storage.go:433 lxc/storage.go:553
#, fuzzy
msgid "No device found for this storage volume."
msgstr "Kein Zertifikat für diese Verbindung"
@@ -911,7 +916,7 @@ msgstr "Kein Zertifikat für diese Verbindung"
msgid "No fingerprint specified."
msgstr "Kein Fingerabdruck angegeben."
-#: lxc/storage.go:355 lxc/storage.go:448
+#: lxc/storage.go:377 lxc/storage.go:470
msgid "Only \"custom\" volumes can be attached to containers."
msgstr ""
@@ -996,7 +1001,7 @@ msgstr ""
msgid "Pid: %d"
msgstr ""
-#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:605 lxc/storage.go:980
+#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:627 lxc/storage.go:1059
msgid "Press enter to open the editor again"
msgstr ""
@@ -1108,7 +1113,7 @@ msgstr ""
msgid "Remove %s (yes/no): "
msgstr ""
-#: lxc/storage.go:1011
+#: lxc/storage.go:1090
#, c-format
msgid "Renamed storage volume from \"%s\" to \"%s\""
msgstr ""
@@ -1148,7 +1153,7 @@ msgstr ""
msgid "SNAPSHOTS"
msgstr ""
-#: lxc/storage.go:684
+#: lxc/storage.go:706
msgid "SOURCE"
msgstr ""
@@ -1218,7 +1223,7 @@ msgstr ""
msgid "Show the resources available to the server"
msgstr ""
-#: lxc/storage.go:151
+#: lxc/storage.go:159
msgid "Show the resources available to the storage pool"
msgstr ""
@@ -1273,12 +1278,12 @@ msgstr "Anhalten des Containers fehlgeschlagen!"
msgid "Stopping the container failed: %s"
msgstr "Anhalten des Containers fehlgeschlagen!"
-#: lxc/storage.go:496
+#: lxc/storage.go:518
#, fuzzy, c-format
msgid "Storage pool %s created"
msgstr "Profil %s erstellt\n"
-#: lxc/storage.go:555
+#: lxc/storage.go:577
#, fuzzy, c-format
msgid "Storage pool %s deleted"
msgstr "Profil %s gelöscht\n"
@@ -1288,12 +1293,12 @@ msgstr "Profil %s gelöscht\n"
msgid "Storage pool name"
msgstr "Profilname kann nicht geändert werden"
-#: lxc/storage.go:826
+#: lxc/storage.go:852
#, fuzzy, c-format
msgid "Storage volume %s created"
msgstr "Profil %s erstellt\n"
-#: lxc/storage.go:841
+#: lxc/storage.go:867
#, fuzzy, c-format
msgid "Storage volume %s deleted"
msgstr "Profil %s gelöscht\n"
@@ -1311,7 +1316,7 @@ msgstr ""
msgid "Swap (peak)"
msgstr ""
-#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:791
+#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:817
msgid "TYPE"
msgstr ""
@@ -1349,7 +1354,7 @@ msgstr ""
msgid "The opposite of \"lxc pause\" is \"lxc start\"."
msgstr ""
-#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:416 lxc/storage.go:536
+#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:438 lxc/storage.go:558
#, fuzzy
msgid "The specified device doesn't exist"
msgstr "entfernte Instanz %s existiert nicht"
@@ -1432,7 +1437,7 @@ msgstr ""
msgid "URL"
msgstr ""
-#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:685 lxc/storage.go:794
+#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:707 lxc/storage.go:820
msgid "USED BY"
msgstr ""
@@ -2351,7 +2356,7 @@ msgid ""
" Create a snapshot of \"u1\" called \"snap0\"."
msgstr ""
-#: lxc/storage.go:64
+#: lxc/storage.go:65
msgid ""
"Usage: lxc storage <subcommand> [options]\n"
"\n"
@@ -2426,7 +2431,14 @@ msgid ""
"\n"
"lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> "
"[device name]\n"
-" Detach a storage volume from the specified profile.\n"
+"\tDetach a storage volume from the specified profile.\n"
+"\n"
+"lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c "
+"<key=value>...]\n"
+" Copy an existing volume to a new volume at the specified pool.\n"
+"\n"
+"lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>\n"
+" Move an existing volume to the specified pool.\n"
"\n"
"Unless specified through a prefix, all volume operations affect \"custom"
"\" (user created) volumes.\n"
diff --git a/po/el.po b/po/el.po
index c4db31451..ffc7b595c 100644
--- a/po/el.po
+++ b/po/el.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: lxd\n"
"Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-01-11 17:16-0500\n"
+"POT-Creation-Date: 2018-01-16 11:17+0100\n"
"PO-Revision-Date: 2017-02-14 08:00+0000\n"
"Last-Translator: Simos Xenitellis <simos.65 at gmail.com>\n"
"Language-Team: Greek <https://hosted.weblate.org/projects/linux-containers/"
@@ -19,7 +19,7 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 2.12-dev\n"
-#: lxc/storage.go:33
+#: lxc/storage.go:34
msgid ""
"### This is a yaml representation of a storage pool.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -36,7 +36,7 @@ msgid ""
"### zfs.pool_name: default"
msgstr ""
-#: lxc/storage.go:50
+#: lxc/storage.go:51
msgid ""
"### This is a yaml representation of a storage volume.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -292,7 +292,7 @@ msgstr ""
msgid "Can't unset key '%s', it's not currently set."
msgstr ""
-#: lxc/profile.go:546 lxc/storage.go:653
+#: lxc/profile.go:546 lxc/storage.go:675
msgid "Cannot provide container name to list"
msgstr ""
@@ -317,8 +317,12 @@ msgstr ""
msgid "Config key/value to apply to the new container"
msgstr ""
+#: lxc/storage.go:158
+msgid "Config key/value to apply to the new storage volume"
+msgstr ""
+
#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190
-#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:604 lxc/storage.go:979
+#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:626 lxc/storage.go:1058
#, c-format
msgid "Config parsing error: %s"
msgstr ""
@@ -385,11 +389,11 @@ msgid "Creating the container"
msgstr ""
#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525
-#: lxc/storage.go:682 lxc/storage.go:793
+#: lxc/storage.go:704 lxc/storage.go:819
msgid "DESCRIPTION"
msgstr ""
-#: lxc/storage.go:683
+#: lxc/storage.go:705
msgid "DRIVER"
msgstr ""
@@ -704,7 +708,7 @@ msgstr " Χρήση μνήμης:"
msgid "Missing summary."
msgstr ""
-#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:402 lxc/storage.go:522
+#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:424 lxc/storage.go:544
msgid "More than one device matches, specify the device name."
msgstr ""
@@ -725,7 +729,7 @@ msgid "Must supply container name for: "
msgstr ""
#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409
-#: lxc/storage.go:681 lxc/storage.go:792
+#: lxc/storage.go:703 lxc/storage.go:818
msgid "NAME"
msgstr ""
@@ -774,7 +778,7 @@ msgstr ""
msgid "No device found for this network"
msgstr ""
-#: lxc/storage.go:411 lxc/storage.go:531
+#: lxc/storage.go:433 lxc/storage.go:553
msgid "No device found for this storage volume."
msgstr ""
@@ -782,7 +786,7 @@ msgstr ""
msgid "No fingerprint specified."
msgstr ""
-#: lxc/storage.go:355 lxc/storage.go:448
+#: lxc/storage.go:377 lxc/storage.go:470
msgid "Only \"custom\" volumes can be attached to containers."
msgstr ""
@@ -864,7 +868,7 @@ msgstr ""
msgid "Pid: %d"
msgstr ""
-#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:605 lxc/storage.go:980
+#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:627 lxc/storage.go:1059
msgid "Press enter to open the editor again"
msgstr ""
@@ -973,7 +977,7 @@ msgstr ""
msgid "Remove %s (yes/no): "
msgstr ""
-#: lxc/storage.go:1011
+#: lxc/storage.go:1090
#, c-format
msgid "Renamed storage volume from \"%s\" to \"%s\""
msgstr ""
@@ -1011,7 +1015,7 @@ msgstr ""
msgid "SNAPSHOTS"
msgstr ""
-#: lxc/storage.go:684
+#: lxc/storage.go:706
msgid "SOURCE"
msgstr ""
@@ -1079,7 +1083,7 @@ msgstr ""
msgid "Show the resources available to the server"
msgstr ""
-#: lxc/storage.go:151
+#: lxc/storage.go:159
msgid "Show the resources available to the storage pool"
msgstr ""
@@ -1132,12 +1136,12 @@ msgstr ""
msgid "Stopping the container failed: %s"
msgstr ""
-#: lxc/storage.go:496
+#: lxc/storage.go:518
#, c-format
msgid "Storage pool %s created"
msgstr ""
-#: lxc/storage.go:555
+#: lxc/storage.go:577
#, c-format
msgid "Storage pool %s deleted"
msgstr ""
@@ -1146,12 +1150,12 @@ msgstr ""
msgid "Storage pool name"
msgstr ""
-#: lxc/storage.go:826
+#: lxc/storage.go:852
#, c-format
msgid "Storage volume %s created"
msgstr ""
-#: lxc/storage.go:841
+#: lxc/storage.go:867
#, c-format
msgid "Storage volume %s deleted"
msgstr ""
@@ -1168,7 +1172,7 @@ msgstr ""
msgid "Swap (peak)"
msgstr ""
-#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:791
+#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:817
msgid "TYPE"
msgstr ""
@@ -1204,7 +1208,7 @@ msgstr ""
msgid "The opposite of \"lxc pause\" is \"lxc start\"."
msgstr ""
-#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:416 lxc/storage.go:536
+#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:438 lxc/storage.go:558
msgid "The specified device doesn't exist"
msgstr ""
@@ -1283,7 +1287,7 @@ msgstr ""
msgid "URL"
msgstr ""
-#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:685 lxc/storage.go:794
+#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:707 lxc/storage.go:820
msgid "USED BY"
msgstr ""
@@ -2042,7 +2046,7 @@ msgid ""
" Create a snapshot of \"u1\" called \"snap0\"."
msgstr ""
-#: lxc/storage.go:64
+#: lxc/storage.go:65
msgid ""
"Usage: lxc storage <subcommand> [options]\n"
"\n"
@@ -2117,7 +2121,14 @@ msgid ""
"\n"
"lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> "
"[device name]\n"
-" Detach a storage volume from the specified profile.\n"
+"\tDetach a storage volume from the specified profile.\n"
+"\n"
+"lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c "
+"<key=value>...]\n"
+" Copy an existing volume to a new volume at the specified pool.\n"
+"\n"
+"lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>\n"
+" Move an existing volume to the specified pool.\n"
"\n"
"Unless specified through a prefix, all volume operations affect \"custom"
"\" (user created) volumes.\n"
diff --git a/po/es.po b/po/es.po
index d2af4eaa1..267b9373f 100644
--- a/po/es.po
+++ b/po/es.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: lxd\n"
"Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-01-11 17:16-0500\n"
+"POT-Creation-Date: 2018-01-16 11:17+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: lxc/storage.go:33
+#: lxc/storage.go:34
msgid ""
"### This is a yaml representation of a storage pool.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -33,7 +33,7 @@ msgid ""
"### zfs.pool_name: default"
msgstr ""
-#: lxc/storage.go:50
+#: lxc/storage.go:51
msgid ""
"### This is a yaml representation of a storage volume.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -288,7 +288,7 @@ msgstr ""
msgid "Can't unset key '%s', it's not currently set."
msgstr ""
-#: lxc/profile.go:546 lxc/storage.go:653
+#: lxc/profile.go:546 lxc/storage.go:675
msgid "Cannot provide container name to list"
msgstr ""
@@ -313,8 +313,12 @@ msgstr ""
msgid "Config key/value to apply to the new container"
msgstr ""
+#: lxc/storage.go:158
+msgid "Config key/value to apply to the new storage volume"
+msgstr ""
+
#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190
-#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:604 lxc/storage.go:979
+#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:626 lxc/storage.go:1058
#, c-format
msgid "Config parsing error: %s"
msgstr ""
@@ -381,11 +385,11 @@ msgid "Creating the container"
msgstr ""
#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525
-#: lxc/storage.go:682 lxc/storage.go:793
+#: lxc/storage.go:704 lxc/storage.go:819
msgid "DESCRIPTION"
msgstr ""
-#: lxc/storage.go:683
+#: lxc/storage.go:705
msgid "DRIVER"
msgstr ""
@@ -698,7 +702,7 @@ msgstr ""
msgid "Missing summary."
msgstr ""
-#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:402 lxc/storage.go:522
+#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:424 lxc/storage.go:544
msgid "More than one device matches, specify the device name."
msgstr ""
@@ -719,7 +723,7 @@ msgid "Must supply container name for: "
msgstr ""
#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409
-#: lxc/storage.go:681 lxc/storage.go:792
+#: lxc/storage.go:703 lxc/storage.go:818
msgid "NAME"
msgstr ""
@@ -767,7 +771,7 @@ msgstr ""
msgid "No device found for this network"
msgstr ""
-#: lxc/storage.go:411 lxc/storage.go:531
+#: lxc/storage.go:433 lxc/storage.go:553
msgid "No device found for this storage volume."
msgstr ""
@@ -775,7 +779,7 @@ msgstr ""
msgid "No fingerprint specified."
msgstr ""
-#: lxc/storage.go:355 lxc/storage.go:448
+#: lxc/storage.go:377 lxc/storage.go:470
msgid "Only \"custom\" volumes can be attached to containers."
msgstr ""
@@ -857,7 +861,7 @@ msgstr ""
msgid "Pid: %d"
msgstr ""
-#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:605 lxc/storage.go:980
+#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:627 lxc/storage.go:1059
msgid "Press enter to open the editor again"
msgstr ""
@@ -966,7 +970,7 @@ msgstr ""
msgid "Remove %s (yes/no): "
msgstr ""
-#: lxc/storage.go:1011
+#: lxc/storage.go:1090
#, c-format
msgid "Renamed storage volume from \"%s\" to \"%s\""
msgstr ""
@@ -1004,7 +1008,7 @@ msgstr ""
msgid "SNAPSHOTS"
msgstr ""
-#: lxc/storage.go:684
+#: lxc/storage.go:706
msgid "SOURCE"
msgstr ""
@@ -1072,7 +1076,7 @@ msgstr ""
msgid "Show the resources available to the server"
msgstr ""
-#: lxc/storage.go:151
+#: lxc/storage.go:159
msgid "Show the resources available to the storage pool"
msgstr ""
@@ -1125,12 +1129,12 @@ msgstr ""
msgid "Stopping the container failed: %s"
msgstr ""
-#: lxc/storage.go:496
+#: lxc/storage.go:518
#, c-format
msgid "Storage pool %s created"
msgstr ""
-#: lxc/storage.go:555
+#: lxc/storage.go:577
#, c-format
msgid "Storage pool %s deleted"
msgstr ""
@@ -1139,12 +1143,12 @@ msgstr ""
msgid "Storage pool name"
msgstr ""
-#: lxc/storage.go:826
+#: lxc/storage.go:852
#, c-format
msgid "Storage volume %s created"
msgstr ""
-#: lxc/storage.go:841
+#: lxc/storage.go:867
#, c-format
msgid "Storage volume %s deleted"
msgstr ""
@@ -1161,7 +1165,7 @@ msgstr ""
msgid "Swap (peak)"
msgstr ""
-#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:791
+#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:817
msgid "TYPE"
msgstr ""
@@ -1197,7 +1201,7 @@ msgstr ""
msgid "The opposite of \"lxc pause\" is \"lxc start\"."
msgstr ""
-#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:416 lxc/storage.go:536
+#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:438 lxc/storage.go:558
msgid "The specified device doesn't exist"
msgstr ""
@@ -1276,7 +1280,7 @@ msgstr ""
msgid "URL"
msgstr ""
-#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:685 lxc/storage.go:794
+#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:707 lxc/storage.go:820
msgid "USED BY"
msgstr ""
@@ -2035,7 +2039,7 @@ msgid ""
" Create a snapshot of \"u1\" called \"snap0\"."
msgstr ""
-#: lxc/storage.go:64
+#: lxc/storage.go:65
msgid ""
"Usage: lxc storage <subcommand> [options]\n"
"\n"
@@ -2110,7 +2114,14 @@ msgid ""
"\n"
"lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> "
"[device name]\n"
-" Detach a storage volume from the specified profile.\n"
+"\tDetach a storage volume from the specified profile.\n"
+"\n"
+"lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c "
+"<key=value>...]\n"
+" Copy an existing volume to a new volume at the specified pool.\n"
+"\n"
+"lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>\n"
+" Move an existing volume to the specified pool.\n"
"\n"
"Unless specified through a prefix, all volume operations affect \"custom"
"\" (user created) volumes.\n"
diff --git a/po/fi.po b/po/fi.po
index d6167f5f4..e0c0cd531 100644
--- a/po/fi.po
+++ b/po/fi.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: lxd\n"
"Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-01-11 17:16-0500\n"
+"POT-Creation-Date: 2018-01-16 11:17+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: lxc/storage.go:33
+#: lxc/storage.go:34
msgid ""
"### This is a yaml representation of a storage pool.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -33,7 +33,7 @@ msgid ""
"### zfs.pool_name: default"
msgstr ""
-#: lxc/storage.go:50
+#: lxc/storage.go:51
msgid ""
"### This is a yaml representation of a storage volume.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -288,7 +288,7 @@ msgstr ""
msgid "Can't unset key '%s', it's not currently set."
msgstr ""
-#: lxc/profile.go:546 lxc/storage.go:653
+#: lxc/profile.go:546 lxc/storage.go:675
msgid "Cannot provide container name to list"
msgstr ""
@@ -313,8 +313,12 @@ msgstr ""
msgid "Config key/value to apply to the new container"
msgstr ""
+#: lxc/storage.go:158
+msgid "Config key/value to apply to the new storage volume"
+msgstr ""
+
#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190
-#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:604 lxc/storage.go:979
+#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:626 lxc/storage.go:1058
#, c-format
msgid "Config parsing error: %s"
msgstr ""
@@ -381,11 +385,11 @@ msgid "Creating the container"
msgstr ""
#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525
-#: lxc/storage.go:682 lxc/storage.go:793
+#: lxc/storage.go:704 lxc/storage.go:819
msgid "DESCRIPTION"
msgstr ""
-#: lxc/storage.go:683
+#: lxc/storage.go:705
msgid "DRIVER"
msgstr ""
@@ -698,7 +702,7 @@ msgstr ""
msgid "Missing summary."
msgstr ""
-#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:402 lxc/storage.go:522
+#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:424 lxc/storage.go:544
msgid "More than one device matches, specify the device name."
msgstr ""
@@ -719,7 +723,7 @@ msgid "Must supply container name for: "
msgstr ""
#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409
-#: lxc/storage.go:681 lxc/storage.go:792
+#: lxc/storage.go:703 lxc/storage.go:818
msgid "NAME"
msgstr ""
@@ -767,7 +771,7 @@ msgstr ""
msgid "No device found for this network"
msgstr ""
-#: lxc/storage.go:411 lxc/storage.go:531
+#: lxc/storage.go:433 lxc/storage.go:553
msgid "No device found for this storage volume."
msgstr ""
@@ -775,7 +779,7 @@ msgstr ""
msgid "No fingerprint specified."
msgstr ""
-#: lxc/storage.go:355 lxc/storage.go:448
+#: lxc/storage.go:377 lxc/storage.go:470
msgid "Only \"custom\" volumes can be attached to containers."
msgstr ""
@@ -857,7 +861,7 @@ msgstr ""
msgid "Pid: %d"
msgstr ""
-#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:605 lxc/storage.go:980
+#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:627 lxc/storage.go:1059
msgid "Press enter to open the editor again"
msgstr ""
@@ -966,7 +970,7 @@ msgstr ""
msgid "Remove %s (yes/no): "
msgstr ""
-#: lxc/storage.go:1011
+#: lxc/storage.go:1090
#, c-format
msgid "Renamed storage volume from \"%s\" to \"%s\""
msgstr ""
@@ -1004,7 +1008,7 @@ msgstr ""
msgid "SNAPSHOTS"
msgstr ""
-#: lxc/storage.go:684
+#: lxc/storage.go:706
msgid "SOURCE"
msgstr ""
@@ -1072,7 +1076,7 @@ msgstr ""
msgid "Show the resources available to the server"
msgstr ""
-#: lxc/storage.go:151
+#: lxc/storage.go:159
msgid "Show the resources available to the storage pool"
msgstr ""
@@ -1125,12 +1129,12 @@ msgstr ""
msgid "Stopping the container failed: %s"
msgstr ""
-#: lxc/storage.go:496
+#: lxc/storage.go:518
#, c-format
msgid "Storage pool %s created"
msgstr ""
-#: lxc/storage.go:555
+#: lxc/storage.go:577
#, c-format
msgid "Storage pool %s deleted"
msgstr ""
@@ -1139,12 +1143,12 @@ msgstr ""
msgid "Storage pool name"
msgstr ""
-#: lxc/storage.go:826
+#: lxc/storage.go:852
#, c-format
msgid "Storage volume %s created"
msgstr ""
-#: lxc/storage.go:841
+#: lxc/storage.go:867
#, c-format
msgid "Storage volume %s deleted"
msgstr ""
@@ -1161,7 +1165,7 @@ msgstr ""
msgid "Swap (peak)"
msgstr ""
-#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:791
+#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:817
msgid "TYPE"
msgstr ""
@@ -1197,7 +1201,7 @@ msgstr ""
msgid "The opposite of \"lxc pause\" is \"lxc start\"."
msgstr ""
-#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:416 lxc/storage.go:536
+#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:438 lxc/storage.go:558
msgid "The specified device doesn't exist"
msgstr ""
@@ -1276,7 +1280,7 @@ msgstr ""
msgid "URL"
msgstr ""
-#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:685 lxc/storage.go:794
+#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:707 lxc/storage.go:820
msgid "USED BY"
msgstr ""
@@ -2035,7 +2039,7 @@ msgid ""
" Create a snapshot of \"u1\" called \"snap0\"."
msgstr ""
-#: lxc/storage.go:64
+#: lxc/storage.go:65
msgid ""
"Usage: lxc storage <subcommand> [options]\n"
"\n"
@@ -2110,7 +2114,14 @@ msgid ""
"\n"
"lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> "
"[device name]\n"
-" Detach a storage volume from the specified profile.\n"
+"\tDetach a storage volume from the specified profile.\n"
+"\n"
+"lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c "
+"<key=value>...]\n"
+" Copy an existing volume to a new volume at the specified pool.\n"
+"\n"
+"lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>\n"
+" Move an existing volume to the specified pool.\n"
"\n"
"Unless specified through a prefix, all volume operations affect \"custom"
"\" (user created) volumes.\n"
diff --git a/po/fr.po b/po/fr.po
index e38fd1091..1c026d3de 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: LXD\n"
"Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-01-11 17:16-0500\n"
+"POT-Creation-Date: 2018-01-16 11:17+0100\n"
"PO-Revision-Date: 2018-01-02 10:52+0000\n"
"Last-Translator: Bruno Perel <brunoperel at gmail.com>\n"
"Language-Team: French <https://hosted.weblate.org/projects/linux-containers/"
@@ -19,7 +19,7 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 2.19-dev\n"
-#: lxc/storage.go:33
+#: lxc/storage.go:34
msgid ""
"### This is a yaml representation of a storage pool.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -50,7 +50,7 @@ msgstr ""
"### source: /home/chb/mnt/lxd_test/default.img\n"
"### zfs.pool_name: default"
-#: lxc/storage.go:50
+#: lxc/storage.go:51
#, fuzzy
msgid ""
"### This is a yaml representation of a storage volume.\n"
@@ -392,7 +392,7 @@ msgid "Can't unset key '%s', it's not currently set."
msgstr ""
"Impossible de désaffecter la clé '%s', elle n'est pas définie actuellement."
-#: lxc/profile.go:546 lxc/storage.go:653
+#: lxc/profile.go:546 lxc/storage.go:675
msgid "Cannot provide container name to list"
msgstr "Impossible de fournir le nom du conteneur à lister"
@@ -417,8 +417,13 @@ msgstr "Commandes :"
msgid "Config key/value to apply to the new container"
msgstr "Clé/valeur de configuration à appliquer au nouveau conteneur"
+#: lxc/storage.go:158
+#, fuzzy
+msgid "Config key/value to apply to the new storage volume"
+msgstr "Clé/valeur de configuration à appliquer au nouveau conteneur"
+
#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190
-#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:604 lxc/storage.go:979
+#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:626 lxc/storage.go:1058
#, c-format
msgid "Config parsing error: %s"
msgstr "Erreur lors de la lecture de la configuration : %s"
@@ -486,11 +491,11 @@ msgid "Creating the container"
msgstr "Création du conteneur"
#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525
-#: lxc/storage.go:682 lxc/storage.go:793
+#: lxc/storage.go:704 lxc/storage.go:819
msgid "DESCRIPTION"
msgstr "DESCRIPTION"
-#: lxc/storage.go:683
+#: lxc/storage.go:705
msgid "DRIVER"
msgstr "PILOTE"
@@ -815,7 +820,7 @@ msgstr " Mémoire utilisée :"
msgid "Missing summary."
msgstr "Résumé manquant."
-#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:402 lxc/storage.go:522
+#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:424 lxc/storage.go:544
msgid "More than one device matches, specify the device name."
msgstr "Plus d'un périphérique correspond, spécifier le nom du périphérique."
@@ -838,7 +843,7 @@ msgid "Must supply container name for: "
msgstr "Vous devez fournir le nom d'un conteneur pour : "
#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409
-#: lxc/storage.go:681 lxc/storage.go:792
+#: lxc/storage.go:703 lxc/storage.go:818
msgid "NAME"
msgstr "NOM"
@@ -887,7 +892,7 @@ msgstr "Un certificat à ajouter n'a pas été fourni"
msgid "No device found for this network"
msgstr "Aucun périphérique existant pour ce réseau"
-#: lxc/storage.go:411 lxc/storage.go:531
+#: lxc/storage.go:433 lxc/storage.go:553
#, fuzzy
msgid "No device found for this storage volume."
msgstr "Aucun périphérique existant pour ce réseau"
@@ -896,7 +901,7 @@ msgstr "Aucun périphérique existant pour ce réseau"
msgid "No fingerprint specified."
msgstr "Aucune empreinte n'a été indiquée."
-#: lxc/storage.go:355 lxc/storage.go:448
+#: lxc/storage.go:377 lxc/storage.go:470
msgid "Only \"custom\" volumes can be attached to containers."
msgstr ""
"Seuls les volumes \"personnalisés\" peuvent être attachés aux conteneurs."
@@ -980,7 +985,7 @@ msgstr "Permission refusée, êtes-vous dans le groupe lxd ?"
msgid "Pid: %d"
msgstr "Pid : %d"
-#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:605 lxc/storage.go:980
+#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:627 lxc/storage.go:1059
msgid "Press enter to open the editor again"
msgstr "Appuyer sur Entrée pour ouvrir à nouveau l'éditeur"
@@ -1090,7 +1095,7 @@ msgstr "Serveur distant : %s"
msgid "Remove %s (yes/no): "
msgstr "Supprimer %s (oui/non) : "
-#: lxc/storage.go:1011
+#: lxc/storage.go:1090
#, c-format
msgid "Renamed storage volume from \"%s\" to \"%s\""
msgstr ""
@@ -1130,7 +1135,7 @@ msgstr "TAILLE"
msgid "SNAPSHOTS"
msgstr "INSTANTANÉS"
-#: lxc/storage.go:684
+#: lxc/storage.go:706
msgid "SOURCE"
msgstr "SOURCE"
@@ -1201,7 +1206,7 @@ msgstr "Afficher la configuration étendue"
msgid "Show the resources available to the server"
msgstr ""
-#: lxc/storage.go:151
+#: lxc/storage.go:159
msgid "Show the resources available to the storage pool"
msgstr ""
@@ -1256,12 +1261,12 @@ msgstr "L'arrêt du conteneur a échoué !"
msgid "Stopping the container failed: %s"
msgstr "L'arrêt du conteneur a échoué !"
-#: lxc/storage.go:496
+#: lxc/storage.go:518
#, fuzzy, c-format
msgid "Storage pool %s created"
msgstr "Le réseau %s a été créé"
-#: lxc/storage.go:555
+#: lxc/storage.go:577
#, fuzzy, c-format
msgid "Storage pool %s deleted"
msgstr "Le réseau %s a été supprimé"
@@ -1270,12 +1275,12 @@ msgstr "Le réseau %s a été supprimé"
msgid "Storage pool name"
msgstr "Nom de l'ensemble de stockage"
-#: lxc/storage.go:826
+#: lxc/storage.go:852
#, fuzzy, c-format
msgid "Storage volume %s created"
msgstr "Profil %s créé"
-#: lxc/storage.go:841
+#: lxc/storage.go:867
#, fuzzy, c-format
msgid "Storage volume %s deleted"
msgstr "Profil %s supprimé"
@@ -1292,7 +1297,7 @@ msgstr "Swap (courant)"
msgid "Swap (peak)"
msgstr "Swap (pointe)"
-#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:791
+#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:817
msgid "TYPE"
msgstr "TYPE"
@@ -1334,7 +1339,7 @@ msgstr "L'image locale '%s' n'a pas été trouvée, essayer '%s:' à la place."
msgid "The opposite of \"lxc pause\" is \"lxc start\"."
msgstr "Le pendant de `lxc pause` est `lxc start`."
-#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:416 lxc/storage.go:536
+#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:438 lxc/storage.go:558
msgid "The specified device doesn't exist"
msgstr "Le périphérique indiqué n'existe pas"
@@ -1419,7 +1424,7 @@ msgstr "DATE DE PUBLICATION"
msgid "URL"
msgstr "URL"
-#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:685 lxc/storage.go:794
+#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:707 lxc/storage.go:820
msgid "USED BY"
msgstr "UTILISÉ PAR"
@@ -2635,7 +2640,7 @@ msgstr ""
"Exemple :\n"
" lxc snapshot u1 snap0"
-#: lxc/storage.go:64
+#: lxc/storage.go:65
msgid ""
"Usage: lxc storage <subcommand> [options]\n"
"\n"
@@ -2710,7 +2715,14 @@ msgid ""
"\n"
"lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> "
"[device name]\n"
-" Detach a storage volume from the specified profile.\n"
+"\tDetach a storage volume from the specified profile.\n"
+"\n"
+"lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c "
+"<key=value>...]\n"
+" Copy an existing volume to a new volume at the specified pool.\n"
+"\n"
+"lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>\n"
+" Move an existing volume to the specified pool.\n"
"\n"
"Unless specified through a prefix, all volume operations affect \"custom"
"\" (user created) volumes.\n"
diff --git a/po/id.po b/po/id.po
index b7583208a..4857a6ea0 100644
--- a/po/id.po
+++ b/po/id.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: lxd\n"
"Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-01-11 17:16-0500\n"
+"POT-Creation-Date: 2018-01-16 11:17+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: lxc/storage.go:33
+#: lxc/storage.go:34
msgid ""
"### This is a yaml representation of a storage pool.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -33,7 +33,7 @@ msgid ""
"### zfs.pool_name: default"
msgstr ""
-#: lxc/storage.go:50
+#: lxc/storage.go:51
msgid ""
"### This is a yaml representation of a storage volume.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -288,7 +288,7 @@ msgstr ""
msgid "Can't unset key '%s', it's not currently set."
msgstr ""
-#: lxc/profile.go:546 lxc/storage.go:653
+#: lxc/profile.go:546 lxc/storage.go:675
msgid "Cannot provide container name to list"
msgstr ""
@@ -313,8 +313,12 @@ msgstr ""
msgid "Config key/value to apply to the new container"
msgstr ""
+#: lxc/storage.go:158
+msgid "Config key/value to apply to the new storage volume"
+msgstr ""
+
#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190
-#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:604 lxc/storage.go:979
+#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:626 lxc/storage.go:1058
#, c-format
msgid "Config parsing error: %s"
msgstr ""
@@ -381,11 +385,11 @@ msgid "Creating the container"
msgstr ""
#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525
-#: lxc/storage.go:682 lxc/storage.go:793
+#: lxc/storage.go:704 lxc/storage.go:819
msgid "DESCRIPTION"
msgstr ""
-#: lxc/storage.go:683
+#: lxc/storage.go:705
msgid "DRIVER"
msgstr ""
@@ -698,7 +702,7 @@ msgstr ""
msgid "Missing summary."
msgstr ""
-#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:402 lxc/storage.go:522
+#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:424 lxc/storage.go:544
msgid "More than one device matches, specify the device name."
msgstr ""
@@ -719,7 +723,7 @@ msgid "Must supply container name for: "
msgstr ""
#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409
-#: lxc/storage.go:681 lxc/storage.go:792
+#: lxc/storage.go:703 lxc/storage.go:818
msgid "NAME"
msgstr ""
@@ -767,7 +771,7 @@ msgstr ""
msgid "No device found for this network"
msgstr ""
-#: lxc/storage.go:411 lxc/storage.go:531
+#: lxc/storage.go:433 lxc/storage.go:553
msgid "No device found for this storage volume."
msgstr ""
@@ -775,7 +779,7 @@ msgstr ""
msgid "No fingerprint specified."
msgstr ""
-#: lxc/storage.go:355 lxc/storage.go:448
+#: lxc/storage.go:377 lxc/storage.go:470
msgid "Only \"custom\" volumes can be attached to containers."
msgstr ""
@@ -857,7 +861,7 @@ msgstr ""
msgid "Pid: %d"
msgstr ""
-#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:605 lxc/storage.go:980
+#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:627 lxc/storage.go:1059
msgid "Press enter to open the editor again"
msgstr ""
@@ -966,7 +970,7 @@ msgstr ""
msgid "Remove %s (yes/no): "
msgstr ""
-#: lxc/storage.go:1011
+#: lxc/storage.go:1090
#, c-format
msgid "Renamed storage volume from \"%s\" to \"%s\""
msgstr ""
@@ -1004,7 +1008,7 @@ msgstr ""
msgid "SNAPSHOTS"
msgstr ""
-#: lxc/storage.go:684
+#: lxc/storage.go:706
msgid "SOURCE"
msgstr ""
@@ -1072,7 +1076,7 @@ msgstr ""
msgid "Show the resources available to the server"
msgstr ""
-#: lxc/storage.go:151
+#: lxc/storage.go:159
msgid "Show the resources available to the storage pool"
msgstr ""
@@ -1125,12 +1129,12 @@ msgstr ""
msgid "Stopping the container failed: %s"
msgstr ""
-#: lxc/storage.go:496
+#: lxc/storage.go:518
#, c-format
msgid "Storage pool %s created"
msgstr ""
-#: lxc/storage.go:555
+#: lxc/storage.go:577
#, c-format
msgid "Storage pool %s deleted"
msgstr ""
@@ -1139,12 +1143,12 @@ msgstr ""
msgid "Storage pool name"
msgstr ""
-#: lxc/storage.go:826
+#: lxc/storage.go:852
#, c-format
msgid "Storage volume %s created"
msgstr ""
-#: lxc/storage.go:841
+#: lxc/storage.go:867
#, c-format
msgid "Storage volume %s deleted"
msgstr ""
@@ -1161,7 +1165,7 @@ msgstr ""
msgid "Swap (peak)"
msgstr ""
-#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:791
+#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:817
msgid "TYPE"
msgstr ""
@@ -1197,7 +1201,7 @@ msgstr ""
msgid "The opposite of \"lxc pause\" is \"lxc start\"."
msgstr ""
-#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:416 lxc/storage.go:536
+#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:438 lxc/storage.go:558
msgid "The specified device doesn't exist"
msgstr ""
@@ -1276,7 +1280,7 @@ msgstr ""
msgid "URL"
msgstr ""
-#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:685 lxc/storage.go:794
+#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:707 lxc/storage.go:820
msgid "USED BY"
msgstr ""
@@ -2035,7 +2039,7 @@ msgid ""
" Create a snapshot of \"u1\" called \"snap0\"."
msgstr ""
-#: lxc/storage.go:64
+#: lxc/storage.go:65
msgid ""
"Usage: lxc storage <subcommand> [options]\n"
"\n"
@@ -2110,7 +2114,14 @@ msgid ""
"\n"
"lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> "
"[device name]\n"
-" Detach a storage volume from the specified profile.\n"
+"\tDetach a storage volume from the specified profile.\n"
+"\n"
+"lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c "
+"<key=value>...]\n"
+" Copy an existing volume to a new volume at the specified pool.\n"
+"\n"
+"lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>\n"
+" Move an existing volume to the specified pool.\n"
"\n"
"Unless specified through a prefix, all volume operations affect \"custom"
"\" (user created) volumes.\n"
diff --git a/po/it.po b/po/it.po
index f92d967e0..0cdc30769 100644
--- a/po/it.po
+++ b/po/it.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: lxd\n"
"Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-01-11 17:16-0500\n"
+"POT-Creation-Date: 2018-01-16 11:17+0100\n"
"PO-Revision-Date: 2017-08-18 14:22+0000\n"
"Last-Translator: Alberto Donato <alberto.donato at gmail.com>\n"
"Language-Team: Italian <https://hosted.weblate.org/projects/linux-containers/"
@@ -19,7 +19,7 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 2.17-dev\n"
-#: lxc/storage.go:33
+#: lxc/storage.go:34
msgid ""
"### This is a yaml representation of a storage pool.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -50,7 +50,7 @@ msgstr ""
"### source: /home/chb/mnt/lxd_test/default.img\n"
"### zfs.pool_name: default"
-#: lxc/storage.go:50
+#: lxc/storage.go:51
msgid ""
"### This is a yaml representation of a storage volume.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -313,7 +313,7 @@ msgstr ""
msgid "Can't unset key '%s', it's not currently set."
msgstr ""
-#: lxc/profile.go:546 lxc/storage.go:653
+#: lxc/profile.go:546 lxc/storage.go:675
msgid "Cannot provide container name to list"
msgstr ""
@@ -338,8 +338,12 @@ msgstr "Comandi:"
msgid "Config key/value to apply to the new container"
msgstr ""
+#: lxc/storage.go:158
+msgid "Config key/value to apply to the new storage volume"
+msgstr ""
+
#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190
-#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:604 lxc/storage.go:979
+#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:626 lxc/storage.go:1058
#, c-format
msgid "Config parsing error: %s"
msgstr ""
@@ -406,11 +410,11 @@ msgid "Creating the container"
msgstr "Creazione del container in corso"
#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525
-#: lxc/storage.go:682 lxc/storage.go:793
+#: lxc/storage.go:704 lxc/storage.go:819
msgid "DESCRIPTION"
msgstr "DESCRIZIONE"
-#: lxc/storage.go:683
+#: lxc/storage.go:705
msgid "DRIVER"
msgstr "DRIVER"
@@ -724,7 +728,7 @@ msgstr ""
msgid "Missing summary."
msgstr ""
-#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:402 lxc/storage.go:522
+#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:424 lxc/storage.go:544
msgid "More than one device matches, specify the device name."
msgstr ""
@@ -745,7 +749,7 @@ msgid "Must supply container name for: "
msgstr ""
#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409
-#: lxc/storage.go:681 lxc/storage.go:792
+#: lxc/storage.go:703 lxc/storage.go:818
msgid "NAME"
msgstr ""
@@ -793,7 +797,7 @@ msgstr ""
msgid "No device found for this network"
msgstr ""
-#: lxc/storage.go:411 lxc/storage.go:531
+#: lxc/storage.go:433 lxc/storage.go:553
msgid "No device found for this storage volume."
msgstr ""
@@ -801,7 +805,7 @@ msgstr ""
msgid "No fingerprint specified."
msgstr ""
-#: lxc/storage.go:355 lxc/storage.go:448
+#: lxc/storage.go:377 lxc/storage.go:470
msgid "Only \"custom\" volumes can be attached to containers."
msgstr ""
@@ -883,7 +887,7 @@ msgstr ""
msgid "Pid: %d"
msgstr ""
-#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:605 lxc/storage.go:980
+#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:627 lxc/storage.go:1059
msgid "Press enter to open the editor again"
msgstr ""
@@ -992,7 +996,7 @@ msgstr ""
msgid "Remove %s (yes/no): "
msgstr ""
-#: lxc/storage.go:1011
+#: lxc/storage.go:1090
#, c-format
msgid "Renamed storage volume from \"%s\" to \"%s\""
msgstr ""
@@ -1030,7 +1034,7 @@ msgstr ""
msgid "SNAPSHOTS"
msgstr ""
-#: lxc/storage.go:684
+#: lxc/storage.go:706
msgid "SOURCE"
msgstr ""
@@ -1098,7 +1102,7 @@ msgstr ""
msgid "Show the resources available to the server"
msgstr ""
-#: lxc/storage.go:151
+#: lxc/storage.go:159
msgid "Show the resources available to the storage pool"
msgstr ""
@@ -1151,12 +1155,12 @@ msgstr ""
msgid "Stopping the container failed: %s"
msgstr ""
-#: lxc/storage.go:496
+#: lxc/storage.go:518
#, c-format
msgid "Storage pool %s created"
msgstr ""
-#: lxc/storage.go:555
+#: lxc/storage.go:577
#, c-format
msgid "Storage pool %s deleted"
msgstr ""
@@ -1165,12 +1169,12 @@ msgstr ""
msgid "Storage pool name"
msgstr ""
-#: lxc/storage.go:826
+#: lxc/storage.go:852
#, c-format
msgid "Storage volume %s created"
msgstr ""
-#: lxc/storage.go:841
+#: lxc/storage.go:867
#, c-format
msgid "Storage volume %s deleted"
msgstr ""
@@ -1187,7 +1191,7 @@ msgstr ""
msgid "Swap (peak)"
msgstr ""
-#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:791
+#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:817
msgid "TYPE"
msgstr ""
@@ -1223,7 +1227,7 @@ msgstr ""
msgid "The opposite of \"lxc pause\" is \"lxc start\"."
msgstr ""
-#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:416 lxc/storage.go:536
+#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:438 lxc/storage.go:558
msgid "The specified device doesn't exist"
msgstr ""
@@ -1302,7 +1306,7 @@ msgstr ""
msgid "URL"
msgstr ""
-#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:685 lxc/storage.go:794
+#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:707 lxc/storage.go:820
msgid "USED BY"
msgstr ""
@@ -2061,7 +2065,7 @@ msgid ""
" Create a snapshot of \"u1\" called \"snap0\"."
msgstr ""
-#: lxc/storage.go:64
+#: lxc/storage.go:65
msgid ""
"Usage: lxc storage <subcommand> [options]\n"
"\n"
@@ -2136,7 +2140,14 @@ msgid ""
"\n"
"lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> "
"[device name]\n"
-" Detach a storage volume from the specified profile.\n"
+"\tDetach a storage volume from the specified profile.\n"
+"\n"
+"lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c "
+"<key=value>...]\n"
+" Copy an existing volume to a new volume at the specified pool.\n"
+"\n"
+"lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>\n"
+" Move an existing volume to the specified pool.\n"
"\n"
"Unless specified through a prefix, all volume operations affect \"custom"
"\" (user created) volumes.\n"
diff --git a/po/ja.po b/po/ja.po
index 31d2bafb5..84b0c992c 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: LXD\n"
"Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-01-11 17:16-0500\n"
+"POT-Creation-Date: 2018-01-16 11:17+0100\n"
"PO-Revision-Date: 2018-01-02 10:52+0000\n"
"Last-Translator: KATOH Yasufumi <karma at jazz.email.ne.jp>\n"
"Language-Team: Japanese <https://hosted.weblate.org/projects/linux-"
@@ -19,7 +19,7 @@ msgstr ""
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 2.19-dev\n"
-#: lxc/storage.go:33
+#: lxc/storage.go:34
msgid ""
"### This is a yaml representation of a storage pool.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -36,7 +36,7 @@ msgid ""
"### zfs.pool_name: default"
msgstr ""
-#: lxc/storage.go:50
+#: lxc/storage.go:51
msgid ""
"### This is a yaml representation of a storage volume.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -293,7 +293,7 @@ msgstr "キー '%s' が設定されていないので削除できません"
msgid "Can't unset key '%s', it's not currently set."
msgstr "キー '%s' が指定されていないので削除できません。"
-#: lxc/profile.go:546 lxc/storage.go:653
+#: lxc/profile.go:546 lxc/storage.go:675
msgid "Cannot provide container name to list"
msgstr "コンテナ名を取得できません"
@@ -318,8 +318,13 @@ msgstr "コマンド:"
msgid "Config key/value to apply to the new container"
msgstr "新しいコンテナに適用するキー/値の設定"
+#: lxc/storage.go:158
+#, fuzzy
+msgid "Config key/value to apply to the new storage volume"
+msgstr "新しいコンテナに適用するキー/値の設定"
+
#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190
-#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:604 lxc/storage.go:979
+#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:626 lxc/storage.go:1058
#, c-format
msgid "Config parsing error: %s"
msgstr "設定の構文エラー: %s"
@@ -386,11 +391,11 @@ msgid "Creating the container"
msgstr "コンテナを作成中"
#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525
-#: lxc/storage.go:682 lxc/storage.go:793
+#: lxc/storage.go:704 lxc/storage.go:819
msgid "DESCRIPTION"
msgstr ""
-#: lxc/storage.go:683
+#: lxc/storage.go:705
msgid "DRIVER"
msgstr ""
@@ -704,7 +709,7 @@ msgstr "メモリ消費量:"
msgid "Missing summary."
msgstr "サマリーはありません。"
-#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:402 lxc/storage.go:522
+#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:424 lxc/storage.go:544
msgid "More than one device matches, specify the device name."
msgstr "複数のデバイスとマッチします。デバイス名を指定してください。"
@@ -727,7 +732,7 @@ msgid "Must supply container name for: "
msgstr "コンテナ名を指定する必要があります: "
#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409
-#: lxc/storage.go:681 lxc/storage.go:792
+#: lxc/storage.go:703 lxc/storage.go:818
msgid "NAME"
msgstr ""
@@ -775,7 +780,7 @@ msgstr "追加すべき証明書が提供されていません"
msgid "No device found for this network"
msgstr "このネットワークに対するデバイスがありません"
-#: lxc/storage.go:411 lxc/storage.go:531
+#: lxc/storage.go:433 lxc/storage.go:553
msgid "No device found for this storage volume."
msgstr "このストレージボリュームに対するデバイスがありません。"
@@ -783,7 +788,7 @@ msgstr "このストレージボリュームに対するデバイスがありま
msgid "No fingerprint specified."
msgstr "フィンガープリントが指定されていません。"
-#: lxc/storage.go:355 lxc/storage.go:448
+#: lxc/storage.go:377 lxc/storage.go:470
msgid "Only \"custom\" volumes can be attached to containers."
msgstr "\"カスタム\" のボリュームのみがコンテナにアタッチできます。"
@@ -865,7 +870,7 @@ msgstr "アクセスが拒否されました。lxd グループに所属して
msgid "Pid: %d"
msgstr "Pid: %d"
-#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:605 lxc/storage.go:980
+#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:627 lxc/storage.go:1059
msgid "Press enter to open the editor again"
msgstr "再度エディタを開くためには Enter キーを押します"
@@ -974,7 +979,7 @@ msgstr "リモート名: %s"
msgid "Remove %s (yes/no): "
msgstr "%s を消去しますか (yes/no): "
-#: lxc/storage.go:1011
+#: lxc/storage.go:1090
#, c-format
msgid "Renamed storage volume from \"%s\" to \"%s\""
msgstr "ストレージボリューム名 \"%s\" を \"%s\" に変更しました"
@@ -1012,7 +1017,7 @@ msgstr ""
msgid "SNAPSHOTS"
msgstr ""
-#: lxc/storage.go:684
+#: lxc/storage.go:706
msgid "SOURCE"
msgstr ""
@@ -1080,7 +1085,7 @@ msgstr "拡張した設定を表示する"
msgid "Show the resources available to the server"
msgstr "サーバで使用可能なリソースを表示します"
-#: lxc/storage.go:151
+#: lxc/storage.go:159
msgid "Show the resources available to the storage pool"
msgstr "ストレージプールで利用可能なリソースを表示します"
@@ -1133,12 +1138,12 @@ msgstr "コンテナの停止に失敗しました!"
msgid "Stopping the container failed: %s"
msgstr "コンテナの停止に失敗しました: %s"
-#: lxc/storage.go:496
+#: lxc/storage.go:518
#, c-format
msgid "Storage pool %s created"
msgstr "ストレージプール %s を作成しました"
-#: lxc/storage.go:555
+#: lxc/storage.go:577
#, c-format
msgid "Storage pool %s deleted"
msgstr "ストレージプール %s を削除しました"
@@ -1147,12 +1152,12 @@ msgstr "ストレージプール %s を削除しました"
msgid "Storage pool name"
msgstr "ストレージプール名"
-#: lxc/storage.go:826
+#: lxc/storage.go:852
#, c-format
msgid "Storage volume %s created"
msgstr "ストレージボリューム %s を作成しました"
-#: lxc/storage.go:841
+#: lxc/storage.go:867
#, c-format
msgid "Storage volume %s deleted"
msgstr "ストレージボリューム %s を削除しました"
@@ -1169,7 +1174,7 @@ msgstr "Swap (現在値)"
msgid "Swap (peak)"
msgstr "Swap (ピーク)"
-#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:791
+#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:817
msgid "TYPE"
msgstr ""
@@ -1208,7 +1213,7 @@ msgstr ""
msgid "The opposite of \"lxc pause\" is \"lxc start\"."
msgstr "\"lxc pause\" の反対のコマンドは \"lxc start\" です。"
-#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:416 lxc/storage.go:536
+#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:438 lxc/storage.go:558
msgid "The specified device doesn't exist"
msgstr "指定したデバイスが存在しません"
@@ -1297,7 +1302,7 @@ msgstr ""
msgid "URL"
msgstr ""
-#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:685 lxc/storage.go:794
+#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:707 lxc/storage.go:820
msgid "USED BY"
msgstr ""
@@ -2685,7 +2690,7 @@ msgstr ""
"lxc snapshot u1 snap0\n"
" \"u1\" のスナップショットを \"snap0\" という名前で作成します。"
-#: lxc/storage.go:64
+#: lxc/storage.go:65
#, fuzzy
msgid ""
"Usage: lxc storage <subcommand> [options]\n"
@@ -2761,7 +2766,14 @@ msgid ""
"\n"
"lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> "
"[device name]\n"
-" Detach a storage volume from the specified profile.\n"
+"\tDetach a storage volume from the specified profile.\n"
+"\n"
+"lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c "
+"<key=value>...]\n"
+" Copy an existing volume to a new volume at the specified pool.\n"
+"\n"
+"lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>\n"
+" Move an existing volume to the specified pool.\n"
"\n"
"Unless specified through a prefix, all volume operations affect \"custom"
"\" (user created) volumes.\n"
diff --git a/po/lxd.pot b/po/lxd.pot
index 30bd65ad6..65f811777 100644
--- a/po/lxd.pot
+++ b/po/lxd.pot
@@ -7,7 +7,7 @@
msgid ""
msgstr "Project-Id-Version: lxd\n"
"Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
- "POT-Creation-Date: 2018-01-11 17:16-0500\n"
+ "POT-Creation-Date: 2018-01-16 11:17+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
"Language-Team: LANGUAGE <LL at li.org>\n"
@@ -16,7 +16,7 @@ msgstr "Project-Id-Version: lxd\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
-#: lxc/storage.go:33
+#: lxc/storage.go:34
msgid "### This is a yaml representation of a storage pool.\n"
"### Any line starting with a '# will be ignored.\n"
"###\n"
@@ -32,7 +32,7 @@ msgid "### This is a yaml representation of a storage pool.\n"
"### zfs.pool_name: default"
msgstr ""
-#: lxc/storage.go:50
+#: lxc/storage.go:51
msgid "### This is a yaml representation of a storage volume.\n"
"### Any line starting with a '# will be ignored.\n"
"###\n"
@@ -281,7 +281,7 @@ msgstr ""
msgid "Can't unset key '%s', it's not currently set."
msgstr ""
-#: lxc/profile.go:546 lxc/storage.go:653
+#: lxc/profile.go:546 lxc/storage.go:675
msgid "Cannot provide container name to list"
msgstr ""
@@ -306,7 +306,11 @@ msgstr ""
msgid "Config key/value to apply to the new container"
msgstr ""
-#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190 lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:604 lxc/storage.go:979
+#: lxc/storage.go:158
+msgid "Config key/value to apply to the new storage volume"
+msgstr ""
+
+#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190 lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:626 lxc/storage.go:1058
#, c-format
msgid "Config parsing error: %s"
msgstr ""
@@ -372,11 +376,11 @@ msgstr ""
msgid "Creating the container"
msgstr ""
-#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525 lxc/storage.go:682 lxc/storage.go:793
+#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525 lxc/storage.go:704 lxc/storage.go:819
msgid "DESCRIPTION"
msgstr ""
-#: lxc/storage.go:683
+#: lxc/storage.go:705
msgid "DRIVER"
msgstr ""
@@ -687,7 +691,7 @@ msgstr ""
msgid "Missing summary."
msgstr ""
-#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:402 lxc/storage.go:522
+#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:424 lxc/storage.go:544
msgid "More than one device matches, specify the device name."
msgstr ""
@@ -707,7 +711,7 @@ msgstr ""
msgid "Must supply container name for: "
msgstr ""
-#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409 lxc/storage.go:681 lxc/storage.go:792
+#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409 lxc/storage.go:703 lxc/storage.go:818
msgid "NAME"
msgstr ""
@@ -755,7 +759,7 @@ msgstr ""
msgid "No device found for this network"
msgstr ""
-#: lxc/storage.go:411 lxc/storage.go:531
+#: lxc/storage.go:433 lxc/storage.go:553
msgid "No device found for this storage volume."
msgstr ""
@@ -763,7 +767,7 @@ msgstr ""
msgid "No fingerprint specified."
msgstr ""
-#: lxc/storage.go:355 lxc/storage.go:448
+#: lxc/storage.go:377 lxc/storage.go:470
msgid "Only \"custom\" volumes can be attached to containers."
msgstr ""
@@ -845,7 +849,7 @@ msgstr ""
msgid "Pid: %d"
msgstr ""
-#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:605 lxc/storage.go:980
+#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:627 lxc/storage.go:1059
msgid "Press enter to open the editor again"
msgstr ""
@@ -953,7 +957,7 @@ msgstr ""
msgid "Remove %s (yes/no): "
msgstr ""
-#: lxc/storage.go:1011
+#: lxc/storage.go:1090
#, c-format
msgid "Renamed storage volume from \"%s\" to \"%s\""
msgstr ""
@@ -991,7 +995,7 @@ msgstr ""
msgid "SNAPSHOTS"
msgstr ""
-#: lxc/storage.go:684
+#: lxc/storage.go:706
msgid "SOURCE"
msgstr ""
@@ -1059,7 +1063,7 @@ msgstr ""
msgid "Show the resources available to the server"
msgstr ""
-#: lxc/storage.go:151
+#: lxc/storage.go:159
msgid "Show the resources available to the storage pool"
msgstr ""
@@ -1112,12 +1116,12 @@ msgstr ""
msgid "Stopping the container failed: %s"
msgstr ""
-#: lxc/storage.go:496
+#: lxc/storage.go:518
#, c-format
msgid "Storage pool %s created"
msgstr ""
-#: lxc/storage.go:555
+#: lxc/storage.go:577
#, c-format
msgid "Storage pool %s deleted"
msgstr ""
@@ -1126,12 +1130,12 @@ msgstr ""
msgid "Storage pool name"
msgstr ""
-#: lxc/storage.go:826
+#: lxc/storage.go:852
#, c-format
msgid "Storage volume %s created"
msgstr ""
-#: lxc/storage.go:841
+#: lxc/storage.go:867
#, c-format
msgid "Storage volume %s deleted"
msgstr ""
@@ -1148,7 +1152,7 @@ msgstr ""
msgid "Swap (peak)"
msgstr ""
-#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:791
+#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:817
msgid "TYPE"
msgstr ""
@@ -1181,7 +1185,7 @@ msgstr ""
msgid "The opposite of \"lxc pause\" is \"lxc start\"."
msgstr ""
-#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:416 lxc/storage.go:536
+#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:438 lxc/storage.go:558
msgid "The specified device doesn't exist"
msgstr ""
@@ -1259,7 +1263,7 @@ msgstr ""
msgid "URL"
msgstr ""
-#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:685 lxc/storage.go:794
+#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:707 lxc/storage.go:820
msgid "USED BY"
msgstr ""
@@ -1941,7 +1945,7 @@ msgid "Usage: lxc snapshot [<remote>:]<container> <snapshot name> [--stateful]
" Create a snapshot of \"u1\" called \"snap0\"."
msgstr ""
-#: lxc/storage.go:64
+#: lxc/storage.go:65
msgid "Usage: lxc storage <subcommand> [options]\n"
"\n"
"Manage storage pools and volumes.\n"
@@ -2009,7 +2013,13 @@ msgid "Usage: lxc storage <subcommand> [options]\n"
" Detach a storage volume from the specified container.\n"
"\n"
"lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> [device name]\n"
- " Detach a storage volume from the specified profile.\n"
+ " Detach a storage volume from the specified profile.\n"
+ "\n"
+ "lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c <key=value>...]\n"
+ " Copy an existing volume to a new volume at the specified pool.\n"
+ "\n"
+ "lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>\n"
+ " Move an existing volume to the specified pool.\n"
"\n"
"Unless specified through a prefix, all volume operations affect \"custom\" (user created) volumes.\n"
"\n"
diff --git a/po/nb_NO.po b/po/nb_NO.po
index f41956143..cb2eed63d 100644
--- a/po/nb_NO.po
+++ b/po/nb_NO.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: lxd\n"
"Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-01-11 17:16-0500\n"
+"POT-Creation-Date: 2018-01-16 11:17+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: lxc/storage.go:33
+#: lxc/storage.go:34
msgid ""
"### This is a yaml representation of a storage pool.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -33,7 +33,7 @@ msgid ""
"### zfs.pool_name: default"
msgstr ""
-#: lxc/storage.go:50
+#: lxc/storage.go:51
msgid ""
"### This is a yaml representation of a storage volume.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -288,7 +288,7 @@ msgstr ""
msgid "Can't unset key '%s', it's not currently set."
msgstr ""
-#: lxc/profile.go:546 lxc/storage.go:653
+#: lxc/profile.go:546 lxc/storage.go:675
msgid "Cannot provide container name to list"
msgstr ""
@@ -313,8 +313,12 @@ msgstr ""
msgid "Config key/value to apply to the new container"
msgstr ""
+#: lxc/storage.go:158
+msgid "Config key/value to apply to the new storage volume"
+msgstr ""
+
#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190
-#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:604 lxc/storage.go:979
+#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:626 lxc/storage.go:1058
#, c-format
msgid "Config parsing error: %s"
msgstr ""
@@ -381,11 +385,11 @@ msgid "Creating the container"
msgstr ""
#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525
-#: lxc/storage.go:682 lxc/storage.go:793
+#: lxc/storage.go:704 lxc/storage.go:819
msgid "DESCRIPTION"
msgstr ""
-#: lxc/storage.go:683
+#: lxc/storage.go:705
msgid "DRIVER"
msgstr ""
@@ -698,7 +702,7 @@ msgstr ""
msgid "Missing summary."
msgstr ""
-#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:402 lxc/storage.go:522
+#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:424 lxc/storage.go:544
msgid "More than one device matches, specify the device name."
msgstr ""
@@ -719,7 +723,7 @@ msgid "Must supply container name for: "
msgstr ""
#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409
-#: lxc/storage.go:681 lxc/storage.go:792
+#: lxc/storage.go:703 lxc/storage.go:818
msgid "NAME"
msgstr ""
@@ -767,7 +771,7 @@ msgstr ""
msgid "No device found for this network"
msgstr ""
-#: lxc/storage.go:411 lxc/storage.go:531
+#: lxc/storage.go:433 lxc/storage.go:553
msgid "No device found for this storage volume."
msgstr ""
@@ -775,7 +779,7 @@ msgstr ""
msgid "No fingerprint specified."
msgstr ""
-#: lxc/storage.go:355 lxc/storage.go:448
+#: lxc/storage.go:377 lxc/storage.go:470
msgid "Only \"custom\" volumes can be attached to containers."
msgstr ""
@@ -857,7 +861,7 @@ msgstr ""
msgid "Pid: %d"
msgstr ""
-#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:605 lxc/storage.go:980
+#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:627 lxc/storage.go:1059
msgid "Press enter to open the editor again"
msgstr ""
@@ -966,7 +970,7 @@ msgstr ""
msgid "Remove %s (yes/no): "
msgstr ""
-#: lxc/storage.go:1011
+#: lxc/storage.go:1090
#, c-format
msgid "Renamed storage volume from \"%s\" to \"%s\""
msgstr ""
@@ -1004,7 +1008,7 @@ msgstr ""
msgid "SNAPSHOTS"
msgstr ""
-#: lxc/storage.go:684
+#: lxc/storage.go:706
msgid "SOURCE"
msgstr ""
@@ -1072,7 +1076,7 @@ msgstr ""
msgid "Show the resources available to the server"
msgstr ""
-#: lxc/storage.go:151
+#: lxc/storage.go:159
msgid "Show the resources available to the storage pool"
msgstr ""
@@ -1125,12 +1129,12 @@ msgstr ""
msgid "Stopping the container failed: %s"
msgstr ""
-#: lxc/storage.go:496
+#: lxc/storage.go:518
#, c-format
msgid "Storage pool %s created"
msgstr ""
-#: lxc/storage.go:555
+#: lxc/storage.go:577
#, c-format
msgid "Storage pool %s deleted"
msgstr ""
@@ -1139,12 +1143,12 @@ msgstr ""
msgid "Storage pool name"
msgstr ""
-#: lxc/storage.go:826
+#: lxc/storage.go:852
#, c-format
msgid "Storage volume %s created"
msgstr ""
-#: lxc/storage.go:841
+#: lxc/storage.go:867
#, c-format
msgid "Storage volume %s deleted"
msgstr ""
@@ -1161,7 +1165,7 @@ msgstr ""
msgid "Swap (peak)"
msgstr ""
-#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:791
+#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:817
msgid "TYPE"
msgstr ""
@@ -1197,7 +1201,7 @@ msgstr ""
msgid "The opposite of \"lxc pause\" is \"lxc start\"."
msgstr ""
-#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:416 lxc/storage.go:536
+#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:438 lxc/storage.go:558
msgid "The specified device doesn't exist"
msgstr ""
@@ -1276,7 +1280,7 @@ msgstr ""
msgid "URL"
msgstr ""
-#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:685 lxc/storage.go:794
+#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:707 lxc/storage.go:820
msgid "USED BY"
msgstr ""
@@ -2035,7 +2039,7 @@ msgid ""
" Create a snapshot of \"u1\" called \"snap0\"."
msgstr ""
-#: lxc/storage.go:64
+#: lxc/storage.go:65
msgid ""
"Usage: lxc storage <subcommand> [options]\n"
"\n"
@@ -2110,7 +2114,14 @@ msgid ""
"\n"
"lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> "
"[device name]\n"
-" Detach a storage volume from the specified profile.\n"
+"\tDetach a storage volume from the specified profile.\n"
+"\n"
+"lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c "
+"<key=value>...]\n"
+" Copy an existing volume to a new volume at the specified pool.\n"
+"\n"
+"lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>\n"
+" Move an existing volume to the specified pool.\n"
"\n"
"Unless specified through a prefix, all volume operations affect \"custom"
"\" (user created) volumes.\n"
diff --git a/po/nl.po b/po/nl.po
index 0fd7dc570..dade54117 100644
--- a/po/nl.po
+++ b/po/nl.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: lxd\n"
"Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-01-11 17:16-0500\n"
+"POT-Creation-Date: 2018-01-16 11:17+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: lxc/storage.go:33
+#: lxc/storage.go:34
msgid ""
"### This is a yaml representation of a storage pool.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -33,7 +33,7 @@ msgid ""
"### zfs.pool_name: default"
msgstr ""
-#: lxc/storage.go:50
+#: lxc/storage.go:51
msgid ""
"### This is a yaml representation of a storage volume.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -288,7 +288,7 @@ msgstr ""
msgid "Can't unset key '%s', it's not currently set."
msgstr ""
-#: lxc/profile.go:546 lxc/storage.go:653
+#: lxc/profile.go:546 lxc/storage.go:675
msgid "Cannot provide container name to list"
msgstr ""
@@ -313,8 +313,12 @@ msgstr ""
msgid "Config key/value to apply to the new container"
msgstr ""
+#: lxc/storage.go:158
+msgid "Config key/value to apply to the new storage volume"
+msgstr ""
+
#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190
-#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:604 lxc/storage.go:979
+#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:626 lxc/storage.go:1058
#, c-format
msgid "Config parsing error: %s"
msgstr ""
@@ -381,11 +385,11 @@ msgid "Creating the container"
msgstr ""
#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525
-#: lxc/storage.go:682 lxc/storage.go:793
+#: lxc/storage.go:704 lxc/storage.go:819
msgid "DESCRIPTION"
msgstr ""
-#: lxc/storage.go:683
+#: lxc/storage.go:705
msgid "DRIVER"
msgstr ""
@@ -698,7 +702,7 @@ msgstr ""
msgid "Missing summary."
msgstr ""
-#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:402 lxc/storage.go:522
+#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:424 lxc/storage.go:544
msgid "More than one device matches, specify the device name."
msgstr ""
@@ -719,7 +723,7 @@ msgid "Must supply container name for: "
msgstr ""
#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409
-#: lxc/storage.go:681 lxc/storage.go:792
+#: lxc/storage.go:703 lxc/storage.go:818
msgid "NAME"
msgstr ""
@@ -767,7 +771,7 @@ msgstr ""
msgid "No device found for this network"
msgstr ""
-#: lxc/storage.go:411 lxc/storage.go:531
+#: lxc/storage.go:433 lxc/storage.go:553
msgid "No device found for this storage volume."
msgstr ""
@@ -775,7 +779,7 @@ msgstr ""
msgid "No fingerprint specified."
msgstr ""
-#: lxc/storage.go:355 lxc/storage.go:448
+#: lxc/storage.go:377 lxc/storage.go:470
msgid "Only \"custom\" volumes can be attached to containers."
msgstr ""
@@ -857,7 +861,7 @@ msgstr ""
msgid "Pid: %d"
msgstr ""
-#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:605 lxc/storage.go:980
+#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:627 lxc/storage.go:1059
msgid "Press enter to open the editor again"
msgstr ""
@@ -966,7 +970,7 @@ msgstr ""
msgid "Remove %s (yes/no): "
msgstr ""
-#: lxc/storage.go:1011
+#: lxc/storage.go:1090
#, c-format
msgid "Renamed storage volume from \"%s\" to \"%s\""
msgstr ""
@@ -1004,7 +1008,7 @@ msgstr ""
msgid "SNAPSHOTS"
msgstr ""
-#: lxc/storage.go:684
+#: lxc/storage.go:706
msgid "SOURCE"
msgstr ""
@@ -1072,7 +1076,7 @@ msgstr ""
msgid "Show the resources available to the server"
msgstr ""
-#: lxc/storage.go:151
+#: lxc/storage.go:159
msgid "Show the resources available to the storage pool"
msgstr ""
@@ -1125,12 +1129,12 @@ msgstr ""
msgid "Stopping the container failed: %s"
msgstr ""
-#: lxc/storage.go:496
+#: lxc/storage.go:518
#, c-format
msgid "Storage pool %s created"
msgstr ""
-#: lxc/storage.go:555
+#: lxc/storage.go:577
#, c-format
msgid "Storage pool %s deleted"
msgstr ""
@@ -1139,12 +1143,12 @@ msgstr ""
msgid "Storage pool name"
msgstr ""
-#: lxc/storage.go:826
+#: lxc/storage.go:852
#, c-format
msgid "Storage volume %s created"
msgstr ""
-#: lxc/storage.go:841
+#: lxc/storage.go:867
#, c-format
msgid "Storage volume %s deleted"
msgstr ""
@@ -1161,7 +1165,7 @@ msgstr ""
msgid "Swap (peak)"
msgstr ""
-#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:791
+#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:817
msgid "TYPE"
msgstr ""
@@ -1197,7 +1201,7 @@ msgstr ""
msgid "The opposite of \"lxc pause\" is \"lxc start\"."
msgstr ""
-#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:416 lxc/storage.go:536
+#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:438 lxc/storage.go:558
msgid "The specified device doesn't exist"
msgstr ""
@@ -1276,7 +1280,7 @@ msgstr ""
msgid "URL"
msgstr ""
-#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:685 lxc/storage.go:794
+#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:707 lxc/storage.go:820
msgid "USED BY"
msgstr ""
@@ -2035,7 +2039,7 @@ msgid ""
" Create a snapshot of \"u1\" called \"snap0\"."
msgstr ""
-#: lxc/storage.go:64
+#: lxc/storage.go:65
msgid ""
"Usage: lxc storage <subcommand> [options]\n"
"\n"
@@ -2110,7 +2114,14 @@ msgid ""
"\n"
"lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> "
"[device name]\n"
-" Detach a storage volume from the specified profile.\n"
+"\tDetach a storage volume from the specified profile.\n"
+"\n"
+"lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c "
+"<key=value>...]\n"
+" Copy an existing volume to a new volume at the specified pool.\n"
+"\n"
+"lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>\n"
+" Move an existing volume to the specified pool.\n"
"\n"
"Unless specified through a prefix, all volume operations affect \"custom"
"\" (user created) volumes.\n"
diff --git a/po/pl.po b/po/pl.po
index 3b311bcea..e13462c6b 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: lxd\n"
"Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-01-11 17:16-0500\n"
+"POT-Creation-Date: 2018-01-16 11:17+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: lxc/storage.go:33
+#: lxc/storage.go:34
msgid ""
"### This is a yaml representation of a storage pool.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -33,7 +33,7 @@ msgid ""
"### zfs.pool_name: default"
msgstr ""
-#: lxc/storage.go:50
+#: lxc/storage.go:51
msgid ""
"### This is a yaml representation of a storage volume.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -288,7 +288,7 @@ msgstr ""
msgid "Can't unset key '%s', it's not currently set."
msgstr ""
-#: lxc/profile.go:546 lxc/storage.go:653
+#: lxc/profile.go:546 lxc/storage.go:675
msgid "Cannot provide container name to list"
msgstr ""
@@ -313,8 +313,12 @@ msgstr ""
msgid "Config key/value to apply to the new container"
msgstr ""
+#: lxc/storage.go:158
+msgid "Config key/value to apply to the new storage volume"
+msgstr ""
+
#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190
-#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:604 lxc/storage.go:979
+#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:626 lxc/storage.go:1058
#, c-format
msgid "Config parsing error: %s"
msgstr ""
@@ -381,11 +385,11 @@ msgid "Creating the container"
msgstr ""
#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525
-#: lxc/storage.go:682 lxc/storage.go:793
+#: lxc/storage.go:704 lxc/storage.go:819
msgid "DESCRIPTION"
msgstr ""
-#: lxc/storage.go:683
+#: lxc/storage.go:705
msgid "DRIVER"
msgstr ""
@@ -698,7 +702,7 @@ msgstr ""
msgid "Missing summary."
msgstr ""
-#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:402 lxc/storage.go:522
+#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:424 lxc/storage.go:544
msgid "More than one device matches, specify the device name."
msgstr ""
@@ -719,7 +723,7 @@ msgid "Must supply container name for: "
msgstr ""
#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409
-#: lxc/storage.go:681 lxc/storage.go:792
+#: lxc/storage.go:703 lxc/storage.go:818
msgid "NAME"
msgstr ""
@@ -767,7 +771,7 @@ msgstr ""
msgid "No device found for this network"
msgstr ""
-#: lxc/storage.go:411 lxc/storage.go:531
+#: lxc/storage.go:433 lxc/storage.go:553
msgid "No device found for this storage volume."
msgstr ""
@@ -775,7 +779,7 @@ msgstr ""
msgid "No fingerprint specified."
msgstr ""
-#: lxc/storage.go:355 lxc/storage.go:448
+#: lxc/storage.go:377 lxc/storage.go:470
msgid "Only \"custom\" volumes can be attached to containers."
msgstr ""
@@ -857,7 +861,7 @@ msgstr ""
msgid "Pid: %d"
msgstr ""
-#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:605 lxc/storage.go:980
+#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:627 lxc/storage.go:1059
msgid "Press enter to open the editor again"
msgstr ""
@@ -966,7 +970,7 @@ msgstr ""
msgid "Remove %s (yes/no): "
msgstr ""
-#: lxc/storage.go:1011
+#: lxc/storage.go:1090
#, c-format
msgid "Renamed storage volume from \"%s\" to \"%s\""
msgstr ""
@@ -1004,7 +1008,7 @@ msgstr ""
msgid "SNAPSHOTS"
msgstr ""
-#: lxc/storage.go:684
+#: lxc/storage.go:706
msgid "SOURCE"
msgstr ""
@@ -1072,7 +1076,7 @@ msgstr ""
msgid "Show the resources available to the server"
msgstr ""
-#: lxc/storage.go:151
+#: lxc/storage.go:159
msgid "Show the resources available to the storage pool"
msgstr ""
@@ -1125,12 +1129,12 @@ msgstr ""
msgid "Stopping the container failed: %s"
msgstr ""
-#: lxc/storage.go:496
+#: lxc/storage.go:518
#, c-format
msgid "Storage pool %s created"
msgstr ""
-#: lxc/storage.go:555
+#: lxc/storage.go:577
#, c-format
msgid "Storage pool %s deleted"
msgstr ""
@@ -1139,12 +1143,12 @@ msgstr ""
msgid "Storage pool name"
msgstr ""
-#: lxc/storage.go:826
+#: lxc/storage.go:852
#, c-format
msgid "Storage volume %s created"
msgstr ""
-#: lxc/storage.go:841
+#: lxc/storage.go:867
#, c-format
msgid "Storage volume %s deleted"
msgstr ""
@@ -1161,7 +1165,7 @@ msgstr ""
msgid "Swap (peak)"
msgstr ""
-#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:791
+#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:817
msgid "TYPE"
msgstr ""
@@ -1197,7 +1201,7 @@ msgstr ""
msgid "The opposite of \"lxc pause\" is \"lxc start\"."
msgstr ""
-#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:416 lxc/storage.go:536
+#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:438 lxc/storage.go:558
msgid "The specified device doesn't exist"
msgstr ""
@@ -1276,7 +1280,7 @@ msgstr ""
msgid "URL"
msgstr ""
-#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:685 lxc/storage.go:794
+#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:707 lxc/storage.go:820
msgid "USED BY"
msgstr ""
@@ -2035,7 +2039,7 @@ msgid ""
" Create a snapshot of \"u1\" called \"snap0\"."
msgstr ""
-#: lxc/storage.go:64
+#: lxc/storage.go:65
msgid ""
"Usage: lxc storage <subcommand> [options]\n"
"\n"
@@ -2110,7 +2114,14 @@ msgid ""
"\n"
"lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> "
"[device name]\n"
-" Detach a storage volume from the specified profile.\n"
+"\tDetach a storage volume from the specified profile.\n"
+"\n"
+"lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c "
+"<key=value>...]\n"
+" Copy an existing volume to a new volume at the specified pool.\n"
+"\n"
+"lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>\n"
+" Move an existing volume to the specified pool.\n"
"\n"
"Unless specified through a prefix, all volume operations affect \"custom"
"\" (user created) volumes.\n"
diff --git a/po/pt_BR.po b/po/pt_BR.po
index c983b3390..9dd9f611c 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: lxd\n"
"Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-01-11 17:16-0500\n"
+"POT-Creation-Date: 2018-01-16 11:17+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: lxc/storage.go:33
+#: lxc/storage.go:34
msgid ""
"### This is a yaml representation of a storage pool.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -33,7 +33,7 @@ msgid ""
"### zfs.pool_name: default"
msgstr ""
-#: lxc/storage.go:50
+#: lxc/storage.go:51
msgid ""
"### This is a yaml representation of a storage volume.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -288,7 +288,7 @@ msgstr ""
msgid "Can't unset key '%s', it's not currently set."
msgstr ""
-#: lxc/profile.go:546 lxc/storage.go:653
+#: lxc/profile.go:546 lxc/storage.go:675
msgid "Cannot provide container name to list"
msgstr ""
@@ -313,8 +313,12 @@ msgstr ""
msgid "Config key/value to apply to the new container"
msgstr ""
+#: lxc/storage.go:158
+msgid "Config key/value to apply to the new storage volume"
+msgstr ""
+
#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190
-#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:604 lxc/storage.go:979
+#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:626 lxc/storage.go:1058
#, c-format
msgid "Config parsing error: %s"
msgstr ""
@@ -381,11 +385,11 @@ msgid "Creating the container"
msgstr ""
#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525
-#: lxc/storage.go:682 lxc/storage.go:793
+#: lxc/storage.go:704 lxc/storage.go:819
msgid "DESCRIPTION"
msgstr ""
-#: lxc/storage.go:683
+#: lxc/storage.go:705
msgid "DRIVER"
msgstr ""
@@ -698,7 +702,7 @@ msgstr ""
msgid "Missing summary."
msgstr ""
-#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:402 lxc/storage.go:522
+#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:424 lxc/storage.go:544
msgid "More than one device matches, specify the device name."
msgstr ""
@@ -719,7 +723,7 @@ msgid "Must supply container name for: "
msgstr ""
#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409
-#: lxc/storage.go:681 lxc/storage.go:792
+#: lxc/storage.go:703 lxc/storage.go:818
msgid "NAME"
msgstr ""
@@ -767,7 +771,7 @@ msgstr ""
msgid "No device found for this network"
msgstr ""
-#: lxc/storage.go:411 lxc/storage.go:531
+#: lxc/storage.go:433 lxc/storage.go:553
msgid "No device found for this storage volume."
msgstr ""
@@ -775,7 +779,7 @@ msgstr ""
msgid "No fingerprint specified."
msgstr ""
-#: lxc/storage.go:355 lxc/storage.go:448
+#: lxc/storage.go:377 lxc/storage.go:470
msgid "Only \"custom\" volumes can be attached to containers."
msgstr ""
@@ -857,7 +861,7 @@ msgstr ""
msgid "Pid: %d"
msgstr ""
-#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:605 lxc/storage.go:980
+#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:627 lxc/storage.go:1059
msgid "Press enter to open the editor again"
msgstr ""
@@ -966,7 +970,7 @@ msgstr ""
msgid "Remove %s (yes/no): "
msgstr ""
-#: lxc/storage.go:1011
+#: lxc/storage.go:1090
#, c-format
msgid "Renamed storage volume from \"%s\" to \"%s\""
msgstr ""
@@ -1004,7 +1008,7 @@ msgstr ""
msgid "SNAPSHOTS"
msgstr ""
-#: lxc/storage.go:684
+#: lxc/storage.go:706
msgid "SOURCE"
msgstr ""
@@ -1072,7 +1076,7 @@ msgstr ""
msgid "Show the resources available to the server"
msgstr ""
-#: lxc/storage.go:151
+#: lxc/storage.go:159
msgid "Show the resources available to the storage pool"
msgstr ""
@@ -1125,12 +1129,12 @@ msgstr ""
msgid "Stopping the container failed: %s"
msgstr ""
-#: lxc/storage.go:496
+#: lxc/storage.go:518
#, c-format
msgid "Storage pool %s created"
msgstr ""
-#: lxc/storage.go:555
+#: lxc/storage.go:577
#, c-format
msgid "Storage pool %s deleted"
msgstr ""
@@ -1139,12 +1143,12 @@ msgstr ""
msgid "Storage pool name"
msgstr ""
-#: lxc/storage.go:826
+#: lxc/storage.go:852
#, c-format
msgid "Storage volume %s created"
msgstr ""
-#: lxc/storage.go:841
+#: lxc/storage.go:867
#, c-format
msgid "Storage volume %s deleted"
msgstr ""
@@ -1161,7 +1165,7 @@ msgstr ""
msgid "Swap (peak)"
msgstr ""
-#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:791
+#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:817
msgid "TYPE"
msgstr ""
@@ -1197,7 +1201,7 @@ msgstr ""
msgid "The opposite of \"lxc pause\" is \"lxc start\"."
msgstr ""
-#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:416 lxc/storage.go:536
+#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:438 lxc/storage.go:558
msgid "The specified device doesn't exist"
msgstr ""
@@ -1276,7 +1280,7 @@ msgstr ""
msgid "URL"
msgstr ""
-#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:685 lxc/storage.go:794
+#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:707 lxc/storage.go:820
msgid "USED BY"
msgstr ""
@@ -2035,7 +2039,7 @@ msgid ""
" Create a snapshot of \"u1\" called \"snap0\"."
msgstr ""
-#: lxc/storage.go:64
+#: lxc/storage.go:65
msgid ""
"Usage: lxc storage <subcommand> [options]\n"
"\n"
@@ -2110,7 +2114,14 @@ msgid ""
"\n"
"lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> "
"[device name]\n"
-" Detach a storage volume from the specified profile.\n"
+"\tDetach a storage volume from the specified profile.\n"
+"\n"
+"lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c "
+"<key=value>...]\n"
+" Copy an existing volume to a new volume at the specified pool.\n"
+"\n"
+"lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>\n"
+" Move an existing volume to the specified pool.\n"
"\n"
"Unless specified through a prefix, all volume operations affect \"custom"
"\" (user created) volumes.\n"
diff --git a/po/ru.po b/po/ru.po
index 986d4b729..60920b371 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: lxd\n"
"Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-01-11 17:16-0500\n"
+"POT-Creation-Date: 2018-01-16 11:17+0100\n"
"PO-Revision-Date: 2017-09-05 16:48+0000\n"
"Last-Translator: Ilya Yakimavets <ilya.yakimavets at backend.expert>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/linux-containers/"
@@ -20,7 +20,7 @@ msgstr ""
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Generator: Weblate 2.17-dev\n"
-#: lxc/storage.go:33
+#: lxc/storage.go:34
msgid ""
"### This is a yaml representation of a storage pool.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -50,7 +50,7 @@ msgstr ""
"### source: /home/chb/mnt/lxd_test/default.img\n"
"### zfs.pool_name: default"
-#: lxc/storage.go:50
+#: lxc/storage.go:51
msgid ""
"### This is a yaml representation of a storage volume.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -376,7 +376,7 @@ msgstr ""
msgid "Can't unset key '%s', it's not currently set."
msgstr ""
-#: lxc/profile.go:546 lxc/storage.go:653
+#: lxc/profile.go:546 lxc/storage.go:675
msgid "Cannot provide container name to list"
msgstr "Невозможно добавить имя контейнера в список"
@@ -401,8 +401,12 @@ msgstr ""
msgid "Config key/value to apply to the new container"
msgstr ""
+#: lxc/storage.go:158
+msgid "Config key/value to apply to the new storage volume"
+msgstr ""
+
#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190
-#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:604 lxc/storage.go:979
+#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:626 lxc/storage.go:1058
#, c-format
msgid "Config parsing error: %s"
msgstr ""
@@ -469,11 +473,11 @@ msgid "Creating the container"
msgstr ""
#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525
-#: lxc/storage.go:682 lxc/storage.go:793
+#: lxc/storage.go:704 lxc/storage.go:819
msgid "DESCRIPTION"
msgstr ""
-#: lxc/storage.go:683
+#: lxc/storage.go:705
msgid "DRIVER"
msgstr ""
@@ -788,7 +792,7 @@ msgstr " Использование памяти:"
msgid "Missing summary."
msgstr ""
-#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:402 lxc/storage.go:522
+#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:424 lxc/storage.go:544
msgid "More than one device matches, specify the device name."
msgstr ""
@@ -809,7 +813,7 @@ msgid "Must supply container name for: "
msgstr ""
#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409
-#: lxc/storage.go:681 lxc/storage.go:792
+#: lxc/storage.go:703 lxc/storage.go:818
msgid "NAME"
msgstr ""
@@ -858,7 +862,7 @@ msgstr ""
msgid "No device found for this network"
msgstr ""
-#: lxc/storage.go:411 lxc/storage.go:531
+#: lxc/storage.go:433 lxc/storage.go:553
msgid "No device found for this storage volume."
msgstr ""
@@ -866,7 +870,7 @@ msgstr ""
msgid "No fingerprint specified."
msgstr ""
-#: lxc/storage.go:355 lxc/storage.go:448
+#: lxc/storage.go:377 lxc/storage.go:470
msgid "Only \"custom\" volumes can be attached to containers."
msgstr ""
@@ -948,7 +952,7 @@ msgstr ""
msgid "Pid: %d"
msgstr ""
-#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:605 lxc/storage.go:980
+#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:627 lxc/storage.go:1059
msgid "Press enter to open the editor again"
msgstr ""
@@ -1057,7 +1061,7 @@ msgstr ""
msgid "Remove %s (yes/no): "
msgstr ""
-#: lxc/storage.go:1011
+#: lxc/storage.go:1090
#, c-format
msgid "Renamed storage volume from \"%s\" to \"%s\""
msgstr ""
@@ -1095,7 +1099,7 @@ msgstr ""
msgid "SNAPSHOTS"
msgstr ""
-#: lxc/storage.go:684
+#: lxc/storage.go:706
msgid "SOURCE"
msgstr ""
@@ -1163,7 +1167,7 @@ msgstr ""
msgid "Show the resources available to the server"
msgstr ""
-#: lxc/storage.go:151
+#: lxc/storage.go:159
msgid "Show the resources available to the storage pool"
msgstr ""
@@ -1216,12 +1220,12 @@ msgstr ""
msgid "Stopping the container failed: %s"
msgstr "Невозможно добавить имя контейнера в список"
-#: lxc/storage.go:496
+#: lxc/storage.go:518
#, c-format
msgid "Storage pool %s created"
msgstr ""
-#: lxc/storage.go:555
+#: lxc/storage.go:577
#, c-format
msgid "Storage pool %s deleted"
msgstr ""
@@ -1230,12 +1234,12 @@ msgstr ""
msgid "Storage pool name"
msgstr ""
-#: lxc/storage.go:826
+#: lxc/storage.go:852
#, c-format
msgid "Storage volume %s created"
msgstr ""
-#: lxc/storage.go:841
+#: lxc/storage.go:867
#, c-format
msgid "Storage volume %s deleted"
msgstr ""
@@ -1252,7 +1256,7 @@ msgstr ""
msgid "Swap (peak)"
msgstr ""
-#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:791
+#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:817
msgid "TYPE"
msgstr ""
@@ -1288,7 +1292,7 @@ msgstr ""
msgid "The opposite of \"lxc pause\" is \"lxc start\"."
msgstr ""
-#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:416 lxc/storage.go:536
+#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:438 lxc/storage.go:558
msgid "The specified device doesn't exist"
msgstr ""
@@ -1367,7 +1371,7 @@ msgstr ""
msgid "URL"
msgstr ""
-#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:685 lxc/storage.go:794
+#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:707 lxc/storage.go:820
msgid "USED BY"
msgstr ""
@@ -2138,7 +2142,7 @@ msgid ""
" Create a snapshot of \"u1\" called \"snap0\"."
msgstr ""
-#: lxc/storage.go:64
+#: lxc/storage.go:65
msgid ""
"Usage: lxc storage <subcommand> [options]\n"
"\n"
@@ -2213,7 +2217,14 @@ msgid ""
"\n"
"lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> "
"[device name]\n"
-" Detach a storage volume from the specified profile.\n"
+"\tDetach a storage volume from the specified profile.\n"
+"\n"
+"lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c "
+"<key=value>...]\n"
+" Copy an existing volume to a new volume at the specified pool.\n"
+"\n"
+"lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>\n"
+" Move an existing volume to the specified pool.\n"
"\n"
"Unless specified through a prefix, all volume operations affect \"custom"
"\" (user created) volumes.\n"
diff --git a/po/sr.po b/po/sr.po
index 35da191cc..3d0b9718a 100644
--- a/po/sr.po
+++ b/po/sr.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: lxd\n"
"Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-01-11 17:16-0500\n"
+"POT-Creation-Date: 2018-01-16 11:17+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: lxc/storage.go:33
+#: lxc/storage.go:34
msgid ""
"### This is a yaml representation of a storage pool.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -33,7 +33,7 @@ msgid ""
"### zfs.pool_name: default"
msgstr ""
-#: lxc/storage.go:50
+#: lxc/storage.go:51
msgid ""
"### This is a yaml representation of a storage volume.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -288,7 +288,7 @@ msgstr ""
msgid "Can't unset key '%s', it's not currently set."
msgstr ""
-#: lxc/profile.go:546 lxc/storage.go:653
+#: lxc/profile.go:546 lxc/storage.go:675
msgid "Cannot provide container name to list"
msgstr ""
@@ -313,8 +313,12 @@ msgstr ""
msgid "Config key/value to apply to the new container"
msgstr ""
+#: lxc/storage.go:158
+msgid "Config key/value to apply to the new storage volume"
+msgstr ""
+
#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190
-#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:604 lxc/storage.go:979
+#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:626 lxc/storage.go:1058
#, c-format
msgid "Config parsing error: %s"
msgstr ""
@@ -381,11 +385,11 @@ msgid "Creating the container"
msgstr ""
#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525
-#: lxc/storage.go:682 lxc/storage.go:793
+#: lxc/storage.go:704 lxc/storage.go:819
msgid "DESCRIPTION"
msgstr ""
-#: lxc/storage.go:683
+#: lxc/storage.go:705
msgid "DRIVER"
msgstr ""
@@ -698,7 +702,7 @@ msgstr ""
msgid "Missing summary."
msgstr ""
-#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:402 lxc/storage.go:522
+#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:424 lxc/storage.go:544
msgid "More than one device matches, specify the device name."
msgstr ""
@@ -719,7 +723,7 @@ msgid "Must supply container name for: "
msgstr ""
#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409
-#: lxc/storage.go:681 lxc/storage.go:792
+#: lxc/storage.go:703 lxc/storage.go:818
msgid "NAME"
msgstr ""
@@ -767,7 +771,7 @@ msgstr ""
msgid "No device found for this network"
msgstr ""
-#: lxc/storage.go:411 lxc/storage.go:531
+#: lxc/storage.go:433 lxc/storage.go:553
msgid "No device found for this storage volume."
msgstr ""
@@ -775,7 +779,7 @@ msgstr ""
msgid "No fingerprint specified."
msgstr ""
-#: lxc/storage.go:355 lxc/storage.go:448
+#: lxc/storage.go:377 lxc/storage.go:470
msgid "Only \"custom\" volumes can be attached to containers."
msgstr ""
@@ -857,7 +861,7 @@ msgstr ""
msgid "Pid: %d"
msgstr ""
-#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:605 lxc/storage.go:980
+#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:627 lxc/storage.go:1059
msgid "Press enter to open the editor again"
msgstr ""
@@ -966,7 +970,7 @@ msgstr ""
msgid "Remove %s (yes/no): "
msgstr ""
-#: lxc/storage.go:1011
+#: lxc/storage.go:1090
#, c-format
msgid "Renamed storage volume from \"%s\" to \"%s\""
msgstr ""
@@ -1004,7 +1008,7 @@ msgstr ""
msgid "SNAPSHOTS"
msgstr ""
-#: lxc/storage.go:684
+#: lxc/storage.go:706
msgid "SOURCE"
msgstr ""
@@ -1072,7 +1076,7 @@ msgstr ""
msgid "Show the resources available to the server"
msgstr ""
-#: lxc/storage.go:151
+#: lxc/storage.go:159
msgid "Show the resources available to the storage pool"
msgstr ""
@@ -1125,12 +1129,12 @@ msgstr ""
msgid "Stopping the container failed: %s"
msgstr ""
-#: lxc/storage.go:496
+#: lxc/storage.go:518
#, c-format
msgid "Storage pool %s created"
msgstr ""
-#: lxc/storage.go:555
+#: lxc/storage.go:577
#, c-format
msgid "Storage pool %s deleted"
msgstr ""
@@ -1139,12 +1143,12 @@ msgstr ""
msgid "Storage pool name"
msgstr ""
-#: lxc/storage.go:826
+#: lxc/storage.go:852
#, c-format
msgid "Storage volume %s created"
msgstr ""
-#: lxc/storage.go:841
+#: lxc/storage.go:867
#, c-format
msgid "Storage volume %s deleted"
msgstr ""
@@ -1161,7 +1165,7 @@ msgstr ""
msgid "Swap (peak)"
msgstr ""
-#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:791
+#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:817
msgid "TYPE"
msgstr ""
@@ -1197,7 +1201,7 @@ msgstr ""
msgid "The opposite of \"lxc pause\" is \"lxc start\"."
msgstr ""
-#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:416 lxc/storage.go:536
+#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:438 lxc/storage.go:558
msgid "The specified device doesn't exist"
msgstr ""
@@ -1276,7 +1280,7 @@ msgstr ""
msgid "URL"
msgstr ""
-#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:685 lxc/storage.go:794
+#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:707 lxc/storage.go:820
msgid "USED BY"
msgstr ""
@@ -2035,7 +2039,7 @@ msgid ""
" Create a snapshot of \"u1\" called \"snap0\"."
msgstr ""
-#: lxc/storage.go:64
+#: lxc/storage.go:65
msgid ""
"Usage: lxc storage <subcommand> [options]\n"
"\n"
@@ -2110,7 +2114,14 @@ msgid ""
"\n"
"lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> "
"[device name]\n"
-" Detach a storage volume from the specified profile.\n"
+"\tDetach a storage volume from the specified profile.\n"
+"\n"
+"lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c "
+"<key=value>...]\n"
+" Copy an existing volume to a new volume at the specified pool.\n"
+"\n"
+"lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>\n"
+" Move an existing volume to the specified pool.\n"
"\n"
"Unless specified through a prefix, all volume operations affect \"custom"
"\" (user created) volumes.\n"
diff --git a/po/sv.po b/po/sv.po
index 669bfc3b1..1a7c3c449 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: lxd\n"
"Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-01-11 17:16-0500\n"
+"POT-Creation-Date: 2018-01-16 11:17+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: lxc/storage.go:33
+#: lxc/storage.go:34
msgid ""
"### This is a yaml representation of a storage pool.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -33,7 +33,7 @@ msgid ""
"### zfs.pool_name: default"
msgstr ""
-#: lxc/storage.go:50
+#: lxc/storage.go:51
msgid ""
"### This is a yaml representation of a storage volume.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -288,7 +288,7 @@ msgstr ""
msgid "Can't unset key '%s', it's not currently set."
msgstr ""
-#: lxc/profile.go:546 lxc/storage.go:653
+#: lxc/profile.go:546 lxc/storage.go:675
msgid "Cannot provide container name to list"
msgstr ""
@@ -313,8 +313,12 @@ msgstr ""
msgid "Config key/value to apply to the new container"
msgstr ""
+#: lxc/storage.go:158
+msgid "Config key/value to apply to the new storage volume"
+msgstr ""
+
#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190
-#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:604 lxc/storage.go:979
+#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:626 lxc/storage.go:1058
#, c-format
msgid "Config parsing error: %s"
msgstr ""
@@ -381,11 +385,11 @@ msgid "Creating the container"
msgstr ""
#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525
-#: lxc/storage.go:682 lxc/storage.go:793
+#: lxc/storage.go:704 lxc/storage.go:819
msgid "DESCRIPTION"
msgstr ""
-#: lxc/storage.go:683
+#: lxc/storage.go:705
msgid "DRIVER"
msgstr ""
@@ -698,7 +702,7 @@ msgstr ""
msgid "Missing summary."
msgstr ""
-#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:402 lxc/storage.go:522
+#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:424 lxc/storage.go:544
msgid "More than one device matches, specify the device name."
msgstr ""
@@ -719,7 +723,7 @@ msgid "Must supply container name for: "
msgstr ""
#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409
-#: lxc/storage.go:681 lxc/storage.go:792
+#: lxc/storage.go:703 lxc/storage.go:818
msgid "NAME"
msgstr ""
@@ -767,7 +771,7 @@ msgstr ""
msgid "No device found for this network"
msgstr ""
-#: lxc/storage.go:411 lxc/storage.go:531
+#: lxc/storage.go:433 lxc/storage.go:553
msgid "No device found for this storage volume."
msgstr ""
@@ -775,7 +779,7 @@ msgstr ""
msgid "No fingerprint specified."
msgstr ""
-#: lxc/storage.go:355 lxc/storage.go:448
+#: lxc/storage.go:377 lxc/storage.go:470
msgid "Only \"custom\" volumes can be attached to containers."
msgstr ""
@@ -857,7 +861,7 @@ msgstr ""
msgid "Pid: %d"
msgstr ""
-#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:605 lxc/storage.go:980
+#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:627 lxc/storage.go:1059
msgid "Press enter to open the editor again"
msgstr ""
@@ -966,7 +970,7 @@ msgstr ""
msgid "Remove %s (yes/no): "
msgstr ""
-#: lxc/storage.go:1011
+#: lxc/storage.go:1090
#, c-format
msgid "Renamed storage volume from \"%s\" to \"%s\""
msgstr ""
@@ -1004,7 +1008,7 @@ msgstr ""
msgid "SNAPSHOTS"
msgstr ""
-#: lxc/storage.go:684
+#: lxc/storage.go:706
msgid "SOURCE"
msgstr ""
@@ -1072,7 +1076,7 @@ msgstr ""
msgid "Show the resources available to the server"
msgstr ""
-#: lxc/storage.go:151
+#: lxc/storage.go:159
msgid "Show the resources available to the storage pool"
msgstr ""
@@ -1125,12 +1129,12 @@ msgstr ""
msgid "Stopping the container failed: %s"
msgstr ""
-#: lxc/storage.go:496
+#: lxc/storage.go:518
#, c-format
msgid "Storage pool %s created"
msgstr ""
-#: lxc/storage.go:555
+#: lxc/storage.go:577
#, c-format
msgid "Storage pool %s deleted"
msgstr ""
@@ -1139,12 +1143,12 @@ msgstr ""
msgid "Storage pool name"
msgstr ""
-#: lxc/storage.go:826
+#: lxc/storage.go:852
#, c-format
msgid "Storage volume %s created"
msgstr ""
-#: lxc/storage.go:841
+#: lxc/storage.go:867
#, c-format
msgid "Storage volume %s deleted"
msgstr ""
@@ -1161,7 +1165,7 @@ msgstr ""
msgid "Swap (peak)"
msgstr ""
-#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:791
+#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:817
msgid "TYPE"
msgstr ""
@@ -1197,7 +1201,7 @@ msgstr ""
msgid "The opposite of \"lxc pause\" is \"lxc start\"."
msgstr ""
-#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:416 lxc/storage.go:536
+#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:438 lxc/storage.go:558
msgid "The specified device doesn't exist"
msgstr ""
@@ -1276,7 +1280,7 @@ msgstr ""
msgid "URL"
msgstr ""
-#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:685 lxc/storage.go:794
+#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:707 lxc/storage.go:820
msgid "USED BY"
msgstr ""
@@ -2035,7 +2039,7 @@ msgid ""
" Create a snapshot of \"u1\" called \"snap0\"."
msgstr ""
-#: lxc/storage.go:64
+#: lxc/storage.go:65
msgid ""
"Usage: lxc storage <subcommand> [options]\n"
"\n"
@@ -2110,7 +2114,14 @@ msgid ""
"\n"
"lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> "
"[device name]\n"
-" Detach a storage volume from the specified profile.\n"
+"\tDetach a storage volume from the specified profile.\n"
+"\n"
+"lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c "
+"<key=value>...]\n"
+" Copy an existing volume to a new volume at the specified pool.\n"
+"\n"
+"lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>\n"
+" Move an existing volume to the specified pool.\n"
"\n"
"Unless specified through a prefix, all volume operations affect \"custom"
"\" (user created) volumes.\n"
diff --git a/po/tr.po b/po/tr.po
index d39f14de5..5dbdaefe9 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: lxd\n"
"Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-01-11 17:16-0500\n"
+"POT-Creation-Date: 2018-01-16 11:17+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: lxc/storage.go:33
+#: lxc/storage.go:34
msgid ""
"### This is a yaml representation of a storage pool.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -33,7 +33,7 @@ msgid ""
"### zfs.pool_name: default"
msgstr ""
-#: lxc/storage.go:50
+#: lxc/storage.go:51
msgid ""
"### This is a yaml representation of a storage volume.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -288,7 +288,7 @@ msgstr ""
msgid "Can't unset key '%s', it's not currently set."
msgstr ""
-#: lxc/profile.go:546 lxc/storage.go:653
+#: lxc/profile.go:546 lxc/storage.go:675
msgid "Cannot provide container name to list"
msgstr ""
@@ -313,8 +313,12 @@ msgstr ""
msgid "Config key/value to apply to the new container"
msgstr ""
+#: lxc/storage.go:158
+msgid "Config key/value to apply to the new storage volume"
+msgstr ""
+
#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190
-#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:604 lxc/storage.go:979
+#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:626 lxc/storage.go:1058
#, c-format
msgid "Config parsing error: %s"
msgstr ""
@@ -381,11 +385,11 @@ msgid "Creating the container"
msgstr ""
#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525
-#: lxc/storage.go:682 lxc/storage.go:793
+#: lxc/storage.go:704 lxc/storage.go:819
msgid "DESCRIPTION"
msgstr ""
-#: lxc/storage.go:683
+#: lxc/storage.go:705
msgid "DRIVER"
msgstr ""
@@ -698,7 +702,7 @@ msgstr ""
msgid "Missing summary."
msgstr ""
-#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:402 lxc/storage.go:522
+#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:424 lxc/storage.go:544
msgid "More than one device matches, specify the device name."
msgstr ""
@@ -719,7 +723,7 @@ msgid "Must supply container name for: "
msgstr ""
#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409
-#: lxc/storage.go:681 lxc/storage.go:792
+#: lxc/storage.go:703 lxc/storage.go:818
msgid "NAME"
msgstr ""
@@ -767,7 +771,7 @@ msgstr ""
msgid "No device found for this network"
msgstr ""
-#: lxc/storage.go:411 lxc/storage.go:531
+#: lxc/storage.go:433 lxc/storage.go:553
msgid "No device found for this storage volume."
msgstr ""
@@ -775,7 +779,7 @@ msgstr ""
msgid "No fingerprint specified."
msgstr ""
-#: lxc/storage.go:355 lxc/storage.go:448
+#: lxc/storage.go:377 lxc/storage.go:470
msgid "Only \"custom\" volumes can be attached to containers."
msgstr ""
@@ -857,7 +861,7 @@ msgstr ""
msgid "Pid: %d"
msgstr ""
-#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:605 lxc/storage.go:980
+#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:627 lxc/storage.go:1059
msgid "Press enter to open the editor again"
msgstr ""
@@ -966,7 +970,7 @@ msgstr ""
msgid "Remove %s (yes/no): "
msgstr ""
-#: lxc/storage.go:1011
+#: lxc/storage.go:1090
#, c-format
msgid "Renamed storage volume from \"%s\" to \"%s\""
msgstr ""
@@ -1004,7 +1008,7 @@ msgstr ""
msgid "SNAPSHOTS"
msgstr ""
-#: lxc/storage.go:684
+#: lxc/storage.go:706
msgid "SOURCE"
msgstr ""
@@ -1072,7 +1076,7 @@ msgstr ""
msgid "Show the resources available to the server"
msgstr ""
-#: lxc/storage.go:151
+#: lxc/storage.go:159
msgid "Show the resources available to the storage pool"
msgstr ""
@@ -1125,12 +1129,12 @@ msgstr ""
msgid "Stopping the container failed: %s"
msgstr ""
-#: lxc/storage.go:496
+#: lxc/storage.go:518
#, c-format
msgid "Storage pool %s created"
msgstr ""
-#: lxc/storage.go:555
+#: lxc/storage.go:577
#, c-format
msgid "Storage pool %s deleted"
msgstr ""
@@ -1139,12 +1143,12 @@ msgstr ""
msgid "Storage pool name"
msgstr ""
-#: lxc/storage.go:826
+#: lxc/storage.go:852
#, c-format
msgid "Storage volume %s created"
msgstr ""
-#: lxc/storage.go:841
+#: lxc/storage.go:867
#, c-format
msgid "Storage volume %s deleted"
msgstr ""
@@ -1161,7 +1165,7 @@ msgstr ""
msgid "Swap (peak)"
msgstr ""
-#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:791
+#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:817
msgid "TYPE"
msgstr ""
@@ -1197,7 +1201,7 @@ msgstr ""
msgid "The opposite of \"lxc pause\" is \"lxc start\"."
msgstr ""
-#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:416 lxc/storage.go:536
+#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:438 lxc/storage.go:558
msgid "The specified device doesn't exist"
msgstr ""
@@ -1276,7 +1280,7 @@ msgstr ""
msgid "URL"
msgstr ""
-#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:685 lxc/storage.go:794
+#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:707 lxc/storage.go:820
msgid "USED BY"
msgstr ""
@@ -2035,7 +2039,7 @@ msgid ""
" Create a snapshot of \"u1\" called \"snap0\"."
msgstr ""
-#: lxc/storage.go:64
+#: lxc/storage.go:65
msgid ""
"Usage: lxc storage <subcommand> [options]\n"
"\n"
@@ -2110,7 +2114,14 @@ msgid ""
"\n"
"lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> "
"[device name]\n"
-" Detach a storage volume from the specified profile.\n"
+"\tDetach a storage volume from the specified profile.\n"
+"\n"
+"lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c "
+"<key=value>...]\n"
+" Copy an existing volume to a new volume at the specified pool.\n"
+"\n"
+"lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>\n"
+" Move an existing volume to the specified pool.\n"
"\n"
"Unless specified through a prefix, all volume operations affect \"custom"
"\" (user created) volumes.\n"
diff --git a/po/zh.po b/po/zh.po
index 68969e136..2b1d8ee9b 100644
--- a/po/zh.po
+++ b/po/zh.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: lxd\n"
"Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-01-11 17:16-0500\n"
+"POT-Creation-Date: 2018-01-16 11:17+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: lxc/storage.go:33
+#: lxc/storage.go:34
msgid ""
"### This is a yaml representation of a storage pool.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -33,7 +33,7 @@ msgid ""
"### zfs.pool_name: default"
msgstr ""
-#: lxc/storage.go:50
+#: lxc/storage.go:51
msgid ""
"### This is a yaml representation of a storage volume.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -288,7 +288,7 @@ msgstr ""
msgid "Can't unset key '%s', it's not currently set."
msgstr ""
-#: lxc/profile.go:546 lxc/storage.go:653
+#: lxc/profile.go:546 lxc/storage.go:675
msgid "Cannot provide container name to list"
msgstr ""
@@ -313,8 +313,12 @@ msgstr ""
msgid "Config key/value to apply to the new container"
msgstr ""
+#: lxc/storage.go:158
+msgid "Config key/value to apply to the new storage volume"
+msgstr ""
+
#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190
-#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:604 lxc/storage.go:979
+#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:626 lxc/storage.go:1058
#, c-format
msgid "Config parsing error: %s"
msgstr ""
@@ -381,11 +385,11 @@ msgid "Creating the container"
msgstr ""
#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525
-#: lxc/storage.go:682 lxc/storage.go:793
+#: lxc/storage.go:704 lxc/storage.go:819
msgid "DESCRIPTION"
msgstr ""
-#: lxc/storage.go:683
+#: lxc/storage.go:705
msgid "DRIVER"
msgstr ""
@@ -698,7 +702,7 @@ msgstr ""
msgid "Missing summary."
msgstr ""
-#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:402 lxc/storage.go:522
+#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:424 lxc/storage.go:544
msgid "More than one device matches, specify the device name."
msgstr ""
@@ -719,7 +723,7 @@ msgid "Must supply container name for: "
msgstr ""
#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409
-#: lxc/storage.go:681 lxc/storage.go:792
+#: lxc/storage.go:703 lxc/storage.go:818
msgid "NAME"
msgstr ""
@@ -767,7 +771,7 @@ msgstr ""
msgid "No device found for this network"
msgstr ""
-#: lxc/storage.go:411 lxc/storage.go:531
+#: lxc/storage.go:433 lxc/storage.go:553
msgid "No device found for this storage volume."
msgstr ""
@@ -775,7 +779,7 @@ msgstr ""
msgid "No fingerprint specified."
msgstr ""
-#: lxc/storage.go:355 lxc/storage.go:448
+#: lxc/storage.go:377 lxc/storage.go:470
msgid "Only \"custom\" volumes can be attached to containers."
msgstr ""
@@ -857,7 +861,7 @@ msgstr ""
msgid "Pid: %d"
msgstr ""
-#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:605 lxc/storage.go:980
+#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:627 lxc/storage.go:1059
msgid "Press enter to open the editor again"
msgstr ""
@@ -966,7 +970,7 @@ msgstr ""
msgid "Remove %s (yes/no): "
msgstr ""
-#: lxc/storage.go:1011
+#: lxc/storage.go:1090
#, c-format
msgid "Renamed storage volume from \"%s\" to \"%s\""
msgstr ""
@@ -1004,7 +1008,7 @@ msgstr ""
msgid "SNAPSHOTS"
msgstr ""
-#: lxc/storage.go:684
+#: lxc/storage.go:706
msgid "SOURCE"
msgstr ""
@@ -1072,7 +1076,7 @@ msgstr ""
msgid "Show the resources available to the server"
msgstr ""
-#: lxc/storage.go:151
+#: lxc/storage.go:159
msgid "Show the resources available to the storage pool"
msgstr ""
@@ -1125,12 +1129,12 @@ msgstr ""
msgid "Stopping the container failed: %s"
msgstr ""
-#: lxc/storage.go:496
+#: lxc/storage.go:518
#, c-format
msgid "Storage pool %s created"
msgstr ""
-#: lxc/storage.go:555
+#: lxc/storage.go:577
#, c-format
msgid "Storage pool %s deleted"
msgstr ""
@@ -1139,12 +1143,12 @@ msgstr ""
msgid "Storage pool name"
msgstr ""
-#: lxc/storage.go:826
+#: lxc/storage.go:852
#, c-format
msgid "Storage volume %s created"
msgstr ""
-#: lxc/storage.go:841
+#: lxc/storage.go:867
#, c-format
msgid "Storage volume %s deleted"
msgstr ""
@@ -1161,7 +1165,7 @@ msgstr ""
msgid "Swap (peak)"
msgstr ""
-#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:791
+#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:817
msgid "TYPE"
msgstr ""
@@ -1197,7 +1201,7 @@ msgstr ""
msgid "The opposite of \"lxc pause\" is \"lxc start\"."
msgstr ""
-#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:416 lxc/storage.go:536
+#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:438 lxc/storage.go:558
msgid "The specified device doesn't exist"
msgstr ""
@@ -1276,7 +1280,7 @@ msgstr ""
msgid "URL"
msgstr ""
-#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:685 lxc/storage.go:794
+#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:707 lxc/storage.go:820
msgid "USED BY"
msgstr ""
@@ -2035,7 +2039,7 @@ msgid ""
" Create a snapshot of \"u1\" called \"snap0\"."
msgstr ""
-#: lxc/storage.go:64
+#: lxc/storage.go:65
msgid ""
"Usage: lxc storage <subcommand> [options]\n"
"\n"
@@ -2110,7 +2114,14 @@ msgid ""
"\n"
"lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> "
"[device name]\n"
-" Detach a storage volume from the specified profile.\n"
+"\tDetach a storage volume from the specified profile.\n"
+"\n"
+"lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c "
+"<key=value>...]\n"
+" Copy an existing volume to a new volume at the specified pool.\n"
+"\n"
+"lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>\n"
+" Move an existing volume to the specified pool.\n"
"\n"
"Unless specified through a prefix, all volume operations affect \"custom"
"\" (user created) volumes.\n"
diff --git a/po/zh_Hans.po b/po/zh_Hans.po
index 44a51efcf..6970e1015 100644
--- a/po/zh_Hans.po
+++ b/po/zh_Hans.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: lxd\n"
"Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-"POT-Creation-Date: 2018-01-11 17:16-0500\n"
+"POT-Creation-Date: 2018-01-16 11:17+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: lxc/storage.go:33
+#: lxc/storage.go:34
msgid ""
"### This is a yaml representation of a storage pool.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -33,7 +33,7 @@ msgid ""
"### zfs.pool_name: default"
msgstr ""
-#: lxc/storage.go:50
+#: lxc/storage.go:51
msgid ""
"### This is a yaml representation of a storage volume.\n"
"### Any line starting with a '# will be ignored.\n"
@@ -288,7 +288,7 @@ msgstr ""
msgid "Can't unset key '%s', it's not currently set."
msgstr ""
-#: lxc/profile.go:546 lxc/storage.go:653
+#: lxc/profile.go:546 lxc/storage.go:675
msgid "Cannot provide container name to list"
msgstr ""
@@ -313,8 +313,12 @@ msgstr ""
msgid "Config key/value to apply to the new container"
msgstr ""
+#: lxc/storage.go:158
+msgid "Config key/value to apply to the new storage volume"
+msgstr ""
+
#: lxc/config.go:816 lxc/config.go:881 lxc/config.go:1331 lxc/image.go:1190
-#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:604 lxc/storage.go:979
+#: lxc/network.go:426 lxc/profile.go:275 lxc/storage.go:626 lxc/storage.go:1058
#, c-format
msgid "Config parsing error: %s"
msgstr ""
@@ -381,11 +385,11 @@ msgid "Creating the container"
msgstr ""
#: lxc/image.go:234 lxc/image.go:1137 lxc/list.go:465 lxc/network.go:525
-#: lxc/storage.go:682 lxc/storage.go:793
+#: lxc/storage.go:704 lxc/storage.go:819
msgid "DESCRIPTION"
msgstr ""
-#: lxc/storage.go:683
+#: lxc/storage.go:705
msgid "DRIVER"
msgstr ""
@@ -698,7 +702,7 @@ msgstr ""
msgid "Missing summary."
msgstr ""
-#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:402 lxc/storage.go:522
+#: lxc/network.go:284 lxc/network.go:337 lxc/storage.go:424 lxc/storage.go:544
msgid "More than one device matches, specify the device name."
msgstr ""
@@ -719,7 +723,7 @@ msgid "Must supply container name for: "
msgstr ""
#: lxc/list.go:467 lxc/network.go:522 lxc/profile.go:573 lxc/remote.go:409
-#: lxc/storage.go:681 lxc/storage.go:792
+#: lxc/storage.go:703 lxc/storage.go:818
msgid "NAME"
msgstr ""
@@ -767,7 +771,7 @@ msgstr ""
msgid "No device found for this network"
msgstr ""
-#: lxc/storage.go:411 lxc/storage.go:531
+#: lxc/storage.go:433 lxc/storage.go:553
msgid "No device found for this storage volume."
msgstr ""
@@ -775,7 +779,7 @@ msgstr ""
msgid "No fingerprint specified."
msgstr ""
-#: lxc/storage.go:355 lxc/storage.go:448
+#: lxc/storage.go:377 lxc/storage.go:470
msgid "Only \"custom\" volumes can be attached to containers."
msgstr ""
@@ -857,7 +861,7 @@ msgstr ""
msgid "Pid: %d"
msgstr ""
-#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:605 lxc/storage.go:980
+#: lxc/network.go:427 lxc/profile.go:276 lxc/storage.go:627 lxc/storage.go:1059
msgid "Press enter to open the editor again"
msgstr ""
@@ -966,7 +970,7 @@ msgstr ""
msgid "Remove %s (yes/no): "
msgstr ""
-#: lxc/storage.go:1011
+#: lxc/storage.go:1090
#, c-format
msgid "Renamed storage volume from \"%s\" to \"%s\""
msgstr ""
@@ -1004,7 +1008,7 @@ msgstr ""
msgid "SNAPSHOTS"
msgstr ""
-#: lxc/storage.go:684
+#: lxc/storage.go:706
msgid "SOURCE"
msgstr ""
@@ -1072,7 +1076,7 @@ msgstr ""
msgid "Show the resources available to the server"
msgstr ""
-#: lxc/storage.go:151
+#: lxc/storage.go:159
msgid "Show the resources available to the storage pool"
msgstr ""
@@ -1125,12 +1129,12 @@ msgstr ""
msgid "Stopping the container failed: %s"
msgstr ""
-#: lxc/storage.go:496
+#: lxc/storage.go:518
#, c-format
msgid "Storage pool %s created"
msgstr ""
-#: lxc/storage.go:555
+#: lxc/storage.go:577
#, c-format
msgid "Storage pool %s deleted"
msgstr ""
@@ -1139,12 +1143,12 @@ msgstr ""
msgid "Storage pool name"
msgstr ""
-#: lxc/storage.go:826
+#: lxc/storage.go:852
#, c-format
msgid "Storage volume %s created"
msgstr ""
-#: lxc/storage.go:841
+#: lxc/storage.go:867
#, c-format
msgid "Storage volume %s deleted"
msgstr ""
@@ -1161,7 +1165,7 @@ msgstr ""
msgid "Swap (peak)"
msgstr ""
-#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:791
+#: lxc/list.go:473 lxc/network.go:523 lxc/operation.go:153 lxc/storage.go:817
msgid "TYPE"
msgstr ""
@@ -1197,7 +1201,7 @@ msgstr ""
msgid "The opposite of \"lxc pause\" is \"lxc start\"."
msgstr ""
-#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:416 lxc/storage.go:536
+#: lxc/network.go:298 lxc/network.go:351 lxc/storage.go:438 lxc/storage.go:558
msgid "The specified device doesn't exist"
msgstr ""
@@ -1276,7 +1280,7 @@ msgstr ""
msgid "URL"
msgstr ""
-#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:685 lxc/storage.go:794
+#: lxc/network.go:526 lxc/profile.go:574 lxc/storage.go:707 lxc/storage.go:820
msgid "USED BY"
msgstr ""
@@ -2035,7 +2039,7 @@ msgid ""
" Create a snapshot of \"u1\" called \"snap0\"."
msgstr ""
-#: lxc/storage.go:64
+#: lxc/storage.go:65
msgid ""
"Usage: lxc storage <subcommand> [options]\n"
"\n"
@@ -2110,7 +2114,14 @@ msgid ""
"\n"
"lxc storage volume detach-profile [<remote:>]<pool> <volume> <profile> "
"[device name]\n"
-" Detach a storage volume from the specified profile.\n"
+"\tDetach a storage volume from the specified profile.\n"
+"\n"
+"lxc storage volume copy [<pool>/]<volume> [<pool>/]<volume> [--config|-c "
+"<key=value>...]\n"
+" Copy an existing volume to a new volume at the specified pool.\n"
+"\n"
+"lxc storage volume move [<pool>/]<volume> [<pool>/]<volume>\n"
+" Move an existing volume to the specified pool.\n"
"\n"
"Unless specified through a prefix, all volume operations affect \"custom"
"\" (user created) volumes.\n"
From 11d7a8d22c8371187efd373af0b1dad967415aab Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 16 Jan 2018 11:16:46 +0100
Subject: [PATCH 09/10] doc: add "storage_api_local_volume_handling"
Closes #3984.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
doc/api-extensions.md | 4 ++++
shared/version/api.go | 1 +
2 files changed, 5 insertions(+)
diff --git a/doc/api-extensions.md b/doc/api-extensions.md
index 1ba3db34d..614afbf88 100644
--- a/doc/api-extensions.md
+++ b/doc/api-extensions.md
@@ -395,3 +395,7 @@ getting a stream of events over websocket.
## proxy
This adds a new `proxy` device type to containers, allowing forwarding
of connections between the host and container.
+
+## storage\_api\_local\_volume\_handling
+This add the ability to copy and move custom storage volumes locally in the
+same and between storage pools.
diff --git a/shared/version/api.go b/shared/version/api.go
index feb31aab8..f292ff7e7 100644
--- a/shared/version/api.go
+++ b/shared/version/api.go
@@ -87,4 +87,5 @@ var APIExtensions = []string{
"maas_network",
"devlxd_events",
"proxy",
+ "storage_api_local_volume_handling",
}
From adec77b53e1d7c1b41a419659be703becbc99305 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 16 Jan 2018 13:50:17 +0100
Subject: [PATCH 10/10] test: add local storage volume handling tests
Closes #3984.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
test/main.sh | 1 +
test/suites/storage_local_volume_handling.sh | 97 ++++++++++++++++++++++++++++
2 files changed, 98 insertions(+)
create mode 100644 test/suites/storage_local_volume_handling.sh
diff --git a/test/main.sh b/test/main.sh
index 0890f9d77..89f7a95ef 100755
--- a/test/main.sh
+++ b/test/main.sh
@@ -191,6 +191,7 @@ run_test test_kernel_limits "kernel limits"
run_test test_macaroon_auth "macaroon authentication"
run_test test_console "console"
run_test test_proxy_device "proxy device"
+run_test test_storage_local_volume_handling "storage local volume handling"
# shellcheck disable=SC2034
TEST_RESULT=success
diff --git a/test/suites/storage_local_volume_handling.sh b/test/suites/storage_local_volume_handling.sh
new file mode 100644
index 000000000..35ed25d63
--- /dev/null
+++ b/test/suites/storage_local_volume_handling.sh
@@ -0,0 +1,97 @@
+test_storage_local_volume_handling() {
+ ensure_import_testimage
+
+ # shellcheck disable=2039
+ local LXD_STORAGE_DIR lxd_backend
+
+ lxd_backend=$(storage_backend "$LXD_DIR")
+ LXD_STORAGE_DIR=$(mktemp -d -p "${TEST_DIR}" XXXXXXXXX)
+ chmod +x "${LXD_STORAGE_DIR}"
+ spawn_lxd "${LXD_STORAGE_DIR}" false
+
+ ensure_import_testimage
+
+ (
+ set -e
+ # shellcheck disable=2030
+ LXD_DIR="${LXD_STORAGE_DIR}"
+
+ if storage_backend_available "btrfs"; then
+ # Create loop file btrfs pool.
+ lxc storage create "lxdtest-$(basename "${LXD_DIR}")-btrfs" btrfs
+ # btrfs -> btrfs
+ lxc storage create "lxdtest-$(basename "${LXD_DIR}")-btrfs1" btrfs
+ lxc storage volume create "lxdtest-$(basename "${LXD_DIR}")-btrfs" vol1
+ lxc storage volume copy "lxdtest-$(basename "${LXD_DIR}")-btrfs/vol1" "lxdtest-$(basename "${LXD_DIR}")-btrfs1/vol1"
+ lxc storage volume delete "lxdtest-$(basename "${LXD_DIR}")-btrfs1 vol1"
+ lxc storage volume move "lxdtest-$(basename "${LXD_DIR}")-btrfs/vol1" "lxdtest-$(basename "${LXD_DIR}")-btrfs1/vol1"
+ ! lxc storage volume show "lxdtest-$(basename "${LXD_DIR}")-btrfs vol1"
+ lxc storage volume show "lxdtest-$(basename "${LXD_DIR}")-btrfs1 vol1"
+ lxc storage volume delete "lxdtest-$(basename "${LXD_DIR}")-btrfs1 vol1"
+ lxc storage delete "lxdtest-$(basename "${LXD_DIR}")-btrfs1"
+ fi
+
+ if storage_backend_available "ceph"; then
+ # Create dir pool.
+ lxc storage create "lxdtest-$(basename "${LXD_DIR}")-ceph" ceph
+ # ceph -> ceph
+ lxc storage create "lxdtest-$(basename "${LXD_DIR}")-ceph1" ceph
+ lxc storage volume create "lxdtest-$(basename "${LXD_DIR}")-ceph" vol1
+ lxc storage volume copy "lxdtest-$(basename "${LXD_DIR}")-ceph/vol1" "lxdtest-$(basename "${LXD_DIR}")-ceph1/vol1"
+ lxc storage volume delete "lxdtest-$(basename "${LXD_DIR}")-ceph1 vol1"
+ lxc storage volume move "lxdtest-$(basename "${LXD_DIR}")-ceph/vol1" "lxdtest-$(basename "${LXD_DIR}")-ceph1/vol1"
+ ! lxc storage volume show "lxdtest-$(basename "${LXD_DIR}")-ceph vol1"
+ lxc storage volume show "lxdtest-$(basename "${LXD_DIR}")-ceph1 vol1"
+ lxc storage volume delete "lxdtest-$(basename "${LXD_DIR}")-ceph1 vol1"
+ lxc storage delete "lxdtest-$(basename "${LXD_DIR}")-ceph1"
+ fi
+
+ # Create dir pool.
+ lxc storage create "lxdtest-$(basename "${LXD_DIR}")-dir" dir
+ # dir -> dir
+ lxc storage create "lxdtest-$(basename "${LXD_DIR}")-dir1" dir
+ lxc storage volume create "lxdtest-$(basename "${LXD_DIR}")-dir" vol1
+ lxc storage volume copy "lxdtest-$(basename "${LXD_DIR}")-dir/vol1" "lxdtest-$(basename "${LXD_DIR}")-dir1/vol1"
+ lxc storage volume delete "lxdtest-$(basename "${LXD_DIR}")-dir1 vol1"
+ lxc storage volume move "lxdtest-$(basename "${LXD_DIR}")-dir/vol1" "lxdtest-$(basename "${LXD_DIR}")-dir1/vol1"
+ ! lxc storage volume show "lxdtest-$(basename "${LXD_DIR}")-dir vol1"
+ lxc storage volume show "lxdtest-$(basename "${LXD_DIR}")-dir1 vol1"
+ lxc storage volume delete "lxdtest-$(basename "${LXD_DIR}")-dir1 vol1"
+ lxc storage delete "lxdtest-$(basename "${LXD_DIR}")-dir1"
+
+ if storage_backend_available "lvm"; then
+ # shellcheck disable=SC2154
+ lxc storage create "lxdtest-$(basename "${LXD_DIR}")-lvm" lvm volume.size=25MB
+ # lvm -> lvm
+ lxc storage create "lxdtest-$(basename "${LXD_DIR}")-lvm1" lvm
+ lxc storage volume create "lxdtest-$(basename "${LXD_DIR}")-lvm" vol1
+ lxc storage volume copy "lxdtest-$(basename "${LXD_DIR}")-lvm/vol1" "lxdtest-$(basename "${LXD_DIR}")-lvm1/vol1"
+ lxc storage volume delete "lxdtest-$(basename "${LXD_DIR}")-lvm1 vol1"
+ lxc storage volume move "lxdtest-$(basename "${LXD_DIR}")-lvm/vol1" "lxdtest-$(basename "${LXD_DIR}")-lvm1/vol1"
+ ! lxc storage volume show "lxdtest-$(basename "${LXD_DIR}")-lvm vol1"
+ lxc storage volume show "lxdtest-$(basename "${LXD_DIR}")-lvm1 vol1"
+ lxc storage volume delete "lxdtest-$(basename "${LXD_DIR}")-lvm1 vol1"
+ lxc storage delete "lxdtest-$(basename "${LXD_DIR}")-lvm1"
+ fi
+
+ # shellcheck disable=SC1009
+ if storage_backend_available "zfs"; then
+ # Create loop file zfs pool.
+ lxc storage create "lxdtest-$(basename "${LXD_DIR}")-zfs" zfs
+ # zfs -> zfs
+ lxc storage create "lxdtest-$(basename "${LXD_DIR}")-zfs1" zfs
+ lxc storage volume create "lxdtest-$(basename "${LXD_DIR}")-zfs" vol1
+ lxc storage volume copy "lxdtest-$(basename "${LXD_DIR}")-zfs/vol1" "lxdtest-$(basename "${LXD_DIR}")-zfs1/vol1"
+ lxc storage volume delete "lxdtest-$(basename "${LXD_DIR}")-zfs1 vol1"
+ lxc storage volume move "lxdtest-$(basename "${LXD_DIR}")-zfs/vol1" "lxdtest-$(basename "${LXD_DIR}")-zfs1/vol1"
+ ! lxc storage volume show "lxdtest-$(basename "${LXD_DIR}")-zfs vol1"
+ lxc storage volume show "lxdtest-$(basename "${LXD_DIR}")-zfs1 vol1"
+ lxc storage volume delete "lxdtest-$(basename "${LXD_DIR}")-zfs1 vol1"
+ lxc storage delete "lxdtest-$(basename "${LXD_DIR}")-zfs1"
+ fi
+ )
+
+ # shellcheck disable=SC2031
+ LXD_DIR="${LXD_DIR}"
+ kill_lxd "${LXD_STORAGE_DIR}"
+}
More information about the lxc-devel
mailing list