Beispiel #1
0
    def main(self):
        self.set_proctitle(self.name)

        # Daemon like init
        self.debug_output = []
        self.modules_dir = modulesctx.get_modulesdir()
        self.modules_manager = ModulesManager('webui',
                                              self.find_modules_path(), [])
        self.modules_manager.set_modules(self.modules)
        # We can now output some previously silenced debug output
        self.do_load_modules()
        for inst in self.modules_manager.instances:
            f = getattr(inst, 'load', None)
            if f and callable(f):
                f(self)
        for s in self.debug_output:
            print s
        del self.debug_output

        # Check if the Bottle view dir really exist
        if not os.path.exists(bottle.TEMPLATE_PATH[0]):
            logger.error("[WebUI] The view path do not exist at %s" %
                         bottle.TEMPLATE_PATH)
            sys.exit(2)

        # Check directories
        # We check if the photo directory exists. If not, try to create it
        for d in [self.photo_dir, self.share_dir, self.config_dir]:
            logger.debug("[WebUI] Checking dir: %s", d)
            if not os.path.exists(d):
                try:
                    os.mkdir(d)
                    logger.info("[WebUI] Created dir: %s", d)
                except Exception, exp:
                    logger.error("[WebUI] Dir creation failed: %s", exp)
Beispiel #2
0
 def get_module(self, mod_name):
     if self.modules_dir and self.modules_dir not in sys.path:
         sys.path.append(self.modules_dir)
     if self.modules_dir:
         mod_dir = os.path.join(self.modules_dir, mod_name)
     else:
         mod_dir = None
     # to keep it back-compatible with previous Shinken module way,
     # we first try with "import `mod_name`.module" and if we succeed
     # then that's the one to actually use:
     mod = ModulesManager.try_best_load('.module', mod_name)
     if mod:
         return mod
     # otherwise simply try new and old style:
     return ModulesManager.try_load(mod_name, mod_dir)
Beispiel #3
0
    def init_livestatus(self, modconf=None, dbmodconf=None, needcache=False):
        self.livelogs = 'tmp/livelogs.db' + self.testid

        if modconf is None:
            modconf = Module({'module_name': 'LiveStatus',
                'module_type': 'livestatus',
                'port': str(50000 + os.getpid()),
                'pnp_path': 'tmp/pnp4nagios_test' + self.testid,
                'host': '127.0.0.1',
                'socket': 'live',
                'name': 'test', #?
            })

        if dbmodconf is None:
            dbmodconf = Module({'module_name': 'LogStore',
                'module_type': 'logstore_sqlite',
                'use_aggressive_sql': "0",
                'database_file': self.livelogs,
                'archive_path': os.path.join(os.path.dirname(self.livelogs), 'archives'),
            })

        modconf.modules = [dbmodconf]
        self.livestatus_broker = LiveStatus_broker(modconf)
        self.livestatus_broker.create_queues()

        #--- livestatus_broker.main
        self.livestatus_broker.log = logger
        # this seems to damage the logger so that the scheduler can't use it
        #self.livestatus_broker.log.load_obj(self.livestatus_broker)
        self.livestatus_broker.debug_output = []
        self.livestatus_broker.modules_manager = ModulesManager('livestatus', modules_dir, [])
        self.livestatus_broker.modules_manager.set_modules(self.livestatus_broker.modules)
        # We can now output some previouly silented debug ouput
        self.livestatus_broker.do_load_modules()
        for inst in self.livestatus_broker.modules_manager.instances:
            if inst.properties["type"].startswith('logstore'):
                f = getattr(inst, 'load', None)
                if f and callable(f):
                    f(self.livestatus_broker)  # !!! NOT self here !!!!
                break
        for s in self.livestatus_broker.debug_output:
            print "errors during load", s
        del self.livestatus_broker.debug_output
        self.livestatus_broker.rg = LiveStatusRegenerator()
        self.livestatus_broker.datamgr = datamgr
        datamgr.load(self.livestatus_broker.rg)
        self.livestatus_broker.query_cache = LiveStatusQueryCache()
        if not needcache:
            self.livestatus_broker.query_cache.disable()
        self.livestatus_broker.rg.register_cache(self.livestatus_broker.query_cache)
        #--- livestatus_broker.main

        self.livestatus_broker.init()
        self.livestatus_broker.db = self.livestatus_broker.modules_manager.instances[0]
        self.livestatus_broker.livestatus = LiveStatus(self.livestatus_broker.datamgr, self.livestatus_broker.query_cache, self.livestatus_broker.db, self.livestatus_broker.pnp_path, self.livestatus_broker.from_q)

        #--- livestatus_broker.do_main
        self.livestatus_broker.db.open()
        if hasattr(self.livestatus_broker.db, 'prepare_log_db_table'):
            self.livestatus_broker.db.prepare_log_db_table()
Beispiel #4
0
    def main(self):
        self.set_proctitle(self.name)

        # Daemon like init
        self.debug_output = []
        self.modules_dir = modulesctx.get_modulesdir()
        self.modules_manager = ModulesManager('webui', self.find_modules_path(), [])
        self.modules_manager.set_modules(self.modules)
        # We can now output some previously silenced debug output
        self.do_load_modules()
        for inst in self.modules_manager.instances:
            f = getattr(inst, 'load', None)
            if f and callable(f):
                f(self)
        for s in self.debug_output:
            print s
        del self.debug_output

        # Check if the Bottle view dir really exist
        if not os.path.exists(bottle.TEMPLATE_PATH[0]):
            logger.error("[WebUI] The view path do not exist at %s" % bottle.TEMPLATE_PATH)
            sys.exit(2)

        # Check directories
        # We check if the photo directory exists. If not, try to create it
        for d in [self.photo_dir, self.share_dir, self.config_dir]:
            logger.debug("[WebUI] Checking dir: %s", d)
            if not os.path.exists(d):
                try:
                    os.mkdir(d)
                    logger.info("[WebUI] Created dir: %s", d)
                except Exception, exp:
                    logger.error("[WebUI] Dir creation failed: %s", exp)
Beispiel #5
0
    def __init__(self, name, config_file, is_daemon, do_replace, debug,
                 debug_file):

        self.check_shm()

        self.name = name
        self.config_file = config_file
        self.is_daemon = is_daemon
        self.do_replace = do_replace
        self.debug = debug
        self.debug_file = debug_file
        self.interrupted = False

        # Track time
        now = time.time()
        self.program_start = now
        self.t_each_loop = now  # used to track system time change
        self.sleep_time = 0.0  #used to track the time we wait

        self.pyro_daemon = None

        # Log init
        self.log = logger
        self.log.load_obj(self)

        self.new_conf = None  # used by controller to push conf
        self.cur_conf = None

        # Flag to know if we need to dump memory or not
        self.need_dump_memory = False

        #Keep a trace of the local_log file desc if need
        self.local_log_fd = None

        self.modules_manager = ModulesManager(name, self.find_modules_path(),
                                              [])

        os.umask(UMASK)
        self.set_exit_handler()
