예제 #1
0
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
예제 #2
0
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
예제 #3
0
# 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,
예제 #4
0
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
예제 #5
0
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