rapi.testutils: Add exported functions to verify opcode input/result
[ganeti-local] / lib / tools / ensure_dirs.py
index 8de0cbf..5fdb723 100644 (file)
@@ -1,3 +1,6 @@
+#
+#
+
 # 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 stat
+import logging
 
 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.
-
-  """
-
-
-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)
+(DIR,
+ FILE,
+ QUEUE_DIR) = range(1, 4)
 
-  """
-  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):
@@ -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
 
+  logging.debug("Recursively processing %s", path)
+
   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:
-      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):
@@ -132,13 +99,17 @@ def ProcessPath(path):
 
   assert pathtype in ALL_TYPES
 
-  if pathtype == DIR:
+  if pathtype in (DIR, QUEUE_DIR):
     # 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:]
-    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():
@@ -166,19 +137,30 @@ def GetPaths():
      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),
     ]
 
   ss = ssconf.SimpleStore()
   for ss_path in ss.GetFileList():
-    paths.append((ss_path, FILE, 0400, getent.noded_uid, 0, False))
+    paths.append((ss_path, FILE, constants.SS_FILE_PERMS,
+                  getent.noded_uid, 0, False))
 
   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_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),
@@ -214,6 +196,26 @@ def GetPaths():
   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.
 
@@ -224,9 +226,11 @@ def ParseOptions():
 
   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",
-                    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()
 
@@ -235,9 +239,15 @@ def Main():
   """Main routine.
 
   """
-  getent = runtime.GetEnts()
   (opts, _) = ParseOptions()
 
+  SetupLogging(opts)
+
+  if opts.full_run:
+    logging.info("Running in full mode")
+
+  getent = runtime.GetEnts()
+
   try:
     for path in GetPaths():
       ProcessPath(path)
@@ -245,8 +255,8 @@ def Main():
     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