Beispiel #6
0
    def __init__(self, name, config_file, is_daemon, do_replace, debug, debug_file):
        
        self.check_shm()
        
        self.name = name
        self.config_file = config_file
        self.is_daemon = is_daemon
        self.do_replace = do_replace
        self.debug = debug
        self.debug_file = debug_file
        self.interrupted = False

        # Track time
        now = time.time()
        self.program_start = now
        self.t_each_loop = now # used to track system time change
        self.sleep_time = 0.0 #used to track the time we wait

        self.pyro_daemon = None

        # Log init
        self.log = logger
        self.log.load_obj(self)
        
        self.new_conf = None # used by controller to push conf 
        self.cur_conf = None

        # Flag to know if we need to dump memory or not
        self.need_dump_memory = False

        #Keep a trace of the local_log file desc if need
        self.local_log_fd = None

        # Put in queue some debug output we will raise
        # when we will be in daemon
        self.debug_output = []

        
        self.modules_manager = ModulesManager(name, self.find_modules_path(), [])

        os.umask(UMASK)
        self.set_exit_handler()
Beispiel #7
0
class Daemon(object):

    properties = {
        # workdir is relative to $(dirname "$0"/..) 
        # where "$0" is the path of the file being executed, 
        # in python normally known as:
        #
        #  os.path.join( os.getcwd(), sys.argv[0] )
        # 
        # as returned once the daemon is started.
        'workdir':       PathProp(default='var'),
        'host':          StringProp(default='0.0.0.0'),
        'user':          StringProp(default=get_cur_user()),
        'group':         StringProp(default=get_cur_group()),
        'use_ssl':       BoolProp(default='0'),
        'certs_dir':     StringProp(default='etc/certs'),
        'ca_cert':       StringProp(default='etc/certs/ca.pem'),
        'server_cert':   StringProp(default='etc/certs/server.pem'),
        'use_local_log': BoolProp(default='1'),
        'hard_ssl_name_check':    BoolProp(default='0'),
        'idontcareaboutsecurity': BoolProp(default='0'),
        'spare':         BoolProp(default='0')
    }

    def __init__(self, name, config_file, is_daemon, do_replace, debug, debug_file):
        
        self.check_shm()
        
        self.name = name
        self.config_file = config_file
        self.is_daemon = is_daemon
        self.do_replace = do_replace
        self.debug = debug
        self.debug_file = debug_file
        self.interrupted = False

        # Track time
        now = time.time()
        self.program_start = now
        self.t_each_loop = now # used to track system time change
        self.sleep_time = 0.0 #used to track the time we wait

        self.pyro_daemon = None

        # Log init
        self.log = logger
        self.log.load_obj(self)
        
        self.new_conf = None # used by controller to push conf 
        self.cur_conf = None

        # Flag to know if we need to dump memory or not
        self.need_dump_memory = False

        #Keep a trace of the local_log file desc if need
        self.local_log_fd = None

        # Put in queue some debug output we will raise
        # when we will be in daemon
        self.debug_output = []

        self.modules_manager = ModulesManager(name, self.find_modules_path(), [])

        os.umask(UMASK)
        self.set_exit_handler()



    # At least, lose the local log file if need
    def do_stop(self):
        if self.modules_manager:
            # We save what we can but NOT for the scheduler
            # because the current sched object is a dummy one
            # and the old one aleady do it!
            if not hasattr(self, 'sched'):
                self.hook_point('save_retention')
            # And we quit
            logger.log('Stopping all modules')
            self.modules_manager.stop_all()
        if self.pyro_daemon:
            pyro.shutdown(self.pyro_daemon)#.shutdown(True)
        logger.quit()
        

    def request_stop(self):
        self.unlink()  ## unlink first
        self.do_stop()
        print("Exiting")
        sys.exit(0)

    def do_loop_turn(self):
        raise NotImplementedError()

    # Main loop for nearly all daemon
    # the scheduler is not managed by it :'(
    def do_mainloop(self):
        while True:
            self.do_loop_turn()
            # If ask us to dump memory, do it
            if self.need_dump_memory:
                self.dump_memory()
                self.need_dump_memory = False
            # Maybe we ask us to die, if so, do it :)
            if self.interrupted:
                break
        self.request_stop()
    
    def do_load_modules(self):
        self.modules_manager.load_and_init()
        self.log.log("I correctly loaded the modules : [%s]" % (','.join([inst.get_name() for inst in self.modules_manager.instances])))
 
 
    def add(self, elt):
        """ Dummy method for adding broker to this daemon """
        pass

    def dump_memory(self):
        logger.log("I dump my memory, it can ask some seconds to do")
        try:
            from guppy import hpy
            hp = hpy()
            logger.log(hp.heap())
        except ImportError:
            logger.log('I do not have the module guppy for memory dump, please install it')
            

 
    def load_config_file(self):
        self.parse_config_file()
        if self.config_file is not None:
            # Some paths can be relatives. We must have a full path by taking
            # the config file by reference
            self.relative_paths_to_full(os.path.dirname(self.config_file))
            pass
        


    def change_to_workdir(self):
        try:
            os.chdir(self.workdir)
        except Exception, e:
            raise InvalidWorkDir(e)
        print("Successfully changed to workdir: %s" % (self.workdir))
