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

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) ===
This resolves #6805.

From d9b6c56b3f1186af5fbd311743de1a3a1c2c1cb5 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.h...@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.h...@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.h...@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.h...@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.h...@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.h...@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{
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to