From 00003458e2096287409ba98df66b6385d9d2caa7 Mon Sep 17 00:00:00 2001
From: Guido Trotter <ultrotter@google.com>
Date: Fri, 7 Sep 2007 11:30:50 +0000
Subject: [PATCH] Make import/export use the auxiliary ssh library to build the
 remote commands.

This avoids forgetting some parameters, as it's happening right now
(the correct known host file is not being passed)

In order to do so we split SSHCall into an auxiliary BuildSSHCmd which builds
the command but doesn't actually call it, and SSHCall itself which runs RunCmd
on top of BuildSSHCmd's result. BuildSSHCmd is then explicitely called by
import/export who has to build a more complex command to be run later.
---
 lib/backend.py | 18 +++++++++---------
 lib/ssh.py     | 35 ++++++++++++++++++++++++++---------
 2 files changed, 35 insertions(+), 18 deletions(-)

diff --git a/lib/backend.py b/lib/backend.py
index 7d38b9184..0150ea2c3 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -1022,13 +1022,14 @@ def ExportSnapshot(disk, dest_node, instance):
 
   comprcmd = "gzip"
 
-  remotecmd = utils.BuildShellCmd("ssh -q -oStrictHostKeyChecking=yes"
-                                  " -oBatchMode=yes -oEscapeChar=none"
-                                  " %s 'mkdir -p %s; cat > %s/%s'",
-                                  dest_node, destdir, destdir, destfile)
+  destcmd = utils.BuildShellCmd("mkdir -p %s; cat > %s/%s", 
+                                destdir, destdir, destfile)
+  remotecmd = ssh.BuildSSHCmd(dest_node, 'root', destcmd)
+  
+  
 
   # all commands have been checked, so we're safe to combine them
-  command = '|'.join([expcmd, comprcmd, remotecmd])
+  command = '|'.join([expcmd, comprcmd, ' '.join(remotecmd)])
 
   result = utils.RunCmd(command)
 
@@ -1168,9 +1169,8 @@ def ImportOSIntoInstance(instance, os_disk, swap_disk, src_node, src_image):
   if not os.path.exists(constants.LOG_OS_DIR):
     os.mkdir(constants.LOG_OS_DIR, 0750)
 
-  remotecmd = utils.BuildShellCmd("ssh -q -oStrictHostKeyChecking=yes"
-                                  " -oBatchMode=yes -oEscapeChar=none"
-                                  " %s 'cat %s'", src_node, src_image)
+  destcmd = utils.BuildShellCmd('cat %s', src_image)
+  remotecmd = ssh.BuildSSHCmd(src_node, 'root', destcmd)
 
   comprcmd = "gunzip"
   impcmd = utils.BuildShellCmd("(cd %s; %s -i %s -b %s -s %s &>%s)",
@@ -1178,7 +1178,7 @@ def ImportOSIntoInstance(instance, os_disk, swap_disk, src_node, src_image):
                                real_os_dev.dev_path, real_swap_dev.dev_path,
                                logfile)
 
-  command = '|'.join([remotecmd, comprcmd, impcmd])
+  command = '|'.join([' '.join(remotecmd), comprcmd, impcmd])
 
   result = utils.RunCmd(command)
 
diff --git a/lib/ssh.py b/lib/ssh.py
index 7cf772a98..55a329292 100644
--- a/lib/ssh.py
+++ b/lib/ssh.py
@@ -54,12 +54,8 @@ ASK_KEY_OPTS = [
   "-oHashKnownHosts=no",
   ]
 
-
-def SSHCall(hostname, user, command, batch=True, ask_key=False):
-  """Execute a command on a remote node.
-
-  This method has the same return value as `utils.RunCmd()`, which it
-  uses to launch ssh.
+def BuildSSHCmd(hostname, user, command, batch=True, ask_key=False):
+  """Build an ssh string to execute a command on a remote node.
 
   Args:
     hostname: the target host, string
@@ -70,7 +66,7 @@ def SSHCall(hostname, user, command, batch=True, ask_key=False):
              we can connect to an unknown host (not valid in batch mode)
 
   Returns:
-    `utils.RunResult` as for `utils.RunCmd()`
+    The ssh call to run 'command' on the remote host.
 
   """
   argv = ["ssh", "-q"]
@@ -82,8 +78,29 @@ def SSHCall(hostname, user, command, batch=True, ask_key=False):
     argv.extend(BATCH_MODE_OPTS)
   elif ask_key:
     argv.extend(ASK_KEY_OPTS)
-  argv.extend(["%s@%s" % (user, hostname), command])
-  return utils.RunCmd(argv)
+  argv.extend(["%s@%s" % (user, hostname), "'%s'" % command])
+  return argv
+
+
+def SSHCall(hostname, user, command, batch=True, ask_key=False):
+  """Execute a command on a remote node.
+
+  This method has the same return value as `utils.RunCmd()`, which it
+  uses to launch ssh.
+
+  Args:
+    hostname: the target host, string
+    user: user to auth as
+    command: the command
+    batch: if true, ssh will run in batch mode with no prompting
+    ask_key: if true, ssh will run with StrictHostKeyChecking=ask, so that
+             we can connect to an unknown host (not valid in batch mode)
+
+  Returns:
+    `utils.RunResult` as for `utils.RunCmd()`
+
+  """
+  return utils.RunCmd(BuildSSHCmd(hostname, user, command, batch=batch, ask_key=ask_key))
 
 
 def CopyFileToNode(node, filename):
-- 
GitLab