fixed many remaining bugs in testbench webserver, should be ready for use.
This commit is contained in:
committed by
UpstreamData
parent
93f2990399
commit
a6df7a83d6
@@ -54,8 +54,8 @@ class BaseMiner:
|
|||||||
raise e
|
raise e
|
||||||
|
|
||||||
async def send_file(self, src, dest):
|
async def send_file(self, src, dest):
|
||||||
conn = self._get_ssh_connection()
|
async with (await self._get_ssh_connection()) as conn:
|
||||||
await asyncssh.scp((conn, src), dest)
|
await asyncssh.scp(src, (conn, dest))
|
||||||
|
|
||||||
async def check_light(self):
|
async def check_light(self):
|
||||||
return self.light
|
return self.light
|
||||||
|
|||||||
@@ -19,8 +19,12 @@ class MinerNetworkRange:
|
|||||||
end_ip = ipaddress.ip_address(end)
|
end_ip = ipaddress.ip_address(end)
|
||||||
networks = ipaddress.summarize_address_range(start_ip, end_ip)
|
networks = ipaddress.summarize_address_range(start_ip, end_ip)
|
||||||
for network in networks:
|
for network in networks:
|
||||||
|
self.host_ips.append(network.network_address)
|
||||||
for host in network.hosts():
|
for host in network.hosts():
|
||||||
|
if host not in self.host_ips:
|
||||||
self.host_ips.append(host)
|
self.host_ips.append(host)
|
||||||
|
if network.broadcast_address not in self.host_ips:
|
||||||
|
self.host_ips.append(network.broadcast_address)
|
||||||
|
|
||||||
def hosts(self):
|
def hosts(self):
|
||||||
for x in self.host_ips:
|
for x in self.host_ips:
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
from ipaddress import ip_address
|
from ipaddress import ip_address
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
import datetime
|
|
||||||
|
|
||||||
from network import ping_miner
|
from network import ping_miner
|
||||||
from miners.miner_factory import MinerFactory
|
from miners.miner_factory import MinerFactory
|
||||||
from miners.antminer.S9.bosminer import BOSMinerS9
|
from miners.antminer.S9.bosminer import BOSMinerS9
|
||||||
from tools.web_testbench.connections import ConnectionManager
|
from tools.web_testbench.connections import ConnectionManager
|
||||||
|
from tools.web_testbench.feeds import get_local_versions
|
||||||
|
|
||||||
REFERRAL_FILE_S9 = os.path.join(os.path.dirname(__file__), "files", "referral.ipk")
|
REFERRAL_FILE_S9 = os.path.join(os.path.dirname(__file__), "files", "referral.ipk")
|
||||||
UPDATE_FILE_S9 = os.path.join(os.path.dirname(__file__), "files", "update.tar")
|
UPDATE_FILE_S9 = os.path.join(os.path.dirname(__file__), "files", "update.tar")
|
||||||
CONFIG_FILE = os.path.join(os.path.dirname(__file__), "files", "config.toml")
|
CONFIG_FILE = os.path.join(os.path.dirname(__file__), "files", "config.toml")
|
||||||
|
|
||||||
|
|
||||||
# static states
|
# static states
|
||||||
(START, UNLOCK, INSTALL, UPDATE, REFERRAL, DONE) = range(6)
|
(START, UNLOCK, INSTALL, UPDATE, REFERRAL, DONE) = range(6)
|
||||||
|
|
||||||
@@ -21,11 +20,20 @@ class TestbenchMiner:
|
|||||||
def __init__(self, host: ip_address):
|
def __init__(self, host: ip_address):
|
||||||
self.host = host
|
self.host = host
|
||||||
self.state = START
|
self.state = START
|
||||||
|
self.latest_version = None
|
||||||
|
|
||||||
|
async def get_bos_version(self):
|
||||||
|
miner = await MinerFactory().get_miner(self.host)
|
||||||
|
result = await miner.send_ssh_command("cat /etc/bos_version")
|
||||||
|
version_base = result.stdout
|
||||||
|
version_base = version_base.strip()
|
||||||
|
version_base = version_base.split("-")
|
||||||
|
version = version_base[-2]
|
||||||
|
return version
|
||||||
|
|
||||||
async def add_to_output(self, message):
|
async def add_to_output(self, message):
|
||||||
print(datetime.datetime.now())
|
|
||||||
await ConnectionManager().broadcast_json(
|
await ConnectionManager().broadcast_json(
|
||||||
{"IP": str(self.host), "text": str(message) + "\n"}
|
{"IP": str(self.host), "text": str(message).replace("\r", "") + "\n"}
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -39,13 +47,17 @@ class TestbenchMiner:
|
|||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
async def install_start(self):
|
async def install_start(self):
|
||||||
if not await ping_miner(self.host):
|
if not await ping_miner(self.host, 80):
|
||||||
await self.add_to_output("Waiting for miner connection...")
|
await self.add_to_output("Waiting for miner connection...")
|
||||||
return
|
return
|
||||||
await self.remove_from_cache()
|
await self.remove_from_cache()
|
||||||
miner = await MinerFactory().get_miner(self.host)
|
miner = await MinerFactory().get_miner(self.host)
|
||||||
await self.add_to_output("Found miner: " + miner)
|
await self.add_to_output("Found miner: " + str(miner))
|
||||||
if isinstance(miner, BOSMinerS9):
|
if isinstance(miner, BOSMinerS9):
|
||||||
|
if await self.get_bos_version() == self.latest_version:
|
||||||
|
await self.add_to_output("Already running the latest version of BraiinsOS, configuring.")
|
||||||
|
self.state = REFERRAL
|
||||||
|
return
|
||||||
await self.add_to_output("Already running BraiinsOS, updating.")
|
await self.add_to_output("Already running BraiinsOS, updating.")
|
||||||
self.state = UPDATE
|
self.state = UPDATE
|
||||||
return
|
return
|
||||||
@@ -84,8 +96,11 @@ class TestbenchMiner:
|
|||||||
)
|
)
|
||||||
# get stdout of the install
|
# get stdout of the install
|
||||||
while True:
|
while True:
|
||||||
|
try:
|
||||||
stdout = await proc.stderr.readuntil(b"\r")
|
stdout = await proc.stderr.readuntil(b"\r")
|
||||||
await self.add_to_output(stdout)
|
except asyncio.exceptions.IncompleteReadError:
|
||||||
|
break
|
||||||
|
await self.add_to_output(stdout.decode("utf-8").strip())
|
||||||
if stdout == b"":
|
if stdout == b"":
|
||||||
break
|
break
|
||||||
await proc.wait()
|
await proc.wait()
|
||||||
@@ -96,40 +111,38 @@ class TestbenchMiner:
|
|||||||
self.state = REFERRAL
|
self.state = REFERRAL
|
||||||
|
|
||||||
async def install_update(self):
|
async def install_update(self):
|
||||||
|
await self.add_to_output("Updating miner...")
|
||||||
await self.remove_from_cache()
|
await self.remove_from_cache()
|
||||||
miner = await MinerFactory().get_miner(self.host)
|
miner = await MinerFactory().get_miner(self.host)
|
||||||
try:
|
try:
|
||||||
await miner.send_file(UPDATE_FILE_S9, "/tmp/firmware.tar")
|
await miner.send_file(UPDATE_FILE_S9, "/tmp/firmware.tar")
|
||||||
await miner.send_ssh_command("sysupgrade /tmp/firmware.tar")
|
await miner.send_ssh_command("sysupgrade /tmp/firmware.tar")
|
||||||
except:
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
await self.add_to_output("Failed to update, restarting.")
|
await self.add_to_output("Failed to update, restarting.")
|
||||||
self.state = START
|
self.state = START
|
||||||
return
|
return
|
||||||
|
await asyncio.sleep(10)
|
||||||
await self.add_to_output("Update complete, configuring.")
|
await self.add_to_output("Update complete, configuring.")
|
||||||
self.state = REFERRAL
|
self.state = REFERRAL
|
||||||
|
|
||||||
async def install_referral(self):
|
async def install_referral(self):
|
||||||
|
while not await ping_miner(self.host):
|
||||||
|
await asyncio.sleep(1)
|
||||||
miner = await MinerFactory().get_miner(self.host)
|
miner = await MinerFactory().get_miner(self.host)
|
||||||
if os.path.exists(REFERRAL_FILE_S9):
|
|
||||||
try:
|
try:
|
||||||
await miner.send_file(REFERRAL_FILE_S9, "/tmp/referral.ipk")
|
await miner.send_file(REFERRAL_FILE_S9, "/tmp/referral.ipk")
|
||||||
await miner.send_file(CONFIG_FILE, "/etc/bosminer.toml")
|
await miner.send_file(CONFIG_FILE, "/etc/bosminer.toml")
|
||||||
|
|
||||||
await miner.send_ssh_command(
|
await miner.send_ssh_command(
|
||||||
"opkg install /tmp/referral.ipk && /etc/init.d/bosminer restart"
|
"opkg install /tmp/referral.ipk && /etc/init.d/bosminer restart"
|
||||||
)
|
)
|
||||||
except:
|
except Exception as e:
|
||||||
await self.add_to_output(
|
|
||||||
"Failed to add referral and configure, restarting."
|
|
||||||
)
|
|
||||||
self.state = START
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
await self.add_to_output(
|
await self.add_to_output(
|
||||||
"Failed to add referral and configure, restarting."
|
"Failed to add referral and configure, restarting."
|
||||||
)
|
)
|
||||||
self.state = START
|
self.state = START
|
||||||
return
|
return
|
||||||
|
await asyncio.sleep(5)
|
||||||
await self.add_to_output("Configuration complete.")
|
await self.add_to_output("Configuration complete.")
|
||||||
self.state = DONE
|
self.state = DONE
|
||||||
|
|
||||||
@@ -183,7 +196,7 @@ class TestbenchMiner:
|
|||||||
|
|
||||||
# set the miner data
|
# set the miner data
|
||||||
miner_data = {
|
miner_data = {
|
||||||
"IP": self.host,
|
"IP": str(self.host),
|
||||||
"Light": "show",
|
"Light": "show",
|
||||||
"Fans": fans_data,
|
"Fans": fans_data,
|
||||||
"HR": hr_data,
|
"HR": hr_data,
|
||||||
@@ -198,11 +211,13 @@ class TestbenchMiner:
|
|||||||
async def install_done(self):
|
async def install_done(self):
|
||||||
await self.add_to_output("Waiting for disconnect...")
|
await self.add_to_output("Waiting for disconnect...")
|
||||||
while await ping_miner(self.host) and self.state == DONE:
|
while await ping_miner(self.host) and self.state == DONE:
|
||||||
await ConnectionManager().broadcast_json(await self.get_web_data())
|
data = await self.get_web_data()
|
||||||
|
await ConnectionManager().broadcast_json(data)
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
self.state = START
|
self.state = START
|
||||||
|
|
||||||
async def install_loop(self):
|
async def install_loop(self):
|
||||||
|
self.latest_version = sorted(await get_local_versions(), reverse=True)[0]
|
||||||
while True:
|
while True:
|
||||||
if self.state == START:
|
if self.state == START:
|
||||||
await self.install_start()
|
await self.install_start()
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
from network import MinerNetwork
|
from network import MinerNetwork
|
||||||
|
|
||||||
miner_network = MinerNetwork("192.168.1.10-192.168.1.33").get_network()
|
miner_network = MinerNetwork("192.168.1.11-192.168.1.34").get_network()
|
||||||
|
|||||||
@@ -35,9 +35,13 @@ async def ws(websocket: WebSocket):
|
|||||||
if "IP" in data.keys():
|
if "IP" in data.keys():
|
||||||
miner = await MinerFactory().get_miner(data["IP"])
|
miner = await MinerFactory().get_miner(data["IP"])
|
||||||
if data["Data"] == "unlight":
|
if data["Data"] == "unlight":
|
||||||
miner.fault_light_off()
|
if data["IP"] in ConnectionManager.lit_miners:
|
||||||
|
ConnectionManager.lit_miners.remove(data["IP"])
|
||||||
|
await miner.fault_light_off()
|
||||||
if data["Data"] == "light":
|
if data["Data"] == "light":
|
||||||
miner.fault_light_on()
|
if data["IP"] not in ConnectionManager().lit_miners:
|
||||||
|
ConnectionManager.lit_miners.append(data["IP"])
|
||||||
|
await miner.fault_light_on()
|
||||||
except WebSocketDisconnect:
|
except WebSocketDisconnect:
|
||||||
ConnectionManager().disconnect(websocket)
|
ConnectionManager().disconnect(websocket)
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ from tools.web_testbench._network import miner_network
|
|||||||
class ConnectionManager:
|
class ConnectionManager:
|
||||||
_instance = None
|
_instance = None
|
||||||
_connections = []
|
_connections = []
|
||||||
|
lit_miners = []
|
||||||
|
|
||||||
def __new__(cls):
|
def __new__(cls):
|
||||||
if not cls._instance:
|
if not cls._instance:
|
||||||
@@ -16,16 +17,17 @@ class ConnectionManager:
|
|||||||
async def connect(self, websocket: WebSocket):
|
async def connect(self, websocket: WebSocket):
|
||||||
await websocket.accept()
|
await websocket.accept()
|
||||||
miners = []
|
miners = []
|
||||||
|
print(ConnectionManager.lit_miners)
|
||||||
for host in miner_network.hosts():
|
for host in miner_network.hosts():
|
||||||
if host in MinerFactory().miners.keys():
|
if str(host) in ConnectionManager.lit_miners:
|
||||||
miners.append(
|
miners.append(
|
||||||
{
|
{
|
||||||
"IP": str(host),
|
"IP": str(host),
|
||||||
"Light_On": await MinerFactory().miners[host].get_light(),
|
"Light_On": True,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
miners.append({"IP": str(host), "Light_On": None})
|
miners.append({"IP": str(host), "Light_On": False})
|
||||||
await websocket.send_json({"miners": miners})
|
await websocket.send_json({"miners": miners})
|
||||||
ConnectionManager._connections.append(websocket)
|
ConnectionManager._connections.append(websocket)
|
||||||
|
|
||||||
|
|||||||
@@ -109,6 +109,23 @@ async def get_latest_install_file(session, version, feeds_path, install_file):
|
|||||||
|
|
||||||
|
|
||||||
async def update_installer_files():
|
async def update_installer_files():
|
||||||
|
feeds_path = os.path.join(
|
||||||
|
os.path.dirname(__file__), "files", "bos-toolbox", "feeds"
|
||||||
|
)
|
||||||
|
feeds_versions = await get_local_versions()
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
version = await get_latest_version(session)
|
||||||
|
|
||||||
|
if version not in feeds_versions:
|
||||||
|
update_file = await get_update_file(session, version)
|
||||||
|
install_file = await get_feeds_file(session, version)
|
||||||
|
await get_latest_update_file(session, update_file)
|
||||||
|
await get_latest_install_file(session, version, feeds_path, install_file)
|
||||||
|
else:
|
||||||
|
logging.info("Feeds are up to date.")
|
||||||
|
|
||||||
|
|
||||||
|
async def get_local_versions():
|
||||||
feeds_versions = []
|
feeds_versions = []
|
||||||
feeds_path = os.path.join(
|
feeds_path = os.path.join(
|
||||||
os.path.dirname(__file__), "files", "bos-toolbox", "feeds"
|
os.path.dirname(__file__), "files", "bos-toolbox", "feeds"
|
||||||
@@ -127,16 +144,8 @@ async def update_installer_files():
|
|||||||
ver = line.strip().split("\t")[0]
|
ver = line.strip().split("\t")[0]
|
||||||
feeds_versions.append(ver)
|
feeds_versions.append(ver)
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
return feeds_versions
|
||||||
version = await get_latest_version(session)
|
|
||||||
|
|
||||||
if version not in feeds_versions:
|
|
||||||
update_file = await get_update_file(session, version)
|
|
||||||
install_file = await get_feeds_file(session, version)
|
|
||||||
await get_latest_update_file(session, update_file)
|
|
||||||
await get_latest_install_file(session, version, feeds_path, install_file)
|
|
||||||
else:
|
|
||||||
logging.info("Feeds are up to date.")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ ws.onmessage = function(event) {
|
|||||||
}
|
}
|
||||||
light_switch.id = miner["IP"] + "-light"
|
light_switch.id = miner["IP"] + "-light"
|
||||||
light_switch.className = "form-check-input"
|
light_switch.className = "form-check-input"
|
||||||
light_switch.addEventListener("click", function(){lightMiner(miner, light_switch);}, false);
|
light_switch.addEventListener("click", function(){lightMiner(miner["IP"], light_switch);}, false);
|
||||||
|
|
||||||
|
|
||||||
// add a light label to the button
|
// add a light label to the button
|
||||||
|
|||||||
Reference in New Issue
Block a user