Added checksum validation and command handling
This commit is contained in:
@@ -14,10 +14,6 @@
|
|||||||
# limitations under the License. -
|
# limitations under the License. -
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
import logging
|
|
||||||
import aiofiles
|
|
||||||
import hashlib
|
|
||||||
import aiohttp
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
@@ -455,69 +451,17 @@ class ePIC(ePICFirmware):
|
|||||||
return pool_data
|
return pool_data
|
||||||
except LookupError:
|
except LookupError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def upgrade_firmware(self, file: Path, keepsettings: bool, password: str):
|
async def upgrade_firmware(self, file: Path | str, keep_settings: bool = True) -> bool:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Upgrade the firmware of the ePIC miner device.
|
Upgrade the firmware of the ePIC miner device.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
file (Path): The local file path of the firmware to be uploaded.
|
file (Path | str): The local file path of the firmware to be uploaded.
|
||||||
keepsettings (bool): Whether to keep the current settings after the update.
|
keep_settings (bool): Whether to keep the current settings after the update.
|
||||||
password (str): The password for authentication.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: Confirmation message after upgrading the firmware.
|
bool: Whether the firmware update succeeded.
|
||||||
"""
|
"""
|
||||||
try:
|
return await self.web.system_update(file=file, keep_settings=keep_settings)
|
||||||
logging.info("Starting firmware upgrade process for ePIC miner.")
|
|
||||||
|
|
||||||
if not file:
|
|
||||||
raise ValueError("File location must be provided for firmware upgrade.")
|
|
||||||
|
|
||||||
# calculate the SHA256 checksum of the firmware file
|
|
||||||
sha256_hash = hashlib.sha256()
|
|
||||||
async with aiofiles.open(file, "rb") as f:
|
|
||||||
while chunk := await f.read(8192):
|
|
||||||
sha256_hash.update(chunk)
|
|
||||||
checksum = sha256_hash.hexdigest()
|
|
||||||
|
|
||||||
# prepare the multipart/form-data request
|
|
||||||
form_data = aiohttp.FormData()
|
|
||||||
form_data.add_field('checksum', checksum)
|
|
||||||
form_data.add_field('keepsettings', str(keepsettings).lower())
|
|
||||||
form_data.add_field('password', password)
|
|
||||||
form_data.add_field('update.zip', open(file, 'rb'), filename='update.zip')
|
|
||||||
|
|
||||||
# Send the POST request to the ePIC miner device
|
|
||||||
async with self.web.post(f"http://{self.ip}:{self.port}/systemupdate", data=form_data) as response:
|
|
||||||
if response.status == 200:
|
|
||||||
result = await response.json()
|
|
||||||
if result.get("result"):
|
|
||||||
logging.info("Firmware upgrade process completed successfully for ePIC miner.")
|
|
||||||
return "Firmware upgrade completed successfully."
|
|
||||||
else:
|
|
||||||
error = result.get("error", "Unknown error")
|
|
||||||
logging.error(f"Firmware upgrade failed: {error}")
|
|
||||||
raise Exception(f"Firmware upgrade failed: {error}")
|
|
||||||
else:
|
|
||||||
logging.error(f"Firmware upgrade failed with status code: {response.status}")
|
|
||||||
raise Exception(f"Firmware upgrade failed with status code: {response.status}")
|
|
||||||
|
|
||||||
except FileNotFoundError as e:
|
|
||||||
logging.error(f"File not found during the firmware upgrade process: {e}")
|
|
||||||
raise
|
|
||||||
except ValueError as e:
|
|
||||||
logging.error(
|
|
||||||
f"Validation error occurred during the firmware upgrade process: {e}"
|
|
||||||
)
|
|
||||||
raise
|
|
||||||
except OSError as e:
|
|
||||||
logging.error(f"OS error occurred during the firmware upgrade process: {e}")
|
|
||||||
raise
|
|
||||||
except Exception as e:
|
|
||||||
logging.error(
|
|
||||||
f"An unexpected error occurred during the firmware upgrade process: {e}",
|
|
||||||
exc_info=True,
|
|
||||||
)
|
|
||||||
raise
|
|
||||||
@@ -19,6 +19,10 @@ import json
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
|
import aiofiles
|
||||||
|
import aiohttp
|
||||||
|
import hashlib
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from pyasic import settings
|
from pyasic import settings
|
||||||
from pyasic.errors import APIError
|
from pyasic.errors import APIError
|
||||||
@@ -46,6 +50,14 @@ class ePICWebAPI(BaseWebAPI):
|
|||||||
async with httpx.AsyncClient(transport=settings.transport()) as client:
|
async with httpx.AsyncClient(transport=settings.transport()) as client:
|
||||||
for retry_cnt in range(settings.get("get_data_retries", 1)):
|
for retry_cnt in range(settings.get("get_data_retries", 1)):
|
||||||
try:
|
try:
|
||||||
|
if parameters.get("form") is not None:
|
||||||
|
form_data = parameters["form"]
|
||||||
|
form_data.add_field('password', self.pwd)
|
||||||
|
response = await client.post(
|
||||||
|
f"http://{self.ip}:{self.port}/{command}",
|
||||||
|
timeout=5,
|
||||||
|
data=form_data,
|
||||||
|
)
|
||||||
if post:
|
if post:
|
||||||
response = await client.post(
|
response = await client.post(
|
||||||
f"http://{self.ip}:{self.port}/{command}",
|
f"http://{self.ip}:{self.port}/{command}",
|
||||||
@@ -135,3 +147,22 @@ class ePICWebAPI(BaseWebAPI):
|
|||||||
|
|
||||||
async def capabilities(self) -> dict:
|
async def capabilities(self) -> dict:
|
||||||
return await self.send_command("capabilities")
|
return await self.send_command("capabilities")
|
||||||
|
|
||||||
|
async def system_update(self, file: Path | str, keep_settings: bool = True):
|
||||||
|
"""Perform a system update by uploading a firmware file and sending a
|
||||||
|
command to initiate the update."""
|
||||||
|
|
||||||
|
# calculate the SHA256 checksum of the firmware file
|
||||||
|
sha256_hash = hashlib.sha256()
|
||||||
|
async with aiofiles.open(str(file), "rb") as f:
|
||||||
|
while chunk := await f.read(8192):
|
||||||
|
sha256_hash.update(chunk)
|
||||||
|
checksum = sha256_hash.hexdigest()
|
||||||
|
|
||||||
|
# prepare the multipart/form-data request
|
||||||
|
form_data = aiohttp.FormData()
|
||||||
|
form_data.add_field('checksum', checksum)
|
||||||
|
form_data.add_field('keepsettings', str(keep_settings).lower())
|
||||||
|
form_data.add_field('update.zip', open(file, 'rb'), filename='update.zip')
|
||||||
|
|
||||||
|
await self.send_command("systemupdate", form=form_data)
|
||||||
Reference in New Issue
Block a user