def keep_running(self, buffer): try: buffer += self.irc.recv(2048).decode() lines = str.split(buffer, "\r\n") buffer = lines.pop() for line in lines: logger.log("Received IRC message: " + line) for line in lines: self.handle_line(line) except KeyboardInterrupt: st = "QUIT :I have to go for now!" self.irc.send(st) raise except: title = "A error occurred in IRCbot %s" % sys.exc_info()[0] body = traceback.format_exc() logger.error(title) logger.error(body) git_issuer.handle_error(title, body) self.send_msg(title) return buffer
def start(): """ Starts Tribler by using the twistd plugin. :return: boolean representing the success of starting Tribler """ env = os.environ.copy() env['PYTHONPATH'] = setup.tribler_home() command = [ 'twistd', '--pidfile=' + setup.tribler_pid(), 'plebnet', '-p', '8085' ] if setup.wallets_testnet(): command.append('--testnet') if setup.tribler_exitnode(): command.append('--exitnode') try: exitcode = subprocess.call(command, cwd=setup.tribler_home(), env=env) if exitcode != 0: logger.error('Failed to start Tribler', "tribler_controller") return False logger.success('Tribler is started', "tribler_controller") logger.log('testnet: ' + str(setup.wallets_testnet())) return True except subprocess.CalledProcessError as e: logger.error(e.output, "tribler_controller") return False
def start(): """ Start tribler :return: """ env = os.environ.copy() env['PYTHONPATH'] = setup.tribler_home() try: if setup.wallets_testnet(): success = subprocess.call([ 'twistd', '--pidfile=' + setup.tribler_pid(), 'plebnet', '-p', '8085' '--testnet' ], cwd=setup.tribler_home(), env=env) else: success = subprocess.call([ 'twistd', '--pidfile=' + setup.tribler_pid(), 'plebnet', '-p', '8085' ], cwd=setup.tribler_home(), env=env) if not success: logger.error('Failed to start Tribler', "tribler_controller") return False logger.success('Tribler is started', "tribler_controller") logger.log('market running: ' + str(market_controller.is_market_running())) return True except subprocess.CalledProcessError as e: logger.error(e.output, "Tribler starter", "tribler_controller") return False
def check_tunnel_helper(): """ Temporary function to track the data stream processed by Tribler :return: None :rtype: None """ # TEMP TO SEE EXITNODE PERFORMANCE, tunnel_helper should merge with market or other way around if not os.path.isfile( os.path.join(settings.tribler_home(), settings.tunnelhelper_pid())): logger.log("Starting tunnel_helper", log_name) env = os.environ.copy() env['PYTHONPATH'] = settings.tribler_home() try: subprocess.call( [ 'twistd', '--pidfile=' + settings.tunnelhelper_pid(), 'tunnel_helper', '-x', '-m' ], #, '-M'], cwd=settings.tribler_home(), env=env) return True except subprocess.CalledProcessError as e: logger.error(e.output, log_name) return False return True
def run(self): """ This method keeps listening to the server for incomming messages and processes them. :return: :rtype: """ buffer = "" try: self.irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.irc.connect((self.server, self.port)) # init the contact self.send("NICK %s" % self.nick) self.send("USER %s %s %s : %s" % (self.nick, self.nick, self.nick, self.gecos)) self.heartbeat() except: # git_issuer("A error occurred in IRCbot", sys.exc_info()[0], ['crash']) logger.error("An error occurred at server connectionthe IRC") logger.error(traceback.format_exc()) while 1: buffer = self.keep_running(buffer)
def execute(cmd=None): if not cmd: cmd = sys.argv[1:2] try: parser = ArgumentParser(description="Plebnet - a working-class bot") subparsers = parser.add_subparsers(dest="command") # create the setup subcommand parser_list = subparsers.add_parser("setup", help="Run the setup of PlebNet") parser_list.set_defaults(func=execute_setup) # create the check subcommand parser_list = subparsers.add_parser("check", help="Checks if the plebbot is able to clone") parser_list.set_defaults(func=execute_check) # create the conf subcommand parser_list = subparsers.add_parser("conf", help="Allows changing the configuration files") parser_list.set_defaults(func=execute_conf) # create the irc subcommand parser_list = subparsers.add_parser("irc", help="Provides access to the IRC client") parser_list.set_defaults(func=execute_irc) args = parser.parse_args(cmd) args.func() except: title = "An error occured!" body = traceback.format_exc() logger.error(title) logger.error(body) git_issuer.handle_error(title, body)
def create_gist(username, password): try: # the log files filename = plebnet_settings.get_instance().logger_file() content = open(filename, 'r').read() # Our url to create issues via POST url = 'https://api.github.com/gists' # Create an authenticated session to create the issue session = requests.Session() session.auth = (username, password) # Create our issue gist = { "description": "the description for this gist", "public": True, "files": { "logfile.txt": { "content": content } } } r = session.post(url, json.dumps(gist)) if r.status_code == 201: logger.success('Successfully created gist') else: logger.warning('Could not create gist') logger.log(r.content, 'Response:') return r.json()['url'], r.json()['html_url'] except: logger.error(sys.exc_info()[0], "git_issuer gist") logger.error(traceback.format_exc())
def check(): """ The method is the main function which should run periodically. It controls the behaviour of the agent, starting Tribler and buying servers. """ global config, dna logger.log("Checking PlebNet", log_name) # Read general configuration if settings.wallets_testnet_created(): os.environ['TESTNET'] = '1' config = PlebNetConfig() dna = DNA() dna.read_dictionary() # check if own vpn is installed before continuing if not check_vpn_install(): logger.error("!!! VPN is not installed, child may get banned !!!", "Plebnet Check") # Requires time to setup, continue in the next iteration. if not check_tribler(): return if not settings.wallets_initiate_once(): create_wallet() select_provider() # These need a matchmaker, otherwise agent will be stuck waiting. if market_controller.has_matchmakers(): update_offer() attempt_purchase() install_vps()
def purchase_choice_vpn(config): provider = plebnet_settings.get_instance().vpn_host() provider_instance = get_vpn_providers()[provider](child_account()) # no need to generate new child config wallet = TriblerWallet(plebnet_settings.get_instance().wallets_testnet_created()) c = cloudomate_providers['vpn'][provider] configurations = c.get_options() # option is assumbed to be the first vpn provider option option = configurations[0] try: transaction_hash = provider_instance.purchase(wallet, option) except: title = "Failed to purchase vpn: %s" % sys.exc_info()[0] body = traceback.format_exc() logger.error(title) logger.error(body) git_issuer.handle_error(title, body) git_issuer.handle_error("Failed to purchase server", sys.exc_info()[0], ['crash']) return plebnet_settings.FAILURE if not transaction_hash: logger.warning("VPN probably purchased, but transaction hash not returned") config.get('bought').append((provider, option, transaction_hash, config.get('child_index'))) config.get('transactions').append(transaction_hash) config.save() return plebnet_settings.SUCCESS
def init_irc(self): try: logger.log("start running an IRC connection on " + self.server + " " + self.channel) self.irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.irc.connect((self.server, self.port)) except: title = "A error occurred in IRCbot init_irc %s" % sys.exc_info()[0] body = traceback.format_exc() logger.error(title) logger.error(body) git_issuer.handle_error(title, body) git_issuer.handle_error("A error occurred in IRCbot", sys.exc_info()[0], ['crash'])
def create_gist(filename=None): """ This method can be used to send a file to github via gist. :param filename: the file to send, if left empty, the log file is send :type filename: String """ # Only execute if PlebNet is activated settings = plebnet_settings.get_instance() if not settings.github_active(): return if not filename: filename = settings.logger_file() try: # Collect variables username = settings.github_username() password = settings.github_password() bot_name = settings.irc_nick() # Get the log files content = open(filename, 'r').read() # Our url to create issues via POST url = 'https://api.github.com/gists' # Create an authenticated session to create the issue session = requests.Session() session.auth = (username, password) # Create our issue gist = { "description": "The logfile for %s" % bot_name, "public": True, "files": { "logfile.txt": { "content": content } } } r = session.post(url, json.dumps(gist)) # Inform about the results if r.status_code == 201: logger.success('Successfully created gist') else: logger.warning('Could not create gist') logger.log(r.content, 'Response:') return r.json()['url'], r.json()['html_url'] except: logger.error(sys.exc_info()[0], "git_issuer gist") logger.error(traceback.format_exc()) return None, None
def test_add_multiple_logs(self): logger.log(msg1) logger.warning(msg2) logger.success(msg3) logger.error(msg4) f = open(logfile) for line in f: if msg1 in line: self.assertTrue("INFO" in line) if msg2 in line: self.assertTrue("WARNING" in line) if msg3 in line: self.assertTrue("INFO" in line) if msg4 in line: self.assertTrue("ERROR" in line)
def start_irc_client(args=None): """ This method starts the IRC client daemon. :param args: The remaining commands from the commandline, can be neglected. :type args: String :return: the exitcode of the call :rtype: exitcode """ logger.log("the IRC client is starting", "start_irc_client") # run the init file success = subprocess.call('sudo %s start' % PATH_TO_DEAMON, shell=True) if success: logger.log("the IRC client is started", "start_irc_client") else: logger.error("the IRC client failed to start", "start_irc_client") return success
def stop_irc_client(args=None): """ This method stops the IRC client deamon :param args: The remaining commands from the commandline, can be neglected. :type args: String :return: None :rtype: None """ logger.log("the IRC client is stopping", "stop_irc_client") # run the init file success = subprocess.call('sudo %s stop' % PATH_TO_DEAMON, shell=True) if success: logger.log("the IRC client is stopped", "stop_irc_client") else: logger.error("the IRC client is not stopped", "stop_irc_client") return success
def save_info_vpn(child_index): """ Stores the child vpn information :param location: where to store the config :return: """ vpn = get_vpn_providers()[plebnet_settings.get_instance().vpn_host()]( child_account()) try: info = vpn.get_configuration() prefix = plebnet_settings.get_instance().vpn_child_prefix() dir = path.expanduser( plebnet_settings.get_instance().vpn_config_path()) credentials = prefix + str( child_index) + plebnet_settings.get_instance( ).vpn_credentials_name() ovpn = prefix + str( child_index) + plebnet_settings.get_instance().vpn_config_name() # the .ovpn file contains the line auth-user-pass so that it knows which credentials file to use # when the child config and credentials are passed to create-child, it is placed on the server as "own" # so the reference to "own" is put in the .ovpn file. own_credentials = plebnet_settings.get_instance().vpn_own_prefix() \ + plebnet_settings.get_instance().vpn_credentials_name() with io.open(path.join(dir, ovpn), 'w', encoding='utf-8') as ovpn_file: ovpn_file.write(info.ovpn + '\nauth-user-pass ' + own_credentials) # write the ovpn file to vpn dir with io.open(path.join(dir, credentials), 'w', encoding='utf-8') as credentials_file: credentials_file.writelines([info.username + '\n', info.password]) logger.log("Saved VPN configuration to " + dir, "cloudomate_controller") return True except: title = "Failed to save VPN info: %s" % sys.exc_info()[0] body = traceback.format_exc() logger.error(title) logger.error(body) return False
def attempt_purchase_vpn(): """ Attempts to purchase a VPN, checks first if balance is sufficient The success message is stored to prevent further unecessary purchases. """ provider = settings.vpn_host() if settings.wallets_testnet(): domain = 'TBTC' else: domain = 'BTC' if market_controller.get_balance( domain) >= cloudomate_controller.calculate_price_vpn(provider): logger.log("Try to buy a new VPN from %s" % provider, log_name) success = cloudomate_controller.purchase_choice_vpn(config) if success == plebnet_settings.SUCCESS: logger.success("Purchasing VPN succesful!", log_name) elif success == plebnet_settings.FAILURE: logger.error("Error purchasing vpn", log_name)
def create_issue(title, body, labels): """ This method creates a github issue when called. :param title: The title of the issue :type title: String :param body: The body text of the issue :type body: String :param labels: The labels which should be attached to the issue :type labels: String[] """ # Only execute if PlebNet is activated settings = plebnet_settings.get_instance() if not settings.github_active(): return try: # Collect variables username = settings.github_username() password = settings.github_password() repo_owner = settings.github_owner() repo_name = settings.github_repo() # Our url to create issues via POST url = 'https://api.github.com/repos/%s/%s/issues' % (repo_owner, repo_name) # Create an authenticated session to create the issue session = requests.Session() session.auth = (username, password) # Create our issue issue = {'title': title, 'body': body, 'labels': labels} # Add the issue to our repository r = session.post(url, json.dumps(issue)) # Inform about the results if r.status_code == 201: logger.success('Successfully created Issue "%s"' % title) else: logger.warning('Could not create Issue "%s"' % title) logger.log(r.content, 'Response:') except: logger.error(sys.exc_info()[0], "git_issuer send") logger.error(traceback.format_exc())
def create_issue(username, password, repo_owner, repo_name, title, body, labels): try: # Our url to create issues via POST url = 'https://api.github.com/repos/%s/%s/issues' % (repo_owner, repo_name) # Create an authenticated session to create the issue session = requests.Session() session.auth = (username, password) # Create our issue issue = {'title': title, 'body': body, 'labels': labels} # Add the issue to our repository r = session.post(url, json.dumps(issue)) if r.status_code == 201: logger.success('Successfully created Issue "%s"' % title) else: logger.warning('Could not create Issue "%s"' % title) logger.log(r.content, 'Response:') except: logger.error(sys.exc_info()[0], "git_issuer send") logger.error(traceback.format_exc())
def start(): """ Starts Tribler by using the twistd plugin. :return: boolean representing the success of starting Tribler """ env = os.environ.copy() # env['PYTHONPATH'] = os.path.join(setup.plebnet_home(), 'plebnet') + ":" # #env['PYTHONPATH'] += os.path.join(setup.plebnet_home(), 'plebnet/twisted/plugins') + ":" # env['PYTHONPATH'] += os.path.join(setup.plebnet_home(), 'tribler/src/pyipv8') + ":" # env['PYTHONPATH'] += os.path.join(setup.plebnet_home(), 'tribler/src/anydex') + ":" # env['PYTHONPATH'] += os.path.join(setup.plebnet_home(), 'tribler/src/tribler-common') + ":" # env['PYTHONPATH'] += os.path.join(setup.plebnet_home(), 'tribler/src/tribler-core') #print(env['PYTHONPATH']) command = ['systemctl', 'start', 'tribler.service'] # if setup.wallets_testnet(): # command.append('--testnet') # if setup.tribler_exitnode(): command.append('*****@*****.**') else: command.append('*****@*****.**') try: exitcode = subprocess.call(command, cwd=os.path.join(setup.plebnet_home(), 'plebnet'), env=env) print("Exitcode was: " + str(exitcode)) if exitcode != 0: logger.error('Failed to start Tribler', "tribler_controller") return False logger.success('Tribler is started', "tribler_controller") logger.log('testnet: ' + str(setup.wallets_testnet())) return True except subprocess.CalledProcessError as e: logger.error(e.output, "tribler_controller") return False
def purchase_choice(config): """ Purchase the cheapest provider in chosen_providers. If buying is successful this provider is moved to bought. In any case the provider is removed from choices. :param config: config :return: plebnet_settings errorcode """ (provider, option, _) = config.get('chosen_provider') provider_instance = cloudomate_providers['vps'][provider](child_account()) wallet = TriblerWallet( plebnet_settings.get_instance().wallets_testnet_created()) vps_option = get_vps_option(provider, option) try: transaction_hash = provider_instance.purchase(wallet, vps_option) except: title = "Failed to purchase server: %s" % sys.exc_info()[0] body = traceback.format_exc() logger.error(title) logger.error(body) git_issuer.handle_error(title, body) git_issuer.handle_error("Failed to purchase server", sys.exc_info()[0], ['crash']) return plebnet_settings.FAILURE # Cloudomate should throw an exception when purchase fails. The transaction hash is not in fact required, # and even when cloudomate fails to return it, the purchase itself could have been successful. if not transaction_hash: logger.warning( "Server probably purchased, but transaction hash not returned") config.get('bought').append( (provider, option, transaction_hash, config.get('child_index'))) config.get('transactions').append(transaction_hash) config.set('chosen_provider', None) config.save() return plebnet_settings.SUCCESS
def check(): """ The method is the main function which should run periodically. It controls the behaviour of the agent, starting Tribler and buying servers. """ global config, qtable global sold_mb_tokens, previous_mb_tokens logger.log("Checking PlebNet", log_name) # Read general configuration if settings.wallets_testnet_created(): os.environ['TESTNET'] = '1' config = PlebNetConfig() qtable = QTable() qtable.read_dictionary() # check if own vpn is installed before continuing if not check_vpn_install(): logger.error("!!! VPN is not installed, child may get banned !!!", "Plebnet Check") # Requires time to setup, continue in the next iteration. if not check_tribler(): return check_irc() if not settings.wallets_initiate_once(): create_wallet() select_provider() # if is going to die, move all currency to a wallet if config.time_to_expiration() < plebnet_settings.TIME_IN_HOUR: save_all_currency() # These need a matchmaker, otherwise agent will be stuck waiting. if market_controller.has_matchmakers(): strategies[plebnet_settings.get_instance().strategy_name()]().apply() install_vps()
def purchase_choice(config): """ Purchase the cheapest provider in chosen_providers. If buying is successful this provider is moved to bought. In any case the provider is removed from choices. :param config: config :return: plebnet_settings errorcode """ (provider, option, _) = config.get('chosen_provider') provider_instance = cloudomate_providers['vps'][provider](child_account()) wallet = TriblerWallet( plebnet_settings.get_instance().wallets_testnet_created()) c = cloudomate_providers['vps'][provider] configurations = c.get_options() option = configurations[option] try: transaction_hash = provider_instance.purchase(wallet, option) except: title = "Failed to purchase server: %s" % sys.exc_info()[0] body = traceback.format_exc() logger.error(title) logger.error(body) git_issuer.handle_error(title, body) git_issuer.handle_error("Failed to purchase server", sys.exc_info()[0], ['crash']) return plebnet_settings.FAILURE if not transaction_hash: return plebnet_settings.FAILURE config.get('bought').append( (provider, transaction_hash, config.get('child_index'))) config.get('transactions').append(transaction_hash) config.set('chosen_provider', None) config.save() return plebnet_settings.SUCCESS
def install_available_servers(config, qtable): """ This function checks if any of the bought servers are ready to be installed and installs PlebNet on them. :param config: The configuration of this Plebbot :type config: dict :param qtable: The qtable of this Plebbot :type qtable: QTable :return: None :rtype: None """ bought = config.get('bought') logger.log("install: %s" % bought, "install_available_servers") for bought_item in list(bought): [provider, option, transaction_hash, child_index] = bought_item # skip vpn providers as they show up as 'bought' as well if provider in cloudomate_controller.get_vpn_providers(): continue try: provider_class = cloudomate_controller.get_vps_providers()[provider] ip = cloudomate_controller.get_ip(provider_class, cloudomate_controller.child_account(child_index)) except Exception as e: logger.log(str(e) + "%s not ready yet" % str(provider), "install_available_servers") continue if is_valid_ip(ip): # VPN configuration, enable tun/tap settings if provider_class.TUN_TAP_SETTINGS: tun_success = provider_class(cloudomate_controller.child_account(child_index)).enable_tun_tap() logger.log("Enabling %s tun/tap: %s"%(provider, tun_success)) if not cloudomate_controller.save_info_vpn(child_index): logger.log("VPN not ready yet, can't save ovpn config") # continue logger.log("Installing child #%s on %s with ip %s" % (child_index, provider, str(ip))) account_settings = cloudomate_controller.child_account(child_index) rootpw = account_settings.get('server', 'root_password') try: provider_class(cloudomate_controller.child_account(child_index)).change_root_password(rootpw) except Exception as e: logger.error("Cannot change root password: %s" % str(e), "install_available_servers") continue time.sleep(5) qtable.create_child_qtable(provider, option, transaction_hash, child_index) # Save config before entering possibly long lasting process config.get('bought').remove(bought_item) config.get('installing').append(bought_item) config.save() success = _install_server(ip, rootpw, child_index, setup.get_instance().wallets_testnet()) # Reload config in case install takes a long time config.load() config.get('installing').remove(bought_item) if success: config.get('installed').append(bought_item) else: # Try again next time config.get('bought').append(bought_item) config.save() # Only install one server at a time return else: logger.log("Server not ready")