Beispiel #8
0
class Webui_broker(BaseModule, Daemon):
    def __init__(self, modconf):
        BaseModule.__init__(self, modconf)

        self.plugins = []
        self.modconf = modconf

        # Web server configuration
        self.host = getattr(modconf, 'host', '0.0.0.0')
        self.port = int(getattr(modconf, 'port', '7767'))
        logger.info("[WebUI] server: %s:%d", self.host, self.port)
        self.endpoint = getattr(modconf, 'endpoint', None)
        if self.endpoint:
            if self.endpoint.endswith('/'):
                self.endpoint = self.endpoint[:-1]
            logger.info("[WebUI] configured endpoint: %s", self.endpoint)
            logger.warning("[WebUI] endpoint feature is not implemented! WebUI is served from root URL: http://%s:%d/", self.host, self.port)
            self.endpoint = None

        self.auth_secret = resolve_auth_secret(modconf)
        # TODO : common preferences
        self.play_sound = to_bool(getattr(modconf, 'play_sound', '0'))
        # TODO : common preferences
        self.login_text = getattr(modconf, 'login_text', None)
        # TODO : common preferences
        self.company_logo = getattr(modconf, 'company_logo', 'default_company')
        if self.company_logo == '':
            # Set a dummy value if webui.cfg value is empty to force using the default logo ...
            self.company_logo = 'abcdef'
        # TODO : common preferences
        self.gravatar = to_bool(getattr(modconf, 'gravatar', '0'))
        # TODO : common preferences
        self.allow_html_output = to_bool(getattr(modconf, 'allow_html_output', '0'))
        # TODO : common preferences
        #self.max_output_length = int(getattr(modconf, 'max_output_length', '100'))
        # TODO : common preferences
        self.refresh_period = int(getattr(modconf, 'refresh_period', '60'))
        # Use element tag as image or use text
        self.tag_as_image = to_bool(getattr(modconf, 'tag_as_image', '0'))

        # Manage user's ACL
        self.manage_acl = to_bool(getattr(modconf, 'manage_acl', '1'))
        self.allow_anonymous = to_bool(getattr(modconf, 'allow_anonymous', '0'))

        # Advanced options
        self.http_backend = getattr(modconf, 'http_backend', 'auto')
        self.remote_user_enable = getattr(modconf, 'remote_user_enable', '0')
        self.remote_user_variable = getattr(modconf, 'remote_user_variable', 'X_REMOTE_USER')
        self.serveropts = {}
        umask = getattr(modconf, 'umask', None)
        if umask is not None:
            self.serveropts['umask'] = int(umask)
        bindAddress = getattr(modconf, 'bindAddress', None)
        if bindAddress:
            self.serveropts['bindAddress'] = str(bindAddress)

        # Apache htpasswd file for authentication
        self.htpasswd_file = getattr(modconf, 'htpasswd_file', None)
        if self.htpasswd_file:
            if not os.path.exists(self.htpasswd_file):
                logger.warning("[WebUI] htpasswd file '%s' does not exist.", self.htpasswd_file)
                self.htpasswd_file = None

        # Load the config dir and make it an absolute path
        self.config_dir = getattr(modconf, 'config_dir', 'share')
        self.config_dir = os.path.abspath(self.config_dir)
        logger.info("[WebUI] Config dir: %s", self.config_dir)

        # Load the share dir and make it an absolute path
        self.share_dir = getattr(modconf, 'share_dir', 'share')
        self.share_dir = os.path.abspath(self.share_dir)
        logger.info("[WebUI] Share dir: %s", self.share_dir)

        # Load the photo dir and make it an absolute path
        self.photo_dir = getattr(modconf, 'photos_dir', 'photos')
        self.photo_dir = os.path.abspath(self.photo_dir)
        logger.info("[WebUI] Photo dir: %s", self.photo_dir)

        self.user_picture = ''

        # @mohierf: still useful ? No value in webui.cfg, so always False ...
        # self.embeded_graph = to_bool(getattr(modconf, 'embeded_graph', '0'))

        # Look for an additional pages dir
        self.additional_plugins_dir = getattr(modconf, 'additional_plugins_dir', '')
        if self.additional_plugins_dir:
            self.additional_plugins_dir = os.path.abspath(self.additional_plugins_dir)
        logger.info("[WebUI] Additional plugins dir: %s", self.additional_plugins_dir)

        # Web UI timezone
        self.timezone = getattr(modconf, 'timezone', 'Europe/Paris')
        if self.timezone:
            logger.info("[WebUI] Setting our timezone to %s", self.timezone)
            os.environ['TZ'] = self.timezone
            time.tzset()
        logger.info("[WebUI] parameter timezone: %s", self.timezone)

        # Visual alerting thresholds
        # Used in the dashboard view to select background color for percentages
        self.hosts_states_warning = int(getattr(modconf, 'hosts_states_warning', '95'))
        self.hosts_states_critical = int(getattr(modconf, 'hosts_states_critical', '90'))
        self.services_states_warning = int(getattr(modconf, 'services_states_warning', '95'))
        self.services_states_critical = int(getattr(modconf, 'services_states_critical', '90'))

        # Web UI information
        self.app_version = getattr(modconf, 'about_version', WEBUI_VERSION)
        self.app_copyright = getattr(modconf, 'about_copyright', WEBUI_COPYRIGHT)
        self.app_release = getattr(modconf, 'about_release', WEBUI_RELEASENOTES)

        # We will save all widgets
        self.widgets = {}

        # We need our regenerator now (before main) so if we are in a scheduler,
        # rg will be able to skip some broks
        self.rg = Regenerator()

        # My bottle object ...
        self.bottle = bottle

        bottle.BaseTemplate.defaults['app'] = self

    # Called by Broker so we can do init stuff
    def init(self):
        logger.info("[WebUI] Initializing ...")
        self.rg.load_external_queue(self.from_q)

    # This is called only when we are in a scheduler
    # and just before we are started. So we can gain time, and
    # just load all scheduler objects without fear :) (we
    # will be in another process, so we will be able to hack objects
    # if need)
    def hook_pre_scheduler_mod_start(self, sched):
        print "pre_scheduler_mod_start::", sched.__dict__
        self.rg.load_from_scheduler(sched)

    # In a scheduler we will have a filter of what we really want as a brok
    def want_brok(self, b):
        return self.rg.want_brok(b)

    def main(self):
        self.set_proctitle(self.name)

        # Daemon like init
        self.debug_output = []
        self.modules_dir = modulesctx.get_modulesdir()
        self.modules_manager = ModulesManager('webui', self.find_modules_path(), [])
        self.modules_manager.set_modules(self.modules)
        # We can now output some previously silenced debug output
        self.do_load_modules()
        for inst in self.modules_manager.instances:
            f = getattr(inst, 'load', None)
            if f and callable(f):
                f(self)
        for s in self.debug_output:
            print s
        del self.debug_output

        # Check if the Bottle view dir really exist
        if not os.path.exists(bottle.TEMPLATE_PATH[0]):
            logger.error("[WebUI] The view path do not exist at %s" % bottle.TEMPLATE_PATH)
            sys.exit(2)

        # Check directories
        # We check if the photo directory exists. If not, try to create it
        for d in [self.photo_dir, self.share_dir, self.config_dir]:
            logger.debug("[WebUI] Checking dir: %s", d)
            if not os.path.exists(d):
                try:
                    os.mkdir(d)
                    logger.info("[WebUI] Created dir: %s", d)
                except Exception, exp:
                    logger.error("[WebUI] Dir creation failed: %s", exp)

        # :TODO:maethor:150724: Complete with other function names
        self.auth_module = AuthMetaModule(AuthMetaModule.find_modules(self.modules_manager.get_internal_instances()), self)
        self.prefs_module = PrefsMetaModule(PrefsMetaModule.find_modules(self.modules_manager.get_internal_instances()), self)
        self.logs_module = LogsMetaModule(LogsMetaModule.find_modules(self.modules_manager.get_internal_instances()), self)
        self.graphs_module = GraphsMetaModule(GraphsMetaModule.find_modules(self.modules_manager.get_internal_instances()), self)
        self.helpdesk_module = HelpdeskMetaModule(HelpdeskMetaModule.find_modules(self.modules_manager.get_internal_instances()), self)

        # Data manager
        self.datamgr = WebUIDataManager(self.rg)
        self.helper = helper

        self.request = bottle.request
        self.response = bottle.response

        # :TODO:maethor:150717: Doesn't work
        #username = self.request.get_cookie("user", secret=self.auth_secret)
        #if username:
            #self.user = User.from_contact(self.datamgr.get_contact(username), self.gravatar)
        #else:
            #self.user = None

        try:
            self.do_main()
        except Exception, exp:
            msg = Message(id=0, type='ICrash', data={'name': self.get_name(), 'exception': exp, 'trace': traceback.format_exc()})
            self.from_q.put(msg)
            # wait 2 sec so we know that the broker got our message, and die
            time.sleep(2)
            raise
