rapi.testutils: Add exported functions to verify opcode input/result
[ganeti-local] / lib / tools / ensure_dirs.py
index 842085b..5fdb723 100644 (file)
@@ -1,3 +1,6 @@
+#
+#
+
 # Copyright (C) 2011 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # Copyright (C) 2011 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 
 """
 
 
 """
 
-import errno
 import os
 import os.path
 import optparse
 import sys
 import os
 import os.path
 import optparse
 import sys
-import stat
+import logging
 
 from ganeti import constants
 from ganeti import errors
 from ganeti import runtime
 from ganeti import ssconf
 
 from ganeti import constants
 from ganeti import errors
 from ganeti import runtime
 from ganeti import ssconf
+from ganeti import utils
+from ganeti import cli
 
 
 
 
-(DIR, FILE) = range(2)
-ALL_TYPES = frozenset([DIR, FILE])
-
-
-class EnsureError(errors.GenericError):
-  """Top-level error class related to this script.
+(DIR,
+ FILE,
+ QUEUE_DIR) = range(1, 4)
 
 
-  """
-
-
-def EnsurePermission(path, mode, uid=-1, gid=-1, must_exist=True,
-                     _chmod_fn=os.chmod, _chown_fn=os.chown):
-  """Ensures that given path has given mode.
-
-  @param path: The path to the file
-  @param mode: The mode of the file
-  @param uid: The uid of the owner of this file
-  @param gid: The gid of the owner of this file
-  @param must_exist: Specifies if non-existance of path will be an error
-  @param _chmod_fn: chmod function to use (unittest only)
-  @param _chown_fn: chown function to use (unittest only)
-
-  """
-  try:
-    _chmod_fn(path, mode)
-
-    if max(uid, gid) > -1:
-      _chown_fn(path, uid, gid)
-  except EnvironmentError, err:
-    if err.errno == errno.ENOENT:
-      if must_exist:
-        raise EnsureError("Path %s does not exists, but should" % path)
-    else:
-      raise EnsureError("Error while changing permission on %s: %s" %
-                        (path, err))
-
-
-def EnsureDir(path, mode, uid, gid, _stat_fn=os.lstat, _mkdir_fn=os.mkdir,
-              _ensure_fn=EnsurePermission):
-  """Ensures that given path is a dir and has given mode, uid and gid set.
-
-  @param path: The path to the file
-  @param mode: The mode of the file
-  @param uid: The uid of the owner of this file
-  @param gid: The gid of the owner of this file
-  @param _stat_fn: Stat function to use (unittest only)
-  @param _mkdir_fn: mkdir function to use (unittest only)
-  @param _ensure_fn: ensure function to use (unittest only)
-
-  """
-  try:
-    # We don't want to follow symlinks
-    st_mode = _stat_fn(path)[stat.ST_MODE]
-
-    if not stat.S_ISDIR(st_mode):
-      raise EnsureError("Path %s is expected to be a directory, but it's not" %
-                        path)
-  except EnvironmentError, err:
-    if err.errno == errno.ENOENT:
-      _mkdir_fn(path)
-    else:
-      raise EnsureError("Error while do a stat() on %s: %s" % (path, err))
-
-  _ensure_fn(path, mode, uid=uid, gid=gid)
+ALL_TYPES = frozenset([
+  DIR,
+  FILE,
+  QUEUE_DIR,
+  ])
 
 
 def RecursiveEnsure(path, uid, gid, dir_perm, file_perm):
 
 
 def RecursiveEnsure(path, uid, gid, dir_perm, file_perm):
@@ -113,13 +62,31 @@ def RecursiveEnsure(path, uid, gid, dir_perm, file_perm):
   assert os.path.isabs(path), "Path %s is not absolute" % path
   assert os.path.isdir(path), "Path %s is not a dir" % path
 
   assert os.path.isabs(path), "Path %s is not absolute" % path
   assert os.path.isdir(path), "Path %s is not a dir" % path
 
