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

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) ===
Avoids errors such as:

```
DBUG[03-12|09:36:31] New task Operation: c0d6aaba-3130-4987-8002-74f069bebe10 
DBUG[03-12|09:36:31] Failure for task operation: 28799184-e121-4ad6-8139-9da30b7130b2: Error retrieving image info 8bac6546bbc5cfbe5c490f2c991cff8cff1428b57fb9a74d33a64cb6dff66601: No such object 
```
From 666fbce982dca85bfd7dfcaa6a8e628499c63303 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 12 Mar 2020 10:12:39 +0000
Subject: [PATCH 1/3] lxd/db/images: Removes unnecessary whitespace

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/db/images.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lxd/db/images.go b/lxd/db/images.go
index d8916d14f6..79d792d451 100644
--- a/lxd/db/images.go
+++ b/lxd/db/images.go
@@ -532,7 +532,7 @@ func (c *Cluster) imageFillProfiles(id int, image 
*api.Image, project string) er
 
        // Get the profiles
        q := `
-SELECT profiles.name FROM profiles 
+SELECT profiles.name FROM profiles
        JOIN images_profiles ON images_profiles.profile_id = profiles.id
        JOIN projects ON profiles.project_id = projects.id
 WHERE images_profiles.image_id = ? AND projects.name = ?
@@ -886,7 +886,7 @@ func (c *Cluster) ImageUpdate(id int, fname string, sz 
int64, public bool, autoU
                        if !enabled {
                                project = "default"
                        }
-                       q := `DELETE FROM images_profiles 
+                       q := `DELETE FROM images_profiles
                                WHERE image_id = ? AND profile_id IN (
                                        SELECT profiles.id FROM profiles
                                        JOIN projects ON profiles.project_id = 
projects.id

From dbc2ef7d06e61daa4a47a5397b75eb9694aa13b3 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 12 Mar 2020 10:10:42 +0000
Subject: [PATCH 2/3] lxd/db/images: Updates ImagesGetExpired to return
 ExpireImage struct with projectName

So that deleting expired images can be done when the image is in a non-default 
project.

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/db/images.go | 37 ++++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/lxd/db/images.go b/lxd/db/images.go
index 79d792d451..f196c3a0ce 100644
--- a/lxd/db/images.go
+++ b/lxd/db/images.go
@@ -88,23 +88,37 @@ SELECT fingerprint
        return results, nil
 }
 
-// ImagesGetExpired returns the names of all images that have expired since the
-// given time.
-func (c *Cluster) ImagesGetExpired(expiry int64) ([]string, error) {
-       q := `SELECT fingerprint, last_use_date, upload_date FROM images WHERE 
cached=1`
+// ExpiredImage used to store expired image info.
+type ExpiredImage struct {
+       Fingerprint string
+       ProjectName string
+}
+
+// ImagesGetExpired returns the names and project name of all images that have 
expired since the given time.
+func (c *Cluster) ImagesGetExpired(expiry int64) ([]ExpiredImage, error) {
+       q := `
+       SELECT
+               fingerprint,
+               last_use_date,
+               upload_date,
+               projects.name as projectName
+       FROM images
+       JOIN projects ON projects.id = images.project_id
+       WHERE images.cached = 1`
 
        var fpStr string
        var useStr string
        var uploadStr string
+       var projectName string
 
        inargs := []interface{}{}
-       outfmt := []interface{}{fpStr, useStr, uploadStr}
+       outfmt := []interface{}{fpStr, useStr, uploadStr, projectName}
        dbResults, err := queryScan(c.db, q, inargs, outfmt)
        if err != nil {
-               return []string{}, err
+               return []ExpiredImage{}, err
        }
 
-       results := []string{}
+       results := []ExpiredImage{}
        for _, r := range dbResults {
                // Figure out the expiry
                timestamp := r[2]
@@ -115,7 +129,7 @@ func (c *Cluster) ImagesGetExpired(expiry int64) ([]string, 
error) {
                var imageExpiry time.Time
                err = imageExpiry.UnmarshalText([]byte(timestamp.(string)))
                if err != nil {
-                       return []string{}, err
+                       return []ExpiredImage{}, err
                }
                imageExpiry = imageExpiry.Add(time.Duration(expiry*24) * 
time.Hour)
 
@@ -124,7 +138,12 @@ func (c *Cluster) ImagesGetExpired(expiry int64) 
([]string, error) {
                        continue
                }
 
-               results = append(results, r[0].(string))
+               result := ExpiredImage{
+                       Fingerprint: r[0].(string),
+                       ProjectName: r[3].(string),
+               }
+
+               results = append(results, result)
        }
 
        return results, nil

From 5a3d40a46d065a21932f9e69c44804c811da2a2a Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 12 Mar 2020 10:12:06 +0000
Subject: [PATCH 3/3] lxd/images: Updates pruneExpiredImages to support
 removing expired images from non-default projects

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/images.go | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/lxd/images.go b/lxd/images.go
index c05c7d6582..9f804c2c8c 100644
--- a/lxd/images.go
+++ b/lxd/images.go
@@ -33,7 +33,6 @@ import (
        "github.com/lxc/lxd/lxd/instance/instancetype"
        "github.com/lxc/lxd/lxd/node"
        "github.com/lxc/lxd/lxd/operations"
-       "github.com/lxc/lxd/lxd/project"
        "github.com/lxc/lxd/lxd/response"
        "github.com/lxc/lxd/lxd/state"
        storagePools "github.com/lxc/lxd/lxd/storage"
@@ -1305,7 +1304,7 @@ func pruneExpiredImages(ctx context.Context, d *Daemon) 
error {
        }
 
        // Delete them
-       for _, fp := range images {
+       for _, img := range images {
                // At each iteration we check if we got cancelled in the
                // meantime. It is safe to abort here since anything not
                // expired now will be expired at the next run.
@@ -1317,7 +1316,7 @@ func pruneExpiredImages(ctx context.Context, d *Daemon) 
error {
 
                // Get the IDs of all storage pools on which a storage volume
                // for the requested image currently exists.
-               poolIDs, err := d.cluster.ImageGetPools(fp)
+               poolIDs, err := d.cluster.ImageGetPools(img.Fingerprint)
                if err != nil {
                        continue
                }
@@ -1329,38 +1328,38 @@ func pruneExpiredImages(ctx context.Context, d *Daemon) 
error {
                }
 
                for _, pool := range poolNames {
-                       err := doDeleteImageFromPool(d.State(), fp, pool)
+                       err := doDeleteImageFromPool(d.State(), 
img.Fingerprint, pool)
                        if err != nil {
-                               return errors.Wrapf(err, "Error deleting image 
%s from storage pool %s", fp, pool)
+                               return errors.Wrapf(err, "Error deleting image 
%q from storage pool %q", img.Fingerprint, pool)
                        }
                }
 
                // Remove main image file.
-               fname := filepath.Join(d.os.VarDir, "images", fp)
+               fname := filepath.Join(d.os.VarDir, "images", img.Fingerprint)
                if shared.PathExists(fname) {
                        err = os.Remove(fname)
                        if err != nil && !os.IsNotExist(err) {
-                               return errors.Wrapf(err, "Error deleting image 
file %s", fname)
+                               return errors.Wrapf(err, "Error deleting image 
file %q", fname)
                        }
                }
 
                // Remove the rootfs file for the image.
-               fname = filepath.Join(d.os.VarDir, "images", fp) + ".rootfs"
+               fname = filepath.Join(d.os.VarDir, "images", img.Fingerprint) + 
".rootfs"
                if shared.PathExists(fname) {
                        err = os.Remove(fname)
                        if err != nil && !os.IsNotExist(err) {
-                               return errors.Wrapf(err, "Error deleting image 
file %s", fname)
+                               return errors.Wrapf(err, "Error deleting image 
file %q", fname)
                        }
                }
 
-               imgID, _, err := d.cluster.ImageGet(project.Default, fp, false, 
false)
+               imgID, _, err := d.cluster.ImageGet(img.ProjectName, 
img.Fingerprint, false, false)
                if err != nil {
-                       return errors.Wrapf(err, "Error retrieving image info 
%s", fp)
+                       return errors.Wrapf(err, "Error retrieving image info 
for fingerprint %q and project %q", img.Fingerprint, img.ProjectName)
                }
 
                // Remove the database entry for the image.
                if err = d.cluster.ImageDelete(imgID); err != nil {
-                       return errors.Wrapf(err, "Error deleting image %s from 
database", fp)
+                       return errors.Wrapf(err, "Error deleting image %q from 
database", img.Fingerprint)
                }
        }
 
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to