def update_poolrate(pool_list, run_time, db, retry): pool_queue = queue.Queue() hashrate_queue = queue.Queue() for p in pool_list: if p['name'] in ['ghash', 'ozcoin', 'btcchina', 'kano', 'cksolo']: pool_queue.put(p) for i in range(len(pool_list)): pool_thread = PoolThread(pool_queue, hashrate_queue, retry) pool_thread.daemon = True pool_thread.start() pool_queue.join() column = ['time'] value = [run_time] while not hashrate_queue.empty(): h = hashrate_queue.get(False) column.append(h['name']) value.append(h['hashrate']) database = DataBase(db) database.connect() if not database.run('insert', 'hashrate', column, value): for i in range(len(column) - 1): database.run( 'raw', 'ALTER TABLE hashrate ADD `{}` DOUBLE'.format(column[i + 1]) ) database.commit() database.run('insert', 'hashrate', column, value) database.commit() database.disconnect()
def luciThread(node_queue, result_queue, commands, db, log, lock): database = DataBase(db) database.connect() while True: try: node = node_queue.get(False) except: break database.start_transaction() result = database.run('select', 'controller_security', ['password'], "`ip` = %s FOR UPDATE", [node['ip']]) if not result or not result[0]: password = '' else: password = result[0][0] if result[0][0] is not None else '' error = False auth = True for i in range(3): j = 0 try: luci = ams.luci.LuCI(node['ip'], 80, password) if not luci.auth(): luci = ams.luci.LuCI(node['ip'], 80, '') if not luci.auth(): auth = False error = True break auth = True database.commit() result = [] for c in commands[j:]: if c['params'] is not None: for i, param in enumerate(c['params']): c['params'][i] = param.replace( '`ip4`', node['ip'].split('.')[3]) if c['method'] == 'user.setpasswd': new_password = base64.b64encode(os.urandom(9)).decode() c['params'] = ['root', new_password] database.start_transaction() result = database.run('select', 'controller_security', ['password'], "`ip` = %s FOR UPDATE", [node['ip']]) r = luci.put(c['lib'], c['method'], c['params'], i + 10) if c['method'] == 'user.setpasswd': if r['error'] is None: database.run( 'raw', '''\ INSERT INTO controller_security (ip, password) VALUES (%s, %s) ON DUPLICATE KEY UPDATE password = %s''', [node['ip'], new_password, new_password]) database.commit() with lock: log.debug('[{}][{}][{}][{}][{}]'.format( node['ip'], c['method'], '|'.join(c['params']), r['result'], r['error'], )) result.append(r) j += 1 error = False break except Exception as e: with lock: log.error('[{}]'.format(e)) error = True continue if not auth: result.append({'result': 'Authentication Failed'}) elif error: result.append({'result': 'Connection Failed'}) result_queue.put({ 'node': node, 'result': result, 'error': error, }) node_queue.task_done() database.disconnect()
cfgfile = os.path.join(os.environ.get('VIRTUAL_ENV') or '/', 'etc/ams.conf') def readCfg(filename): import configparser config = configparser.ConfigParser(interpolation=None) config.read(filename, encoding="utf8") return config if __name__ == '__main__': cfg = readCfg(cfgfile) db = cfg['DataBase'] database = DataBase(db) database.connect() database.run( command='create', name='blocks', column_def=[ {'name': 'time', 'type': 'TIMESTAMP DEFAULT "0000-00-00 00:00:00"'}, {'name': 'ip', 'type': 'VARCHAR(40)'}, {'name': 'port', 'type': 'SMALLINT UNSIGNED'}, {'name': 'blocks', 'type': 'INT UNSIGNED'} ], additional='PRIMARY KEY (`time`, `ip`, `port`)', ) minerList = database.run('select', 'controller_config', ['ip', 'port'])
cfgfile = os.path.join(os.environ.get('VIRTUAL_ENV') or '/', 'etc/ams.conf') def readCfg(filename): import configparser config = configparser.ConfigParser(interpolation=None) config.read(filename, encoding="utf8") return config if __name__ == '__main__': cfg = readCfg(cfgfile) db = cfg['DataBase'] database = DataBase(db) database.connect() columns = [] for i in range(4): for j in range(18, 22): columns.append({ 'name': 'mw{}_{}'.format(i, j), 'type': 'INT', }) for name in ['ghsmm0', 'eratio']: columns.append({ 'name': '{}{}_{}'.format(name, i, j), 'type': 'DOUBLE', })
def update_poolrate(pool_list, run_time, db, retry): pool_queue = queue.Queue() hashrate_queue = queue.Queue() for p in pool_list: if p['name'] in ['ghash', 'ozcoin', 'btcchina', 'kano', 'cksolo']: pool_queue.put(p) for i in range(len(pool_list)): pool_thread = PoolThread(pool_queue, hashrate_queue, retry) pool_thread.daemon = True pool_thread.start() pool_queue.join() column = ['time'] value = [run_time] while not hashrate_queue.empty(): h = hashrate_queue.get(False) column.append(h['name']) value.append(h['hashrate']) database = DataBase(db) database.connect() if not database.run('insert', 'hashrate', column, value): for i in range(len(column) - 1): database.run( 'raw', 'ALTER TABLE hashrate ADD `{}` DOUBLE'.format(column[i + 1])) database.commit() database.run('insert', 'hashrate', column, value) database.commit() database.disconnect()
def update(argv): import datetime from multiprocessing import Process from ams.farm import Farm from ams.pool import update_poolrate from ams.sql import sql_handler, DataBase, SQLQueue cfg = readCfg(cfgfile) db = cfg['DataBase'] farm_type = cfg['Farm']['type'] database = DataBase(db) database.connect() controllerList = database.run( 'select', 'controller_config', ['ip', 'port', 'mods']) if not controllerList: print("No miner found.\n Run subcommand 'controller' to add.") exit() miners = [ { 'ip': m[0], 'port': m[1], # 'mods': [int(mod) for mod in m[2].split(',')] 'mods': m[2], } for m in controllerList ] myFarm = Farm(miners, farm_type) poolList = database.run( 'select', 'pool_config', ['name', 'user', 'worker', 'key', 'seckey'] ) # TODO: should automatically get worker name from cgminer api if not poolList: pools = [] else: pools = [ { 'name': p[0], 'user': p[1], 'worker': p[2], 'key': p[3], 'seckey': p[4] } for p in poolList ] database.disconnect() now = '{:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now()) sql_queue = SQLQueue() farm_process = Process( target=myFarm.run, args=(now, sql_queue, 5, 100) ) pool_process = Process( target=update_poolrate, args=(pools, now, db, 3) ) db_process = Process( target=sql_handler, args=(sql_queue, db, int(db['thread_num'])) ) db_process.start() pool_process.start() farm_process.start() pool_process.join() farm_process.join() db_process.join()
def luciThread(node_queue, result_queue, commands, db, log, lock): database = DataBase(db) database.connect() while True: try: node = node_queue.get(False) except: break database.start_transaction() result = database.run( 'select', 'controller_security', ['password'], "`ip` = %s FOR UPDATE", [node['ip']] ) if not result or not result[0]: password = '' else: password = result[0][0] if result[0][0] is not None else '' error = False auth = True for i in range(3): j = 0 try: luci = ams.luci.LuCI(node['ip'], 80, password) if not luci.auth(): luci = ams.luci.LuCI(node['ip'], 80, '') if not luci.auth(): auth = False error = True break auth = True database.commit() result = [] for c in commands[j:]: if c['params'] is not None: for i, param in enumerate(c['params']): c['params'][i] = param.replace( '`ip4`', node['ip'].split('.')[3] ) if c['method'] == 'user.setpasswd': new_password = base64.b64encode(os.urandom(9)).decode() c['params'] = ['root', new_password] database.start_transaction() result = database.run( 'select', 'controller_security', ['password'], "`ip` = %s FOR UPDATE", [node['ip']] ) r = luci.put(c['lib'], c['method'], c['params'], i + 10) if c['method'] == 'user.setpasswd': if r['error'] is None: database.run( 'raw', '''\ INSERT INTO controller_security (ip, password) VALUES (%s, %s) ON DUPLICATE KEY UPDATE password = %s''', [node['ip'], new_password, new_password]) database.commit() with lock: log.debug('[{}][{}][{}][{}][{}]'.format( node['ip'], c['method'], '|'.join(c['params']), r['result'], r['error'], )) result.append(r) j += 1 error = False break except Exception as e: with lock: log.error('[{}]'.format(e)) error = True continue if not auth: result.append({'result': 'Authentication Failed'}) elif error: result.append({'result': 'Connection Failed'}) result_queue.put({ 'node': node, 'result': result, 'error': error, }) node_queue.task_done() database.disconnect()
def pool(argv): import tempfile import subprocess import re from ams.sql import DataBase db = readCfg(cfgfile)['DataBase'] database = DataBase(db) database.connect() poolList = database.run( 'select', 'pool_config', ['name', 'address', 'user', 'worker', 'key', 'seckey'] ) with tempfile.NamedTemporaryFile(mode='w+', suffix='.ams') as temp: temp.write('#name\taddress\tuser\tworker\tkey\tseckey') if poolList: temp.write('\n') temp.write( '\n'.join('\t'.join(i for i in m if i is not None) for m in poolList) ) temp.write('\n') temp.flush() subprocess.call(['vim', temp.name]) temp.seek(0) cfg = temp.readlines() pattern = re.compile( r'\s*(?P<name>btcchina|kano|ghash|cksolo)\s+' '(?P<address>[^\s]+)\s+' '(?P<user>[^\s]+)\s+' '(?P<worker>[^\s]+)\s+' '(?P<key>[^\s]+)' '(\s+(?P<seckey>[^\s]+))?\s*', re.X ) result = [] for c in cfg: if len(c.lstrip()) == 0 or c.lstrip()[0] == '#': continue match = re.match(pattern, c) if match is None: result = None break name = match.group('name') address = match.group('address') user = match.group('user') worker = match.group('worker') key = match.group('key') seckey = match.group('seckey') result.append({ "name": name, "address": address, "user": user, "worker": worker, "key": key, "seckey": seckey }) if result is None: print('Invalid configuration.') database.disconnect() exit() database.run('raw', 'DROP TABLES pool_config') database.run('create', 'pool_config', [ {"name": "name", "type": "VARCHAR(16)"}, {"name": "address", "type": "VARCHAR(64)"}, {"name": "user", "type": "VARCHAR(64)"}, {"name": "worker", "type": "VARCHAR(64)"}, {"name": "key", "type": "VARCHAR(64)"}, {"name": "seckey", "type": "VARCHAR(64)"} ]) for r in result: database.run('insert', 'pool_config', list(r.keys()), list(r.values())) database.commit() database.disconnect()
def controller(argv): import tempfile import subprocess import re from ams.sql import DataBase db = readCfg(cfgfile)['DataBase'] database = DataBase(db) database.connect() minerList = database.run( 'select', 'controller_config', ['ip', 'port', 'mods', 'password'] ) with tempfile.NamedTemporaryFile(mode='w+', suffix='.ams') as temp: temp.write('#ip\tport\tmods\tpassword') if minerList: temp.write('\n') temp.write( '\n'.join('\t'.join(str(i) for i in m if i is not None) for m in minerList) ) temp.write('\n') temp.flush() subprocess.call(['vim', temp.name]) temp.seek(0) cfg = temp.readlines() pattern = re.compile( r'\s*(?P<ip>[0-9a-fA-F.:\[\]]+)\s+' '(?P<port>[0-9]+)\s+' '(?P<mods>[0-9]+)\s+' '(?P<password>[^\s]+)?\s*', re.X ) result = [] for c in cfg: if len(c.lstrip()) == 0 or c.lstrip()[0] == '#': continue match = re.match(pattern, c) if match is None: result = None break ip = match.group('ip') port = int(match.group('port')) if not validIP(ip) or port > 65535: result = None break result.append({ "ip": ip, "port": port, "mods": match.group('mods'), "password": match.group('password') }) if result is None: print('Invalid configuration.') database.disconnect() exit() database.run('raw', 'DROP TABLES IF EXISTS controller_config') database.run('create', 'controller_config', [ {"name": "ip", "type": "VARCHAR(40)"}, {"name": "port", "type": "SMALLINT UNSIGNED"}, {"name": "mods", "type": "SMALLINT UNSIGNED"}, {"name": "password", "type": "VARCHAR(32)"} ]) for r in result: database.run( 'insert', 'controller_config', list(r.keys()), list(r.values())) database.commit() database.disconnect()
def config(argv): from ams.sql import DataBase from ams.luci import LuCI data = [] if argv[1] == '-f': with open(argv[2], 'r') as f: for d in f.readlines(): data.append({ 'lib': d.split(' ')[0], 'method': d.split(' ')[1], 'param': [' '.join(d.split(' ')[2:])] }) else: data.append({ 'lib': argv[1], 'method': argv[2], 'param': [argv[3]], }) if argv[0] != "all": result = ipDecode(argv[0]) if not result: exit() ip, port = result clause = "`ip` = '{}'".format(ip) db = readCfg(cfgfile)['DataBase'] database = DataBase(db) database.connect() minerList = database.run( 'select', 'controller_config', ['password'], clause) database.disconnect() if not minerList: exit() password = minerList[0][0] luci = LuCI(ip, port, password) luci.auth() for d in data: print(json.dumps(luci.put(d['lib'], d['method'], d['param']))) else: db = readCfg(cfgfile)['DataBase'] database = DataBase(db) database.connect() minerList = database.run( 'select', 'controller_config', ['ip', 'password'] ) database.disconnect() if not minerList: exit()
def before_request(): g.database = DataBase(db) g.database.connect()
from ams.sql import DataBase cfgfile = os.path.join(os.environ.get('VIRTUAL_ENV') or '/', 'etc/ams.conf') def readCfg(filename): import configparser config = configparser.ConfigParser(interpolation=None) config.read(filename, encoding="utf8") return config if __name__ == '__main__': cfg = readCfg(cfgfile) db = cfg['DataBase'] database = DataBase(db) database.connect() columns = [] for i in range(4): for j in range(18, 22): columns.append({ 'name': 'mw{}_{}'.format(i, j), 'type': 'INT', }) for name in ['ghsmm0', 'eratio']: columns.append({ 'name': '{}{}_{}'.format(name, i, j), 'type': 'DOUBLE', })