Beispiel #9
0
    def main(self, stand_alone=False):
        """
            Module main function
        """
        self.stand_alone = stand_alone
        if self.stand_alone:
            setproctitle(self.name)
        else:
            self.set_proctitle(self.name)

        # Modules management
        self.debug_output = []
        self.modules_dir = modulesctx.get_modulesdir()
        self.modules_manager = ModulesManager('webui',
                                              self.find_modules_path(), [])
        self.modules_manager.set_modules(self.modules)
        logger.info("[WebUI] modules %s", self.modules)

        # We can now output some previously silenced debug output
        self.do_load_modules()
        for inst in self.modules_manager.instances:
            f = getattr(inst, 'load', None)
            if f and callable(f):
                f(self)
        for s in self.debug_output:
            print s
        del self.debug_output
        logger.info("[WebUI] loaded modules %s", self.modules)

        # Check if the Bottle view dir really exist
        if not os.path.exists(bottle.TEMPLATE_PATH[0]):
            logger.error("[WebUI] The view path do not exist at %s",
                         bottle.TEMPLATE_PATH)
            sys.exit(2)

        # Load internal sub modules
        self.auth_module = AuthMetaModule(
            AuthMetaModule.find_modules(
                self.modules_manager.get_internal_instances()), self)
        self.prefs_module = PrefsMetaModule(
            PrefsMetaModule.find_modules(
                self.modules_manager.get_internal_instances()), self)
        self.logs_module = LogsMetaModule(
            LogsMetaModule.find_modules(
                self.modules_manager.get_internal_instances()), self)
        self.graphs_module = GraphsMetaModule(
            GraphsMetaModule.find_modules(
                self.modules_manager.get_internal_instances()), self)
        self.helpdesk_module = HelpdeskMetaModule(
            HelpdeskMetaModule.find_modules(
                self.modules_manager.get_internal_instances()), self)

        # Data manager
        self.datamgr = WebUIDataManager(self.rg, self.frontend,
                                        self.alignak_backend_objects)
        self.helper = helper

        # Check directories
        # We check if the photo directory exists. If not, try to create it
        for dir in [self.share_dir, self.photo_dir, self.config_dir]:
            logger.debug("[WebUI] Checking dir: %s", dir)
            if not os.path.exists(dir):
                try:
                    # os.mkdir(dir)
                    os.makedirs(dir, mode=0o777)
                    logger.info("[WebUI] Created directory: %s", dir)
                except Exception as e:
                    logger.error(
                        "[WebUI] Directory creation failed: %s, error: %s",
                        dir, str(e))
            else:
                logger.debug("[WebUI] Still existing directory: %s", dir)

        # Bottle objects
        self.request = bottle.request
        self.response = bottle.response

        try:
            # I register my exit function
            self.set_exit_handler()

            # First load the additional plugins so they will have the lead on URI routes
            if self.additional_plugins_dir:
                self.load_plugins(self.additional_plugins_dir)

            # Modules can also override some views if need
            for inst in self.modules_manager.instances:
                f = getattr(inst, 'get_webui_plugins_path', None)
                if f and callable(f):
                    mod_plugins_path = os.path.abspath(f(self))
                    self.load_plugins(mod_plugins_path)

            # Then look at the plugins into core and load all we can there
            core_plugin_dir = os.path.join(
                os.path.abspath(os.path.dirname(__file__)), 'plugins')
            self.load_plugins(core_plugin_dir)

            # Declare the whole app static files AFTER the plugin ones
            self.declare_common_static()

            # Mount Web UI application
            # if self.endpoint:
            # root_app.mount(self.endpoint, webui_app)
            # logger.info("[WebUI] root routes: %s", root_app.routes)
            # for route in webui_app.routes:
            # logger.info("[WebUI] route: %s", route)

            for route in webui_app.routes:
                logger.info("[WebUI] route: %s", route)

            # We will protect the operations on
            # the non read+write with a lock and
            # 2 int
            self.global_lock = threading.RLock()
            self.nb_readers = 0
            self.nb_writers = 0

            self.data_thread = None
            self.ls_thread = None

            # For alignak backend ...
            if self.frontend:
                # Launch the livestate thread ...
                self.ls_thread = threading.Thread(None, self.manage_ls_thread,
                                                  'lsthread')
                self.ls_thread.start()
            else:
                # Launch the data thread ...
                self.data_thread = threading.Thread(None,
                                                    self.manage_brok_thread,
                                                    'datathread')
                self.data_thread.start()
                # TODO: look for alive and killing

            logger.info("[WebUI] starting Web UI server on %s:%d ...",
                        self.host, self.port)
            bottle.TEMPLATES.clear()
            webui_app.run(host=self.host,
                          port=self.port,
                          server=self.http_backend,
                          **self.serveropts)
        except Exception as e:
            if self.stand_alone:
                logger.error("[WebUI] do_main exception: %s", str(e))
                logger.error("[WebUI] traceback: %s", traceback.format_exc())
                exit(1)
            else:
                msg = Message(id=0,
                              type='ICrash',
                              data={
                                  'name': self.get_name(),
                                  'exception': e,
                                  'trace': traceback.format_exc()
                              })
                self.from_q.put(msg)
                # wait 2 sec so we know that the broker got our message, and die
                time.sleep(2)
                raise
