Hi everyone,

I've applied to Ganeti as part of Google Summer of Code. As per Guido's 
suggestion, I'm working on fixing the Issue 
235<https://code.google.com/p/ganeti/issues/detail?id=235>, 
allow non-standard ssh ports. I'm attaching the patch which allows 
non-standard port for gnt-node add command. I couldn't get the code from 
the master repo to compile, hence I developed and tested it on 2.7.0~rc1. 
The relevant code is same in both of them, hence the patch should be 
compatible.

Changes include

   - Implemented '--ssh-port <port>' option in gnt-node
   - Included an additional option for port in bootstrap.py's - 
   .RunNodeSetupCmd, _SetupSSH; ssh.py's BuildCmd and _BuildSshOptions.
   - Modified SshRunner._BuildSshOptions to include "-p <port>" option for 
   ssh command.

I'm having a little trouble performing the complete "node add" operation 
though, irrespective of this patch. I get the following error when I issue 
"gnt-node add <nodename>"

2013-05-14 12:34:46,939: Unhandled Ganeti error: Given cluster certificate 
does not match local key
Failure: command execution error:
Command 'ssh -oEscapeChar=none -oHashKnownHosts=no 
-oGlobalKnownHostsFile=/var/lib/ganeti/known_hosts 
-oUserKnownHostsFile=/dev/null -oCheckHostIp=no -p1111 
-oStrictHostKeyChecking=ask [email protected] 
/usr/local/lib/ganeti/prepare-node-join' failed: exited with exit code 1

I kindly request your suggestions and feedback.

Thanks,

Pulkit Singhal
commit b5c769224432761698c7eccd3d23e5dd7da2444a
Author: pulkit <pulkit@lab-pc>
Date:   Tue May 14 09:58:48 2013 -0400

    fixed ssh port issue

diff --git a/lib/bootstrap.py b/lib/bootstrap.py
index 620de88..eaed25c 100644
--- a/lib/bootstrap.py
+++ b/lib/bootstrap.py
@@ -257,7 +257,7 @@ def _WaitForMasterDaemon():
 
 
 def RunNodeSetupCmd(cluster_name, node, basecmd, debug, verbose,
-                    use_cluster_key, ask_key, strict_host_check, data):
+                    use_cluster_key, ask_key, strict_host_check, data, port):
   """Runs a command to configure something on a remote machine.
 
   @type cluster_name: string
@@ -280,7 +280,6 @@ def RunNodeSetupCmd(cluster_name, node, basecmd, debug, verbose,
 
   """
   cmd = [basecmd]
-
   # Pass --debug/--verbose to the external script if set on our invocation
   if debug:
     cmd.append("--debug")
@@ -295,7 +294,7 @@ def RunNodeSetupCmd(cluster_name, node, basecmd, debug, verbose,
                        utils.ShellQuoteArgs(cmd),
                        batch=False, ask_key=ask_key, quiet=False,
                        strict_host_check=strict_host_check,
-                       use_cluster_key=use_cluster_key)
+                       use_cluster_key=use_cluster_key, port=port)
 
   tempfh = tempfile.TemporaryFile()
   try:
