[lxc-devel] [lxd/master] Improve cancellation handling in client
stgraber on Github
lxc-bot at linuxcontainers.org
Fri Nov 2 04:09:50 UTC 2018
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20181102/11ca106f/attachment.bin>
-------------- next part --------------
From 8165c24cce7f27d1df3ce45c3355cb2014449dd6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 1 Nov 2018 23:29:28 -0400
Subject: [PATCH 1/2] lxc: Switch all progress op handling to cancelable
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Closes #5233
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxc/action.go | 7 +++++--
lxc/copy.go | 2 +-
lxc/image.go | 3 ++-
lxc/import.go | 4 +++-
lxc/storage_volume.go | 3 ++-
lxc/utils/cancel.go | 29 ++++++++++++++++++++++++++---
6 files changed, 39 insertions(+), 9 deletions(-)
diff --git a/lxc/action.go b/lxc/action.go
index 9c74fe668e..98c811f825 100644
--- a/lxc/action.go
+++ b/lxc/action.go
@@ -189,12 +189,15 @@ func (c *cmdAction) doAction(action string, conf *config.Config, nameArg string)
return err
}
- err = op.Wait()
- progress.Done("")
+ // Wait for operation to finish
+ err = utils.CancelableWait(op, &progress)
if err != nil {
+ progress.Done("")
return fmt.Errorf("%s\n"+i18n.G("Try `lxc info --show-log %s` for more info"), err, nameArg)
}
+ progress.Done("")
+
return nil
}
diff --git a/lxc/copy.go b/lxc/copy.go
index eef1b28be6..f34b05d74e 100644
--- a/lxc/copy.go
+++ b/lxc/copy.go
@@ -323,7 +323,7 @@ func (c *cmdCopy) copyContainer(conf *config.Config, sourceResource string,
}
// Wait for the copy to complete
- err = op.Wait()
+ err = utils.CancelableWait(op, &progress)
if err != nil {
progress.Done("")
return err
diff --git a/lxc/image.go b/lxc/image.go
index 5a603e4eaa..9a6825a381 100644
--- a/lxc/image.go
+++ b/lxc/image.go
@@ -749,7 +749,8 @@ func (c *cmdImageImport) Run(cmd *cobra.Command, args []string) error {
return err
}
- err = op.Wait()
+ // Wait for operation to finish
+ err = utils.CancelableWait(op, &progress)
if err != nil {
progress.Done("")
return err
diff --git a/lxc/import.go b/lxc/import.go
index 74d4bc0d19..6d2ea724d7 100644
--- a/lxc/import.go
+++ b/lxc/import.go
@@ -85,11 +85,13 @@ func (c *cmdImport) Run(cmd *cobra.Command, args []string) error {
return err
}
- err = op.Wait()
+ // Wait for operation to finish
+ err = utils.CancelableWait(op, &progress)
if err != nil {
progress.Done("")
return err
}
+
progress.Done("")
return nil
diff --git a/lxc/storage_volume.go b/lxc/storage_volume.go
index 7f7733ea59..ce6038b01c 100644
--- a/lxc/storage_volume.go
+++ b/lxc/storage_volume.go
@@ -431,7 +431,8 @@ func (c *cmdStorageVolumeCopy) Run(cmd *cobra.Command, args []string) error {
return err
}
- err = op.Wait()
+ // Wait for operation to finish
+ err = utils.CancelableWait(op, &progress)
if err != nil {
progress.Done("")
return err
diff --git a/lxc/utils/cancel.go b/lxc/utils/cancel.go
index 8b378db653..0b0a684288 100644
--- a/lxc/utils/cancel.go
+++ b/lxc/utils/cancel.go
@@ -11,7 +11,20 @@ import (
)
// CancelableWait waits for an operation and cancel it on SIGINT/SIGTERM
-func CancelableWait(op lxd.RemoteOperation, progress *ProgressRenderer) error {
+func CancelableWait(rawOp interface{}, progress *ProgressRenderer) error {
+ var op lxd.Operation
+ var rop lxd.RemoteOperation
+
+ // Check what type of operation we're dealing with
+ switch v := rawOp.(type) {
+ case lxd.Operation:
+ op = v
+ case lxd.RemoteOperation:
+ rop = v
+ default:
+ return fmt.Errorf("Invalid operation type for CancelableWait")
+ }
+
// Signal handling
chSignal := make(chan os.Signal)
signal.Notify(chSignal, os.Interrupt)
@@ -19,17 +32,27 @@ func CancelableWait(op lxd.RemoteOperation, progress *ProgressRenderer) error {
// Operation handling
chOperation := make(chan error)
go func() {
- chOperation <- op.Wait()
+ if op != nil {
+ chOperation <- op.Wait()
+ } else {
+ chOperation <- rop.Wait()
+ }
close(chOperation)
}()
count := 0
for {
+ var err error
+
select {
case err := <-chOperation:
return err
case <-chSignal:
- err := op.CancelTarget()
+ if op != nil {
+ err = op.Cancel()
+ } else {
+ err = rop.CancelTarget()
+ }
if err == nil {
return fmt.Errorf(i18n.G("Remote operation canceled by user"))
}
From 293ebe9aae481a365fce0b2492a3403060527f6d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 2 Nov 2018 00:08:55 -0400
Subject: [PATCH 2/2] client: Fix cancelation of image download
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
client/simplestreams_images.go | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/client/simplestreams_images.go b/client/simplestreams_images.go
index 7f67ad9554..ac2bae5a31 100644
--- a/client/simplestreams_images.go
+++ b/client/simplestreams_images.go
@@ -84,6 +84,11 @@ func (r *ProtocolSimpleStreams) GetImageFile(fingerprint string, req ImageFileRe
size, err := shared.DownloadFileSha256(r.http, r.httpUserAgent, req.ProgressHandler, req.Canceler, filename, url, sha256, target)
if err != nil {
+ // Handle cancelation
+ if err.Error() == "net/http: request canceled" {
+ return -1, err
+ }
+
// Try over https
url = fmt.Sprintf("%s/%s", r.httpHost, path)
size, err = shared.DownloadFileSha256(r.http, r.httpUserAgent, req.ProgressHandler, req.Canceler, filename, url, sha256, target)
More information about the lxc-devel
mailing list