def test_simple_config_file_is_read(): test_cfg_dir = get_current_dir() create_config_file(test_cfg_dir, SIMPLE_CONFIG_FILE) try: cfg = ConfigManager(test_cfg_dir) cfg.load() finally: cleanup_configuration(test_cfg_dir)
def test_obsolete_fields_are_removed(): old_config = filerockclient.config.DEFAULT_CONFIG filerockclient.config.DEFAULT_CONFIG = COMPLEX_CONFIG_FILE test_cfg_dir = get_current_dir() create_config_file(test_cfg_dir, OBSOLETE_CONFIG_FILE) try: cfg = ConfigManager(test_cfg_dir) cfg.load() assert_false(cfg.has_option('System', 'field0')) finally: filerockclient.config.DEFAULT_CONFIG = old_config cleanup_configuration(test_cfg_dir)
def test_changed_fields_are_overwritten(): old_config = filerockclient.config.DEFAULT_CONFIG filerockclient.config.DEFAULT_CONFIG = COMPLEX_CONFIG_FILE test_cfg_dir = get_current_dir() create_config_file(test_cfg_dir, OBSOLETE_CONFIG_FILE) try: cfg = ConfigManager(test_cfg_dir) cfg.load() assert_true(cfg.has_option('System', 'field1')) assert_equal(cfg.get('System', 'field1'), 'new_f1') finally: filerockclient.config.DEFAULT_CONFIG = old_config cleanup_configuration(test_cfg_dir)
def test_changed_fields_in_nonwriteable_section_are_not_overwritten(): old_config = filerockclient.config.DEFAULT_CONFIG filerockclient.config.DEFAULT_CONFIG = COMPLEX_CONFIG_FILE filerockclient.config.DONT_OVERWRITE_ON_MERGE = [('System', '*')] test_cfg_dir = get_current_dir() create_config_file(test_cfg_dir, OBSOLETE_CONFIG_FILE) try: cfg = ConfigManager(test_cfg_dir) cfg.load() assert_true(cfg.has_option('System', 'field1')) assert_equal(cfg.get('System', 'field1'), 'f1') finally: filerockclient.config.DEFAULT_CONFIG = old_config filerockclient.config.DONT_OVERWRITE_ON_MERGE = [] cleanup_configuration(test_cfg_dir)
def test_autodiscovery_fields_are_parsed(): old_discovery = filerockclient.config.AUTO_DISCOVERY filerockclient.config.AUTO_DISCOVERY = { ('Application Paths', 'to_auto_discover'): lambda: 'auto_discovered' } test_cfg_dir = get_current_dir() create_config_file(test_cfg_dir, COMPLEX_CONFIG_FILE) try: cfg = ConfigManager(test_cfg_dir) cfg.load() value = cfg.get('Application Paths', 'to_auto_discover') assert_equal(value, 'auto_discovered') finally: filerockclient.config.AUTO_DISCOVERY = old_discovery cleanup_configuration(test_cfg_dir)
def test_file_is_not_accepted_as_directory(): test_cfg_dir = os.path.abspath(__file__) try: cfg = ConfigManager(test_cfg_dir) except ConfigException: assert_true(True, 'Correctly rejected') return assert_true(False, 'Exception expected')
def test_simple_config_file_is_read_correctly(): test_cfg_dir = get_current_dir() create_config_file(test_cfg_dir, SIMPLE_CONFIG_FILE) try: cfg = ConfigManager(test_cfg_dir) cfg.load() assert_equal(cfg.getint('System', 'config_version'), 1) assert_equal(cfg.get('Application Paths', 'caches_dir'), u'caches') assert_equal(cfg.get('User', 'temp_dir'), u'temp') assert_equal(cfg.get('User', 'field'), u'value') finally: cleanup_configuration(test_cfg_dir)
def test_autodiscovery_fields_are_saved_if_modified(): old_discovery = filerockclient.config.AUTO_DISCOVERY filerockclient.config.AUTO_DISCOVERY = { ('Application Paths', 'to_auto_discover'): lambda: 'auto_discovered' } test_cfg_dir = get_current_dir() create_config_file(test_cfg_dir, COMPLEX_CONFIG_FILE) try: cfg = ConfigManager(test_cfg_dir) cfg.load() cfg.set('Application Paths', 'to_auto_discover', 'something') cfg.write_to_file() plain_cfg = SafeConfigParser() with codecs.open(os.path.join(test_cfg_dir, CONFIG_FILE_NAME), encoding='utf-8_sig') as fp: plain_cfg.readfp(fp) value = plain_cfg.get('Application Paths', 'to_auto_discover') assert_equal(value, 'something') finally: filerockclient.config.AUTO_DISCOVERY = old_discovery cleanup_configuration(test_cfg_dir)
def main_loop(self): """ The never-ending loop where the main thread runs, listening for termination events. Calling this method means actually starting FileRock. Each iteration of the loop implies a re-initialization of some part of the application: just the core, the UI as well, the whole OS process, etc. Most of the time the thread sleeps, waiting for a command in the input queue, in a blocking fashion. """ logging_helper = LoggerManager() logger = self._get_logger(logging_helper) self.logger = logger cfg = ConfigManager(self.configdir) cfg.load() self._lockfile = self._check_unique_instance_running(cfg, logger) if not self._lockfile: self._open_warebox_folder(cfg) return self._save_process_pid() running = True skip_ui_creation = False command_queue = Queue.Queue() file_handler = None oldhook = None last_reset_time = datetime.datetime.now() - datetime.timedelta(days=1) if self.restartcount > 0: self.startupslides = False self.showpanel = False if self.restartcount >= MAX_NUMBER_OF_RESTART: self.restartcount = 0 self._pause_client(True) def sigterm_handler(sig, sframe): command_queue.put('TERMINATE') def sigabrt_handler(sig, sframe): command_queue.put('HARD_RESET') signal.signal(signal.SIGTERM, sigterm_handler) signal.signal(signal.SIGABRT, sigabrt_handler) while running: cfg.load() self._reload_connection_proxy_settings(cfg, logger) file_handler = self._configure_file_logging( logger, logging_helper, file_handler, cfg.get_config_dir()) logger.debug("Current configuration:\n%s" % cfg) core = Core(cfg, self.startupslides, self.showpanel, command_queue, self.cmdline_args, self._lockfile.fileno(), self.auto_start, self.restart_after_minute) # In case of SOFT_RESET startupslides and panel # should not be shown self.startupslides = False self.showpanel = False logger.debug("Command line arguments: %r" % self.cmdline_args) bug_reporter, oldhook = self._setup_bug_reporting( core, cfg, logging_helper, command_queue) try: self._setup_user_interfaces(core, logger, logging_helper, cfg, skip_ui_creation) skip_ui_creation = False self.auto_start = True # Let the magic begin core.start_service() # Listen for termination commands from other threads while True: try: # Note: the actual blocking get cannot be interrupted # by signals, e.g. by pressing Ctrl-C, so we use the # timeout version with a very large timeout value. command = command_queue.get(True, 999999) except Queue.Empty: continue if command == 'TERMINATE': logger.debug('Executing command TERMINATE...') self._terminate(core, logger) running = False logger.debug('Command TERMINATE executed.') break elif command == 'START': logger.debug('Executing command START...') self.restart_after_minute = -1 core.connect() logger.debug('Command START executed.') elif command == 'PAUSE': logger.debug('Executing command PAUSE...') self._terminate(core, logger, terminate_ui=False) core.unschedule_start() skip_ui_creation = True self._pause_client() logger.debug('Command PAUSE executed.') break elif command == 'PAUSE_AND_RESTART': logger.debug('Executing command PAUSE AND RESTART...') self._terminate(core, logger, terminate_ui=False) skip_ui_creation = True self._pause_client(schedule_a_start=True) logger.debug('Command PAUSE AND RESTART executed.') break elif command == 'RESET_PAUSE_TIMER': logger.debug('Resetting waiting after reset') self.restart_after_minute = -1 elif command == 'SOFT_RESET': logger.debug('Executing command SOFT_RESET...') self._terminate(core, logger, terminate_ui=False) skip_ui_creation = True logger.debug('Command SOFT_RESET executed.') break elif command == 'FULL_RESET': running = self._full_reset(core, logger, last_reset_time) last_reset_time = datetime.datetime.now() break elif command == 'HARD_RESET': logger.debug('Executing command HARD_RESET...') self._terminate(core, logger) exc = None try: # Note: this call doesn't return self._hard_reset(logger) except Exception as e: exc = e logger.critical('Error while hard resetting: %r' % exc) os._exit(1) else: logger.error('Application is unable to handle ' 'command %s. Forcing termination...' % command) raise UnknownCommandError(command) except KeyboardInterrupt: # Ctrl-C is equivalent to the TERMINATE command self._terminate(core, logger) running = False except LogOutRequiredException: logger.info(u"Logout is required to continue, shutting down..") self._terminate(core, logger) running = False except MandatoryUpdateDeniedException: logger.info( u"User denied a mandatory update, shutting down...") self._terminate(core, logger) running = False except UpdateRequestedException: # TODO: this will be replaced by an UPDATE command logger.info(u"Client is going to be updated, shutting down") self._terminate(core, logger) self._close_lockfile() logger.info(u"Starting update procedure...") try: updater = PlatformUpdater( cfg.get_config_dir(), cfg.get('Application Paths', 'webserver_ca_chain')) updater.execute_update() except UpdateProcedureException as e: logger.error(u"Update procedure error: %s" % e) except Exception: # The main thread shouldn't rely on automatic bug reporting, # she must handle her own exceptions or nobody will be there to # terminate the application at the end! bug_reporter.on_exception(*sys.exc_info()) running = self._full_reset(core, logger, last_reset_time) last_reset_time = datetime.datetime.now() if oldhook: sys.excepthook = oldhook logger.info(u"Shut down. Goodbye.")
self.logger.debug(u'Setting new configuration username:%s client_id:%s' % (username, strId)) self.cfg.set('User', 'client_id', strId) self.cfg.set('User', 'username', username) #TODO: check the presence of encryption dir in config self.cfg.set('User', 'encryption_key', hexlify(enc_key)) priv_key_file = self.cfg.get('Application Paths', 'client_priv_key_file') #Write private Key self.logger.debug(u'Writing private key to %s' % priv_key_file) try: with codecs.open(priv_key_file, 'w', encoding='utf-8') as f: f.write(pvt_key) #Rewrite new configuration self.cfg.write_to_file() except: self.logger.error(u'Failed writing linking information') raise FailedLinkingException( "Linking failed on write configuration") if __name__ == "__main__": file_name = u'./config.ini' config = ConfigManager() config.load() linker = Linker(config) linker.link()
def test_nonexisting_directory_is_accepted(): test_cfg_dir = os.path.abspath(u'xsfgsdfghldfgfdgbdf') test_cfg_file = os.path.join(test_cfg_dir, CONFIG_FILE_NAME) cfg = ConfigManager(test_cfg_dir) assert_equal(cfg.config_dir, test_cfg_dir) assert_equal(cfg.file_path, test_cfg_file)
def main_loop(self): """ The never-ending loop where the main thread runs, listening for termination events. Calling this method means actually starting FileRock. Each iteration of the loop implies a re-initialization of some part of the application: just the core, the UI as well, the whole OS process, etc. Most of the time the thread sleeps, waiting for a command in the input queue, in a blocking fashion. """ logging_helper = LoggerManager() logger = self._get_logger(logging_helper) self.logger = logger cfg = ConfigManager(self.configdir) cfg.load() self._lockfile = self._check_unique_instance_running(cfg, logger) if not self._lockfile: self._open_warebox_folder(cfg) return self._save_process_pid() running = True skip_ui_creation = False command_queue = Queue.Queue() file_handler = None oldhook = None last_reset_time = datetime.datetime.now() - datetime.timedelta(days=1) if self.restartcount > 0: self.startupslides = False self.showpanel = False if self.restartcount >= MAX_NUMBER_OF_RESTART: self.restartcount = 0 self._pause_client(True) def sigterm_handler(sig, sframe): command_queue.put('TERMINATE') def sigabrt_handler(sig, sframe): command_queue.put('HARD_RESET') signal.signal(signal.SIGTERM, sigterm_handler) signal.signal(signal.SIGABRT, sigabrt_handler) while running: cfg.load() self._reload_connection_proxy_settings(cfg, logger) file_handler = self._configure_file_logging(logger, logging_helper, file_handler, cfg.get_config_dir()) logger.debug("Current configuration:\n%s" % cfg) core = Core(cfg, self.startupslides, self.showpanel, command_queue, self.cmdline_args, self._lockfile.fileno(), self.auto_start, self.restart_after_minute) # In case of SOFT_RESET startupslides and panel # should not be shown self.startupslides = False self.showpanel = False logger.debug("Command line arguments: %r" % self.cmdline_args) bug_reporter, oldhook = self._setup_bug_reporting( core, cfg, logging_helper, command_queue) try: self._setup_user_interfaces(core, logger, logging_helper, cfg, skip_ui_creation) skip_ui_creation = False self.auto_start = True # Let the magic begin core.start_service() # Listen for termination commands from other threads while True: try: # Note: the actual blocking get cannot be interrupted # by signals, e.g. by pressing Ctrl-C, so we use the # timeout version with a very large timeout value. command = command_queue.get(True, 999999) except Queue.Empty: continue if command == 'TERMINATE': logger.debug('Executing command TERMINATE...') self._terminate(core, logger) running = False logger.debug('Command TERMINATE executed.') break elif command == 'START': logger.debug('Executing command START...') self.restart_after_minute = -1 core.connect() logger.debug('Command START executed.') elif command == 'PAUSE': logger.debug('Executing command PAUSE...') self._terminate(core, logger, terminate_ui=False) core.unschedule_start() skip_ui_creation = True self._pause_client() logger.debug('Command PAUSE executed.') break elif command == 'PAUSE_AND_RESTART': logger.debug('Executing command PAUSE AND RESTART...') self._terminate(core, logger, terminate_ui=False) skip_ui_creation = True self._pause_client(schedule_a_start=True) logger.debug('Command PAUSE AND RESTART executed.') break elif command == 'RESET_PAUSE_TIMER': logger.debug('Resetting waiting after reset') self.restart_after_minute = -1 elif command == 'SOFT_RESET': logger.debug('Executing command SOFT_RESET...') self._terminate(core, logger, terminate_ui=False) skip_ui_creation = True logger.debug('Command SOFT_RESET executed.') break elif command == 'FULL_RESET': running = self._full_reset( core, logger, last_reset_time) last_reset_time = datetime.datetime.now() break elif command == 'HARD_RESET': logger.debug('Executing command HARD_RESET...') self._terminate(core, logger) exc = None try: # Note: this call doesn't return self._hard_reset(logger) except Exception as e: exc = e logger.critical('Error while hard resetting: %r' % exc) os._exit(1) else: logger.error( 'Application is unable to handle ' 'command %s. Forcing termination...' % command) raise UnknownCommandError(command) except KeyboardInterrupt: # Ctrl-C is equivalent to the TERMINATE command self._terminate(core, logger) running = False except LogOutRequiredException: logger.info(u"Logout is required to continue, shutting down..") self._terminate(core, logger) running = False except MandatoryUpdateDeniedException: logger.info(u"User denied a mandatory update, shutting down...") self._terminate(core, logger) running = False except UpdateRequestedException: # TODO: this will be replaced by an UPDATE command logger.info(u"Client is going to be updated, shutting down") self._terminate(core, logger) self._close_lockfile() logger.info(u"Starting update procedure...") try: updater = PlatformUpdater( cfg.get_config_dir(), cfg.get('Application Paths', 'webserver_ca_chain')) updater.execute_update() except UpdateProcedureException as e: logger.error(u"Update procedure error: %s" % e) except Exception: # The main thread shouldn't rely on automatic bug reporting, # she must handle her own exceptions or nobody will be there to # terminate the application at the end! bug_reporter.on_exception(*sys.exc_info()) running = self._full_reset(core, logger, last_reset_time) last_reset_time = datetime.datetime.now() if oldhook: sys.excepthook = oldhook logger.info(u"Shut down. Goodbye.")
def test_existing_directory_is_accepted(): test_cfg_dir = get_current_dir() test_cfg_file = os.path.join(test_cfg_dir, CONFIG_FILE_NAME) cfg = ConfigManager(test_cfg_dir) assert_equal(cfg.config_dir, test_cfg_dir) assert_equal(cfg.file_path, test_cfg_file)