[lxc-devel] [lxd/master] Bugfixes

stgraber on Github lxc-bot at linuxcontainers.org
Wed Sep 7 21:30:43 UTC 2016


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/20160907/9a38f3df/attachment.bin>
-------------- next part --------------
From 16f8e3e2b45f14260ae85d3787cdaf5b41244291 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 7 Sep 2016 17:15:48 -0400
Subject: [PATCH 1/2] doc: Spacing cleanup
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>
---
 doc/rest-api.md | 15 ---------------
 1 file changed, 15 deletions(-)

diff --git a/doc/rest-api.md b/doc/rest-api.md
index b92dc09..4e0752e 100644
--- a/doc/rest-api.md
+++ b/doc/rest-api.md
@@ -135,7 +135,6 @@ Code  | Meaning
 400   | Failure
 401   | Cancelled
 
-
 # Recursion
 To optimize queries of large lists, recursion is implemented for collections.
 A "recursion" argument can be passed to a GET query against a collection.
@@ -460,7 +459,6 @@ Input (using a public remote image):
                    "alias": "ubuntu/devel"},                                # Name of the alias
     }
 
-
 Input (using a private remote image after having obtained a secret for that image):
 
     {
@@ -519,7 +517,6 @@ Input (using a local container):
                    "source": "my-old-container"}                                        # Name of the source container
     }
 
-
 ## /1.0/containers/\<name\>
 ### GET
  * Description: Container information
@@ -571,7 +568,6 @@ Output:
         "status_code": 103
     }
 
-
 ### PUT (ETag supported)
  * Description: replaces container configuration or restore snapshot
  * Authentication: trusted
@@ -599,7 +595,6 @@ Input (update container configuration):
         ]
     }
 
-
 Takes the same structure as that returned by GET but doesn't allow name
 changes (see POST below) or changes to the status sub-dict (since that's
 read-only).
@@ -630,7 +625,6 @@ Input:
         "ephemeral": true
     }
 
-
 ### POST
  * Description: used to rename/migrate the container
  * Authentication: trusted
@@ -824,7 +818,6 @@ Output:
         }
     }
 
-
 ### PUT
  * Description: change the container state
  * Authentication: trusted
@@ -1046,7 +1039,6 @@ Return (with wait-for-websocket=true and interactive=true):
         }
     }
 
-
 When the exec command finishes, its exit status is available from the
 operation's metadata:
 
@@ -1124,7 +1116,6 @@ This never returns. Each notification is sent as a separate JSON dict:
         }
     }
 
-
 ## /1.0/images
 ### GET
  * Description: list of images (public or private)
@@ -1209,7 +1200,6 @@ In the remote image URL case, the following dict must be used:
         }
     }
 
-
 After the input is received by LXD, a background operation is started
 which will add the image to the store and possibly do some backend
 filesystem-specific optimizations.
@@ -1318,7 +1308,6 @@ client will POST to /1.0/images/\<fingerprint\>/export to get a secret
 token which it'll then pass to the target LXD. That target LXD will then
 GET the image as a guest, passing the secret token.
 
-
 ## /1.0/images/\<fingerprint\>/secret
 ### POST
  * Description: Generate a random token and tell LXD to expect it be used by a guest
@@ -1413,7 +1402,6 @@ Input:
         "description": "New description"
     }
 
-
 ### POST
  * Description: rename an alias
  * Authentication: trusted
@@ -1557,7 +1545,6 @@ Return:
         "/1.0/profiles/default"
     ]
 
-
 ### POST
  * Description: define a new profile
  * Authentication: trusted
@@ -1660,13 +1647,11 @@ Input (rename a profile):
         "name": "new-name"
     }
 
-
 HTTP return value must be 204 (No content) and Location must point to
 the renamed resource.
 
 Renaming to an existing name must return the 409 (Conflict) HTTP code.
 
-
 ### DELETE
  * Description: remove a profile
  * Authentication: trusted

