Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

- improve debug logging #12

Merged
merged 1 commit into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ Please, use the format:

## [Unreleased]

- beta-builder: automatically publish beta packages into pypi from main branch
- beta-builder: automatically publish beta packages into pypi from main branch
- improve debug logging
- fix issues encountered with PR #11
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# LuxOS Tools Repository

> **WARNING** There are references into the PR luxos-code-refactoring

This repository contains scripts we built to operate and troubleshoot miners running LuxOS.

## Install
Expand All @@ -11,14 +9,14 @@ There are few ways to install the luxos package:
1. Using pip (suggested for end-users):
```shell
pip install luxos
pip install git+https://github.com/LuxorLabs/luxos-tooling.git@pr/luxos-code-refactoring
pip install git+https://github.com/LuxorLabs/luxos-tooling.git
```
Using pip gives you access to the cli commands `luxos` and `health-checker` as well
the ability to import in python the `import luxos.api` api for luxos.

2. A single drop in file (for support):
```shell
curl -LO https://github.com/LuxorLabs/luxos-tooling/raw/pr/luxos-code-refactoring/luxos.pyz
curl -LO https://github.com/LuxorLabs/luxos-tooling/raw/luxos.pyz
```
These are two standalone [zipapp](https://docs.python.org/3/library/zipapp.html) files, you can use
from the command line as `python luxos.pyz`, no dependencies beside a recent-*ish* python
Expand Down
Binary file added make.pyz
Binary file not shown.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "luxos"
version = "0.0.0"
version = "0.0.1"
description = "The all encompassing LuxOS python library."
readme = "README.md"
license = { text = "MIT" } # TODO I don't think this is a MIT??
Expand Down
27 changes: 22 additions & 5 deletions src/luxos/asyncops.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def somcode(host: str, port: int, ...):
e.address
raise MyNewExecption() from e <- this will re-raise
"""

@functools.wraps(function)
async def _function(host: str, port: int, *args, **kwargs):
try:
Expand All @@ -43,6 +44,7 @@ async def _function(host: str, port: int, *args, **kwargs):
# we augment any other exception with (host, port) info
log.exception("internal error")
raise exceptions.MinerConnectionError(host, port, "internal error") from e

return _function


Expand Down Expand Up @@ -75,6 +77,7 @@ async def _roundtrip(

return response.decode()


# TODO add annotations
async def roundtrip(
host: str,
Expand Down Expand Up @@ -131,7 +134,9 @@ def validate_message(
for key in ["STATUS", "id", *([extrakey] if extrakey else [])]:
if key in res:
continue
raise exceptions.MinerCommandMalformedMessageError(host, port, f"missing {key} from logon message", res)
raise exceptions.MinerCommandMalformedMessageError(
host, port, f"missing {key} from logon message", res
)

if not extrakey or not (minfields or maxfields):
return res
Expand All @@ -157,13 +162,17 @@ async def logon(host: str, port: int, timeout: float | None = 3) -> str:
# on subsequent logon, we receive a
# [STATUS][Msg] == "Another session is active" ([STATUS][Code] 402)
if "SESSION" not in res and res.get("STATUS", [{}])[0].get("Code") == 402:
raise exceptions.MinerCommandSessionAlreadyActive(host, port, "connection active", res)
raise exceptions.MinerCommandSessionAlreadyActive(
host, port, "connection active", res
)
sessions = validate_message(host, port, res, "SESSION", 1, 1)

session = sessions[0] # type: ignore

if "SessionID" not in session:
raise exceptions.MinerCommandSessionAlreadyActive(host, port, "no SessionID in data", res)
raise exceptions.MinerCommandSessionAlreadyActive(
host, port, "no SessionID in data", res
)
return str(session["SessionID"])


Expand All @@ -184,7 +193,7 @@ async def execute_command(
parameters: list[str] | None = None,
verbose: bool = False,
asjson: bool | None = True,
add_address: bool = False
add_address: bool = False,
) -> tuple[tuple[str, int], dict[str, Any]] | dict[str, Any]:
timeout = TIMEOUT if timeout_sec is None else timeout_sec
parameters = parameters or []
Expand All @@ -195,13 +204,21 @@ async def execute_command(
parameters = [sid, *parameters]
log.info("session id requested & obtained for %s:%i (%s)", host, port, sid)
else:
log.debug("no logon required for command %s on %s:%i", cmd, host, port)
log.debug("no logon required for command '%s' on %s:%i", cmd, host, port)

try:
packet = {"command": cmd}
if parameters:
packet["parameter"] = ",".join(parameters)
log.debug(
"executing command '%s' on '%s:%i' with parameters: %s",
cmd,
host,
port,
packet.get("parameter", ""),
)
ret = await roundtrip(host, port, packet, timeout, asjson=asjson)
log.debug("received from %s:%s: %s", host, port, str(ret))
return ((host, port), ret) if add_address else ret
finally:
if sid:
Expand Down
6 changes: 3 additions & 3 deletions src/luxos/scripts/async_luxos.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


async def run(
ip_list: list[str],
ipaddresses: list[str],
port: int,
cmd: str,
params: list[str],
Expand All @@ -20,7 +20,7 @@ async def run(
batchsize = max(batchsize, 2)

for grupid, addresses in enumerate(
misc.batched([(ip, port) for ip in ip_list], n=batchsize)
misc.batched([(ip, port) for ip in ipaddresses], n=batchsize)
):
tasks = []
for host, port in addresses:
Expand All @@ -40,7 +40,7 @@ async def run(
failures = [task for task in alltasks if isinstance(task, Exception)]

# print a nice report
print(f"task executed sucessfully: {len(successes)}")
print(f"task executed sucessfully (use -a|--all for details): {len(successes)}")
if details:
for (host, port), task in successes: # type: ignore
print(f" > {host}:{port}")
Expand Down
6 changes: 2 additions & 4 deletions src/luxos/scripts/luxos.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,7 @@ def main():
parser.add_argument(
"--port", required=False, default=4028, type=int, help="Port for LuxOS API"
)
parser.add_argument(
"--verbose", required=False, default=False, type=bool, help="Verbose output"
)
parser.add_argument("--verbose", action="store_true", help="Verbose output")
parser.add_argument(
"--batch_delay",
required=False,
Expand Down Expand Up @@ -326,7 +324,7 @@ def main():

asyncio.run(
async_luxos.run(
ipaddress=ip_list,
ipaddresses=ip_list,
port=args.port,
cmd=args.cmd,
params=args.params,
Expand Down