[lxc-devel] [lxd/master] Return an error if an image already exists on import
albertodonato on Github
lxc-bot at linuxcontainers.org
Wed May 3 15:47:01 UTC 2017
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 397 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170503/586b8c4d/attachment.bin>
-------------- next part --------------
From ffef165814825126bc01a935760424e430a7d027 Mon Sep 17 00:00:00 2001
From: Alberto Donato <alberto.donato at canonical.com>
Date: Wed, 3 May 2017 16:36:12 +0200
Subject: [PATCH] Check if the image already exists.
Signed-off-by: Alberto Donato <alberto.donato at canonical.com>
---
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 {
More information about the lxc-devel
mailing list