[lxc-devel] [lxd/master] Add push and relay mode to image copy

monstermunchkin on Github lxc-bot at linuxcontainers.org
Fri Apr 3 09:56:47 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 322 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200403/8682b704/attachment.bin>
-------------- next part --------------
From d9b6c56b3f1186af5fbd311743de1a3a1c2c1cb5 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Thu, 2 Apr 2020 19:21:48 +0200
Subject: [PATCH 1/3] client/interfaces: Add Mode to ImageCopyArgs

This adds the Mode field to ImageCopyArgs.

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 client/interfaces.go | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/client/interfaces.go b/client/interfaces.go
index ec5c3de008..16b51b9342 100644
--- a/client/interfaces.go
+++ b/client/interfaces.go
@@ -393,6 +393,9 @@ type ImageCopyArgs struct {
 
 	// The image type to use for resolution
 	Type string
+
+	// The transfer mode, can be "pull" (default), "push" or "relay"
+	Mode string
 }
 
 // The StoragePoolVolumeCopyArgs struct is used to pass additional options

From 6c9573a39b68a7d678a08daf8622d63505297fbe Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Thu, 2 Apr 2020 19:18:53 +0200
Subject: [PATCH 2/3] lxc/image: Add mode flag to image copy

This adds the mode flag to image copy. It accepts the same values as for
instance copy: pull (default), push and relay.

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxc/image.go | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lxc/image.go b/lxc/image.go
index eb04c11c0e..d421ae6ce0 100644
--- a/lxc/image.go
+++ b/lxc/image.go
@@ -118,6 +118,7 @@ type cmdImageCopy struct {
 	flagCopyAliases bool
 	flagAutoUpdate  bool
 	flagVM          bool
+	flagMode        string
 }
 
 func (c *cmdImageCopy) Command() *cobra.Command {
@@ -136,6 +137,7 @@ It requires the source to be an alias and for it to be public.`))
 	cmd.Flags().BoolVar(&c.flagAutoUpdate, "auto-update", false, i18n.G("Keep the image up to date after initial copy"))
 	cmd.Flags().StringArrayVar(&c.flagAliases, "alias", nil, i18n.G("New aliases to add to the image")+"``")
 	cmd.Flags().BoolVar(&c.flagVM, "vm", false, i18n.G("Copy virtual machine images"))
+	cmd.Flags().StringVar(&c.flagMode, "mode", "pull", i18n.G("Transfer mode. One of pull (default), push or relay")+"``")
 	cmd.RunE = c.Run
 
 	return cmd
@@ -210,6 +212,7 @@ func (c *cmdImageCopy) Run(cmd *cobra.Command, args []string) error {
 		AutoUpdate: c.flagAutoUpdate,
 		Public:     c.flagPublic,
 		Type:       imageType,
+		Mode:       c.flagMode,
 	}
 
 	// Do the copy

From 0e5957084df4ebd0bc93c1968575ebe48b29db04 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Thu, 2 Apr 2020 22:06:08 +0200
Subject: [PATCH 3/3] client: Add relay mode for image copy

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 client/lxd_images.go | 109 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 109 insertions(+)

diff --git a/client/lxd_images.go b/client/lxd_images.go
index 50d90e6616..38a8193e90 100644
--- a/client/lxd_images.go
+++ b/client/lxd_images.go
@@ -608,6 +608,115 @@ func (r *ProtocolLXD) CopyImage(source ImageServer, image api.Image, args *Image
 		return nil, err
 	}
 
+	// Relay mode
+	if args != nil && args.Mode == "relay" {
+		metaFile, err := ioutil.TempFile("", "lxc_image_")
+		if err != nil {
+			return nil, err
+		}
+		defer os.Remove(metaFile.Name())
+
+		rootfsFile, err := ioutil.TempFile("", "lxc_image_")
+		if err != nil {
+			return nil, err
+		}
+		defer os.Remove(rootfsFile.Name())
+
+		// Import image
+		req := ImageFileRequest{
+			MetaFile:   metaFile,
+			RootfsFile: rootfsFile,
+		}
+
+		_, err = source.GetImageFile(image.Fingerprint, req)
+		if err != nil {
+			return nil, err
+		}
+
+		// Export image
+		_, err = metaFile.Seek(0, 0)
+		if err != nil {
+			return nil, err
+		}
+
+		_, err = rootfsFile.Seek(0, 0)
+		if err != nil {
+			return nil, err
+		}
+
+		imagePost := api.ImagesPost{}
+		imagePost.Public = args.Public
+
+		createArgs := &ImageCreateArgs{
+			MetaFile:   metaFile,
+			MetaName:   image.Filename,
+			RootfsFile: rootfsFile,
+			RootfsName: image.Filename,
+			Type:       image.Type,
+		}
+
+		rop := remoteOperation{
+			chDone: make(chan bool),
+		}
+
+		// For older servers, apply the aliases after copy
+		if !r.HasExtension("image_create_aliases") && image.Aliases != nil {
+			rop.chPost = make(chan bool)
+
+			go func() {
+				defer close(rop.chPost)
+
+				// Wait for the main operation to finish
+				<-rop.chDone
+				if rop.err != nil {
+					return
+				}
+
+				// Get the operation data
+				op, err := rop.GetTarget()
+				if err != nil {
+					return
+				}
+
+				// Extract the fingerprint
+				fingerprint := op.Metadata["fingerprint"].(string)
+
+				// Add the aliases
+				for _, entry := range image.Aliases {
+					alias := api.ImageAliasesPost{}
+					alias.Name = entry.Name
+					alias.Target = fingerprint
+
+					r.CreateImageAlias(alias)
+				}
+			}()
+		}
+
+		go func() {
+			defer close(rop.chDone)
+
+			op, err := r.CreateImage(imagePost, createArgs)
+			if err != nil {
+				rop.err = remoteOperationError("Failed to copy image", nil)
+				return
+			}
+
+			rop.targetOp = op
+
+			for _, handler := range rop.handlers {
+				rop.targetOp.AddHandler(handler)
+			}
+
+			err = rop.targetOp.Wait()
+			if err != nil {
+				rop.err = remoteOperationError("Failed to copy image", nil)
+				return
+			}
+		}()
+
+		return &rop, nil
+	}
+
 	// Prepare the copy request
 	req := api.ImagesPost{
 		Source: &api.ImagesPostSource{


More information about the lxc-devel mailing list