Statistics
| Branch: | Tag: | Revision:

root / lib / ssh.py @ 098c0958

History | View | Annotate | Download (3.4 kB)

1
#!/usr/bin/python
2
#
3

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

    
21

    
22
"""Module encapsulating ssh functionality.
23

24
"""
25

    
26

    
27
import os
28

    
29
from ganeti import logger
30
from ganeti import utils
31
from ganeti import errors
32

    
33
def SSHCall(hostname, user, command, batch=True, ask_key=False):
34
  """Execute a command on a remote node.
35

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

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

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

47
  """
48
  argv = ["ssh", "-q", "-oEscapeChar=none"]
49
  if batch:
50
    argv.append("-oBatchMode=yes")
51
    # if we are in batch mode, we can't ask the key
52
    if ask_key:
53
      raise errors.ProgrammerError, ("SSH call requested conflicting options")
54
  if ask_key:
55
    argv.append("-oStrictHostKeyChecking=ask")
56
  else:
57
    argv.append("-oStrictHostKeyChecking=yes")
58
  argv.extend(["%s@%s" % (user, hostname), command])
59
  return utils.RunCmd(argv)
60

    
61

    
62
def CopyFileToNode(node, filename):
63
  """Copy a file to another node with scp.
64

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

69
  Returns:
70
    success: True/False
71

72
  """
73
  if not os.path.isfile(filename):
74
    logger.Error("file %s does not exist" % (filename))
75
    return False
76

    
77
  if not os.path.isabs(filename):
78
    logger.Error("file %s must be an absolute path" % (filename))
79
    return False
80

    
81
  command = ["scp", "-q", "-p", "-oStrictHostKeyChecking=yes",
82
             "-oBatchMode=yes", filename, "%s:%s" % (node, filename)]
83

    
84
  result = utils.RunCmd(command)
85

    
86
  if result.failed:
87
    logger.Error("copy to node %s failed (%s) error %s,"
88
                 " command was %s" %
89
                 (node, result.fail_reason, result.output, result.cmd))
90

    
91
  return not result.failed
92

    
93

    
94
def VerifyNodeHostname(node):
95
  """Verify hostname consistency via SSH.
96

97

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

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

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

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

115
  """
116
  retval = SSHCall(node, 'root', 'hostname')
117

    
118
  if retval.failed:
119
    msg = "ssh problem"
120
    output = retval.output
121
    if output:
122
      msg += ": %s" % output
123
    return False, msg
124

    
125
  remotehostname = retval.stdout.strip()
126

    
127
  if not remotehostname or remotehostname != node:
128
    return False, "hostname mismatch, got %s" % remotehostname
129

    
130
  return True, "host matches"