LUSetInstanceParams: nic parameters
[ganeti-local] / qa / qa_utils.py
index 3889352..fbc92e8 100644 (file)
@@ -1,3 +1,6 @@
+#
+#
+
 # Copyright (C) 2007 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -21,6 +24,7 @@
 """
 
 import os
+import sys
 import subprocess
 
 from ganeti import utils
@@ -29,19 +33,75 @@ import qa_config
 import qa_error
 
 
-def AssertEqual(first, second, msg=None):
+_INFO_SEQ = None
+_WARNING_SEQ = None
+_ERROR_SEQ = None
+_RESET_SEQ = None
+
+
+def _SetupColours():
+  """Initializes the colour constants.
+
+  """
+  global _INFO_SEQ, _WARNING_SEQ, _ERROR_SEQ, _RESET_SEQ
+
+  # Don't use colours if stdout isn't a terminal
+  if not sys.stdout.isatty():
+    return
+
+  try:
+    import curses
+  except ImportError:
+    # Don't use colours if curses module can't be imported
+    return
+
+  curses.setupterm()
+
+  _RESET_SEQ = curses.tigetstr("op")
+
+  setaf = curses.tigetstr("setaf")
+  _INFO_SEQ = curses.tparm(setaf, curses.COLOR_GREEN)
+  _WARNING_SEQ = curses.tparm(setaf, curses.COLOR_YELLOW)
+  _ERROR_SEQ = curses.tparm(setaf, curses.COLOR_RED)
+
+
+_SetupColours()
+
+
+def AssertIn(item, sequence):
+  """Raises an error when item is not in sequence.
+
+  """
+  if item not in sequence:
+    raise qa_error.Error('%r not in %r' % (item, sequence))
+
+
+def AssertEqual(first, second):
   """Raises an error when values aren't equal.
 
   """
   if not first == second:
-    raise qa_error.Error(msg or '%r == %r' % (first, second))
+    raise qa_error.Error('%r == %r' % (first, second))
+
+
+def AssertNotEqual(first, second):
+  """Raises an error when values are equal.
+
+  """
+  if not first != second:
+    raise qa_error.Error('%r != %r' % (first, second))
 
 
 def GetSSHCommand(node, cmd, strict=True):
   """Builds SSH command to be executed.
 
+  Args:
+  - node: Node the command should run on
+  - cmd: Command to be executed as a list with all parameters
+  - strict: Whether to enable strict host key checking
+
   """
-  args = [ 'ssh', '-oEscapeChar=none', '-oBatchMode=yes', '-l', 'root' ]
+  args = [ 'ssh', '-oEscapeChar=none', '-oBatchMode=yes', '-l', 'root', '-t' ]
 
   if strict:
     tmp = 'yes'
@@ -51,13 +111,7 @@ def GetSSHCommand(node, cmd, strict=True):
   args.append('-oClearAllForwardings=yes')
   args.append('-oForwardAgent=yes')
   args.append(node)
-
-  if qa_config.options.dry_run:
-    prefix = 'exit 0; '
-  else:
-    prefix = ''
-
-  args.append(prefix + cmd)
+  args.append(cmd)
 
   print 'SSH:', utils.ShellQuoteArgs(args)
 
@@ -68,8 +122,18 @@ def StartSSH(node, cmd, strict=True):
   """Starts SSH.
 
   """
-  args = GetSSHCommand(node, cmd, strict=strict)
-  return subprocess.Popen(args, shell=False)
+  return subprocess.Popen(GetSSHCommand(node, cmd, strict=strict),
+                          shell=False)
+
+
+def GetCommandOutput(node, cmd):
+  """Returns the output of a command executed on the given node.
+
+  """
+  p = subprocess.Popen(GetSSHCommand(node, cmd),
+                       shell=False, stdout=subprocess.PIPE)
+  AssertEqual(p.wait(), 0)
+  return p.stdout.read()
 
 
 def UploadFile(node, src):
@@ -96,4 +160,66 @@ def UploadFile(node, src):
     return p.stdout.read().strip()
   finally:
     f.close()
-# }}}
+
+
+def _ResolveName(cmd, key):
+  """Helper function.
+
+  """
+  master = qa_config.GetMasterNode()
+
+  output = GetCommandOutput(master['primary'], utils.ShellQuoteArgs(cmd))
+  for line in output.splitlines():
+    (lkey, lvalue) = line.split(':', 1)
+    if lkey == key:
+      return lvalue.lstrip()
+  raise KeyError("Key not found")
+
+
+def ResolveInstanceName(instance):
+  """Gets the full name of an instance.
+
+  """
+  return _ResolveName(['gnt-instance', 'info', instance['name']],
+                      'Instance name')
+
+
+def ResolveNodeName(node):
+  """Gets the full name of a node.
+
+  """
+  return _ResolveName(['gnt-node', 'info', node['primary']],
+                      'Node name')
+
+
+def GetNodeInstances(node, secondaries=False):
+  """Gets a list of instances on a node.
+
+  """
+  master = qa_config.GetMasterNode()
+  node_name = ResolveNodeName(node)
+
+  # Get list of all instances
+  cmd = ['gnt-instance', 'list', '--separator=:', '--no-headers',
+         '--output=name,pnode,snodes']
+  output = GetCommandOutput(master['primary'], utils.ShellQuoteArgs(cmd))
+
+  instances = []
+  for line in output.splitlines():
+    (name, pnode, snodes) = line.split(':', 2)
+    if ((not secondaries and pnode == node_name) or
+        (secondaries and node_name in snodes.split(','))):
+      instances.append(name)
+
+  return instances
+
+
+def _FormatWithColor(text, seq):
+  if not seq:
+    return text
+  return "%s%s%s" % (seq, text, _RESET_SEQ)
+
+
+FormatWarning = lambda text: _FormatWithColor(text, _WARNING_SEQ)
+FormatError = lambda text: _FormatWithColor(text, _ERROR_SEQ)
+FormatInfo = lambda text: _FormatWithColor(text, _INFO_SEQ)