+  logging.debug("Recursively processing %s", path)
+
   for root, dirs, files in os.walk(path):
     for subdir in dirs:
   for root, dirs, files in os.walk(path):
     for subdir in dirs:
-      EnsurePermission(os.path.join(root, subdir), dir_perm, uid=uid, gid=gid)
+      utils.EnforcePermission(os.path.join(root, subdir), dir_perm, uid=uid,
+                              gid=gid)
 
     for filename in files:
 
     for filename in files:
-      EnsurePermission(os.path.join(root, filename), file_perm, uid=uid,
-                       gid=gid)
+      utils.EnforcePermission(os.path.join(root, filename), file_perm, uid=uid,
+                              gid=gid)
+
+
+def EnsureQueueDir(path, mode, uid, gid):
+  """Sets the correct permissions on all job files in the queue.
+
+  @param path: Directory path
+  @param mode: Wanted file mode
+  @param uid: Wanted user ID
+  @param gid: Wanted group ID
+
+  """
+  for filename in utils.ListVisibleFiles(path):
+    if constants.JOB_FILE_RE.match(filename):
+      utils.EnforcePermission(utils.PathJoin(path, filename), mode, uid=uid,
+                              gid=gid)
 
 
 def ProcessPath(path):
 
 
 def ProcessPath(path):
@@ -132,13 +99,17 @@ def ProcessPath(path):
 
   assert pathtype in ALL_TYPES
 
 
   assert pathtype in ALL_TYPES
 
-  if pathtype == DIR:
+  if pathtype in (DIR, QUEUE_DIR):
     # No additional parameters
     assert len(path[5:]) == 0
     # No additional parameters
     assert len(path[5:]) == 0
-    EnsureDir(pathname, mode, uid, gid)
+    if pathtype == DIR:
+      utils.MakeDirWithPerm(pathname, mode, uid, gid)
+    elif pathtype == QUEUE_DIR:
+      EnsureQueueDir(pathname, mode, uid, gid)
   elif pathtype == FILE:
     (must_exist, ) = path[5:]
   elif pathtype == FILE:
     (must_exist, ) = path[5:]
-    EnsurePermission(pathname, mode, uid=uid, gid=gid, must_exist=must_exist)
+    utils.EnforcePermission(pathname, mode, uid=uid, gid=gid,
+                            must_exist=must_exist)
 
 
 def GetPaths():
 
 
 def GetPaths():
@@ -166,6 +137,10 @@ def GetPaths():
      getent.masterd_gid, False),
     (constants.RAPI_CERT_FILE, FILE, 0440, getent.rapi_uid,
      getent.masterd_gid, False),
      getent.masterd_gid, False),
     (constants.RAPI_CERT_FILE, FILE, 0440, getent.rapi_uid,
      getent.masterd_gid, False),
+    (constants.SPICE_CERT_FILE, FILE, 0440, getent.noded_uid,
+     getent.masterd_gid, False),
+    (constants.SPICE_CACERT_FILE, FILE, 0440, getent.noded_uid,
+     getent.masterd_gid, False),
     (constants.NODED_CERT_FILE, FILE, 0440, getent.masterd_uid,
      getent.masterd_gid, False),
     ]
     (constants.NODED_CERT_FILE, FILE, 0440, getent.masterd_uid,
      getent.masterd_gid, False),
     ]