Beispiel #10
0
class Webui_broker(BaseModule, Daemon):
    def __init__(self, modconf):
        BaseModule.__init__(self, modconf)

        self.plugins = []
        self.modconf = modconf

        # Web server configuration
        self.host = getattr(modconf, 'host', '0.0.0.0')
        self.port = int(getattr(modconf, 'port', '7767'))
        logger.info("[WebUI] server: %s:%d", self.host, self.port)
        self.endpoint = getattr(modconf, 'endpoint', None)
        if self.endpoint:
            if self.endpoint.endswith('/'):
                self.endpoint = self.endpoint[:-1]
            logger.info("[WebUI] configured endpoint: %s", self.endpoint)
            logger.warning(
                "[WebUI] endpoint feature is not implemented! WebUI is served from root URL: http://%s:%d/",
                self.host, self.port)
            self.endpoint = None

        # Build session cookie
        self.session_cookie = getattr(modconf, 'cookie_name', 'user')
        self.auth_secret = resolve_auth_secret(modconf)
        logger.info("[WebUI] cookie: %s", self.session_cookie)
        # TODO : common preferences
        self.play_sound = to_bool(getattr(modconf, 'play_sound', '0'))
        # TODO : common preferences
        self.login_text = getattr(modconf, 'login_text', None)
        # TODO : common preferences
        self.company_logo = getattr(modconf, 'company_logo', 'default_company')
        if self.company_logo == '':
            # Set a dummy value if webui.cfg value is empty to force using the default logo ...
            self.company_logo = 'abcdef'
        # TODO : common preferences
        self.gravatar = to_bool(getattr(modconf, 'gravatar', '0'))
        # TODO : common preferences
        self.allow_html_output = to_bool(
            getattr(modconf, 'allow_html_output', '0'))
        # TODO : common preferences
        #self.max_output_length = int(getattr(modconf, 'max_output_length', '100'))
        # TODO : common preferences
        self.refresh_period = int(getattr(modconf, 'refresh_period', '60'))
        self.refresh = False if self.refresh_period == 0 else True
        # Use element tag as image or use text
        self.tag_as_image = to_bool(getattr(modconf, 'tag_as_image', '0'))

        # Manage user's ACL
        self.manage_acl = to_bool(getattr(modconf, 'manage_acl', '1'))
        self.allow_anonymous = to_bool(getattr(modconf, 'allow_anonymous',
                                               '0'))

        # Allow to customize default downtime duration
        self.default_downtime_hours = int(
            getattr(modconf, 'default_downtime_hours', '48'))
        self.shinken_downtime_fixed = int(
            getattr(modconf, 'shinken_downtime_fixed', '1'))
        self.shinken_downtime_trigger = int(
            getattr(modconf, 'shinken_downtime_trigger', '0'))
        self.shinken_downtime_duration = int(
            getattr(modconf, 'shinken_downtime_duration', '0'))

        # Allow to customize default acknowledge parameters
        self.default_ack_sticky = int(
            getattr(modconf, 'default_ack_sticky', '2'))
        self.default_ack_notify = int(
            getattr(modconf, 'default_ack_notify', '1'))
        self.default_ack_persistent = int(
            getattr(modconf, 'default_ack_persistent', '1'))

        # Advanced options
        self.http_backend = getattr(modconf, 'http_backend', 'auto')
        self.remote_user_enable = getattr(modconf, 'remote_user_enable', '0')
        self.remote_user_variable = getattr(modconf, 'remote_user_variable',
                                            'X_REMOTE_USER')
        self.serveropts = {}
        umask = getattr(modconf, 'umask', None)
        if umask is not None:
            self.serveropts['umask'] = int(umask)
        bindAddress = getattr(modconf, 'bindAddress', None)
        if bindAddress:
            self.serveropts['bindAddress'] = str(bindAddress)

        # Apache htpasswd file for authentication
        self.htpasswd_file = getattr(modconf, 'htpasswd_file', None)
        if self.htpasswd_file:
            if not os.path.exists(self.htpasswd_file):
                logger.warning("[WebUI] htpasswd file '%s' does not exist.",
                               self.htpasswd_file)
                self.htpasswd_file = None

        # Alignak backend for authentication
        self.frontend = None
        self.alignak_backend_objects = False
        self.alignak_backend_endpoint = getattr(modconf,
                                                'alignak_backend_endpoint',
                                                None)
        if frontend_available and self.alignak_backend_endpoint:
            self.frontend = FrontEnd()
            if self.frontend:
                self.frontend.configure(self.alignak_backend_endpoint)
            logger.info("[WebUI] alignak backend: %s",
                        self.frontend.url_endpoint_root)

            self.alignak_backend_objects = to_bool(
                getattr(modconf, 'alignak_backend_objects', '0'))

        # Load the config dir and make it an absolute path
        self.config_dir = getattr(modconf, 'config_dir', 'share')
        self.config_dir = os.path.abspath(self.config_dir)
        logger.info("[WebUI] Config dir: %s", self.config_dir)

        # Load the share dir and make it an absolute path
        self.share_dir = getattr(modconf, 'share_dir', 'share')
        self.share_dir = os.path.abspath(self.share_dir)
        logger.info("[WebUI] Share dir: %s", self.share_dir)

        # Load the photo dir and make it an absolute path
        self.photo_dir = getattr(modconf, 'photos_dir', 'photos')
        self.photo_dir = os.path.abspath(self.photo_dir)
        logger.info("[WebUI] Photo dir: %s", self.photo_dir)

        # User information
        self.user_session = None
        self.user_info = None

        # @mohierf: still useful ? No value in webui.cfg, so always False ...
        # self.embeded_graph = to_bool(getattr(modconf, 'embeded_graph', '0'))

        # Look for an additional pages dir
        self.additional_plugins_dir = getattr(modconf,
                                              'additional_plugins_dir', '')
        if self.additional_plugins_dir:
            self.additional_plugins_dir = os.path.abspath(
                self.additional_plugins_dir)
        logger.info("[WebUI] Additional plugins dir: %s",
                    self.additional_plugins_dir)

        # Web UI timezone
        self.timezone = getattr(modconf, 'timezone', 'Europe/Paris')
        if self.timezone:
            logger.info("[WebUI] Setting our timezone to %s", self.timezone)
            os.environ['TZ'] = self.timezone
            time.tzset()
        logger.info("[WebUI] parameter timezone: %s", self.timezone)

        # Visual alerting thresholds
        # Used in the dashboard view to select background color for percentages
        self.hosts_states_warning = int(
            getattr(modconf, 'hosts_states_warning', '95'))
        self.hosts_states_critical = int(
            getattr(modconf, 'hosts_states_critical', '90'))
        self.services_states_warning = int(
            getattr(modconf, 'services_states_warning', '95'))
        self.services_states_critical = int(
            getattr(modconf, 'services_states_critical', '90'))

        # Web UI information
        self.app_version = getattr(modconf, 'about_version', WEBUI_VERSION)
        self.app_copyright = getattr(modconf, 'about_copyright',
                                     WEBUI_COPYRIGHT)

        # We will save all widgets
        self.widgets = {}

        # We need our regenerator now (before main) so if we are in a scheduler,
        # rg will be able to skip some broks
        self.rg = None
        if not self.alignak_backend_objects:
            self.rg = Regenerator()

        # My bottle object ...
        self.bottle = bottle

        bottle.BaseTemplate.defaults['app'] = self

    # Called by Broker so we can do init stuff
    def init(self):
        logger.info("[WebUI] Initializing ...")
        if not self.alignak_backend_objects:
            self.rg.load_external_queue(self.from_q)

    # This is called only when we are in a scheduler
    # and just before we are started. So we can gain time, and
    # just load all scheduler objects without fear :) (we
    # will be in another process, so we will be able to hack objects
    # if need)
    def hook_pre_scheduler_mod_start(self, sched):
        print "pre_scheduler_mod_start::", sched.__dict__
        self.rg.load_from_scheduler(sched)

    # In a scheduler we will have a filter of what we really want as a brok
    def want_brok(self, b):
        return self.rg.want_brok(b)

    def main(self, stand_alone=False):
        """
            Module main function
        """
        self.stand_alone = stand_alone
        if self.stand_alone:
            setproctitle(self.name)
        else:
            self.set_proctitle(self.name)

        # Modules management
        self.debug_output = []
        self.modules_dir = modulesctx.get_modulesdir()
        self.modules_manager = ModulesManager('webui',
                                              self.find_modules_path(), [])
        self.modules_manager.set_modules(self.modules)
        logger.info("[WebUI] modules %s", self.modules)

        # We can now output some previously silenced debug output
        self.do_load_modules()
        for inst in self.modules_manager.instances:
            f = getattr(inst, 'load', None)
            if f and callable(f):
                f(self)
        for s in self.debug_output:
            print s
        del self.debug_output
        logger.info("[WebUI] loaded modules %s", self.modules)

        # Check if the Bottle view dir really exist
        if not os.path.exists(bottle.TEMPLATE_PATH[0]):
            logger.error("[WebUI] The view path do not exist at %s",
                         bottle.TEMPLATE_PATH)
            sys.exit(2)

        # Load internal sub modules
        self.auth_module = AuthMetaModule(
            AuthMetaModule.find_modules(
                self.modules_manager.get_internal_instances()), self)
        self.prefs_module = PrefsMetaModule(
            PrefsMetaModule.find_modules(
                self.modules_manager.get_internal_instances()), self)
        self.logs_module = LogsMetaModule(
            LogsMetaModule.find_modules(
                self.modules_manager.get_internal_instances()), self)
        self.graphs_module = GraphsMetaModule(
            GraphsMetaModule.find_modules(
                self.modules_manager.get_internal_instances()), self)
        self.helpdesk_module = HelpdeskMetaModule(
            HelpdeskMetaModule.find_modules(
                self.modules_manager.get_internal_instances()), self)

        # Data manager
        self.datamgr = WebUIDataManager(self.rg, self.frontend,
                                        self.alignak_backend_objects)
        self.helper = helper

        # Check directories
        # We check if the photo directory exists. If not, try to create it
        for dir in [self.share_dir, self.photo_dir, self.config_dir]:
            logger.debug("[WebUI] Checking dir: %s", dir)
            if not os.path.exists(dir):
                try:
                    # os.mkdir(dir)
                    os.makedirs(dir, mode=0o777)
                    logger.info("[WebUI] Created directory: %s", dir)
                except Exception as e:
                    logger.error(
                        "[WebUI] Directory creation failed: %s, error: %s",
                        dir, str(e))
            else:
                logger.debug("[WebUI] Still existing directory: %s", dir)

        # Bottle objects
        self.request = bottle.request
        self.response = bottle.response

        try:
            # I register my exit function
            self.set_exit_handler()

            # First load the additional plugins so they will have the lead on URI routes
            if self.additional_plugins_dir:
                self.load_plugins(self.additional_plugins_dir)

            # Modules can also override some views if need
            for inst in self.modules_manager.instances:
                f = getattr(inst, 'get_webui_plugins_path', None)
                if f and callable(f):
                    mod_plugins_path = os.path.abspath(f(self))
                    self.load_plugins(mod_plugins_path)

            # Then look at the plugins into core and load all we can there
            core_plugin_dir = os.path.join(
                os.path.abspath(os.path.dirname(__file__)), 'plugins')
            self.load_plugins(core_plugin_dir)

            # Declare the whole app static files AFTER the plugin ones
            self.declare_common_static()

            # Mount Web UI application
            # if self.endpoint:
            # root_app.mount(self.endpoint, webui_app)
            # logger.info("[WebUI] root routes: %s", root_app.routes)
            # for route in webui_app.routes:
            # logger.info("[WebUI] route: %s", route)

            for route in webui_app.routes:
                logger.info("[WebUI] route: %s", route)

            # We will protect the operations on
            # the non read+write with a lock and
            # 2 int
            self.global_lock = threading.RLock()
            self.nb_readers = 0
            self.nb_writers = 0

            self.data_thread = None
            self.ls_thread = None

            # For alignak backend ...
            if self.frontend:
                # Launch the livestate thread ...
                self.ls_thread = threading.Thread(None, self.manage_ls_thread,
                                                  'lsthread')
                self.ls_thread.start()
            else:
                # Launch the data thread ...
                self.data_thread = threading.Thread(None,
                                                    self.manage_brok_thread,
                                                    'datathread')
                self.data_thread.start()
                # TODO: look for alive and killing

            logger.info("[WebUI] starting Web UI server on %s:%d ...",
                        self.host, self.port)
            bottle.TEMPLATES.clear()
            webui_app.run(host=self.host,
                          port=self.port,
                          server=self.http_backend,
                          **self.serveropts)
        except Exception as e:
            if self.stand_alone:
                logger.error("[WebUI] do_main exception: %s", str(e))
                logger.error("[WebUI] traceback: %s", traceback.format_exc())
                exit(1)
            else:
                msg = Message(id=0,
                              type='ICrash',
                              data={
                                  'name': self.get_name(),
                                  'exception': e,
                                  'trace': traceback.format_exc()
                              })
                self.from_q.put(msg)
                # wait 2 sec so we know that the broker got our message, and die
                time.sleep(2)
                raise

    # External commands
    # -----------------------------------------------------
    def push_external_command(self, e):
        """
            A plugin sends us an external command. Notify this command to the monitoring framework ...
        """
        logger.debug("[WebUI] Got an external command: %s", e.__dict__)
        if self.stand_alone:
            logger.warning(
                "[WebUI] --------------------------------------------------")
            logger.warning("[WebUI] TODO: notify external command: %s",
                           e.__dict__)
            logger.warning(
                "[WebUI] --------------------------------------------------")
        else:
            try:
                self.from_q.put(e)
            except Exception, exp:
                logger.error("[WebUI] External command push, exception: %s",
                             str(exp))
    def test_modulemanager(self):
        mod = Module({'module_name': 'DummyExternal', 'module_type': 'dummy_broker_external'})
        self.modulemanager = ModulesManager('broker', modules_dir, [])
        self.modulemanager.set_modules([mod])
        self.modulemanager.load_and_init()
        # And start external ones, like our LiveStatus
        self.modulemanager.start_external_instances()
        print "I correctly loaded the modules: %s " % ([inst.get_name() for inst in self.modulemanager.instances])

        print "*** First kill ****"
        # Now I will try to kill the livestatus module
        ls = self.modulemanager.instances[0]
        ls._BaseModule__kill()

        time.sleep(1)
        print "Check alive?"
        print "Is alive?", ls.process.is_alive()
        # Should be dead
        self.assertFalse(ls.process.is_alive())
        self.modulemanager.check_alive_instances()
        self.modulemanager.try_to_restart_deads()

        # In fact it's too early, so it won't do it

        # Here the inst should still be dead
        print "Is alive?", ls.process.is_alive()
        self.assertFalse(ls.process.is_alive())

        # So we lie
        ls.last_init_try = -5
        self.modulemanager.check_alive_instances()
        self.modulemanager.try_to_restart_deads()

        # In fact it's too early, so it won't do it

        # Here the inst should be alive again
        print "Is alive?", ls.process.is_alive()
        self.assertTrue(ls.process.is_alive())

        # should be nothing more in to_restart of
        # the module manager
        self.assertEqual([], self.modulemanager.to_restart)

        # Now we look for time restart so we kill it again
        ls._BaseModule__kill()
        time.sleep(1)
        self.assertFalse(ls.process.is_alive())

        # Should be too early
        self.modulemanager.check_alive_instances()
        self.modulemanager.try_to_restart_deads()
        print "Is alive or not", ls.process.is_alive()
        self.assertFalse(ls.process.is_alive())
        # We lie for the test again
        ls.last_init_try = -5
        self.modulemanager.check_alive_instances()
        self.modulemanager.try_to_restart_deads()

        # Here the inst should be alive again
        print "Is alive?", ls.process.is_alive()
        self.assertTrue(ls.process.is_alive())

        # And we clear all now
        print "Ask to die"
        self.modulemanager.stop_all()
        print "Died"
