def _recursive_manager_init(inspected_package, prefix=base_prefix): """ Takes a package and iterates all of the modules. If it's a module (e.g. not a package), it will look for ObjectManager class definitions and add and instance of it to the object_managers store. :param inspected_package: Package """ # iter all modules in package for _, modname, ispkg in pkgutil.iter_modules(inspected_package.__path__): current_loc = prefix + modname # import module mod = __import__(current_loc, fromlist='dummy') if ispkg: # if it is another package, recursively call this function current_prefix = current_loc + '.' _recursive_manager_init(mod, prefix=current_prefix) else: # otherwise if it is a module walk the objects to find ObjectManagers for obj in mod.__dict__.itervalues(): # if it is a class defintion if inspect.isclass(obj): # and it is a subclass of ObjectManager (but not ObjectManager itself) if issubclass(obj, ObjectManager) and obj.__name__ != ObjectManager.__name__: # check that the extension is enabled in the config if obj.ext in context.app_config.get('extensions', {}) and \ boolean(context.app_config.get('extensions', {}).get(obj.ext, False)): # add to object_managers self.object_managers[obj.type] = obj() self.external_managers.append(obj.type) context.log.debug('loaded "%s" object manager from %s' % (obj.type, obj)) else: context.log.debug('ignored "%s" object manager from %s' % (obj.type, obj))
def enabled_extension(modname): # not defined in the config if modname not in context.app_config.get('extensions', {}): return False # not enabled if not boolean( context.app_config.get('extensions', {}).get( modname, False)): return False return True
def bin_path(self): """ Finds and sets as a var the path to the running binary of the mysql server """ if '/' in self.object.cmd: self._bin_path = self.object.cmd.split(' ')[0] if boolean(context.app_config['mysql'].get('remote', False)) == True: self._bin_path = "unknown" if self._bin_path is None: ls_cmd_template = LS_CMD_FREEBSD if host.linux_name( ) == 'freebsd' else LS_CMD ls_cmd = ls_cmd_template % self.object.pid try: ls, _ = subp.call(ls_cmd, check=False) context.log.debug('ls "%s" output: %s' % (ls_cmd, ls)) except Exception as e: exc_name = e.__class__.__name__ # this is being kept as an error because it has # implications for meta collection success/failure context.log.debug( 'failed to find MySQL bin path: "%s" failed due to %s' % (ls_cmd, exc_name)) context.log.debug('additional info:', exc_info=True) else: try: self._bin_path = ls_parser(ls[0]) except Exception as e: exc_name = e.__class__.__name__ context.log.debug( 'failed to parse ls result "%s" due to %s' % (ls[0], exc_name)) context.log.debug('additional info:', exc_info=True) self.meta['bin_path'] = self._bin_path
def _discover_objects(self): # save the current ids existing_hashes = [ obj.definition_hash for obj in self.objects.find_all(types=self.types) ] discovered_hashes = [] if boolean(context.app_config['mysql'].get('remote', False)): mysql_daemons = self._find_remote() else: mysql_daemons = self._find_local() while len(mysql_daemons): try: data = mysql_daemons.pop() definition = { 'type': 'mysql', 'local_id': data['local_id'], 'root_uuid': context.uuid } definition_hash = MySQLObject.hash(definition) discovered_hashes.append(definition_hash) if definition_hash not in existing_hashes: # New object -- create it new_obj = MySQLObject(data=data) # Send discover event. new_obj.eventd.event( level=INFO, message='mysqld process found, pid %s' % new_obj.pid ) self.objects.register(new_obj, parent_id=self.objects.root_id) elif definition_hash in existing_hashes: for obj in self.objects.find_all(types=self.types): if obj.definition_hash == definition_hash: current_obj = obj break if current_obj.pid != data['pid']: # PIDs changed... MySQL must have been restarted context.log.debug( 'mysqld was restarted (pid was %s now %s)' % ( current_obj.pid, data['pid'] ) ) new_obj = MySQLObject(data=data) # send MySQL restart event new_obj.eventd.event( level=INFO, message='mysqld process was restarted, new pid %s, old pid %s' % ( new_obj.pid, current_obj.pid ) ) # stop and un-register children children_objects = self.objects.find_all( obj_id=current_obj.id, children=True, include_self=False ) for child_obj in children_objects: child_obj.stop() self.objects.unregister(obj=child_obj) # un-register old object self.objects.unregister(current_obj) # stop old object current_obj.stop() self.objects.register(new_obj, parent_id=self.objects.root_id) except psutil.NoSuchProcess: context.log.debug('mysqld is restarting/reloading, pids are changing, agent is waiting') # check if we left something in objects (MySQL could be stopped or something) dropped_hashes = filter(lambda x: x not in discovered_hashes, existing_hashes) if len(dropped_hashes): for dropped_hash in dropped_hashes: for obj in self.objects.find_all(types=self.types): if obj.definition_hash == dropped_hash: dropped_obj = obj break context.log.debug('mysqld was stopped (pid was %s)' % dropped_obj.pid) # stop and un-register children children_objects = self.objects.find_all( obj_id=dropped_obj.id, children=True, include_self=False ) for child_obj in children_objects: child_obj.stop() self.objects.unregister(child_obj) dropped_obj.stop() self.objects.unregister(dropped_obj)