From 06d8fec90b5028148f70ddd1addb82586dd4f016 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 7 Sep 2016 17:20:08 -0400
Subject: [PATCH 2/2] Consistently handle name conflicts
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

All of those were documented as returning a 409 and clearly weren't :)

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/container_post.go     |  6 ++++++
 lxd/container_snapshot.go | 14 +++++++++++---
 lxd/images.go             |  6 ++++++
 lxd/profiles.go           |  6 ++++++
 4 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/lxd/container_post.go b/lxd/container_post.go
index 58ebf07..5603f29 100644
--- a/lxd/container_post.go
+++ b/lxd/container_post.go
@@ -47,6 +47,12 @@ func containerPost(d *Daemon, r *http.Request) Response {
 		return OperationResponse(op)
 	}
 
+	// Check that the name isn't already in use
+	id, _ := dbContainerId(d.db, body.Name)
+	if id != 0 {
+		return Conflict
+	}
+
 	run := func(*operation) error {
 		return c.Rename(body.Name)
 	}
diff --git a/lxd/container_snapshot.go b/lxd/container_snapshot.go
index 7d5e409..0bcea8b 100644
--- a/lxd/container_snapshot.go
+++ b/lxd/container_snapshot.go
@@ -174,7 +174,7 @@ func snapshotHandler(d *Daemon, r *http.Request) Response {
 	case "GET":
 		return snapshotGet(sc, snapshotName)
 	case "POST":
-		return snapshotPost(r, sc, containerName)
+		return snapshotPost(d, r, sc, containerName)
 	case "DELETE":
 		return snapshotDelete(sc, snapshotName)
 	default:
@@ -191,7 +191,7 @@ func snapshotGet(sc container, name string) Response {
 	return SyncResponse(true, render.(*shared.SnapshotInfo))
 }
 
-func snapshotPost(r *http.Request, sc container, containerName string) Response {
+func snapshotPost(d *Daemon, r *http.Request, sc container, containerName string) Response {
 	raw := shared.Jmap{}
 	if err := json.NewDecoder(r.Body).Decode(&raw); err != nil {
 		return BadRequest(err)
@@ -220,8 +220,16 @@ func snapshotPost(r *http.Request, sc container, containerName string) Response
 		return BadRequest(err)
 	}
 
+	fullName := containerName + shared.SnapshotDelimiter + newName
+
+	// Check that the name isn't already in use
+	id, _ := dbContainerId(d.db, fullName)
+	if id != 0 {
+		return Conflict
+	}
+
 	rename := func(op *operation) error {
-		return sc.Rename(containerName + shared.SnapshotDelimiter + newName)
+		return sc.Rename(fullName)
 	}
 
 	resources := map[string][]string{}
diff --git a/lxd/images.go b/lxd/images.go
index 5600936..dba16ca 100644
--- a/lxd/images.go
+++ b/lxd/images.go
@@ -1343,6 +1343,12 @@ func aliasPost(d *Daemon, r *http.Request) Response {
 		return BadRequest(err)
 	}
 
+	// Check that the name isn't already in use
+	id, _, _ := dbImageAliasGet(d.db, req.Name, true)
+	if id != 0 {
+		return Conflict
+	}
+
 	id, _, err := dbImageAliasGet(d.db, name, true)
 	if err != nil {
 		return SmartError(err)
diff --git a/lxd/profiles.go b/lxd/profiles.go
index 8daca31..2e95915 100644
--- a/lxd/profiles.go
+++ b/lxd/profiles.go
@@ -339,6 +339,12 @@ func profilePost(d *Daemon, r *http.Request) Response {
 		return BadRequest(fmt.Errorf("No name provided"))
 	}
 
+	// Check that the name isn't already in use
+	id, _, _ := dbProfileGet(d.db, req.Name)
+	if id != 0 {
+		return Conflict
+	}
+
 	if strings.Contains(req.Name, "/") {
 		return BadRequest(fmt.Errorf("Profile names may not contain slashes"))
 	}


More information about the lxc-devel mailing list