@@ -178,10 +153,14 @@ def GetPaths():
   paths.extend([
     (constants.QUEUE_DIR, DIR, 0700, getent.masterd_uid,
      getent.masterd_gid),
   paths.extend([
     (constants.QUEUE_DIR, DIR, 0700, getent.masterd_uid,
      getent.masterd_gid),
+    (constants.QUEUE_DIR, QUEUE_DIR, 0600, getent.masterd_uid,
+     getent.masterd_gid),
     (constants.JOB_QUEUE_LOCK_FILE, FILE, 0600,
      getent.masterd_uid, getent.masterd_gid, False),
     (constants.JOB_QUEUE_SERIAL_FILE, FILE, 0600,
      getent.masterd_uid, getent.masterd_gid, False),
     (constants.JOB_QUEUE_LOCK_FILE, FILE, 0600,
      getent.masterd_uid, getent.masterd_gid, False),
     (constants.JOB_QUEUE_SERIAL_FILE, FILE, 0600,
      getent.masterd_uid, getent.masterd_gid, False),
+    (constants.JOB_QUEUE_VERSION_FILE, FILE, 0600,
+     getent.masterd_uid, getent.masterd_gid, False),
     (constants.JOB_QUEUE_ARCHIVE_DIR, DIR, 0700,
      getent.masterd_uid, getent.masterd_gid),
     (rapi_dir, DIR, 0750, getent.rapi_uid, getent.masterd_gid),
     (constants.JOB_QUEUE_ARCHIVE_DIR, DIR, 0700,
      getent.masterd_uid, getent.masterd_gid),
     (rapi_dir, DIR, 0750, getent.rapi_uid, getent.masterd_gid),
@@ -217,6 +196,26 @@ def GetPaths():
   return tuple(paths)
 
 
   return tuple(paths)
 
 
+def SetupLogging(opts):
+  """Configures the logging module.
+
+  """
+  formatter = logging.Formatter("%(asctime)s: %(message)s")
+
+  stderr_handler = logging.StreamHandler()
+  stderr_handler.setFormatter(formatter)
+  if opts.debug:
+    stderr_handler.setLevel(logging.NOTSET)
+  elif opts.verbose:
+    stderr_handler.setLevel(logging.INFO)
+  else:
+    stderr_handler.setLevel(logging.WARNING)
+
+  root_logger = logging.getLogger("")
+  root_logger.setLevel(logging.NOTSET)
+  root_logger.addHandler(stderr_handler)
+
+
 def ParseOptions():
   """Parses the options passed to the program.
 
 def ParseOptions():
   """Parses the options passed to the program.
 
@@ -227,9 +226,11 @@ def ParseOptions():
 
   parser = optparse.OptionParser(usage="%%prog [--full-run]",
                                  prog=program)
 
   parser = optparse.OptionParser(usage="%%prog [--full-run]",
                                  prog=program)
+  parser.add_option(cli.DEBUG_OPT)
+  parser.add_option(cli.VERBOSE_OPT)
   parser.add_option("--full-run", "-f", dest="full_run", action="store_true",
   parser.add_option("--full-run", "-f", dest="full_run", action="store_true",
-                    default=False, help=("Make a full run and collect"
-                                         " additional files (time consuming)"))
+                    default=False, help=("Make a full run and set permissions"
+                                         " on archived jobs (time consuming)"))
 
   return parser.parse_args()
 
 
   return parser.parse_args()
 
@@ -238,9 +239,15 @@ def Main():
   """Main routine.
 
   """
   """Main routine.
 
   """
-  getent = runtime.GetEnts()
   (opts, _) = ParseOptions()
 
   (opts, _) = ParseOptions()
 
+  SetupLogging(opts)
+
+  if opts.full_run:
+    logging.info("Running in full mode")
+
+  getent = runtime.GetEnts()
+
   try:
     for path in GetPaths():
       ProcessPath(path)
   try:
     for path in GetPaths():
       ProcessPath(path)
@@ -248,8 +255,8 @@ def Main():
     if opts.full_run:
       RecursiveEnsure(constants.JOB_QUEUE_ARCHIVE_DIR, getent.masterd_uid,
                       getent.masterd_gid, 0700, 0600)
     if opts.full_run:
       RecursiveEnsure(constants.JOB_QUEUE_ARCHIVE_DIR, getent.masterd_uid,
                       getent.masterd_gid, 0700, 0600)
-  except EnsureError, err:
-    print >> sys.stderr, "An error occurred while ensure permissions:", err
+  except errors.GenericError, err:
+    logging.error("An error occurred while setting permissions: %s", err)
     return constants.EXIT_FAILURE
 
   return constants.EXIT_SUCCESS
     return constants.EXIT_FAILURE
 
   return constants.EXIT_SUCCESS