Ignore man/*.in.
[ganeti-local] / lib / ssh.py
index 26b61d2..2f33d46 100644 (file)
@@ -29,6 +29,59 @@ import os
 from ganeti import logger
 from ganeti import utils
 from ganeti import errors
+from ganeti import constants
+
+
+__all__ = ["SSHCall", "CopyFileToNode", "VerifyNodeHostname",
+           "KNOWN_HOSTS_OPTS", "BATCH_MODE_OPTS", "ASK_KEY_OPTS"]
+
+
+KNOWN_HOSTS_OPTS = [
+  "-oGlobalKnownHostsFile=%s" % constants.SSH_KNOWN_HOSTS_FILE,
+  "-oUserKnownHostsFile=/dev/null",
+  ]
+
+# Note: BATCH_MODE conflicts with ASK_KEY
+BATCH_MODE_OPTS = [
+  "-oEscapeChar=none",
+  "-oBatchMode=yes",
+  "-oStrictHostKeyChecking=yes",
+  ]
+
+ASK_KEY_OPTS = [
+  "-oStrictHostKeyChecking=ask",
+  "-oEscapeChar=none",
+  "-oHashKnownHosts=no",
+  ]
+
+
+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
+    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:
+    The ssh call to run 'command' on the remote host.
+
+  """
+  argv = ["ssh", "-q"]
+  argv.extend(KNOWN_HOSTS_OPTS)
+  if batch:
+    # if we are in batch mode, we can't ask the key
+    if ask_key:
+      raise errors.ProgrammerError("SSH call requested conflicting options")
+    argv.extend(BATCH_MODE_OPTS)
+  elif ask_key:
+    argv.extend(ASK_KEY_OPTS)
+  argv.extend(["%s@%s" % (user, hostname), command])
+  return argv
+
 
 def SSHCall(hostname, user, command, batch=True, ask_key=False):
   """Execute a command on a remote node.
@@ -40,23 +93,15 @@ def SSHCall(hostname, user, command, batch=True, ask_key=False):
     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()`
 
   """
-  argv = ["ssh", "-q", "-oEscapeChar=none"]
-  if batch:
-    argv.append("-oBatchMode=yes")
-    # if we are in batch mode, we can't ask the key
-    if ask_key:
-      raise errors.ProgrammerError, ("SSH call requested conflicting options")
-  if ask_key:
-    argv.append("-oStrictHostKeyChecking=ask")
-  else:
-    argv.append("-oStrictHostKeyChecking=yes")
-  argv.extend(["%s@%s" % (user, hostname), command])
-  return utils.RunCmd(argv)
+  return utils.RunCmd(BuildSSHCmd(hostname, user, command, batch=batch, ask_key=ask_key))
 
 
 def CopyFileToNode(node, filename):
@@ -78,8 +123,11 @@ def CopyFileToNode(node, filename):
     logger.Error("file %s must be an absolute path" % (filename))
     return False
 
-  command = ["scp", "-q", "-p", "-oStrictHostKeyChecking=yes",
-             "-oBatchMode=yes", filename, "%s:%s" % (node, filename)]
+  command = ["scp", "-q", "-p"]
+  command.extend(KNOWN_HOSTS_OPTS)
+  command.extend(BATCH_MODE_OPTS)
+  command.append(filename)
+  command.append("%s:%s" % (node, filename))
 
   result = utils.RunCmd(command)