def doprovisiondispatch(miner_type=None): '''put all miners in provision worker queue''' entries = QueueEntries() miners = PROVISION_DISPATCH.app.miners() print("{0} miners configured".format(len(miners))) for miner in miners: if miner.is_disabled(): continue try: minerinfo = antminerhelper.getminerinfo(miner) if miner_type is not None and miner_type != '' and minerinfo.miner_type != miner_type: continue mineraccess = PROVISION_DISPATCH.app.antminer.getaccesslevel(miner) if mineraccess == MinerAccessLevel.Restricted: print( Fore.RED + " Log: setting {0} to privileged...".format(miner.name)) PROVISION_DISPATCH.app.antminer.set_privileged(miner) PROVISION_DISPATCH.app.antminer.waitforonline(miner) mineraccess = PROVISION_DISPATCH.app.antminer.getaccesslevel( miner) print(Fore.GREEN + "{0} {1} {2}".format( miner.name, minerinfo.miner_type, mineraccess)) if mineraccess == MinerAccessLevel.Restricted: print(" skipping restricted access") else: entries.add(QueueName.Q_PROVISION, PROVISION_DISPATCH.app.messageencode(miner)) except BaseException as ex: print(PROVISION_DISPATCH.app.exceptionmessage(ex)) return entries
def doprovision(miner): '''provision/configure a miner''' entries = QueueEntries() poollist = PROVISION.app.pools() print("{0} pools configured".format(len(poollist))) print('{0} {1}'.format(miner.name, miner.ipaddress)) mineraccess = '' addpools = None minerinfo = None minerpool = None try: minerinfo = antminerhelper.getminerinfo(miner) miner.minerinfo = minerinfo minerpool = antminerhelper.pools(miner) #find the current pool in known pools knownpool = PROVISION.app.findpool(minerpool) if knownpool is not None: minerpool.poolname = knownpool.name miner.minerpool = minerpool PROVISION.app.updateknownminer(miner) #find pools that need to be added and add them addpools = services.poolstoadd(miner, minerpool, poollist) mineraccess = PROVISION.app.antminer.getaccesslevel(miner) except antminerhelper.MinerMonitorException as ex: if ex.istimedout(): mineraccess = MinerAccessLevel.Waiting if mineraccess == MinerAccessLevel.Restricted or mineraccess == MinerAccessLevel.Waiting: if mineraccess == MinerAccessLevel.Restricted: PROVISION.app.antminer.set_privileged(miner) PROVISION.app.antminer.waitforonline(miner) mineraccess = PROVISION.app.antminer.getaccesslevel(miner) if mineraccess == MinerAccessLevel.Restricted: entries.addalert('could not set {0} to privileged access'.format( miner.name)) #try a few more times then give up else: for pool in addpools or []: print( Fore.YELLOW + " Add", pool.name, "(addpool|{0},{1},{2})".format(pool.url, pool.user + miner.name, "x")) #this command adds the pool to miner and prints the result result = antminerhelper.addpool(miner, pool) if result.startswith("Access denied"): print(Fore.RED + result) else: print(result) namedpools = PROVISION.app.pools() #process the pools found on the miner. This will pick up any pools added manually for pool in miner.pools_available: #check if pools is a named pool... foundnamed = None for namedpool in namedpools: if namedpool.is_same_as(pool): foundnamed = namedpool break if foundnamed: #pool should take on the cononical attributes of the named pool pool.named_pool = foundnamed pool.user = foundnamed.user PROVISION.app.add_pool(MinerPool(miner, pool.priority, pool)) #enforce default pool if miner has one set up if miner.defaultpool: founddefault = next( (p for p in poollist if p.name == miner.defaultpool), None) if founddefault is not None: switchtopool(miner, founddefault) #enforce default pool if it doesnt have one. find highest priority pool if not miner.defaultpool: def sort_by_priority(j): return j.priority filtered = [ x for x in poollist if miner.miner_type.startswith(x.pool_type) ] filtered.sort(key=sort_by_priority) #foundpriority = next((p for p in poollist if p.priority == 0), None) if filtered: switchtopool(miner, filtered[0]) entries.add(QueueName.Q_MONITORMINER, PROVISION.app.messageencode(miner)) return entries
# call all the api command of miner APP = ApplicationService(component='fullcycle') MINERS = APP.knownminers() print("{0} miners configured".format(len(MINERS))) POOLS = APP.pools() for miner in MINERS: try: savedminer = APP.getminer(miner) if not miner.is_manually_disabled(): minerpool = None start = time.perf_counter() minerinfo = antminerhelper.getminerinfo(miner) minerstats = antminerhelper.stats(miner) #minerlcd = antminerhelper.getminerlcd(miner) if minerstats is None: APP.logerror('{0} Offline? {1}'.format(miner.name, miner.ipaddress)) else: minerpool = antminerhelper.pools(miner) end = time.perf_counter() monitorperf = end - start poolname = '{0} {1}'.format(minerpool.currentpool, minerpool.currentworker) foundpool = APP.findpool(minerpool) if foundpool is not None: minerpool.poolname = foundpool.name savedminer.monitored(minerstats, minerpool, minerinfo,
def findminers(hosts_list, knownminers): '''find miners on network''' entries = QueueEntries() minerstotal = 0 minersnew = 0 shownonminers = True hostsup = 0 print('Querying {0} hosts...'.format(len(hosts_list))) for host, status, macaddress in hosts_list: try: if status != 'down': hostsup += 1 if shownonminers: print("{0} {1} {2}".format(host, status, macaddress)) miner = mining.Miner(name=host, ipaddress=host, port=MINERPORT, ftpport='', networkid=macaddress) try: minerinfo = antminerhelper.getminerinfo(miner) miner.setminerinfo(minerinfo) if minerinfo.miner_type: minerstotal += 1 if not shownonminers: print("{0} {1} {2}".format(host, status, macaddress)) print(Fore.GREEN + ' found {0} with id {1}'.format( minerinfo.miner_type, minerinfo.minerid)) #find by mac address or miner_id, not name found = None for known in knownminers: if known.networkid == miner.networkid or known.minerid == miner.minerid: found = known if found is not None: print( Fore.YELLOW + ' already know about {0}'.format(found.name)) else: minersnew += 1 entries.add(QueueName.Q_DISCOVERED, DISCOVER.app.messageencode(miner)) print(Fore.GREEN + ' discovered {0}'.format(miner.name)) except antminerhelper.MinerMonitorException as monitorex: try: if monitorex.istimedout: if shownonminers: print(Fore.RED + ' Not a miner') except Exception: DISCOVER.app.logexception(monitorex) except BaseException as baseex: print(Fore.RED + DISCOVER.app.exceptionmessage(baseex)) except KeyboardInterrupt: break print('nmap queried {0} hosts on network'.format(len(hosts_list))) print('{0} hosts are up'.format(hostsup)) print('FCM knows about {0} miners configured'.format(len(knownminers))) print('FCM determined {0} miners this attempt'.format(minerstotal)) print( 'FCM determined there are {0} new miners on network'.format(minersnew)) return entries
def domonitorminer(miner): '''get statistics from miner''' entries = QueueEntries() savedminer = APPMONITOR.app.getminer(miner) if savedminer is None: savedminer = miner try: #individual miner can be monitored even if manually disabled if not savedminer.should_monitor(): print('skipped monitoring {0}'.format(miner.name)) return entries mineroriginalstatus = savedminer.status start = time.perf_counter() minerinfo = getminerinfo(savedminer) minerstats = stats(savedminer) #minerlcd = antminerhelper.getminerlcd(miner) if minerstats is None: print('could not monitor {0}'.format(savedminer.name)) else: minerpool = pools(savedminer) end = time.perf_counter() monitorperf = end - start #what to do if monitored miner type conflicts with saved miner type??? #should probably provision? foundpool = APPMONITOR.app.findpool(minerpool) if foundpool is not None: minerpool.poolname = foundpool.name savedminer.monitored(minerstats, minerpool, minerinfo, monitorperf) if mineroriginalstatus == '': #first time monitoring since bootup print(Fore.GREEN + APPMONITOR.app.now(), savedminer.name, 'first time monitoring') elif savedminer.status == mining.MinerStatus.Online and (mineroriginalstatus == mining.MinerStatus.Disabled or mineroriginalstatus == mining.MinerStatus.Offline): #changing status from offline to online so raise event entries.add(QueueName.Q_ONLINE, APPMONITOR.app.messageencode(savedminer)) print(Fore.GREEN + APPMONITOR.app.now(), savedminer.name, 'back online!') #TODO: if stats.elapsed < previous.elapsed then raise provision or online events APPMONITOR.app.putminerandstats(savedminer, minerstats, minerpool) #TODO:show name of current pool instead of worker poolname = '{0} {1}'.format(minerpool.currentpool, minerpool.currentworker) foundpool = APPMONITOR.app.findpool(minerpool) if foundpool is not None: poolname = foundpool.name print('{0} mining at {1}'.format(savedminer.name, poolname)) #most users won't want to mine solo, so provision the miner if not APPMONITOR.app.configuration('mining.allowsolomining'): if minerpool.currentpool.startswith(APPMONITOR.app.configuration('mining.solopool')): entries.add(QueueName.Q_PROVISION, APPMONITOR.app.messageencode(savedminer)) print(Fore.CYAN+str(APPMONITOR.app.now()), savedminer.name, savedminer.status, 'h='+str(minerstats.currenthash), str(minerstats.minercount), '{0}/{1}/{2}'.format(str(minerstats.tempboard1), str(minerstats.tempboard2), str(minerstats.tempboard3)), savedminer.uptime(minerstats.elapsed), '{0:0f}ms'.format(savedminer.monitorresponsetime() * 1000)) msg = APPMONITOR.app.createmessagestats(savedminer, minerstats, minerpool) entries.addbroadcast(QueueName.Q_STATISTICSUPDATED, msg) except pika.exceptions.ConnectionClosed as qex: #could not enqueue a message print(Fore.RED + '{0} Queue Error: {1}'.format(savedminer.name, APPMONITOR.app.exceptionmessage(qex))) APPMONITOR.app.logexception(qex) except MinerMonitorException as monitorex: print(Fore.RED + '{0} Miner Error: {1}'.format(savedminer.name, APPMONITOR.app.exceptionmessage(monitorex))) savedminer.lastmonitor = datetime.datetime.utcnow() #TODO: this should be a rule. publish miner offline event #and let event handler decide how to handle it savedminer.offline_now() print(Fore.RED + APPMONITOR.app.now(), savedminer.name, savedminer.status) entries.add(QueueName.Q_OFFLINE, APPMONITOR.app.messageencode(savedminer)) except BaseException as ex: print(Fore.RED+'{0} Unexpected Error in monitorminer: {1}'.format(savedminer.name, APPMONITOR.app.exceptionmessage(ex))) # we have to consider any exception to be a miner error. sets status to offline #if str(e) == "timed out": #(timeout('timed out',),) APPMONITOR.app.logexception(ex) APPMONITOR.app.putminer(savedminer) APPMONITOR.app.updateknownminer(savedminer) return entries