Statistics
| Branch: | Tag: | Revision:

root / lib / ssh.py @ 5c947f38

History | View | Annotate | Download (3.4 kB)

1 a8083063 Iustin Pop
#!/usr/bin/python
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 a8083063 Iustin Pop
# Copyright (C) 2006, 2007 Google Inc.
5 a8083063 Iustin Pop
#
6 a8083063 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 a8083063 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 a8083063 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 a8083063 Iustin Pop
# (at your option) any later version.
10 a8083063 Iustin Pop
#
11 a8083063 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 a8083063 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a8083063 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a8083063 Iustin Pop
# General Public License for more details.
15 a8083063 Iustin Pop
#
16 a8083063 Iustin Pop
# You should have received a copy of the GNU General Public License
17 a8083063 Iustin Pop
# along with this program; if not, write to the Free Software
18 a8083063 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a8083063 Iustin Pop
# 02110-1301, USA.
20 a8083063 Iustin Pop
21 a8083063 Iustin Pop
22 a8083063 Iustin Pop
"""Module encapsulating ssh functionality.
23 a8083063 Iustin Pop

24 a8083063 Iustin Pop
"""
25 a8083063 Iustin Pop
26 a8083063 Iustin Pop
27 a8083063 Iustin Pop
import os
28 a8083063 Iustin Pop
29 a8083063 Iustin Pop
from ganeti import logger
30 a8083063 Iustin Pop
from ganeti import utils
31 a8083063 Iustin Pop
from ganeti import errors
32 a8083063 Iustin Pop
33 a8083063 Iustin Pop
def SSHCall(hostname, user, command, batch=True, ask_key=False):
34 a8083063 Iustin Pop
  """Execute a command on a remote node.
35 a8083063 Iustin Pop

36 a8083063 Iustin Pop
  This method has the same return value as `utils.RunCmd()`, which it
37 a8083063 Iustin Pop
  uses to launch ssh.
38 a8083063 Iustin Pop

39 a8083063 Iustin Pop
  Args:
40 a8083063 Iustin Pop
    hostname: the target host, string
41 a8083063 Iustin Pop
    user: user to auth as
42 a8083063 Iustin Pop
    command: the command
43 a8083063 Iustin Pop

44 a8083063 Iustin Pop
  Returns:
45 a8083063 Iustin Pop
    `utils.RunResult` as for `utils.RunCmd()`
46 a8083063 Iustin Pop

47 a8083063 Iustin Pop
  """
48 a8083063 Iustin Pop
  argv = ["ssh", "-q", "-oEscapeChar=none"]
49 a8083063 Iustin Pop
  if batch:
50 a8083063 Iustin Pop
    argv.append("-oBatchMode=yes")
51 a8083063 Iustin Pop
    # if we are in batch mode, we can't ask the key
52 a8083063 Iustin Pop
    if ask_key:
53 a8083063 Iustin Pop
      raise errors.ProgrammerError, ("SSH call requested conflicting options")
54 a8083063 Iustin Pop
  if ask_key:
55 a8083063 Iustin Pop
    argv.append("-oStrictHostKeyChecking=ask")
56 a8083063 Iustin Pop
  else:
57 a8083063 Iustin Pop
    argv.append("-oStrictHostKeyChecking=yes")
58 a8083063 Iustin Pop
  argv.extend(["%s@%s" % (user, hostname), command])
59 a8083063 Iustin Pop
  return utils.RunCmd(argv)
60 a8083063 Iustin Pop
61 a8083063 Iustin Pop
62 a8083063 Iustin Pop
def CopyFileToNode(node, filename):
63 a8083063 Iustin Pop
  """Copy a file to another node with scp.
64 a8083063 Iustin Pop

65 a8083063 Iustin Pop
  Args:
66 a8083063 Iustin Pop
    node: node in the cluster
67 a8083063 Iustin Pop
    filename: absolute pathname of a local file
68 a8083063 Iustin Pop

69 a8083063 Iustin Pop
  Returns:
70 a8083063 Iustin Pop
    success: True/False
71 a8083063 Iustin Pop

72 a8083063 Iustin Pop
  """