Beispiel #12
0
class Webui_broker(BaseModule, Daemon):
    def __init__(self, modconf):
        BaseModule.__init__(self, modconf)

        self.plugins = []
        self.modconf = modconf

        # Web server configuration
        self.host = getattr(modconf, 'host', '0.0.0.0')
        self.port = int(getattr(modconf, 'port', '7767'))
        self.auth_secret = getattr(modconf, 'auth_secret',
                                   'secret').encode('utf8', 'replace')

        # TODO : common preferences
        self.play_sound = to_bool(getattr(modconf, 'play_sound', '0'))
        # TODO : common preferences
        self.login_text = getattr(modconf, 'login_text', None)
        # TODO : common preferences
        self.company_logo = getattr(modconf, 'company_logo', 'default_company')
        if self.company_logo == '':
            # Set a dummy value if webui.cfg value is empty to force using the default logo ...
            self.company_logo = 'abcdef'
        # TODO : common preferences
        self.gravatar = to_bool(getattr(modconf, 'gravatar', '0'))
        # TODO : common preferences
        self.allow_html_output = to_bool(
            getattr(modconf, 'allow_html_output', '0'))
        # TODO : common preferences
        #self.max_output_length = int(getattr(modconf, 'max_output_length', '100'))
        # TODO : common preferences
        self.refresh_period = int(getattr(modconf, 'refresh_period', '60'))
        # Use element tag as image or use text
        self.tag_as_image = to_bool(getattr(modconf, 'tag_as_image', '0'))

        # Manage user's ACL
        self.manage_acl = to_bool(getattr(modconf, 'manage_acl', '1'))
        self.allow_anonymous = to_bool(getattr(modconf, 'allow_anonymous',
                                               '0'))

        # Advanced options
        self.http_backend = getattr(modconf, 'http_backend', 'auto')
        self.remote_user_enable = getattr(modconf, 'remote_user_enable', '0')
        self.remote_user_variable = getattr(modconf, 'remote_user_variable',
                                            'X_REMOTE_USER')
        self.serveropts = {}
        umask = getattr(modconf, 'umask', None)
        if umask is not None:
            self.serveropts['umask'] = int(umask)
        bindAddress = getattr(modconf, 'bindAddress', None)
        if bindAddress:
            self.serveropts['bindAddress'] = str(bindAddress)

        # Apache htpasswd file for authentication
        self.htpasswd_file = getattr(modconf, 'htpasswd_file',
                                     '/etc/shinken/htpasswd.users')
        logger.info("[WebUI] htpasswd file: %s", self.htpasswd_file)
        if self.htpasswd_file:
            if not os.path.exists(self.htpasswd_file):
                logger.warning("[WebUI] htpasswd file '%s' does not exist.",
                               self.htpasswd_file)
                self.htpasswd_file = None

        # Load the config dir and make it an absolute path
        self.config_dir = getattr(modconf, 'config_dir', 'share')
        self.config_dir = os.path.abspath(self.config_dir)
        logger.info("[WebUI] Config dir: %s", self.config_dir)

        # Load the share dir and make it an absolute path
        self.share_dir = getattr(modconf, 'share_dir', 'share')
        self.share_dir = os.path.abspath(self.share_dir)
        logger.info("[WebUI] Share dir: %s", self.share_dir)

        # Load the photo dir and make it an absolute path
        self.photo_dir = getattr(modconf, 'photos_dir', 'photos')
        self.photo_dir = os.path.abspath(self.photo_dir)
        logger.info("[WebUI] Photo dir: %s", self.photo_dir)

        self.user_picture = ''

        # @mohierf: still useful ? No value in webui.cfg, so always False ...
        # self.embeded_graph = to_bool(getattr(modconf, 'embeded_graph', '0'))

        # Look for an additional pages dir
        self.additional_plugins_dir = getattr(modconf,
                                              'additional_plugins_dir', '')
        if self.additional_plugins_dir:
            self.additional_plugins_dir = os.path.abspath(
                self.additional_plugins_dir)
        logger.info("[WebUI] Additional plugins dir: %s",
                    self.additional_plugins_dir)

        # Web UI timezone
        self.timezone = getattr(modconf, 'timezone', 'Europe/Paris')
        if self.timezone:
            logger.info("[WebUI] Setting our timezone to %s", self.timezone)
            os.environ['TZ'] = self.timezone
            time.tzset()
        logger.info("[WebUI] parameter timezone: %s", self.timezone)

        # Visual alerting thresholds
        # Used in the dashboard view to select background color for percentages
        self.hosts_states_warning = int(
            getattr(modconf, 'hosts_states_warning', '95'))
        self.hosts_states_critical = int(
            getattr(modconf, 'hosts_states_critical', '90'))
        self.services_states_warning = int(
            getattr(modconf, 'services_states_warning', '95'))
        self.services_states_critical = int(
            getattr(modconf, 'services_states_critical', '90'))

        # Web UI information
        self.app_version = getattr(modconf, 'about_version', WEBUI_VERSION)
        self.app_copyright = getattr(modconf, 'about_copyright',
                                     WEBUI_COPYRIGHT)
        self.app_release = getattr(modconf, 'about_release',
                                   WEBUI_RELEASENOTES)

        # We will save all widgets
        self.widgets = {}

        # We need our regenerator now (before main) so if we are in a scheduler,
        # rg will be able to skip some broks
        self.rg = Regenerator()

        # My bottle object ...
        self.bottle = bottle

        bottle.BaseTemplate.defaults['app'] = self

    # Called by Broker so we can do init stuff
    def init(self):
        logger.info("[WebUI] Initializing ...")
        self.rg.load_external_queue(self.from_q)

    # This is called only when we are in a scheduler
    # and just before we are started. So we can gain time, and
    # just load all scheduler objects without fear :) (we
    # will be in another process, so we will be able to hack objects
    # if need)
    def hook_pre_scheduler_mod_start(self, sched):
        print "pre_scheduler_mod_start::", sched.__dict__
        self.rg.load_from_scheduler(sched)

    # In a scheduler we will have a filter of what we really want as a brok
    def want_brok(self, b):
        return self.rg.want_brok(b)

    def main(self):
        self.set_proctitle(self.name)

        # Daemon like init
        self.debug_output = []
        self.modules_dir = modulesctx.get_modulesdir()
        self.modules_manager = ModulesManager('webui',
                                              self.find_modules_path(), [])
        self.modules_manager.set_modules(self.modules)
        # We can now output some previously silenced debug output
        self.do_load_modules()
        for inst in self.modules_manager.instances:
            f = getattr(inst, 'load', None)
            if f and callable(f):
                f(self)
        for s in self.debug_output:
            print s
        del self.debug_output

        # Check if the Bottle view dir really exist
        if not os.path.exists(bottle.TEMPLATE_PATH[0]):
            logger.error("[WebUI] The view path do not exist at %s" %
                         bottle.TEMPLATE_PATH)
            sys.exit(2)

        # Check directories
        # We check if the photo directory exists. If not, try to create it
        for d in [self.photo_dir, self.share_dir, self.config_dir]:
            logger.debug("[WebUI] Checking dir: %s", d)
            if not os.path.exists(d):
                try:
                    os.mkdir(d)
                    logger.info("[WebUI] Created dir: %s", d)
                except Exception, exp:
                    logger.error("[WebUI] Dir creation failed: %s", exp)

        # :TODO:maethor:150724: Complete with other function names
        self.auth_module = AuthMetaModule(
            AuthMetaModule.find_modules(
                self.modules_manager.get_internal_instances()), self)
        self.prefs_module = PrefsMetaModule(
            PrefsMetaModule.find_modules(
                self.modules_manager.get_internal_instances()), self)
        self.logs_module = LogsMetaModule(
            LogsMetaModule.find_modules(
                self.modules_manager.get_internal_instances()), self)
        self.graphs_module = GraphsMetaModule(
            GraphsMetaModule.find_modules(
                self.modules_manager.get_internal_instances()), self)
        self.helpdesk_module = HelpdeskMetaModule(
            HelpdeskMetaModule.find_modules(
                self.modules_manager.get_internal_instances()), self)

        # Data manager
        self.datamgr = WebUIDataManager(self.rg)
        self.helper = helper

        self.request = request
        self.response = response
        self.template_call = template

        # :TODO:maethor:150717: Doesn't work
        #username = self.request.get_cookie("user", secret=self.auth_secret)
        #if username:
        #self.user = User.from_contact(self.datamgr.get_contact(username), self.gravatar)
        #else:
        #self.user = None

        try:
            self.do_main()
        except Exception, exp:
            msg = Message(id=0,
                          type='ICrash',
                          data={
                              'name': self.get_name(),
                              'exception': exp,
                              'trace': traceback.format_exc()
                          })
            self.from_q.put(msg)
            # wait 2 sec so we know that the broker got our message, and die
            time.sleep(2)
            raise
    def test_modulemanager(self):
        mod = Module({
            'module_name': 'DummyExternal',
            'module_type': 'dummy_broker_external'
        })
        self.modulemanager = ModulesManager('broker',
                                            "var/lib/shinken/modules", [])
        self.modulemanager.set_modules([mod])
        self.modulemanager.load_and_init()
        # And start external ones, like our LiveStatus
        self.modulemanager.start_external_instances()
        print "I correctly loaded the modules: %s " % (
            [inst.get_name() for inst in self.modulemanager.instances])

        print "*** First kill ****"
        # Now I will try to kill the livestatus module
        ls = self.modulemanager.instances[0]
        ls._BaseModule__kill()

        time.sleep(1)
        print "Check alive?"
        print "Is alive?", ls.process.is_alive()
        # Should be dead
        self.assertFalse(ls.process.is_alive())
        self.modulemanager.check_alive_instances()
        self.modulemanager.try_to_restart_deads()

        # In fact it's too early, so it won't do it

        # Here the inst should still be dead
        print "Is alive?", ls.process.is_alive()
        self.assertFalse(ls.process.is_alive())

        # So we lie
        ls.last_init_try = -5
        self.modulemanager.check_alive_instances()
        self.modulemanager.try_to_restart_deads()

        # In fact it's too early, so it won't do it

        # Here the inst should be alive again
        print "Is alive?", ls.process.is_alive()
        self.assertTrue(ls.process.is_alive())

        # should be nothing more in to_restart of
        # the module manager
        self.assertEqual([], self.modulemanager.to_restart)

        # Now we look for time restart so we kill it again
        ls._BaseModule__kill()
        time.sleep(1)
        self.assertFalse(ls.process.is_alive())

        # Should be too early
        self.modulemanager.check_alive_instances()
        self.modulemanager.try_to_restart_deads()
        print "Is alive or not", ls.process.is_alive()
        self.assertFalse(ls.process.is_alive())
        # We lie for the test again
        ls.last_init_try = -5
        self.modulemanager.check_alive_instances()
        self.modulemanager.try_to_restart_deads()

        # Here the inst should be alive again
        print "Is alive?", ls.process.is_alive()
        self.assertTrue(ls.process.is_alive())

        # And we clear all now
        print "Ask to die"
        self.modulemanager.stop_all()
        print "Died"
