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
