Statistics
| Branch: | Tag: | Revision:

root / qa / qa_utils.py @ 305cb9bb

History | View | Annotate | Download (5.4 kB)

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

24 cec9845c Michael Hanselmann
"""
25 cec9845c Michael Hanselmann
26 cec9845c Michael Hanselmann
import os
27 23269c5b Michael Hanselmann
import sys
28 cec9845c Michael Hanselmann
import subprocess
29 cec9845c Michael Hanselmann
30 cec9845c Michael Hanselmann
from ganeti import utils
31 cec9845c Michael Hanselmann
32 cec9845c Michael Hanselmann
import qa_config
33 cec9845c Michael Hanselmann
import qa_error
34 cec9845c Michael Hanselmann
35 cec9845c Michael Hanselmann
36 23269c5b Michael Hanselmann
_INFO_SEQ = None
37 23269c5b Michael Hanselmann
_WARNING_SEQ = None
38 23269c5b Michael Hanselmann
_ERROR_SEQ = None
39 23269c5b Michael Hanselmann
_RESET_SEQ = None
40 23269c5b Michael Hanselmann
41 23269c5b Michael Hanselmann
42 23269c5b Michael Hanselmann
def _SetupColours():
43 23269c5b Michael Hanselmann
  """Initializes the colour constants.
44 23269c5b Michael Hanselmann

45 23269c5b Michael Hanselmann
  """
46 23269c5b Michael Hanselmann
  global _INFO_SEQ, _WARNING_SEQ, _ERROR_SEQ, _RESET_SEQ
47 23269c5b Michael Hanselmann
48 dfe11bad Michael Hanselmann
  # Don't use colours if stdout isn't a terminal
49 dfe11bad Michael Hanselmann
  if not sys.stdout.isatty():
50 dfe11bad Michael Hanselmann
    return
51 dfe11bad Michael Hanselmann
52 23269c5b Michael Hanselmann
  try:
53 23269c5b Michael Hanselmann
    import curses
54 23269c5b Michael Hanselmann
  except ImportError:
55 23269c5b Michael Hanselmann
    # Don't use colours if curses module can't be imported
56 23269c5b Michael Hanselmann
    return
57 23269c5b Michael Hanselmann
58 23269c5b Michael Hanselmann
  curses.setupterm()
59 23269c5b Michael Hanselmann
60 23269c5b Michael Hanselmann
  _RESET_SEQ = curses.tigetstr("op")
61 23269c5b Michael Hanselmann
62 23269c5b Michael Hanselmann
  setaf = curses.tigetstr("setaf")
63 23269c5b Michael Hanselmann
  _INFO_SEQ = curses.tparm(setaf, curses.COLOR_GREEN)
64 23269c5b Michael Hanselmann
  _WARNING_SEQ = curses.tparm(setaf, curses.COLOR_YELLOW)
65 23269c5b Michael Hanselmann
  _ERROR_SEQ = curses.tparm(setaf, curses.COLOR_RED)
66 23269c5b Michael Hanselmann
67 23269c5b Michael Hanselmann
68 23269c5b Michael Hanselmann
_SetupColours()
69 23269c5b Michael Hanselmann
70 23269c5b Michael Hanselmann
71 eaef8a05 Michael Hanselmann
def AssertIn(item, sequence):
72 eaef8a05 Michael Hanselmann
  """Raises an error when item is not in sequence.
73 eaef8a05 Michael Hanselmann

74 eaef8a05 Michael Hanselmann
  """
75 eaef8a05 Michael Hanselmann
  if item not in sequence:
76 eaef8a05 Michael Hanselmann
    raise qa_error.Error('%r not in %r' % (item, sequence))
77 eaef8a05 Michael Hanselmann
78 eaef8a05 Michael Hanselmann
79 e8ae0c20 Michael Hanselmann
def AssertEqual(first, second):
80 cec9845c Michael Hanselmann
  """Raises an error when values aren't equal.
81 cec9845c Michael Hanselmann

82 cec9845c Michael Hanselmann
  """
83 cec9845c Michael Hanselmann
  if not first == second:
84 e8ae0c20 Michael Hanselmann
    raise qa_error.Error('%r == %r' % (first, second))
85 e8ae0c20 Michael Hanselmann
86 e8ae0c20 Michael Hanselmann
87 e8ae0c20 Michael Hanselmann
def AssertNotEqual(first, second):
88 e8ae0c20 Michael Hanselmann
  """Raises an error when values are equal.
89 e8ae0c20 Michael Hanselmann

90 e8ae0c20 Michael Hanselmann
  """
91 e8ae0c20 Michael Hanselmann
  if not first != second:
92 e8ae0c20 Michael Hanselmann
    raise qa_error.Error('%r != %r' % (first, second))
93 cec9845c Michael Hanselmann
94 cec9845c Michael Hanselmann
95 cec9845c Michael Hanselmann
def GetSSHCommand(node, cmd, strict=True):
96 cec9845c Michael Hanselmann
  """Builds SSH command to be executed.
