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

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) ===
Signed-off-by: Tycho Andersen <tycho.ander...@canonical.com>
From 0d5b05c3f501159ca4a743790564c46b5e2948a2 Mon Sep 17 00:00:00 2001
From: Tycho Andersen <tycho.ander...@canonical.com>
Date: Tue, 4 Oct 2016 16:35:42 +0000
Subject: [PATCH] migrate: don't use ActionScript if it's not available

Signed-off-by: Tycho Andersen <tycho.ander...@canonical.com>
---
 lxd/migrate.go | 172 +++++++++++++++++++++++++++++----------------------------
 1 file changed, 88 insertions(+), 84 deletions(-)

diff --git a/lxd/migrate.go b/lxd/migrate.go
index 947fd1c..2a10261 100644
--- a/lxd/migrate.go
+++ b/lxd/migrate.go
@@ -386,98 +386,102 @@ func (s *migrationSourceWs) Do(migrateOp *operation) 
error {
                        return abort(fmt.Errorf("Formats other than criu rsync 
not understood"))
                }
 
-               /* What happens below is slightly convoluted. Due to various
-                * complications with networking, there's no easy way for criu
-                * to exit and leave the container in a frozen state for us to
-                * somehow resume later.
-                *
-                * Instead, we use what criu calls an "action-script", which is
-                * basically a callback that lets us know when the dump is
-                * done. (Unfortunately, we can't pass arguments, just an
-                * executable path, so we write a custom action script with the
-                * real command we want to run.)
-                *
-                * This script then hangs until the migration operation either
-                * finishes successfully or fails, and exits 1 or 0, which
-                * causes criu to either leave the container running or kill it
-                * as we asked.
-                */
-               dumpDone := make(chan bool, 1)
-               actionScriptOpSecret, err := shared.RandomCryptoString()
-               if err != nil {
-                       return abort(err)
-               }
-
-               actionScriptOp, err := operationCreate(
-                       operationClassWebsocket,
-                       nil,
-                       nil,
-                       func(op *operation) error {
-                               _, err := migrateOp.WaitFinal(-1)
-                               if err != nil {
-                                       return err
-                               }
-
-                               if migrateOp.status != shared.Success {
-                                       return fmt.Errorf("restore failed: %s", 
op.status.String())
-                               }
-                               return nil
-                       },
-                       nil,
-                       func(op *operation, r *http.Request, w 
http.ResponseWriter) error {
-                               secret := r.FormValue("secret")
-                               if secret == "" {
-                                       return fmt.Errorf("missing secret")
-                               }
-
-                               if secret != actionScriptOpSecret {
-                                       return os.ErrPermission
-                               }
-
-                               c, err := shared.WebsocketUpgrader.Upgrade(w, 
r, nil)
-                               if err != nil {
-                                       return err
-                               }
-
-                               dumpDone <- true
-
-                               closeMsg := 
websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")
-                               return c.WriteMessage(websocket.CloseMessage, 
closeMsg)
-                       },
-               )
-               if err != nil {
-                       return abort(err)
-               }
-
                checkpointDir, err := ioutil.TempDir("", "lxd_checkpoint_")
                if err != nil {
                        return abort(err)
                }
+               defer os.RemoveAll(checkpointDir)
+
+               if lxc.VersionAtLeast(2, 0, 4) {
+                       /* What happens below is slightly convoluted. Due to 
various
+                        * complications with networking, there's no easy way 
for criu
+                        * to exit and leave the container in a frozen state 
for us to
+                        * somehow resume later.
+                        *
+                        * Instead, we use what criu calls an "action-script", 
which is
+                        * basically a callback that lets us know when the dump 
is
+                        * done. (Unfortunately, we can't pass arguments, just 
an
+                        * executable path, so we write a custom action script 
with the
+                        * real command we want to run.)
+                        *
+                        * This script then hangs until the migration operation 
either
+                        * finishes successfully or fails, and exits 1 or 0, 
which
+                        * causes criu to either leave the container running or 
kill it
+                        * as we asked.
+                        */
+                       dumpDone := make(chan bool, 1)
+                       actionScriptOpSecret, err := shared.RandomCryptoString()
+                       if err != nil {
+                               return abort(err)
+                       }
 
-               if err := writeActionScript(checkpointDir, actionScriptOp.url, 
actionScriptOpSecret); err != nil {
-                       os.RemoveAll(checkpointDir)
-                       return abort(err)
-               }
+                       actionScriptOp, err := operationCreate(
+                               operationClassWebsocket,
+                               nil,
+                               nil,
+                               func(op *operation) error {
+                                       _, err := migrateOp.WaitFinal(-1)
+                                       if err != nil {
+                                               return err
+                                       }
+
+                                       if migrateOp.status != shared.Success {
+                                               return fmt.Errorf("restore 
failed: %s", op.status.String())
+                                       }
+                                       return nil
+                               },
+                               nil,
+                               func(op *operation, r *http.Request, w 
http.ResponseWriter) error {
+                                       secret := r.FormValue("secret")
+                                       if secret == "" {
+                                               return fmt.Errorf("missing 
secret")
+                                       }
+
+                                       if secret != actionScriptOpSecret {
+                                               return os.ErrPermission
+                                       }
+
+                                       c, err := 
shared.WebsocketUpgrader.Upgrade(w, r, nil)
+                                       if err != nil {
+                                               return err
+                                       }
+
+                                       dumpDone <- true
+
+                                       closeMsg := 
websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")
+                                       return 
c.WriteMessage(websocket.CloseMessage, closeMsg)
+                               },
+                       )
+                       if err != nil {
+                               return abort(err)
+                       }
 
-               _, err = actionScriptOp.Run()
-               if err != nil {
-                       os.RemoveAll(checkpointDir)
-                       return abort(err)
-               }
+                       if err := writeActionScript(checkpointDir, 
actionScriptOp.url, actionScriptOpSecret); err != nil {
+                               return abort(err)
+                       }
 
-               migrateDone := make(chan error, 1)
-               go func() {
-                       defer os.RemoveAll(checkpointDir)
-                       migrateDone <- s.container.Migrate(lxc.MIGRATE_DUMP, 
checkpointDir, "migration", true, true)
-               }()
+                       _, err = actionScriptOp.Run()
+                       if err != nil {
+                               return abort(err)
+                       }
 
-               select {
-               /* the checkpoint failed, let's just abort */
-               case err = <-migrateDone:
-                       return abort(err)
-               /* the dump finished, let's continue on to the restore */
-               case <-dumpDone:
-                       shared.LogDebugf("Dump finished, continuing with 
restore...")
+                       migrateDone := make(chan error, 1)
+                       go func() {
+                               migrateDone <- 
s.container.Migrate(lxc.MIGRATE_DUMP, checkpointDir, "migration", true, true)
+                       }()
+
+                       select {
+                       /* the checkpoint failed, let's just abort */
+                       case err = <-migrateDone:
+                               return abort(err)
+                       /* the dump finished, let's continue on to the restore 
*/
+                       case <-dumpDone:
+                               shared.LogDebugf("Dump finished, continuing 
with restore...")
+                       }
+               } else {
+                       if err := s.container.Migrate(lxc.MIGRATE_DUMP, 
checkpointDir, "migration", true, false); err != nil {
+                               return abort(err)
+                       }
                }
 
                /*
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to