73 a8083063 Iustin Pop
  if not os.path.isfile(filename):
74 a8083063 Iustin Pop
    logger.Error("file %s does not exist" % (filename))
75 a8083063 Iustin Pop
    return False
76 a8083063 Iustin Pop
77 a8083063 Iustin Pop
  if not os.path.isabs(filename):
78 a8083063 Iustin Pop
    logger.Error("file %s must be an absolute path" % (filename))
79 a8083063 Iustin Pop
    return False
80 a8083063 Iustin Pop
81 a8083063 Iustin Pop
  command = ["scp", "-q", "-p", "-oStrictHostKeyChecking=yes",
82 a8083063 Iustin Pop
             "-oBatchMode=yes", filename, "%s:%s" % (node, filename)]
83 a8083063 Iustin Pop
84 a8083063 Iustin Pop
  result = utils.RunCmd(command)
85 a8083063 Iustin Pop
86 a8083063 Iustin Pop
  if result.failed:
87 a8083063 Iustin Pop
    logger.Error("copy to node %s failed (%s) error %s,"
88 a8083063 Iustin Pop
                 " command was %s" %
89 a8083063 Iustin Pop
                 (node, result.fail_reason, result.output, result.cmd))
90 a8083063 Iustin Pop
91 a8083063 Iustin Pop
  return not result.failed
92 a8083063 Iustin Pop
93 a8083063 Iustin Pop
94 a8083063 Iustin Pop
def VerifyNodeHostname(node):
95 a8083063 Iustin Pop
  """Verify hostname consistency via SSH.
96 a8083063 Iustin Pop

97 a8083063 Iustin Pop

98 a8083063 Iustin Pop
  This functions connects via ssh to a node and compares the hostname
99 a8083063 Iustin Pop
  reported by the node to the name with have (the one that we
100 a8083063 Iustin Pop
  connected to).
101 a8083063 Iustin Pop

102 a8083063 Iustin Pop
  This is used to detect problems in ssh known_hosts files
103 a8083063 Iustin Pop
  (conflicting known hosts) and incosistencies between dns/hosts
104 a8083063 Iustin Pop
  entries and local machine names
105 a8083063 Iustin Pop

106 a8083063 Iustin Pop
  Args:
107 a8083063 Iustin Pop
    node: nodename of a host to check. can be short or full qualified hostname
108 a8083063 Iustin Pop

109 a8083063 Iustin Pop
  Returns:
110 a8083063 Iustin Pop
    (success, detail)
111 a8083063 Iustin Pop
    where
112 a8083063 Iustin Pop
      success: True/False
113 a8083063 Iustin Pop
      detail: String with details
114 a8083063 Iustin Pop

115 a8083063 Iustin Pop
  """
116 a8083063 Iustin Pop
  retval = SSHCall(node, 'root', 'hostname')
117 a8083063 Iustin Pop
118 a8083063 Iustin Pop
  if retval.failed:
119 a8083063 Iustin Pop
    msg = "ssh problem"
120 a8083063 Iustin Pop
    output = retval.output
121 a8083063 Iustin Pop
    if output:
122 a8083063 Iustin Pop
      msg += ": %s" % output
123 a8083063 Iustin Pop
    return False, msg
124 a8083063 Iustin Pop
125 a8083063 Iustin Pop
  remotehostname = retval.stdout.strip()
126 a8083063 Iustin Pop
127 a8083063 Iustin Pop
  if not remotehostname or remotehostname != node:
128 a8083063 Iustin Pop
    return False, "hostname mismatch, got %s" % remotehostname
129 a8083063 Iustin Pop
130 a8083063 Iustin Pop
  return True, "host matches"