97 cec9845c Michael Hanselmann

98 c68d1f43 Michael Hanselmann
  Args:
99 c68d1f43 Michael Hanselmann
  - node: Node the command should run on
100 c68d1f43 Michael Hanselmann
  - cmd: Command to be executed as a list with all parameters
101 c68d1f43 Michael Hanselmann
  - strict: Whether to enable strict host key checking
102 c68d1f43 Michael Hanselmann

103 cec9845c Michael Hanselmann
  """
104 305cb9bb Michael Hanselmann
  args = [ 'ssh', '-oEscapeChar=none', '-oBatchMode=yes', '-l', 'root', '-t' ]
105 cec9845c Michael Hanselmann
106 cec9845c Michael Hanselmann
  if strict:
107 cec9845c Michael Hanselmann
    tmp = 'yes'
108 cec9845c Michael Hanselmann
  else:
109 cec9845c Michael Hanselmann
    tmp = 'no'
110 cec9845c Michael Hanselmann
  args.append('-oStrictHostKeyChecking=%s' % tmp)
111 cec9845c Michael Hanselmann
  args.append('-oClearAllForwardings=yes')
112 cec9845c Michael Hanselmann
  args.append('-oForwardAgent=yes')
113 cec9845c Michael Hanselmann
  args.append(node)
114 cec9845c Michael Hanselmann
115 cec9845c Michael Hanselmann
  if qa_config.options.dry_run:
116 cec9845c Michael Hanselmann
    prefix = 'exit 0; '
117 cec9845c Michael Hanselmann
  else:
118 cec9845c Michael Hanselmann
    prefix = ''
119 cec9845c Michael Hanselmann
120 cec9845c Michael Hanselmann
  args.append(prefix + cmd)
121 cec9845c Michael Hanselmann
122 cec9845c Michael Hanselmann
  print 'SSH:', utils.ShellQuoteArgs(args)
123 cec9845c Michael Hanselmann
124 cec9845c Michael Hanselmann
  return args
125 cec9845c Michael Hanselmann
126 cec9845c Michael Hanselmann
127 cec9845c Michael Hanselmann
def StartSSH(node, cmd, strict=True):
128 cec9845c Michael Hanselmann
  """Starts SSH.
129 cec9845c Michael Hanselmann

130 cec9845c Michael Hanselmann
  """
131 4b62db14 Michael Hanselmann
  return subprocess.Popen(GetSSHCommand(node, cmd, strict=strict),
132 4b62db14 Michael Hanselmann
                          shell=False)
133 4b62db14 Michael Hanselmann
134 4b62db14 Michael Hanselmann
135 4b62db14 Michael Hanselmann
def GetCommandOutput(node, cmd):
136 4b62db14 Michael Hanselmann
  """Returns the output of a command executed on the given node.
137 4b62db14 Michael Hanselmann

138 4b62db14 Michael Hanselmann
  """
139 4b62db14 Michael Hanselmann
  p = subprocess.Popen(GetSSHCommand(node, cmd),
140 4b62db14 Michael Hanselmann
                       shell=False, stdout=subprocess.PIPE)
141 4b62db14 Michael Hanselmann
  AssertEqual(p.wait(), 0)
142 4b62db14 Michael Hanselmann
  return p.stdout.read()
143 cec9845c Michael Hanselmann
144 cec9845c Michael Hanselmann
145 cec9845c Michael Hanselmann
def UploadFile(node, src):
146 cec9845c Michael Hanselmann
  """Uploads a file to a node and returns the filename.
147 cec9845c Michael Hanselmann

148 cec9845c Michael Hanselmann
  Caller needs to remove the returned file on the node when it's not needed
149 cec9845c Michael Hanselmann
  anymore.
150 cec9845c Michael Hanselmann
  """
151 cec9845c Michael Hanselmann
  # Make sure nobody else has access to it while preserving local permissions
152 cec9845c Michael Hanselmann
  mode = os.stat(src).st_mode & 0700
153 cec9845c Michael Hanselmann
154 cec9845c Michael Hanselmann
  cmd = ('tmp=$(tempfile --mode %o --prefix gnt) && '
155 cec9845c Michael Hanselmann
         '[[ -f "${tmp}" ]] && '
156 cec9845c Michael Hanselmann
         'cat > "${tmp}" && '
157 cec9845c Michael Hanselmann
         'echo "${tmp}"') % mode
158 cec9845c Michael Hanselmann
159 cec9845c Michael Hanselmann
  f = open(src, 'r')
160 cec9845c Michael Hanselmann
  try:
161 cec9845c Michael Hanselmann
    p = subprocess.Popen(GetSSHCommand(node, cmd), shell=False, stdin=f,
162 cec9845c Michael Hanselmann
                         stdout=subprocess.PIPE)
163 cec9845c Michael Hanselmann
    AssertEqual(p.wait(), 0)
164 cec9845c Michael Hanselmann
165 cec9845c Michael Hanselmann
    # Return temporary filename
166 cec9845c Michael Hanselmann
    return p.stdout.read().strip()
167 cec9845c Michael Hanselmann
  finally:
168 cec9845c Michael Hanselmann
    f.close()
169 5d640672 Michael Hanselmann
170 5d640672 Michael Hanselmann
171 4b62db14 Michael Hanselmann
def _ResolveName(cmd, key):
172 4b62db14 Michael Hanselmann
  """Helper function.
