[lxc-devel] [lxd/master] Send a notification to other nodes when an image is removed

freeekanayaka on Github lxc-bot at linuxcontainers.org
Mon Aug 13 13:37:24 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 455 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180813/06e8833d/attachment.bin>
-------------- next part --------------
From c1a84f7bd5c416e66fbdcac0f4cbb8ce2072fc7d Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Mon, 13 Aug 2018 15:34:28 +0200
Subject: [PATCH] Send a notification to other nodes when an image is removed

The peers will remove the image from disk upon receiving the notification

Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
 lxd/images.go             | 68 +++++++++++++++++++++++++++++++++++----
 test/suites/clustering.sh |  3 ++
 2 files changed, 64 insertions(+), 7 deletions(-)

diff --git a/lxd/images.go b/lxd/images.go
index c3dfbf27a..5bdd5ca9a 100644
--- a/lxd/images.go
+++ b/lxd/images.go
@@ -1176,20 +1176,53 @@ func imageDelete(d *Daemon, r *http.Request) Response {
 			}
 		}
 
-		// Remove the rootfs file for the image.
-		fname = shared.VarPath("images", imgInfo.Fingerprint) + ".rootfs"
-		if shared.PathExists(fname) {
-			err = os.Remove(fname)
+		imageDeleteFromDisk(imgInfo.Fingerprint)
+
+		err = d.cluster.ImageDelete(imgID)
+		if err != nil {
+			return errors.Wrap(err, "Error deleting image info from the database")
+		}
+
+		// Notify the other nodes about the removed image.
+		notifier, err := cluster.NewNotifier(d.State(), d.endpoints.NetworkCert(), cluster.NotifyAlive)
+		if err != nil {
+			// This isn't fatal.
+			logger.Warnf("Error notifying other nodes about image removal: %v", err)
+			return nil
+		}
+
+		err = notifier(func(client lxd.ContainerServer) error {
+			op, err := client.DeleteImage(imgInfo.Fingerprint)
 			if err != nil {
-				logger.Debugf("Error deleting image file %s: %s", fname, err)
+				return errors.Wrap(err, "Failed to request to delete image from peer node")
 			}
+
+			err = op.Wait()
+			if err != nil {
+				return errors.Wrap(err, "Failed to delete image from peer node")
+			}
+
+			return nil
+		})
+		if err != nil {
+			// This isn't fatal.
+			logger.Warnf("Failed to notify other nodes about removed image: %v", err)
+			return nil
 		}
 
-		// Remove the database entry for the image.
-		return d.cluster.ImageDelete(imgID)
+		return nil
+	}
+
+	deleteFromDisk := func() error {
+		imageDeleteFromDisk(fingerprint)
+		return nil
 	}
 
 	rmimg := func(op *operation) error {
+		if isClusterNotification(r) {
+			return deleteFromDisk()
+		}
+
 		return deleteFromAllPools()
 	}
 
@@ -1204,6 +1237,27 @@ func imageDelete(d *Daemon, r *http.Request) Response {
 	return OperationResponse(op)
 }
 
+// Helper to delete an image file from the local images directory.
+func imageDeleteFromDisk(fingerprint string) {
+	// Remove main image file.
+	fname := shared.VarPath("images", fingerprint)
+	if shared.PathExists(fname) {
+		err := os.Remove(fname)
+		if err != nil {
+			logger.Debugf("Error deleting image file %s: %s", fname, err)
+		}
+	}
+
+	// Remove the rootfs file for the image.
+	fname = shared.VarPath("images", fingerprint) + ".rootfs"
+	if shared.PathExists(fname) {
+		err := os.Remove(fname)
+		if err != nil {
+			logger.Debugf("Error deleting image file %s: %s", fname, err)
+		}
+	}
+}
+
 func doImageGet(db *db.Cluster, fingerprint string, public bool) (*api.Image, Response) {
 	_, imgInfo, err := db.ImageGet(fingerprint, public, false)
 	if err != nil {
diff --git a/test/suites/clustering.sh b/test/suites/clustering.sh
index f30bf0ce4..e5a8c6309 100644
--- a/test/suites/clustering.sh
+++ b/test/suites/clustering.sh
@@ -144,6 +144,9 @@ test_clustering_membership() {
   ! LXD_DIR="${LXD_FOUR_DIR}" lxc cluster remove node3
   LXD_DIR="${LXD_TWO_DIR}" lxc image delete testimage
 
+  # The image got deleted from the LXD_DIR tree.
+  [ "$(ls ${LXD_FOUR_DIR}/images)" = "" ] || false
+
   # Remove a node gracefully.
   LXD_DIR="${LXD_ONE_DIR}" lxc cluster remove node3
   ! LXD_DIR="${LXD_FOUR_DIR}" lxc cluster list


More information about the lxc-devel mailing list