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

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Return a more meaningful error when trying to import an already existing image.

Closes #3244 
From ffef165814825126bc01a935760424e430a7d027 Mon Sep 17 00:00:00 2001
From: Alberto Donato <[email protected]>
Date: Wed, 3 May 2017 16:36:12 +0200
Subject: [PATCH] Check if the image already exists.

Signed-off-by: Alberto Donato <[email protected]>
---
 lxd/db_images.go | 36 ++++++++++++++++++------------------
 lxd/db_test.go   | 30 ++++++++++++++++++++++++++++++
 lxd/images.go    |  8 ++++++++
 3 files changed, 56 insertions(+), 18 deletions(-)

diff --git a/lxd/db_images.go b/lxd/db_images.go
index 19f4269..cc6af2e 100644
--- a/lxd/db_images.go
+++ b/lxd/db_images.go
@@ -105,8 +105,17 @@ func dbImageSourceGet(db *sql.DB, imageId int) (int, 
api.ImageSource, error) {
 
 }
 
-// dbImageGet gets an ImageBaseInfo object from the database.
-// The argument fingerprint will be queried with a LIKE query, means you can
+// Whether an image with the given fingerprint exists.
+func dbImageExists(db *sql.DB, fingerprint string) (exists bool, err error) {
+       query := "SELECT COUNT(*) > 0 FROM images WHERE fingerprint=?"
+       inargs := []interface{}{fingerprint}
+       outargs := []interface{}{&exists}
+       err = dbQueryRowScan(db, query, inargs, outargs)
+       return
+}
+
+// dbImageGet gets an Image object from the database.
+// If strictMatching is false, The fingerprint argument will be queried with a 
LIKE query, means you can
 // pass a shortform and will get the full fingerprint.
 // There can never be more than one image with a given fingerprint, as it is
 // enforced by a UNIQUE constraint in the schema.
@@ -124,31 +133,22 @@ func dbImageGet(db *sql.DB, fingerprint string, public 
bool, strictMatching bool
                &image.Size, &image.Cached, &image.Public, &image.AutoUpdate, 
&arch,
                &create, &expire, &used, &upload}
 
-       var query string
-
        var inargs []interface{}
-       if strictMatching {
-               inargs = []interface{}{fingerprint}
-               query = `
+       query := `
         SELECT
             id, fingerprint, filename, size, cached, public, auto_update, 
architecture,
             creation_date, expiry_date, last_use_date, upload_date
-        FROM
-            images
-        WHERE fingerprint = ?`
+        FROM images`
+       if strictMatching {
+               inargs = []interface{}{fingerprint}
+               query += " WHERE fingerprint = ?"
        } else {
                inargs = []interface{}{fingerprint + "%"}
-               query = `
-        SELECT
-            id, fingerprint, filename, size, cached, public, auto_update, 
architecture,
-            creation_date, expiry_date, last_use_date, upload_date
-        FROM
-            images
-        WHERE fingerprint LIKE ?`
+               query += " WHERE fingerprint LIKE ?"
        }
 
        if public {
-               query = query + " AND public=1"
+               query += " AND public=1"
        }
 
        err = dbQueryRowScan(db, query, inargs, outfmt)
diff --git a/lxd/db_test.go b/lxd/db_test.go
index 03adce0..2a406e6 100644
--- a/lxd/db_test.go
+++ b/lxd/db_test.go
@@ -463,6 +463,36 @@ func Test_dbImageGet_for_missing_fingerprint(t *testing.T) 
{
        }
 }
 
+func Test_dbImageExists(t *testing.T) {
+       var db *sql.DB
+       var err error
+
+       db = createTestDb(t)
+       defer db.Close()
+
+       t.Run("true", func(t *testing.T) {
+               exists, err := dbImageExists(db, "fingerprint")
+
+               if err != nil {
+                       t.Fatal(err)
+               }
+               if !exists {
+                       t.Fatal("Image not found by fingerprint")
+               }
+       })
+
+       t.Run("false", func(t *testing.T) {
+               exists, err := dbImageExists(db, "foobar")
+
+               if err != nil {
+                       t.Fatal(err)
+               }
+               if exists {
+                       t.Fatal("Image should not have been found")
+               }
+       })
+}
+
 func Test_dbImageAliasGet_alias_exists(t *testing.T) {
        var db *sql.DB
        var err error
diff --git a/lxd/images.go b/lxd/images.go
index 01c44f6..1bcd5d9 100644
--- a/lxd/images.go
+++ b/lxd/images.go
@@ -620,6 +620,14 @@ func getImgPostInfo(d *Daemon, r *http.Request, builddir 
string, post *os.File)
                }
        }
 
+       // Check if the image already exists
+       exists, err := dbImageExists(d.db, info.Fingerprint)
+       if err != nil {
+               return nil, err
+       }
+       if exists {
+               return nil, fmt.Errorf("Image with same fingerprint already 
exists")
+       }
        // Create the database entry
        err = dbImageInsert(d.db, info.Fingerprint, info.Filename, info.Size, 
info.Public, info.AutoUpdate, info.Architecture, info.CreatedAt, 
info.ExpiresAt, info.Properties)
        if err != nil {
_______________________________________________
lxc-devel mailing list
[email protected]
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to