173 4b62db14 Michael Hanselmann

174 4b62db14 Michael Hanselmann
  """
175 4b62db14 Michael Hanselmann
  master = qa_config.GetMasterNode()
176 4b62db14 Michael Hanselmann
177 4b62db14 Michael Hanselmann
  output = GetCommandOutput(master['primary'], utils.ShellQuoteArgs(cmd))
178 4b62db14 Michael Hanselmann
  for line in output.splitlines():
179 4b62db14 Michael Hanselmann
    (lkey, lvalue) = line.split(':', 1)
180 4b62db14 Michael Hanselmann
    if lkey == key:
181 4b62db14 Michael Hanselmann
      return lvalue.lstrip()
182 4b62db14 Michael Hanselmann
  raise KeyError("Key not found")
183 4b62db14 Michael Hanselmann
184 4b62db14 Michael Hanselmann
185 5d640672 Michael Hanselmann
def ResolveInstanceName(instance):
186 5d640672 Michael Hanselmann
  """Gets the full name of an instance.
187 5d640672 Michael Hanselmann

188 5d640672 Michael Hanselmann
  """
189 e8ae0c20 Michael Hanselmann
  return _ResolveName(['gnt-instance', 'info', instance['name']],
190 4b62db14 Michael Hanselmann
                      'Instance name')
191 4b62db14 Michael Hanselmann
192 4b62db14 Michael Hanselmann
193 4b62db14 Michael Hanselmann
def ResolveNodeName(node):
194 4b62db14 Michael Hanselmann
  """Gets the full name of a node.
195 4b62db14 Michael Hanselmann

196 4b62db14 Michael Hanselmann
  """
197 4b62db14 Michael Hanselmann
  return _ResolveName(['gnt-node', 'info', node['primary']],
198 4b62db14 Michael Hanselmann
                      'Node name')
199 4b62db14 Michael Hanselmann
200 4b62db14 Michael Hanselmann
201 4b62db14 Michael Hanselmann
def GetNodeInstances(node, secondaries=False):
202 4b62db14 Michael Hanselmann
  """Gets a list of instances on a node.
203 4b62db14 Michael Hanselmann

204 4b62db14 Michael Hanselmann
  """
205 5d640672 Michael Hanselmann
  master = qa_config.GetMasterNode()
206 4b62db14 Michael Hanselmann
  node_name = ResolveNodeName(node)
207 5d640672 Michael Hanselmann
208 4b62db14 Michael Hanselmann
  # Get list of all instances
209 4b62db14 Michael Hanselmann
  cmd = ['gnt-instance', 'list', '--separator=:', '--no-headers',
210 4b62db14 Michael Hanselmann
         '--output=name,pnode,snodes']
211 4b62db14 Michael Hanselmann
  output = GetCommandOutput(master['primary'], utils.ShellQuoteArgs(cmd))
212 4b62db14 Michael Hanselmann
213 4b62db14 Michael Hanselmann
  instances = []
214 4b62db14 Michael Hanselmann
  for line in output.splitlines():
215 4b62db14 Michael Hanselmann
    (name, pnode, snodes) = line.split(':', 2)
216 4b62db14 Michael Hanselmann
    if ((not secondaries and pnode == node_name) or
217 4b62db14 Michael Hanselmann
        (secondaries and node_name in snodes.split(','))):
218 4b62db14 Michael Hanselmann
      instances.append(name)
219 5d640672 Michael Hanselmann
220 4b62db14 Michael Hanselmann
  return instances
221 23269c5b Michael Hanselmann
222 23269c5b Michael Hanselmann
223 dfe11bad Michael Hanselmann
def _FormatWithColor(text, seq):
224 dfe11bad Michael Hanselmann
  if not seq:
225 dfe11bad Michael Hanselmann
    return text
226 dfe11bad Michael Hanselmann
  return "%s%s%s" % (seq, text, _RESET_SEQ)
227 23269c5b Michael Hanselmann
228 23269c5b Michael Hanselmann
229 dfe11bad Michael Hanselmann
FormatWarning = lambda text: _FormatWithColor(text, _WARNING_SEQ)
230 dfe11bad Michael Hanselmann
FormatError = lambda text: _FormatWithColor(text, _ERROR_SEQ)
231 dfe11bad Michael Hanselmann
FormatInfo = lambda text: _FormatWithColor(text, _INFO_SEQ)