[lxc-devel] [lxd/master] Fix volume creation API
stgraber on Github
lxc-bot at linuxcontainers.org
Wed Jul 4 03:20:27 UTC 2018
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180704/df258bcd/attachment.bin>
-------------- next part --------------
From dd82f404a5728d69cbc6de375f8f7b8e55e09fd8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 3 Jul 2018 12:25:44 -0400
Subject: [PATCH 1/3] lxc/cluster: Remove bad alias
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxc/cluster.go | 1 -
1 file changed, 1 deletion(-)
diff --git a/lxc/cluster.go b/lxc/cluster.go
index ce7e7e8ef..ec20cfe6b 100644
--- a/lxc/cluster.go
+++ b/lxc/cluster.go
@@ -285,7 +285,6 @@ type cmdClusterEnable struct {
func (c *cmdClusterEnable) Command() *cobra.Command {
cmd := &cobra.Command{}
cmd.Use = i18n.G("enable [<remote>:] <name>")
- cmd.Aliases = []string{"rm"}
cmd.Short = i18n.G("Enable clustering on a single non-clustered LXD instance")
cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
`Enable clustering on a single non-clustered LXD instance
From 4fe32c14dba37d872712cc27138f5edd3266509b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 3 Jul 2018 21:13:25 -0400
Subject: [PATCH 2/3] doc: Fix storage volume examples
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Closes #4723
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
doc/rest-api.md | 46 ++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 42 insertions(+), 4 deletions(-)
diff --git a/doc/rest-api.md b/doc/rest-api.md
index 7bbdd984c..3c8d2f98e 100644
--- a/doc/rest-api.md
+++ b/doc/rest-api.md
@@ -219,7 +219,8 @@ won't work and PUT needs to be used instead.
* [`/1.0/storage-pools/<name>`](#10storage-poolsname)
* [`/1.0/storage-pools/<name>/resources`](#10storage-poolsnameresources)
* [`/1.0/storage-pools/<name>/volumes`](#10storage-poolsnamevolumes)
- * [`/1.0/storage-pools/<pool>/volumes/<type>/<name>`](#10storage-poolspoolvolumestypename)
+ * [`/1.0/storage-pools/<name>/volumes/<type>`](#10storage-poolsnamevolumestype)
+ * [`/1.0/storage-pools/<pool>/volumes/<type>/<name>`](#10storage-poolspoolvolumestypename)
* [`/1.0/resources`](#10resources)
* [`/1.0/cluster`](#10cluster)
* [`/1.0/cluster/members`](#10clustermembers)
@@ -2431,7 +2432,6 @@ Input:
{
"config": {},
- "pool": "pool1",
"name": "vol1",
"type": "custom"
}
@@ -2440,7 +2440,6 @@ Input (when copying a volume):
{
"config": {},
- "pool": "pool1",
"name": "vol1",
"type": "custom"
"source": {
@@ -2454,7 +2453,6 @@ Input (when migrating a volume):
{
"config": {},
- "pool": "pool1",
"name": "vol1",
"type": "custom"
"source": {
@@ -2465,6 +2463,46 @@ Input (when migrating a volume):
}
}
+## `/1.0/storage-pools/<pool>/volumes/<type>`
+### POST
+ * Description: create a new storage volume of a particular type on a given storage pool
+ * Introduced: with API extension `storage`
+ * Authentication: trusted
+ * Operation: sync or async (when copying an existing volume)
+ * Return: standard return value or standard error
+
+Input:
+
+ {
+ "config": {},
+ "name": "vol1",
+ }
+
+Input (when copying a volume):
+
+ {
+ "config": {},
+ "name": "vol1",
+ "source": {
+ "pool": "pool2",
+ "name": "vol2",
+ "type": "copy"
+ }
+ }
+
+Input (when migrating a volume):
+
+ {
+ "config": {},
+ "name": "vol1",
+ "source": {
+ "pool": "pool2",
+ "name": "vol2",
+ "type": "migration"
+ "mode": "pull", # One of "pull" (default), "push", "relay"
+ }
+ }
+
## `/1.0/storage-pools/<pool>/volumes/<type>/<name>`
### POST
* Description: rename a storage volume on a given storage pool
From c87dac872d473d1b03e442d923693835dc877136 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 3 Jul 2018 23:19:48 -0400
Subject: [PATCH 3/3] lxd/storage: Fix volume creation API
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Closes #4723
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxd/storage_volumes.go | 64 ++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 57 insertions(+), 7 deletions(-)
diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go
index ef97153d5..8d7ac4fc4 100644
--- a/lxd/storage_volumes.go
+++ b/lxd/storage_volumes.go
@@ -67,7 +67,7 @@ func storagePoolVolumesGet(d *Daemon, r *http.Request) Response {
return SyncResponse(true, volumes)
}
-var storagePoolVolumesCmd = Command{name: "storage-pools/{name}/volumes", get: storagePoolVolumesGet}
+var storagePoolVolumesCmd = Command{name: "storage-pools/{name}/volumes", get: storagePoolVolumesGet, post: storagePoolVolumesPost}
// /1.0/storage-pools/{name}/volumes/{type}
// List all storage volumes of a given volume type for a given storage pool.
@@ -138,7 +138,7 @@ func storagePoolVolumesTypeGet(d *Daemon, r *http.Request) Response {
}
// /1.0/storage-pools/{name}/volumes/{type}
-// Create a storage volume of a given volume type in a given storage pool.
+// Create a storage volume in a given storage pool.
func storagePoolVolumesTypePost(d *Daemon, r *http.Request) Response {
response := ForwardedResponseIfTargetIsRemote(d, r)
if response != nil {
@@ -162,11 +162,7 @@ func storagePoolVolumesTypePost(d *Daemon, r *http.Request) Response {
return BadRequest(fmt.Errorf("Storage volume names may not contain slashes"))
}
- // Check that the user gave use a storage volume type for the storage
- // volume we are about to create.
- if req.Type == "" {
- return BadRequest(fmt.Errorf("you must provide a storage volume type of the storage volume"))
- }
+ req.Type = mux.Vars(r)["type"]
// We currently only allow to create storage volumes of type
// storagePoolVolumeTypeCustom. So check, that nothing else was
@@ -218,6 +214,60 @@ func doVolumeCreateOrCopy(d *Daemon, poolName string, req *api.StorageVolumesPos
}
return OperationResponse(op)
+
+}
+
+// /1.0/storage-pools/{name}/volumes/{type}
+// Create a storage volume of a given volume type in a given storage pool.
+func storagePoolVolumesPost(d *Daemon, r *http.Request) Response {
+ response := ForwardedResponseIfTargetIsRemote(d, r)
+ if response != nil {
+ return response
+ }
+
+ req := api.StorageVolumesPost{}
+
+ // Parse the request.
+ err := json.NewDecoder(r.Body).Decode(&req)
+ if err != nil {
+ return BadRequest(err)
+ }
+
+ // Sanity checks.
+ if req.Name == "" {
+ return BadRequest(fmt.Errorf("No name provided"))
+ }
+
+ if strings.Contains(req.Name, "/") {
+ return BadRequest(fmt.Errorf("Storage volume names may not contain slashes"))
+ }
+
+ // Check that the user gave use a storage volume type for the storage
+ // volume we are about to create.
+ if req.Type == "" {
+ return BadRequest(fmt.Errorf("You must provide a storage volume type of the storage volume"))
+ }
+
+ // We currently only allow to create storage volumes of type
+ // storagePoolVolumeTypeCustom. So check, that nothing else was
+ // requested.
+ if req.Type != storagePoolVolumeTypeNameCustom {
+ return BadRequest(fmt.Errorf(`Currently not allowed to create `+
+ `storage volumes of type %s`, req.Type))
+ }
+
+ poolName := mux.Vars(r)["name"]
+
+ switch req.Source.Type {
+ case "":
+ return doVolumeCreateOrCopy(d, poolName, &req)
+ case "copy":
+ return doVolumeCreateOrCopy(d, poolName, &req)
+ case "migration":
+ return doVolumeMigration(d, poolName, &req)
+ default:
+ return BadRequest(fmt.Errorf("unknown source type %s", req.Source.Type))
+ }
}
func doVolumeMigration(d *Daemon, poolName string, req *api.StorageVolumesPost) Response {
More information about the lxc-devel
mailing list