async def test_config_error_notification(tmpdir): """ Test if config error is notified on session startup. """ # 1. Setup corrupted config shutil.copy2(CONFIG_PATH / 'corrupt-triblerd.conf', tmpdir / 'triblerd.conf') tribler_config = TriblerConfig(tmpdir, config_file=tmpdir / 'triblerd.conf', reset_config_on_error=True) # 2. Initialize session with corrupted config, disable upgrader for simplicity. # By mocking the notifier, we can check if the notify was called with correct parameters session = Session(tribler_config) session.upgrader_enabled = False session.notifier = Mock() # 3. Start the session which should internally call the notifier. await session.start() # Notifier uses asyncio loop internally, so we must wait at least a single loop cycle await asyncio.sleep(0) # 4. There could be multiple notify calls but we are only interested in the config error # so using 'assert_any_call' here to check if the notify was called. session.notifier.notify.assert_any_call(NTFY.REPORT_CONFIG_ERROR, tribler_config.config_error) # 5. Always shutdown the session at the end. await session.shutdown()
async def hidden_seeder_session(seed_config, video_tdef): seed_config.set_libtorrent_enabled(False) seeder_session = Session(seed_config) seeder_session.upgrader_enabled = False await seeder_session.start() # Also load the tunnel community in the seeder session await load_tunnel_community_in_session(seeder_session, start_lt=True) seeder_session.tunnel_community.build_tunnels(1) dscfg_seed = DownloadConfig() dscfg_seed.set_dest_dir(TESTS_DATA_DIR) dscfg_seed.set_hops(1) upload = seeder_session.dlmgr.start_download(tdef=video_tdef, config=dscfg_seed) def seeder_state_callback(ds): """ The callback of the seeder download. For now, this only logs the state of the download that's seeder and is useful for debugging purposes. """ seeder_session.tunnel_community.monitor_downloads([ds]) d = ds.get_download() print( f"seeder: {repr(d.get_def().get_name())} {dlstatus_strings[ds.get_status()]} {ds.get_progress()}" ) return 2 upload.set_state_callback(seeder_state_callback) await upload.wait_for_status(DLSTATUS_SEEDING) yield seeder_session await seeder_session.shutdown()
async def _start_session(self): self.logger.info(f"Starting Tribler session with config: {self.config}") self.session = Session(self.config) await self.session.start() self.logger.info("Tribler session started")
async def start_crawler(tribler_config): session = Session(tribler_config) # We use our own community loader loader = IPv8CommunityLoader() session.ipv8_community_loader = loader loader.set_launcher(BandwidthCommunityCrawlerLauncher()) await session.start()
async def start(self, options): # Determine ipv8 port ipv8_port = options.ipv8_port if ipv8_port == -1 and "HELPER_INDEX" in os.environ and "HELPER_BASE" in os.environ: base_port = int(os.environ["HELPER_BASE"]) ipv8_port = base_port + int(os.environ["HELPER_INDEX"]) * 5 statedir = Path( os.path.join(get_root_state_directory(), "tunnel-%d") % ipv8_port) config = TriblerConfig(statedir, config_file=statedir / 'triblerd.conf') config.set_tunnel_community_socks5_listen_ports([]) config.set_tunnel_community_random_slots(options.random_slots) config.set_tunnel_community_competing_slots(options.competing_slots) config.set_torrent_checking_enabled(False) config.set_ipv8_enabled(True) config.set_libtorrent_enabled(False) config.set_ipv8_port(ipv8_port) config.set_ipv8_address(options.ipv8_address) config.set_trustchain_enabled(True) config.set_market_community_enabled(False) config.set_dht_enabled(True) config.set_tunnel_community_exitnode_enabled(bool(options.exit)) config.set_popularity_community_enabled(False) config.set_testnet(bool(options.testnet)) config.set_chant_enabled(False) config.set_bootstrap_enabled(False) if not options.no_rest_api: config.set_http_api_enabled(True) api_port = options.restapi if "HELPER_INDEX" in os.environ and "HELPER_BASE" in os.environ: api_port = int(os.environ["HELPER_BASE"]) + 10000 + int( os.environ["HELPER_INDEX"]) config.set_http_api_port(api_port) if options.ipv8_bootstrap_override is not None: config.set_ipv8_bootstrap_override(options.ipv8_bootstrap_override) self.session = Session(config) self.log_circuits = options.log_circuits self.session.notifier.add_observer(NTFY.TUNNEL_REMOVE, self.circuit_removed) await self.session.start() if options.log_rejects: # We set this after Tribler has started since the tunnel_community won't be available otherwise self.session.tunnel_community.reject_callback = self.on_circuit_reject # Tunnel helpers store more TrustChain blocks self.session.trustchain_community.settings.max_db_blocks = 5000000 self.tribler_started()
async def channel_seeder_session(seed_config, channel_tdef): seeder_session = Session(seed_config) seeder_session.upgrader_enabled = False await seeder_session.start() dscfg_seed = DownloadConfig() dscfg_seed.set_dest_dir(TESTS_DATA_DIR / 'sample_channel') upload = seeder_session.dlmgr.start_download(tdef=channel_tdef, config=dscfg_seed) await upload.wait_for_status(DLSTATUS_SEEDING) yield seeder_session await seeder_session.shutdown()
async def get(self, exitnode=False): config = self.base_tribler_config.copy() config.set_libtorrent_enabled(False) config.set_tunnel_community_socks5_listen_ports( self.free_ports_factory(5)) config.set_state_dir(Path(self.tmpdir_factory.mktemp("session"))) session = Session(config) session.upgrader_enabled = False await session.start() self.sessions.append(session) await load_tunnel_community_in_session(session, exitnode=exitnode) return session
async def setup_tunnel_seeder(self, hops): """ Setup the seeder. """ from tribler_core.session import Session self.seed_config = self.config.copy() self.seed_config._state_dir = self.getRootStateDir(2) self.seed_config.set_libtorrent_enabled(hops == 0) self.seed_config.set_tunnel_community_socks5_listen_ports( self.get_ports(5)) if self.session2 is None: self.session2 = Session(self.seed_config) self.session2.upgrader_enabled = False await self.session2.start() tdef = TorrentDef() tdef.add_content(TESTS_DATA_DIR / "video.avi") tdef.set_tracker("http://localhost/announce") torrentfn = self.session2.config.get_state_dir() / "gen.torrent" tdef.save(torrent_filepath=torrentfn) self.seed_tdef = tdef if hops > 0: # Safe seeding enabled self.tunnel_community_seeder = await self.load_tunnel_community_in_session( self.session2, start_lt=True) self.tunnel_community_seeder.build_tunnels(hops) else: await self.sanitize_network(self.session2) dscfg = DownloadConfig() dscfg.set_dest_dir( TESTS_DATA_DIR) # basedir of the file we are seeding dscfg.set_hops(hops) d = self.session2.dlmgr.start_download(tdef=tdef, config=dscfg) d.set_state_callback(self.seeder_state_callback)
async def create_proxy(self, index, exitnode=False): """ Create a single proxy and load the tunnel community in the session of that proxy. """ from tribler_core.session import Session self.setUpPreSession() config = self.config.copy() config.set_libtorrent_enabled(False) config.set_tunnel_community_socks5_listen_ports(self.get_ports(5)) session = Session(config) session.upgrader_enabled = False await session.start() self.sessions.append(session) return await self.load_tunnel_community_in_session(session, exitnode=exitnode)
async def start_tribler(self, options): """ Main method to startup Tribler. """ async def signal_handler(sig): print("Received shut down signal %s" % sig) if not self._stopping: self._stopping = True await self.session.shutdown() print("Tribler shut down") get_event_loop().stop() self.process_checker.remove_lock_file() signal.signal(signal.SIGINT, lambda sig, _: ensure_future(signal_handler(sig))) signal.signal(signal.SIGTERM, lambda sig, _: ensure_future(signal_handler(sig))) statedir = Path(options.statedir or Path(get_appstate_dir(), '.Tribler')) config = TriblerConfig(statedir, config_file=statedir / 'triblerd.conf') # Check if we are already running a Tribler instance self.process_checker = ProcessChecker() if self.process_checker.already_running: print("Another Tribler instance is already using statedir %s" % config.get_state_dir()) get_event_loop().stop() return print("Starting Tribler") if options.restapi > 0: config.set_http_api_enabled(True) config.set_http_api_port(options.restapi) if options.ipv8 > 0: config.set_ipv8_port(options.ipv8) elif options.ipv8 == 0: config.set_ipv8_enabled(False) if options.libtorrent != -1 and options.libtorrent > 0: config.set_libtorrent_port(options.libtorrent) if options.ipv8_bootstrap_override is not None: config.set_ipv8_bootstrap_override(options.ipv8_bootstrap_override) if options.testnet: config.set_testnet(True) self.session = Session(config) try: await self.session.start() except Exception as e: print(str(e)) get_event_loop().stop() else: print("Tribler started")
async def setUp(self): await super(TestDHTSession, self).setUp() self.session = Session(TriblerConfig(self.root_state_dir)) self.session.dlmgr = MockObject() self.session.dlmgr.dht_health_manager = MockObject() dht_health_dict = { "infohash": hexlify(b'a' * 20), "seeders": 1, "leechers": 2 } self.session.dlmgr.dht_health_manager.get_health = lambda *_, **__: succeed( {"DHT": [dht_health_dict]}) self.dht_session = FakeDHTSession(self.session, b'a' * 20, 10) self.bep33_dht_session = FakeBep33DHTSession(self.session, b'a' * 20, 10)
async def start_tribler(): # Check if we are already running a Tribler instance process_checker = ProcessChecker(root_state_dir) if process_checker.already_running: return process_checker.create_lock_file() # Before any upgrade, prepare a separate state directory for the update version so it does not # affect the older version state directory. This allows for safe rollback. version_history = VersionHistory(root_state_dir) version_history.fork_state_directory_if_necessary() version_history.save_if_necessary() state_dir = version_history.code_version.directory config = TriblerConfig(state_dir, config_file=state_dir / CONFIG_FILENAME, reset_config_on_error=True) if not config.get_core_error_reporting_requires_user_consent(): SentryReporter.global_strategy = SentryStrategy.SEND_ALLOWED config.set_api_http_port(int(api_port)) # If the API key is set to an empty string, it will remain disabled if config.get_api_key() not in ('', api_key): config.set_api_key(api_key) config.write( ) # Immediately write the API key so other applications can use it config.set_api_http_enabled(True) priority_order = config.get_cpu_priority_order() set_process_priority(pid=os.getpid(), priority_order=priority_order) global trace_logger # Enable tracer if --trace-debug or --trace-exceptions flag is present in sys.argv trace_logger = check_and_enable_code_tracing('core', config.get_log_dir()) session = Session(config, core_test_mode=core_test_mode) signal.signal(signal.SIGTERM, lambda signum, stack: shutdown(session, signum, stack)) await session.start()
class TinyTriblerService: """Lightweight tribler service, that used for experiments. All overlays are disabled by default. """ def __init__(self, config, timeout_in_sec=None, working_dir=Path('/tmp/tribler'), config_path=Path('tribler.conf')): self.logger = logging.getLogger(self.__class__.__name__) self.session = None self.process_checker = None self.working_dir = working_dir self.config_path = config_path self.config = config self.timeout_in_sec = timeout_in_sec async def on_tribler_started(self): """Function will calls after the Tribler session is started It is good place to add a custom code. """ async def start_tribler(self): self.logger.info(f'Starting tribler instance in directory: {self.working_dir}') self._check_already_running() await self._start_session() if self.timeout_in_sec: asyncio.create_task(self._terminate_by_timeout()) self._enable_graceful_shutdown() await self.on_tribler_started() @staticmethod def create_default_config(working_dir, config_path): config = TriblerConfig(working_dir, config_path) config.set_tunnel_community_enabled(False) config.set_popularity_community_enabled(False) config.set_bootstrap_enabled(False) config.set_torrent_checking_enabled(True) config.set_ipv8_enabled(False) config.set_libtorrent_enabled(False) config.set_dht_enabled(False) config.set_chant_enabled(False) return config async def _start_session(self): self.logger.info(f"Starting Tribler session with config: {self.config}") self.session = Session(self.config) await self.session.start() self.logger.info("Tribler session started") def _check_already_running(self): self.logger.info(f'Check if we are already running a Tribler instance in: {self.working_dir}') self.process_checker = ProcessChecker() if self.process_checker.already_running: self.logger.error(f"Another Tribler instance is already using directory: {self.working_dir}") asyncio.get_running_loop().stop() def _enable_graceful_shutdown(self): self.logger.info("Enabling graceful shutdown") def signal_handler(signum, frame): self.logger.info(f"Received shut down signal {signum} in frame {frame}") self._graceful_shutdown() signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) def _graceful_shutdown(self): self.logger.info("Shutdown gracefully") if not self.session.shutdownstarttime: task = asyncio.create_task(self.session.shutdown()) task.add_done_callback(lambda result: asyncio.get_running_loop().stop()) async def _terminate_by_timeout(self): self.logger.info(f"Scheduling terminating by timeout {self.timeout_in_sec}s from now") await asyncio.sleep(self.timeout_in_sec) self.logger.info("Terminating by timeout") self._graceful_shutdown()
async def _session(tribler_config): session = Session(tribler_config) session.upgrader_enabled = False await session.start() yield session await session.shutdown()
class TunnelHelperService(TaskManager): def __init__(self): super(TunnelHelperService, self).__init__() self._stopping = False self.log_circuits = False self.session = None self.community = None def on_circuit_reject(self, reject_time, balance): with open( os.path.join(self.session.config.get_state_dir(), "circuit_rejects.log"), 'a') as out_file: time_millis = int(round(reject_time * 1000)) out_file.write("%d,%d\n" % (time_millis, balance)) def tribler_started(self): async def signal_handler(sig): print("Received shut down signal %s" % sig) if not self._stopping: self._stopping = True await self.session.shutdown() get_event_loop().stop() signal.signal(signal.SIGINT, lambda sig, _: ensure_future(signal_handler(sig))) signal.signal(signal.SIGTERM, lambda sig, _: ensure_future(signal_handler(sig))) self.register_task("bootstrap", self.session.tunnel_community.bootstrap, interval=30) # Remove all logging handlers root_logger = logging.getLogger() handlers = root_logger.handlers for handler in handlers: root_logger.removeHandler(handler) logging.getLogger().setLevel(logging.ERROR) new_strategies = [] with self.session.ipv8.overlay_lock: for strategy, target_peers in self.session.ipv8.strategies: if strategy.overlay == self.session.tunnel_community: new_strategies.append((strategy, -1)) else: new_strategies.append((strategy, target_peers)) self.session.ipv8.strategies = new_strategies def circuit_removed(self, circuit, additional_info): self.session.ipv8.network.remove_by_address(circuit.peer.address) if self.log_circuits: with open( os.path.join(self.session.config.get_state_dir(), "circuits.log"), 'a') as out_file: duration = time.time() - circuit.creation_time out_file.write("%d,%f,%d,%d,%s\n" % (circuit.circuit_id, duration, circuit.bytes_up, circuit.bytes_down, additional_info)) async def start(self, options): # Determine ipv8 port ipv8_port = options.ipv8_port if ipv8_port == -1 and "HELPER_INDEX" in os.environ and "HELPER_BASE" in os.environ: base_port = int(os.environ["HELPER_BASE"]) ipv8_port = base_port + int(os.environ["HELPER_INDEX"]) * 5 statedir = Path( os.path.join(get_root_state_directory(), "tunnel-%d") % ipv8_port) config = TriblerConfig(statedir, config_file=statedir / 'triblerd.conf') config.set_tunnel_community_socks5_listen_ports([]) config.set_tunnel_community_random_slots(options.random_slots) config.set_tunnel_community_competing_slots(options.competing_slots) config.set_torrent_checking_enabled(False) config.set_ipv8_enabled(True) config.set_libtorrent_enabled(False) config.set_ipv8_port(ipv8_port) config.set_ipv8_address(options.ipv8_address) config.set_trustchain_enabled(True) config.set_market_community_enabled(False) config.set_dht_enabled(True) config.set_tunnel_community_exitnode_enabled(bool(options.exit)) config.set_popularity_community_enabled(False) config.set_testnet(bool(options.testnet)) config.set_chant_enabled(False) config.set_bootstrap_enabled(False) if not options.no_rest_api: config.set_http_api_enabled(True) api_port = options.restapi if "HELPER_INDEX" in os.environ and "HELPER_BASE" in os.environ: api_port = int(os.environ["HELPER_BASE"]) + 10000 + int( os.environ["HELPER_INDEX"]) config.set_http_api_port(api_port) if options.ipv8_bootstrap_override is not None: config.set_ipv8_bootstrap_override(options.ipv8_bootstrap_override) self.session = Session(config) self.log_circuits = options.log_circuits self.session.notifier.add_observer(NTFY.TUNNEL_REMOVE, self.circuit_removed) await self.session.start() if options.log_rejects: # We set this after Tribler has started since the tunnel_community won't be available otherwise self.session.tunnel_community.reject_callback = self.on_circuit_reject # Tunnel helpers store more TrustChain blocks self.session.trustchain_community.settings.max_db_blocks = 5000000 self.tribler_started() async def stop(self): await self.shutdown_task_manager() if self.session: return self.session.shutdown()
def start_tribler(self, options): """ Main method to startup Tribler. """ def on_tribler_shutdown(_): msg("Tribler shut down") reactor.stop() self.process_checker.remove_lock_file() def signal_handler(sig, _): msg("Received shut down signal %s" % sig) if not self._stopping: self._stopping = True self.session.shutdown().addCallback(on_tribler_shutdown) signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) config = TriblerConfig() self.process_checker = ProcessChecker() if self.process_checker.already_running: self.shutdown_process( "Another Tribler instance is already using statedir %s" % config.get_state_dir()) return # Enable exitnode if set in options if "exitnode" in options and options["exitnode"]: msg("Enabling exitnode") config.set_tunnel_community_enabled(True) config.set_tunnel_community_exitnode_enabled(True) else: config.set_tunnel_community_exitnode_enabled(False) # Enable bitcoin testnet if "testnet" in options and options["testnet"]: msg("Enabling bitcoin testnet") config.set_testnet(True) # Enable dummy wallets if "dummy" in options and options["dummy"]: msg("Enabling dummy wallets") config.set_dummy_wallets_enabled(True) # Enable record transactions msg("Enabling record transactions") config.set_record_transactions(True) # Minimize functionality enabled for plebnet # For now, config taken from market_plugin in devos tribler repo config.set_http_api_enabled(True) config.set_video_server_enabled(False) config.set_torrent_search_enabled(False) config.set_channel_search_enabled(False) config.set_mainline_dht_enabled(True) config.set_dht_enabled(True) config.set_chant_enabled(False) config.set_bitcoinlib_enabled(True) msg("Starting Tribler") if options["statedir"]: config.set_state_dir(options["statedir"]) if options["restapi"] > 0: config.set_http_api_enabled(True) config.set_http_api_port(options["restapi"]) if options["dispersy"] != -1 and options["dispersy"] > 0: config.set_dispersy_port(options["dispersy"]) if options["libtorrent"] != -1 and options["libtorrent"] > 0: config.set_libtorrent_port(options["libtorrent"]) self.session = Session(config) self.session.start().addErrback( lambda failure: self.shutdown_process(failure.getErrorMessage())) msg("Tribler started")
class MarketServiceMaker(object): # implementer(IServiceMaker, IPlugin) tapname = "plebnet" description = "headless tribler for plebnet agent" options = Options def __init__(self): self.session = None self._stopping = False self.process_checker = None self.market_community = None self.plebmail_community = None def shutdown_process(self, shutdown_message, code=1): msg(shutdown_message) reactor.addSystemEventTrigger('after', 'shutdown', os._exit, code) reactor.stop() def load_communities(self, _): self.load_market_community(_) self.load_plebmail_community(_) def load_market_community(self, _): """ Load the Market community """ msg("Loading market community...") self.market_community = self.session.get_dispersy_instance( ).define_auto_load(MarketCommunity, self.session.dispersy_member, load=True, kargs={'tribler_session': self.session}) def start_tribler(self, options): """ Main method to startup Tribler. """ def on_tribler_shutdown(_): msg("Tribler shut down") reactor.stop() self.process_checker.remove_lock_file() def signal_handler(sig, _): msg("Received shut down signal %s" % sig) if not self._stopping: self._stopping = True self.session.shutdown().addCallback(on_tribler_shutdown) signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) config = TriblerConfig() self.process_checker = ProcessChecker() if self.process_checker.already_running: self.shutdown_process( "Another Tribler instance is already using statedir %s" % config.get_state_dir()) return # Enable exitnode if set in options if "exitnode" in options and options["exitnode"]: msg("Enabling exitnode") config.set_tunnel_community_enabled(True) config.set_tunnel_community_exitnode_enabled(True) else: config.set_tunnel_community_exitnode_enabled(False) # Enable bitcoin testnet if "testnet" in options and options["testnet"]: msg("Enabling bitcoin testnet") config.set_testnet(True) # Enable dummy wallets if "dummy" in options and options["dummy"]: msg("Enabling dummy wallets") config.set_dummy_wallets_enabled(True) # Enable record transactions msg("Enabling record transactions") config.set_record_transactions(True) # Minimize functionality enabled for plebnet # For now, config taken from market_plugin in devos tribler repo config.set_http_api_enabled(True) config.set_video_server_enabled(False) config.set_torrent_search_enabled(False) config.set_channel_search_enabled(False) config.set_mainline_dht_enabled(True) config.set_dht_enabled(True) config.set_chant_enabled(False) config.set_bitcoinlib_enabled(True) msg("Starting Tribler") if options["statedir"]: config.set_state_dir(options["statedir"]) if options["restapi"] > 0: config.set_http_api_enabled(True) config.set_http_api_port(options["restapi"]) if options["dispersy"] != -1 and options["dispersy"] > 0: config.set_dispersy_port(options["dispersy"]) if options["libtorrent"] != -1 and options["libtorrent"] > 0: config.set_libtorrent_port(options["libtorrent"]) self.session = Session(config) self.session.start().addErrback( lambda failure: self.shutdown_process(failure.getErrorMessage())) msg("Tribler started") def makeService(self, options): """ Construct a Tribler service. """ tribler_service = MultiService() tribler_service.setName("Market") reactor.callWhenRunning(self.start_tribler, options) return tribler_service