QA: Factorize retrieving non-existent groups from config
[ganeti-local] / qa / qa_utils.py
index bf4f226..45baea6 100644 (file)
@@ -1,7 +1,7 @@
 #
 #
 
-# Copyright (C) 2007, 2011 Google Inc.
+# Copyright (C) 2007, 2011, 2012 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -39,6 +39,7 @@ from ganeti import utils
 from ganeti import compat
 from ganeti import constants
 from ganeti import ht
+from ganeti import pathutils
 
 import qa_config
 import qa_error
@@ -117,14 +118,6 @@ def AssertEqual(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 AssertMatch(string, pattern):
   """Raises an error when string doesn't match regexp pattern.
 
@@ -165,6 +158,8 @@ def AssertCommand(cmd, fail=False, node=None):
   @param node: if passed, it should be the node on which the command
       should be executed, instead of the master node (can be either a
       dict or a string)
+  @return: the return code of the command
+  @raise qa_error.Error: if the command fails when it shouldn't or vice versa
 
   """
   if node is None:
@@ -207,7 +202,7 @@ def GetSSHCommand(node, cmd, strict=True, opts=None, tty=None):
   @param tty: if we should use tty; if None, will be auto-detected
 
   """
-  args = ["ssh", "-oEscapeChar=none", "-oBatchMode=yes", "-l", "root"]
+  args = ["ssh", "-oEscapeChar=none", "-oBatchMode=yes", "-lroot"]
 
   if tty is None:
     tty = sys.stdout.isatty()
@@ -235,11 +230,15 @@ def GetSSHCommand(node, cmd, strict=True, opts=None, tty=None):
   return args
 
 
-def StartLocalCommand(cmd, **kwargs):
+def StartLocalCommand(cmd, _nolog_opts=False, **kwargs):
   """Starts a local command.
 
   """
-  print "Command: %s" % utils.ShellQuoteArgs(cmd)
+  if _nolog_opts:
+    pcmd = [i for i in cmd if not i.startswith("-")]
+  else:
+    pcmd = cmd
+  print "Command: %s" % utils.ShellQuoteArgs(pcmd)
   return subprocess.Popen(cmd, shell=False, **kwargs)
 
 
@@ -247,7 +246,8 @@ def StartSSH(node, cmd, strict=True):
   """Starts SSH.
 
   """
-  return StartLocalCommand(GetSSHCommand(node, cmd, strict=strict))
+  return StartLocalCommand(GetSSHCommand(node, cmd, strict=strict),
+                           _nolog_opts=True)
 
 
 def StartMultiplexer(node):
@@ -530,17 +530,20 @@ def AddToEtcHosts(hostnames):
   master = qa_config.GetMasterNode()
   tmp_hosts = UploadData(master["primary"], "", mode=0644)
 
-  quoted_tmp_hosts = utils.ShellQuote(tmp_hosts)
   data = []
   for localhost in ("::1", "127.0.0.1"):
     data.append("%s %s" % (localhost, " ".join(hostnames)))
 
   try:
-    AssertCommand(("cat /etc/hosts > %s && echo -e '%s' >> %s && mv %s"
-                   " /etc/hosts") % (quoted_tmp_hosts, "\\n".join(data),
-                                     quoted_tmp_hosts, quoted_tmp_hosts))
-  except qa_error.Error:
-    AssertCommand(["rm", tmp_hosts])
+    AssertCommand("{ cat %s && echo -e '%s'; } > %s && mv %s %s" %
+                  (utils.ShellQuote(pathutils.ETC_HOSTS),
+                   "\\n".join(data),
+                   utils.ShellQuote(tmp_hosts),
+                   utils.ShellQuote(tmp_hosts),
+                   utils.ShellQuote(pathutils.ETC_HOSTS)))
+  except Exception:
+    AssertCommand(["rm", "-f", tmp_hosts])
+    raise
 
 
 def RemoveFromEtcHosts(hostnames):
@@ -555,11 +558,14 @@ def RemoveFromEtcHosts(hostnames):
 
   sed_data = " ".join(hostnames)
   try:
-    AssertCommand(("sed -e '/^\(::1\|127\.0\.0\.1\)\s\+%s/d' /etc/hosts > %s"
-                   " && mv %s /etc/hosts") % (sed_data, quoted_tmp_hosts,
-                                              quoted_tmp_hosts))
-  except qa_error.Error:
-    AssertCommand(["rm", tmp_hosts])
+    AssertCommand(("sed -e '/^\(::1\|127\.0\.0\.1\)\s\+%s/d' %s > %s"
+                   " && mv %s %s") %
+                   (sed_data, utils.ShellQuote(pathutils.ETC_HOSTS),
+                    quoted_tmp_hosts, quoted_tmp_hosts,
+                    utils.ShellQuote(pathutils.ETC_HOSTS)))
+  except Exception:
+    AssertCommand(["rm", "-f", tmp_hosts])
+    raise
 
 
 def RunInstanceCheck(instance, running):
@@ -641,3 +647,23 @@ def InstanceCheck(before, after, instarg):
       return result
     return wrapper
   return decorator
+
+
+def GetNonexistentGroups(count):
+  """Gets group names which shouldn't exist on the cluster.
+
+  @param count: Number of groups to get
+  @rtype: list
+
+  """
+  groups = qa_config.get("groups", {})
+
+  default = ["group1", "group2", "group3"]
+  assert count <= len(default)
+
+  candidates = groups.get("inexistent-groups", default)[:count]
+
+  if len(candidates) < count:
+    raise Exception("At least %s non-existent groups are needed" % count)
+
+  return candidates