def _load(cls):
        def _walk_parents(dir):
            """Walk backwards up the tree to first non-module directory."""
            components = []

            if (os.path.isfile("%s/__init__.pyc" % dir)
                    or os.path.isfile("%s/__init__.py" % dir)):
                parent, child = os.path.split(dir)
                components.append(child)
                components.extend(_walk_parents(parent))

            return components

        def _build_namespace(dir):
            """Builds a namespace by finding all parent modules."""
            return ".".join(reversed(_walk_parents(dir)))

        names = set()

        assert os.path.isdir(cls.path)
        for modfile in sorted(glob.glob("%s/*.py*" % cls.path)):
            dir, filename = os.path.split(modfile)
            module = filename.split(".py")[0]
            if not module in EXCLUDED_PLUGINS:
                namespace = _build_namespace(dir)
                name = "%s.%s" % (namespace, module)
                names.add(name)

        daemon_log.info("Found action plugin modules: %s" % names)

        cls.commands = {}
        capabilities = set()
        for name in [n for n in names if not n.split(".")[-1].startswith('_')]:
            try:
                module = __import__(name, None, None,
                                    ['ACTIONS', 'CAPABILITIES'])
                if hasattr(module, 'ACTIONS'):
                    for fn in module.ACTIONS:
                        cls.commands[fn.func_name] = fn

                    daemon_log.info(
                        "Loaded actions from %s: %s" %
                        (name, [fn.func_name for fn in module.ACTIONS]))
                else:
                    daemon_log.warning(
                        "No 'ACTIONS' defined in action module %s" % name)

                if hasattr(module, 'CAPABILITIES') and module.CAPABILITIES:
                    capabilities.add(*module.CAPABILITIES)

            except Exception:
                daemon_log.warn("** error loading plugin %s" % name)
                daemon_log.warn(traceback.format_exc())

        cls.capabilities = list(capabilities)
    def _add_zfs_pool(self, line, block_devices):
        pool, size_str, uuid, health = line.split()

        if health in self.acceptable_health:
            size = util.human_to_bytes(size_str)

            drive_mms = block_devices.paths_to_major_minors(
                self._get_all_zpool_devices(pool))

            if drive_mms is None:
                daemon_log.warn("Could not find major minors for zpool '%s'" %
                                pool)
                return

            # This will need discussion, but for now fabricate a major:minor. Do we ever use them as numbers?
            block_device = "zfspool:%s" % pool

            datasets = self._get_zpool_datasets(pool, uuid, drive_mms,
                                                block_devices)
            zvols = self._get_zpool_zvols(pool, drive_mms, uuid, block_devices)

            if (datasets == {}) and (zvols == {}):
                block_devices.block_device_nodes[block_device] = {
                    'major_minor': block_device,
                    'path': pool,
                    'serial_80': None,
                    'serial_83': None,
                    'size': size,
                    'filesystem_type': None,
                    'parent': None
                }

                # Do this to cache the device, type see blockdevice and filesystem for info.
                BlockDevice('zfs', pool)
                FileSystem('zfs', pool)

                self._zpools[uuid] = {
                    "name": pool,
                    "path": pool,
                    "block_device": block_device,
                    "uuid": uuid,
                    "size": size,
                    "drives": drive_mms,
                }

            if datasets != {}:
                self._datasets.update(datasets)

            if zvols != {}:
                self._zvols.update(zvols)
Beispiel #3
0
def detect_scan(target_devices=None):
    """Look for Lustre on possible devices

    Save the input devices when possible.  Then future calls will
    not need to specify the target_devices
    """

    right_now = str(datetime.now())

    if target_devices is not None:
        target_devices_time_stamped = dict(timestamp=right_now,
                                           target_devices=target_devices)
        config.update('settings', 'last_detect_scan_target_devices',
                      target_devices_time_stamped)

    try:
        # Recall the last target_devices used in this method
        settings = config.get('settings', 'last_detect_scan_target_devices')
    except KeyError:
        # This method was never called with a non-null target_devices
        # or the setting file holding the device record is not found.
        daemon_log.warn("detect_scan improperly called without target_devices "
                        "and without a previous call's target_devices to use.")

        # TODO: Consider an exception here. But, since this is a rare case, it seems reasonable to return emptiness
        # TODO: If this raised an exception, it should be a handled one in any client, and that seems too heavy
        local_targets = LocalTargets([])
        timestamp = right_now

    else:
        # Have target devices, so process them
        timestamp = settings['timestamp']
        daemon_log.info(
            "detect_scan called at %s with target_devices saved on %s" %
            (str(datetime.now()), timestamp))
        local_targets = LocalTargets(settings['target_devices'])

    # Return the discovered Lustre components on the target devices, may return emptiness.
    mgs_targets = MgsTargets(local_targets.targets)
    return {
        "target_devices_saved_timestamp": timestamp,
        "local_targets": local_targets.targets,
        "mgs_targets": mgs_targets.filesystems
    }
    def get(self, section, key):
        dir = os.path.join(self.path, self._ck_str(section))
        safe_key = self._encode_key(key)

        with self._lock:
            try:
                with open(os.path.join(dir, safe_key), "r") as f:
                    return json.load(f)
            except IOError as e:
                if e.errno == errno.ENOENT:
                    if not section in self.sections:
                        raise TypeError("Invalid config section: '%s'" %
                                        section)
                    elif not key in self.get_section_keys(section):
                        raise KeyError(
                            "Invalid key '%s' for config section '%s'" %
                            (key, section))
                raise
            except Exception as e:
                daemon_log.warn("Json error %s, file was %s" %
                                (e, os.path.join(dir, safe_key)))
                daemon_log.warn("File contents %s" %
                                open(os.path.join(dir, safe_key), "r").read())
                raise
Beispiel #5
0
    def _load_plugins(cls, names):
        """Given a list of plugin names, try to import them."""

        for name in names:
            try:
                try:
                    __import__(name, None, None)
                except ImportError, e:
                    if e.args[0].endswith(" " + name):
                        daemon_log.warn("** plugin %s not found" % name)
                    else:
                        raise
            except Exception:
                daemon_log.warn("** error loading plugin %s" % name)
                daemon_log.warn(traceback.format_exc())