diff --git a/lib/cli.py b/lib/cli.py
index c82de33..c65a87b 100644
--- a/lib/cli.py
+++ b/lib/cli.py
@@ -185,6 +185,7 @@ __all__ = [
   "SPECS_DISK_SIZE_OPT",
   "SPECS_MEM_SIZE_OPT",
   "SPECS_NIC_COUNT_OPT",
+  "SSH_PORT",
   "IPOLICY_DISK_TEMPLATES",
   "IPOLICY_VCPU_RATIO",
   "SPICE_CACERT_OPT",
@@ -903,6 +904,10 @@ SPECS_NIC_COUNT_OPT = cli_option("--specs-nic-count", dest="ispecs_nic_count",
                                  help="NIC count specs: list of key=value,"
                                  " where key is one of min, max, std")
 
+SSH_PORT = cli_option("--ssh-port", dest="ssh_port",
+                                 type="string", default='22',
+                                 help="Node's custom ssh port")
+
 IPOLICY_DISK_TEMPLATES = cli_option("--ipolicy-disk-templates",
                                     dest="ipolicy_disk_templates",
                                     type="list", default=None,
diff --git a/lib/client/gnt_node.py b/lib/client/gnt_node.py
index e15a6d8..fbe3117 100644
--- a/lib/client/gnt_node.py
+++ b/lib/client/gnt_node.py
@@ -215,7 +215,7 @@ def _SetupSSH(options, cluster_name, node):
 
   bootstrap.RunNodeSetupCmd(cluster_name, node, pathutils.PREPARE_NODE_JOIN,
                             options.debug, options.verbose, False,
-                            options.ssh_key_check, options.ssh_key_check, data)
+                            options.ssh_key_check, options.ssh_key_check, data, options.ssh_port)
 
 
 @UsesRPC
@@ -229,6 +229,7 @@ def AddNode(opts, args):
   @return: the desired exit code
 
   """
   cl = GetClient()
   node = netutils.GetHostname(name=args[0]).name
   readd = opts.readd
@@ -1081,8 +1082,8 @@ commands = {
     [SECONDARY_IP_OPT, READD_OPT, NOSSH_KEYCHECK_OPT, NODE_FORCE_JOIN_OPT,
      NONODE_SETUP_OPT, VERBOSE_OPT, NODEGROUP_OPT, PRIORITY_OPT,
      CAPAB_MASTER_OPT, CAPAB_VM_OPT, NODE_PARAMS_OPT, HV_STATE_OPT,
-     DISK_STATE_OPT],
-    "[-s ip] [--readd] [--no-ssh-key-check] [--force-join]"
+     DISK_STATE_OPT, SSH_PORT],
+    "[-s ip] [--ssh-port port] [--readd] [--no-ssh-key-check] [--force-join]"
     " [--no-node-setup] [--verbose]"
     " <node_name>",
     "Add a node to the cluster"),
diff --git a/lib/ssh.py b/lib/ssh.py
index dba13df..c3486ec 100644
--- a/lib/ssh.py
+++ b/lib/ssh.py
@@ -123,7 +123,7 @@ class SshRunner:
     self.ipv6 = ipv6
 
   def _BuildSshOptions(self, batch, ask_key, use_cluster_key,
-                       strict_host_check, private_key=None, quiet=True):
+                       strict_host_check, port, private_key=None, quiet=True):
     """Builds a list with needed SSH options.
 
     @param batch: same as ssh's batch option
@@ -139,6 +139,7 @@ class SshRunner:
     @return: the list of options ready to use in L{utils.process.RunCmd}
 
     """
     options = [
       "-oEscapeChar=none",
       "-oHashKnownHosts=no",
@@ -155,6 +156,8 @@ class SshRunner:
 
     if private_key:
       options.append("-i%s" % private_key)
+    if port:
+      options.append("-p%s" % port)
 
     # TODO: Too many boolean options, maybe convert them to more descriptive
     # constants.
@@ -186,7 +189,7 @@ class SshRunner:
 
     return options
 
-  def BuildCmd(self, hostname, user, command, batch=True, ask_key=False,
+  def BuildCmd(self, hostname, user, command, port, batch=True, ask_key=False,
                tty=False, use_cluster_key=True, strict_host_check=True,
                private_key=None, quiet=True):
     """Build an ssh command to execute a command on a remote node.
@@ -209,7 +212,7 @@ class SshRunner:
     """
     argv = [constants.SSH]
     argv.extend(self._BuildSshOptions(batch, ask_key, use_cluster_key,
-                                      strict_host_check, private_key,
+                                      strict_host_check, port, private_key,
                                       quiet=quiet))
     if tty:
       argv.extend(["-t", "-t"])

Reply via email to