Compare commits
18 Commits
448ffa443d
...
0.4.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a6363f8591 | ||
| f065d26a5f | |||
|
0a46ac4527
|
|||
|
85553eefc5
|
|||
|
f24f7c9b08
|
|||
|
|
c3a8c2011c | ||
|
7099853125
|
|||
|
|
a1afd261d5 | ||
|
29ed2c8e5d
|
|||
|
|
b8fe5d66d4 | ||
| 4ee7a56695 | |||
|
eb46889157
|
|||
|
|
48df6e4534 | ||
| 76ef047551 | |||
|
2d8dc06fa1
|
|||
|
11ae93ed3c
|
|||
|
ac5521618b
|
|||
|
64866079d7
|
48
CHANGELOG.md
48
CHANGELOG.md
@@ -2,6 +2,54 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [0.4.4] - 2026-03-05
|
||||||
|
|
||||||
|
### Refactor
|
||||||
|
|
||||||
|
- [`85553ee`](https://gitea.pufereq.pl/judas/judas_client/commit/85553eefc56e30f6d6ce40ff428fa46dc0c880fa) **connector.py**: refactor calls to Message class constructors after protocol changes
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
- [`0a46ac4`](https://gitea.pufereq.pl/judas/judas_client/commit/0a46ac45273d516ac061fd3ef2515281a3adb1de) **uv.lock**: update judas_protocol to 0.8.0
|
||||||
|
- [`f24f7c9`](https://gitea.pufereq.pl/judas/judas_client/commit/f24f7c9b08624a7ce3a765fb259d6f126dec82fa) **uv.lock**: update judas_protocol to 0.7.0
|
||||||
|
|
||||||
|
## [0.4.3] - 2026-03-01
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- [`7099853`](https://gitea.pufereq.pl/judas/judas_client/commit/709985312514f866b760610fe7d8374763d188b2) **connector.py**: fix no timeout on connection error
|
||||||
|
|
||||||
|
## [0.4.2] - 2026-03-01
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- [`29ed2c8`](https://gitea.pufereq.pl/judas/judas_client/commit/29ed2c8e5d256aa7b75424e6d71e14463f8b9caa) **connector.py**: do not connect multiple times when BlockingIOError encountered in `Connector.connect()`
|
||||||
|
|
||||||
|
## [0.4.1] - 2026-02-28
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- [`eb46889`](https://gitea.pufereq.pl/judas/judas_client/commit/eb4688915747e2dcff3b331618c2b0185f1b611d) **connector.py**: fix `address already in use` error
|
||||||
|
|
||||||
|
## [0.4.0] - 2026-02-28
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- [`ac55216`](https://gitea.pufereq.pl/judas/judas_client/commit/ac5521618ba89b25fd31f09357470ed96cd405cf) **client.py**: add custom ID support with `JUDAS_ID` env variable
|
||||||
|
- [`6486607`](https://gitea.pufereq.pl/judas/judas_client/commit/64866079d7e2087be7dd8588b22be73006605a91) **connector.py**: handle `CONTROL.CLOSE` msgs
|
||||||
|
|
||||||
|
### Miscellaneous Tasks
|
||||||
|
|
||||||
|
- [`448ffa4`](https://gitea.pufereq.pl/judas/judas_client/commit/448ffa443d0b7b464d3f70f81a0b1b3f17765484) **uv.lock**: update depedencies for Python 3.14
|
||||||
|
|
||||||
|
### Refactor
|
||||||
|
|
||||||
|
- [`11ae93e`](https://gitea.pufereq.pl/judas/judas_client/commit/11ae93ed3ceac148097f4246e53e2150a653fcf8) **client.py**: rename `Client.mac_address` -> `Client.id`
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
- [`2d8dc06`](https://gitea.pufereq.pl/judas/judas_client/commit/2d8dc06fa1087bb1ed968d798dc82cd0c6159e16) **uv.lock**: update judas_protocol to 0.6.0
|
||||||
|
|
||||||
## [0.3.0] - 2025-11-30
|
## [0.3.0] - 2025-11-30
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ build-backend = "uv_build"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "judas_client"
|
name = "judas_client"
|
||||||
version = "0.3.0"
|
version = "0.4.4"
|
||||||
description = "A client for judas, a remote PC fleet management system."
|
description = "A client for judas, a remote PC fleet management system."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
authors = []
|
authors = []
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging as lg
|
import logging as lg
|
||||||
|
import os
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from judas_protocol import Message
|
from judas_protocol import Message
|
||||||
@@ -29,11 +30,18 @@ class Client:
|
|||||||
self.server_host: str = server_host
|
self.server_host: str = server_host
|
||||||
self.server_port: int = server_port
|
self.server_port: int = server_port
|
||||||
|
|
||||||
self.mac_address: str = self._get_mac_address()
|
if "JUDAS_ID" in os.environ:
|
||||||
self.logger.debug(f"MAC address: {self.mac_address}")
|
self.id: str = os.environ["JUDAS_ID"]
|
||||||
|
self.logger.debug(
|
||||||
|
f"Using ID from environment variable JUDAS_ID: {self.id}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.id = self._get_mac_address()
|
||||||
|
|
||||||
|
self.logger.debug(f"ID: {self.id}")
|
||||||
|
|
||||||
self.connector: Connector = Connector(
|
self.connector: Connector = Connector(
|
||||||
mac_address=self.mac_address,
|
mac_address=self.id,
|
||||||
host=self.server_host,
|
host=self.server_host,
|
||||||
port=self.server_port,
|
port=self.server_port,
|
||||||
on_message=self.handle_message,
|
on_message=self.handle_message,
|
||||||
@@ -63,5 +71,5 @@ class Client:
|
|||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
"""Run the client."""
|
"""Run the client."""
|
||||||
self.logger.info(f"Starting Client ({self.mac_address})...")
|
self.logger.info(f"Starting Client ({self.id})...")
|
||||||
self.connector.run()
|
self.connector.run()
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ class Connector:
|
|||||||
self.socket: socket.socket = socket.socket(
|
self.socket: socket.socket = socket.socket(
|
||||||
socket.AF_INET, socket.SOCK_STREAM
|
socket.AF_INET, socket.SOCK_STREAM
|
||||||
)
|
)
|
||||||
|
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
self.socket.setblocking(False)
|
self.socket.setblocking(False)
|
||||||
|
|
||||||
self.selector.register(
|
self.selector.register(
|
||||||
@@ -106,7 +107,7 @@ class Connector:
|
|||||||
def send_hello(self) -> None:
|
def send_hello(self) -> None:
|
||||||
"""Send a HELLO message to the server."""
|
"""Send a HELLO message to the server."""
|
||||||
self.logger.debug("[*] Sending HELLO message...")
|
self.logger.debug("[*] Sending HELLO message...")
|
||||||
hello_message: Message = Message.hello(self.mac_address)
|
hello_message: Message = Message.Control.hello(self.mac_address)
|
||||||
self.send(hello_message)
|
self.send(hello_message)
|
||||||
|
|
||||||
def close(self) -> None:
|
def close(self) -> None:
|
||||||
@@ -144,8 +145,24 @@ class Connector:
|
|||||||
self.socket.connect((self.host, self.port))
|
self.socket.connect((self.host, self.port))
|
||||||
connected = True
|
connected = True
|
||||||
except BlockingIOError:
|
except BlockingIOError:
|
||||||
# Connection in progress
|
# connection in progress, wait for socket to become writable
|
||||||
time.sleep(0.1)
|
self.logger.debug(
|
||||||
|
"[.] Connection in progress, waiting for completion..."
|
||||||
|
)
|
||||||
|
events = self.selector.select(timeout=1)
|
||||||
|
for _, mask in events:
|
||||||
|
if mask & selectors.EVENT_WRITE:
|
||||||
|
err = self.socket.getsockopt(
|
||||||
|
socket.SOL_SOCKET, socket.SO_ERROR
|
||||||
|
)
|
||||||
|
if err == 0:
|
||||||
|
connected = True
|
||||||
|
else:
|
||||||
|
self.logger.error(
|
||||||
|
f"[!] Connection failed with error code: {err}"
|
||||||
|
)
|
||||||
|
if not connected:
|
||||||
|
continue
|
||||||
except socket.error as e:
|
except socket.error as e:
|
||||||
self.logger.error(f"[!] Connection error: {e}")
|
self.logger.error(f"[!] Connection error: {e}")
|
||||||
self.logger.debug(f"[.] Retrying in {delay} seconds...")
|
self.logger.debug(f"[.] Retrying in {delay} seconds...")
|
||||||
@@ -174,8 +191,17 @@ class Connector:
|
|||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
message: Message = Message.from_bytes(message_bytes)
|
message: Message = Message.from_bytes(message_bytes)
|
||||||
# handle incoming ACKs
|
|
||||||
if (
|
if (
|
||||||
|
message.category == Category.CONTROL
|
||||||
|
and message.action == ControlAction.CLOSE
|
||||||
|
):
|
||||||
|
self.logger.warning(
|
||||||
|
"[!] Received CLOSE command from server, shutting down."
|
||||||
|
)
|
||||||
|
self.running = False
|
||||||
|
break
|
||||||
|
# handle incoming ACKs
|
||||||
|
elif (
|
||||||
message.category == Category.CONTROL
|
message.category == Category.CONTROL
|
||||||
and message.action == ControlAction.ACK
|
and message.action == ControlAction.ACK
|
||||||
):
|
):
|
||||||
@@ -192,7 +218,9 @@ class Connector:
|
|||||||
self.on_message(message)
|
self.on_message(message)
|
||||||
|
|
||||||
if message.ack_required:
|
if message.ack_required:
|
||||||
ack_message: Message = Message.ack(message.id)
|
ack_message: Message = Message.Control.ack(
|
||||||
|
message.id
|
||||||
|
)
|
||||||
self.send(ack_message)
|
self.send(ack_message)
|
||||||
self._send_outbound()
|
self._send_outbound()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
6
uv.lock
generated
6
uv.lock
generated
@@ -275,7 +275,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "judas-client"
|
name = "judas-client"
|
||||||
version = "0.3.0"
|
version = "0.4.4"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "judas-protocol" },
|
{ name = "judas-protocol" },
|
||||||
@@ -318,8 +318,8 @@ test = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "judas-protocol"
|
name = "judas-protocol"
|
||||||
version = "0.5.0"
|
version = "0.8.0"
|
||||||
source = { git = "https://gitea.pufereq.pl/judas/judas_protocol.git#c48b69ecee16f5824ffd8bce8921341d5fa326b7" }
|
source = { git = "https://gitea.pufereq.pl/judas/judas_protocol.git#a805ccf38edffadc1b8c8b276e60758c86516cd3" }
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "markdown-it-py"
|
name = "markdown-it-py"
|
||||||
|
|||||||
Reference in New Issue
Block a user