+def _TransformFileStorageDir(file_storage_dir):
+ """Checks whether given file_storage_dir is valid.
+
+ Checks wheter the given file_storage_dir is within the cluster-wide
+ default file_storage_dir stored in SimpleStore. Only paths under that
+ directory are allowed.
+
+ Args:
+ file_storage_dir: string with path
+
+ Returns:
+ normalized file_storage_dir (string) if valid, None otherwise
+
+ """
+ cfg = _GetConfig()
+ file_storage_dir = os.path.normpath(file_storage_dir)
+ base_file_storage_dir = cfg.GetFileStorageDir()
+ if (not os.path.commonprefix([file_storage_dir, base_file_storage_dir]) ==
+ base_file_storage_dir):
+ logging.error("file storage directory '%s' is not under base file"
+ " storage directory '%s'",
+ file_storage_dir, base_file_storage_dir)
+ return None
+ return file_storage_dir
+
+
+def CreateFileStorageDir(file_storage_dir):
+ """Create file storage directory.
+
+ Args:
+ file_storage_dir: string containing the path
+
+ Returns:
+ tuple with first element a boolean indicating wheter dir
+ creation was successful or not
+
+ """
+ file_storage_dir = _TransformFileStorageDir(file_storage_dir)
+ result = True,
+ if not file_storage_dir:
+ result = False,
+ else:
+ if os.path.exists(file_storage_dir):
+ if not os.path.isdir(file_storage_dir):
+ logging.error("'%s' is not a directory", file_storage_dir)
+ result = False,
+ else:
+ try:
+ os.makedirs(file_storage_dir, 0750)
+ except OSError, err:
+ logging.error("Cannot create file storage directory '%s': %s",
+ file_storage_dir, err)
+ result = False,
+ return result
+
+
+def RemoveFileStorageDir(file_storage_dir):
+ """Remove file storage directory.
+
+ Remove it only if it's empty. If not log an error and return.
+
+ Args:
+ file_storage_dir: string containing the path
+
+ Returns:
+ tuple with first element a boolean indicating wheter dir
+ removal was successful or not
+
+ """
+ file_storage_dir = _TransformFileStorageDir(file_storage_dir)
+ result = True,
+ if not file_storage_dir:
+ result = False,
+ else:
+ if os.path.exists(file_storage_dir):
+ if not os.path.isdir(file_storage_dir):
+ logging.error("'%s' is not a directory", file_storage_dir)
+ result = False,
+ # deletes dir only if empty, otherwise we want to return False
+ try:
+ os.rmdir(file_storage_dir)
+ except OSError, err:
+ logging.exception("Cannot remove file storage directory '%s'",
+ file_storage_dir)
+ result = False,
+ return result
+
+
+def RenameFileStorageDir(old_file_storage_dir, new_file_storage_dir):
+ """Rename the file storage directory.
+
+ Args:
+ old_file_storage_dir: string containing the old path
+ new_file_storage_dir: string containing the new path
+
+ Returns:
+ tuple with first element a boolean indicating wheter dir
+ rename was successful or not
+
+ """
+ old_file_storage_dir = _TransformFileStorageDir(old_file_storage_dir)
+ new_file_storage_dir = _TransformFileStorageDir(new_file_storage_dir)
+ result = True,
+ if not old_file_storage_dir or not new_file_storage_dir:
+ result = False,
+ else:
+ if not os.path.exists(new_file_storage_dir):
+ if os.path.isdir(old_file_storage_dir):
+ try:
+ os.rename(old_file_storage_dir, new_file_storage_dir)
+ except OSError, err:
+ logging.exception("Cannot rename '%s' to '%s'",
+ old_file_storage_dir, new_file_storage_dir)
+ result = False,
+ else:
+ logging.error("'%s' is not a directory", old_file_storage_dir)
+ result = False,
+ else:
+ if os.path.exists(old_file_storage_dir):
+ logging.error("Cannot rename '%s' to '%s'. Both locations exist.",
+ old_file_storage_dir, new_file_storage_dir)
+ result = False,
+ return result
+
+
+def _IsJobQueueFile(file_name):
+ """Checks whether the given filename is in the queue directory.
+
+ """
+ queue_dir = os.path.normpath(constants.QUEUE_DIR)
+ result = (os.path.commonprefix([queue_dir, file_name]) == queue_dir)
+
+ if not result:
+ logging.error("'%s' is not a file in the queue directory",
+ file_name)
+
+ return result
+
+
+def JobQueueUpdate(file_name, content):
+ """Updates a file in the queue directory.
+
+ """
+ if not _IsJobQueueFile(file_name):
+ return False
+
+ # Write and replace the file atomically
+ utils.WriteFile(file_name, data=content)
+
+ return True
+
+
+def JobQueueRename(old, new):
+ """Renames a job queue file.
+
+ """
+ if not (_IsJobQueueFile(old) and _IsJobQueueFile(new)):
+ return False
+
+ os.rename(old, new)
+
+ return True
+
+
+def JobQueueSetDrainFlag(drain_flag):
+ """Set the drain flag for the queue.
+
+ This will set or unset the queue drain flag.
+
+ @type drain_flag: bool
+ @param drain_flag: if True, will set the drain flag, otherwise reset it.
+
+ """
+ if drain_flag:
+ utils.WriteFile(constants.JOB_QUEUE_DRAIN_FILE, data="", close=True)
+ else:
+ utils.RemoveFile(constants.JOB_QUEUE_DRAIN_FILE)
+
+ return True
+
+
+def CloseBlockDevices(disks):
+ """Closes the given block devices.
+
+ This means they will be switched to secondary mode (in case of DRBD).
+
+ """
+ bdevs = []
+ for cf in disks:
+ rd = _RecursiveFindBD(cf)
+ if rd is None:
+ return (False, "Can't find device %s" % cf)
+ bdevs.append(rd)
+
+ msg = []
+ for rd in bdevs:
+ try:
+ rd.Close()
+ except errors.BlockDeviceError, err:
+ msg.append(str(err))
+ if msg:
+ return (False, "Can't make devices secondary: %s" % ",".join(msg))
+ else:
+ return (True, "All devices secondary")
+
+
+def ValidateHVParams(hvname, hvparams):
+ """Validates the given hypervisor parameters.
+
+ @type hvname: string
+ @param hvname: the hypervisor name
+ @type hvparams: dict
+ @param hvparams: the hypervisor parameters to be validated
+ @rtype: tuple (bool, str)
+ @return: tuple of (success, message)
+
+ """
+ try:
+ hv_type = hypervisor.GetHypervisor(hvname)
+ hv_type.ValidateParameters(hvparams)
+ return (True, "Validation passed")
+ except errors.HypervisorError, err:
+ return (False, str(err))
+
+