Beispiel #14
0
class Daemon(object):

    properties = {
        'workdir': PathProp(default='/usr/local/shinken/var'),
        'host': StringProp(default='0.0.0.0'),
        'user': StringProp(default='shinken'),
        'group': StringProp(default='shinken'),
        'use_ssl': BoolProp(default='0'),
        'certs_dir': StringProp(default='etc/certs'),
        'ca_cert': StringProp(default='etc/certs/ca.pem'),
        'server_cert': StringProp(default='etc/certs/server.pem'),
        'use_local_log': BoolProp(default='0'),
        'hard_ssl_name_check': BoolProp(default='0'),
        'idontcareaboutsecurity': BoolProp(default='0'),
        'spare': BoolProp(default='0')
    }

    def __init__(self, name, config_file, is_daemon, do_replace, debug,
                 debug_file):

        self.check_shm()

        self.name = name
        self.config_file = config_file
        self.is_daemon = is_daemon
        self.do_replace = do_replace
        self.debug = debug
        self.debug_file = debug_file
        self.interrupted = False

        # Track time
        now = time.time()
        self.program_start = now
        self.t_each_loop = now  # used to track system time change
        self.sleep_time = 0.0  #used to track the time we wait

        self.pyro_daemon = None

        # Log init
        self.log = logger
        self.log.load_obj(self)

        self.new_conf = None  # used by controller to push conf
        self.cur_conf = None

        # Flag to know if we need to dump memory or not
        self.need_dump_memory = False

        #Keep a trace of the local_log file desc if need
        self.local_log_fd = None

        self.modules_manager = ModulesManager(name, self.find_modules_path(),
                                              [])

        os.umask(UMASK)
        self.set_exit_handler()

    # At least, lose the local log file if need
    def do_stop(self):
        if self.modules_manager:
            # We save what we can but NOT for the scheduler
            # because the current sched object is a dummy one
            # and the old one aleady do it!
            if not hasattr(self, 'sched'):
                self.hook_point('save_retention')
            # And we quit
            logger.log('Stopping all modules')
            self.modules_manager.stop_all()
        if self.pyro_daemon:
            pyro.shutdown(self.pyro_daemon)  #.shutdown(True)
        logger.quit()

    def request_stop(self):
        self.unlink()  ## unlink first
        self.do_stop()
        print("Exiting")
        sys.exit(0)

    def do_loop_turn(self):
        raise NotImplementedError()

    # Main loop for nearly all daemon
    # the scheduler is not managed by it :'(
    def do_mainloop(self):
        while True:
            self.do_loop_turn()
            # If ask us to dump memory, do it
            if self.need_dump_memory:
                self.dump_memory()
                self.need_dump_memory = False
            # Maybe we ask us to die, if so, do it :)
            if self.interrupted:
                break
        self.request_stop()

    def do_load_modules(self):
        self.modules_manager.load_and_init()
        self.log.log("I correctly loaded the modules : [%s]" % (','.join(
            [inst.get_name() for inst in self.modules_manager.instances])))

    def add(self, elt):
        """ Dummy method for adding broker to this daemon """
        pass

    def dump_memory(self):
        logger.log("I dump my memory, it can ask some seconds to do")
        try:
            from guppy import hpy
            hp = hpy()
            logger.log(hp.heap())
        except ImportError:
            logger.log(
                'I do not have the module guppy for memory dump, please install it'
            )

    def load_config_file(self):
        self.parse_config_file()
        if self.config_file is not None:
            # Some paths can be relatives. We must have a full path by taking
            # the config file by reference
            self.relative_paths_to_full(os.path.dirname(self.config_file))
        # Then start to log all in the local file if asked so
        self.register_local_log()

    def change_to_workdir(self):
        try:
            os.chdir(self.workdir)
        except Exception, e:
            raise InvalidWorkDir(e)
        print("Successfully changed to workdir: %s" % (self.workdir))