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