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)
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
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())