manta-node 0.6b0.dev526__py3-none-any.whl → 0.6b0.dev534__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,7 +17,7 @@ from manta_common.logging_config import configure_logging
17
17
  from rich.console import Console
18
18
 
19
19
  from ...infrastructure.config import NodeConfigManager
20
- from ...node_orchestrator import Node
20
+ from ...node_orchestrator import Node, NodeFatalError
21
21
 
22
22
  console = Console()
23
23
 
@@ -125,7 +125,15 @@ def start_node_foreground(
125
125
  stop_task.cancel()
126
126
  with contextlib.suppress(asyncio.CancelledError):
127
127
  await stop_task
128
- start_task.result() # Re-raise a genuine start failure unchanged
128
+ try:
129
+ start_task.result() # Re-raise a genuine start failure unchanged
130
+ except NodeFatalError:
131
+ # Tear down a partially-started node before surfacing the fatal error.
132
+ try:
133
+ await node.stop()
134
+ except Exception as exc:
135
+ console.print(f"[red]Error during node cleanup: {exc}[/red]")
136
+ raise
129
137
  return False
130
138
 
131
139
  # MUST precede start_task.cancel(): Node.stop() skips the DISCONNECTED
@@ -136,7 +144,7 @@ def start_node_foreground(
136
144
  console.print(f"[red]Error during node cleanup: {exc}[/red]")
137
145
 
138
146
  start_task.cancel()
139
- with contextlib.suppress(asyncio.CancelledError):
147
+ with contextlib.suppress(asyncio.CancelledError, NodeFatalError):
140
148
  await start_task
141
149
  return True
142
150
 
@@ -5,12 +5,14 @@ from pathlib import Path
5
5
  from typing import Any
6
6
 
7
7
  from manta_common.build.common.informations import DatasetOverviews, Overview
8
- from manta_common.const import CHUNK_SIZE
9
8
  from manta_common.errors import MantaSecurityError, MantaValidationError
10
9
  from manta_common.traces import Tracer
11
10
 
12
11
  __all__ = ["DatasetManager"]
13
12
 
13
+ # Bounded read size for streaming dataset files; not the 4 GiB message-size ceiling manta_common.CHUNK_SIZE.
14
+ STREAM_CHUNK_SIZE = 1024 * 1024
15
+
14
16
  # File type to dtype mapping
15
17
  DTYPES = {
16
18
  ".txt": "text",
@@ -243,7 +245,7 @@ class DatasetManager:
243
245
  if not file_path.exists():
244
246
  raise FileNotFoundError(f"File not found: {file_path}")
245
247
  with file_path.open("rb") as f:
246
- while chunk := f.read(CHUNK_SIZE):
248
+ while chunk := f.read(STREAM_CHUNK_SIZE):
247
249
  yield chunk
248
250
 
249
251
  def _validate_file_path(self, file_path: str) -> str:
@@ -24,7 +24,7 @@ from manta_common.build.common.results import (
24
24
  ResultQuery,
25
25
  )
26
26
  from manta_common.build.common.system import Empty, Logs, Ok
27
- from manta_common.build.common.tasks import TaskScheduling
27
+ from manta_common.build.common.tasks import TaskScheduling, TaskUpdate
28
28
  from manta_common.build.common.wireguard import (
29
29
  DeregisterWireGuardNodeRequest,
30
30
  RegisterWireGuardNodeRequest,
@@ -360,6 +360,26 @@ class NodeClient(GrpcClientBase):
360
360
  """
361
361
  return await self.call_service_method("schedule_task", request)
362
362
 
363
+ async def update_task(self, request: TaskUpdate) -> Ok:
364
+ """
365
+ Report a task status update to the manager.
366
+
367
+ This is the authoritative channel the manager's task scheduler
368
+ consumes; MQTT ``manager/update_task_status`` is a secondary,
369
+ lossy channel (refs #287).
370
+
371
+ Parameters
372
+ ----------
373
+ request : TaskUpdate
374
+ Task status update
375
+
376
+ Returns
377
+ -------
378
+ Ok
379
+ Response
380
+ """
381
+ return await self.call_service_method("update_task", request)
382
+
363
383
  async def send_error(self, manta_error: MantaError):
364
384
  """
365
385
  Send the error to the Manager
@@ -1,5 +1,8 @@
1
1
  import asyncio
2
+ import base64
2
3
  import io
4
+ import json
5
+ import re
3
6
  from collections.abc import AsyncIterable, Awaitable, Callable
4
7
  from datetime import datetime, timezone
5
8
  from logging import getLogger
@@ -12,7 +15,7 @@ from manta_common.build.common.mqtt import MqMetricsSnapshot, MqTaskUpdate
12
15
  from manta_common.build.common.system import Logs
13
16
  from manta_common.build.common.tasks import MqttTask, TaskStatus, TaskUpdate
14
17
  from manta_common.const import CHUNK_SIZE
15
- from manta_common.conversions import ID
18
+ from manta_common.conversions import ID, b2x
16
19
  from manta_common.errors import (
17
20
  MantaError,
18
21
  MantaGRPCError,
@@ -42,6 +45,30 @@ def _is_permanent_upload_rejection(exc: Exception) -> bool:
42
45
  )
43
46
 
44
47
 
48
+ _NODE_ID_CLAIM_PATTERN = re.compile(r"^[0-9a-fA-F]{24}$")
49
+
50
+
51
+ def _node_id_from_token(secured_token: str) -> str | None:
52
+ """Return the 24-hex ``node_id`` claim from a JWT payload, else None.
53
+
54
+ Reads the payload without verifying the signature: the node trusts the
55
+ manager-minted token it already holds. Never logs the token.
56
+ """
57
+ try:
58
+ _, payload, _ = secured_token.split(".", 2)
59
+ except ValueError:
60
+ return None
61
+ try:
62
+ padded = payload + "=" * (-len(payload) % 4)
63
+ claims = json.loads(base64.urlsafe_b64decode(padded))
64
+ except (ValueError, UnicodeDecodeError):
65
+ return None
66
+ node_id = claims.get("node_id") if isinstance(claims, dict) else None
67
+ if not isinstance(node_id, str) or not _NODE_ID_CLAIM_PATTERN.fullmatch(node_id):
68
+ return None
69
+ return node_id
70
+
71
+
45
72
  class CommandHandler(Collector, MqttBase):
46
73
  """
47
74
  CommandHandler class to handle commands from the Manager.
@@ -97,12 +124,17 @@ class CommandHandler(Collector, MqttBase):
97
124
  self.max_concurrent_tasks = max_concurrent_tasks
98
125
  self.task_timeout = task_timeout
99
126
 
127
+ # Never expose the cluster JWT as the client id: derive it from the node_id claim.
128
+ client_id = ID(
129
+ _node_id_from_token(node_client.secured_token)
130
+ or b2x(node_client.secured_token.encode())
131
+ )
100
132
  MqttBase.__init__(
101
133
  self,
102
134
  mqtt_broker_host=mqtt_broker_host,
103
135
  mqtt_broker_port=mqtt_broker_port,
104
136
  topics=topics,
105
- client_id=ID(node_client.metadata.get("authorization", "node_client")),
137
+ client_id=client_id,
106
138
  ssl_cert_folder=ssl_cert_folder,
107
139
  )
108
140
 
@@ -171,6 +203,9 @@ class CommandHandler(Collector, MqttBase):
171
203
  async def get_task_logs(self, task_progression):
172
204
  return await self._task_manager.get_task_logs(task_progression)
173
205
 
206
+ async def get_image_task_status(self, swarm_id, task_id):
207
+ return await self._task_manager.get_image_task_status(swarm_id, task_id)
208
+
174
209
  async def restart_container(self, swarm_id, task_id):
175
210
  return await self._task_manager.restart_container(swarm_id, task_id)
176
211
 
@@ -539,6 +574,14 @@ class CommandHandler(Collector, MqttBase):
539
574
  "manager/update_task_status",
540
575
  MqTaskUpdate(token=self.node_client.secured_token, update=task_update),
541
576
  )
577
+ # Also report via the gRPC UpdateTask RPC the manager's scheduler consumes.
578
+ try:
579
+ await self.node_client.update_task(task_update)
580
+ except Exception:
581
+ self.tracer.exception(
582
+ f"Failed to report task status via gRPC for task "
583
+ f"{ID(task_update.task_id)}"
584
+ )
542
585
 
543
586
  async def send_task_logs(self, date: datetime, processed_logs: bytes):
544
587
  """
@@ -2,7 +2,6 @@ import asyncio
2
2
  import socket
3
3
  import ssl
4
4
  import struct
5
- import sys
6
5
  import uuid
7
6
  from logging import getLogger
8
7
  from pathlib import Path
@@ -36,7 +35,16 @@ from .infrastructure.mqtt.command_handler import CommandHandler
36
35
  from .infrastructure.process.executor import ProcessExecutor
37
36
  from .task_manager import TaskManager
38
37
 
39
- __all__ = ["Node"]
38
+ __all__ = ["Node", "NodeFatalError"]
39
+
40
+
41
+ class NodeFatalError(Exception):
42
+ """Raised by Node.start()'s fatal paths instead of sys.exit() from inside a task.
43
+
44
+ The CLI maps it to a non-zero exit code and keeps shutdown ordering under
45
+ its own control.
46
+ """
47
+
40
48
 
41
49
  # Docker-specific exceptions. Imported lazily so a light node (no Docker
42
50
  # package installed) can import this module and run in process mode without
@@ -184,6 +192,8 @@ class Node:
184
192
  """
185
193
 
186
194
  __slots__ = [
195
+ "_stop_done",
196
+ "_stop_lock",
187
197
  "cert_folder",
188
198
  "command_handler",
189
199
  "command_loop",
@@ -262,6 +272,10 @@ class Node:
262
272
  self.command_loop = None
263
273
  self.light_server_task = None
264
274
 
275
+ # Serialise teardown so concurrent stop() callers wait and then no-op.
276
+ self._stop_lock = asyncio.Lock()
277
+ self._stop_done = False
278
+
265
279
  # Register configuration observer for runtime updates
266
280
  self.config_manager.register_observer(self._on_config_change)
267
281
 
@@ -365,11 +379,11 @@ class Node:
365
379
  Then, it will check if the manager is available by calling
366
380
  the `is_available` function of the node client.
367
381
  If the manager is not available, it will log an error and
368
- exit with a non-zero status code.
382
+ raise a :code:`NodeFatalError` with a non-zero status report.
369
383
 
370
384
  Raises
371
385
  ------
372
- SystemExit
386
+ NodeFatalError
373
387
  If the manager is not available.
374
388
  """
375
389
  # Log endpoint details before attempting connection
@@ -400,11 +414,13 @@ class Node:
400
414
  f" 3. Verify JWT_SECRET matches between node and manager\n"
401
415
  f" 4. Check network connectivity to {self.config.network.manager_host}:{self.config.network.manager_port}\n"
402
416
  )
403
- sys.exit(troubleshooting)
417
+ raise NodeFatalError(troubleshooting) from error
404
418
  except MantaError as manta_error:
405
419
  tls_error = _find_tls_error(manta_error)
406
420
  if tls_error is not None:
407
- sys.exit(self._tls_troubleshooting(manta_error, tls_error))
421
+ raise NodeFatalError(
422
+ self._tls_troubleshooting(manta_error, tls_error)
423
+ ) from manta_error
408
424
 
409
425
  message = f"Manager authentication failed at {endpoint}: {manta_error}"
410
426
  self.tracer.exception(message)
@@ -418,11 +434,11 @@ class Node:
418
434
  f" - Verify secured_token in node config matches manager's JWT_SECRET\n"
419
435
  f" - Check token format: should be a valid JWT with 3 parts (header.payload.signature)\n"
420
436
  )
421
- sys.exit(troubleshooting)
437
+ raise NodeFatalError(troubleshooting) from manta_error
422
438
  except Exception as exc:
423
439
  message = f"Unknown error connecting to {endpoint}: {exc}"
424
440
  self.tracer.exception(message)
425
- sys.exit(f"[ERROR] {message}")
441
+ raise NodeFatalError(f"[ERROR] {message}") from exc
426
442
 
427
443
  async def start(self) -> None:
428
444
  """
@@ -436,7 +452,7 @@ class Node:
436
452
 
437
453
  Raises
438
454
  ------
439
- SystemExit
455
+ NodeFatalError
440
456
  If MQTT client unreacheable or gRPC error occurs
441
457
  """
442
458
  await self.check_manager_availability()
@@ -542,14 +558,16 @@ class Node:
542
558
  await asyncio.gather(self.command_loop, self.light_server_task)
543
559
  except ConnectionRefusedError:
544
560
  self.tracer.exception("Unable to start and connect to MQTT Message Broker")
545
- sys.exit("[ERROR] Unable to start and connect to MQTT Message Broker")
561
+ raise NodeFatalError(
562
+ "[ERROR] Unable to start and connect to MQTT Message Broker"
563
+ ) from None
546
564
  except GRPCError:
547
565
  self.tracer.exception("Unable to register to the Manager")
548
- sys.exit("[ERROR] Unable to register to the Manager")
566
+ raise NodeFatalError("[ERROR] Unable to register to the Manager") from None
549
567
  except OSError as os_error:
550
568
  self.tracer.exception(f"OS error: {os_error}")
551
569
  await self.stop()
552
- sys.exit(f"[ERROR] OS error: {os_error}")
570
+ raise NodeFatalError(f"[ERROR] OS error: {os_error}") from os_error
553
571
  except Exception as exc:
554
572
  # Docker-specific failures are only meaningful in container mode.
555
573
  # In process mode they would mask unrelated OS errors, so they are
@@ -561,39 +579,41 @@ class Node:
561
579
  ):
562
580
  self.tracer.exception(f"Docker is not available: {exc}")
563
581
  await self.stop()
564
- sys.exit(f"[ERROR] Docker is not available: {exc}")
582
+ raise NodeFatalError(f"[ERROR] Docker is not available: {exc}") from exc
565
583
  self.tracer.exception(f"Unknown error: {exc}")
566
584
  await self.stop()
567
- sys.exit(f"[ERROR] Unknown error: {exc}")
585
+ raise NodeFatalError(f"[ERROR] Unknown error: {exc}") from exc
568
586
 
569
587
  async def stop(self) -> None:
570
- """
571
- Stop the node
572
- """
573
- self.tracer.info("Stopping node")
574
- if (
575
- self.command_handler is not None
576
- and self.command_loop is not None
577
- and not self.command_loop.cancelled()
578
- ):
579
- self.tracer.info("Publishing node status to manager")
580
- await self.command_handler.client.publish(
581
- "manager/set_node_status",
582
- NodeStatus(status=NodeStatusEnum.DISCONNECTED).SerializeToString(),
583
- )
584
-
585
- if self.command_handler is not None:
586
- self.tracer.info("Cleaning up command handler")
587
- await self.command_handler.clean()
588
-
589
- if self.command_loop is not None:
590
- self.tracer.info("Stopping command loop")
591
- self.command_loop.cancel()
592
-
593
- if self.light_server_task is not None:
594
- self.tracer.info("Stopping light server task")
595
- self.light_server_task.cancel()
596
-
597
- # if self.server is not None:
598
- # self.tracer.info("Stopping light server")
599
- # self.server.close()
588
+ """Stop the node"""
589
+ async with self._stop_lock:
590
+ if self._stop_done:
591
+ return
592
+ try:
593
+ self.tracer.info("Stopping node")
594
+ if (
595
+ self.command_handler is not None
596
+ and self.command_loop is not None
597
+ and not self.command_loop.cancelled()
598
+ ):
599
+ self.tracer.info("Publishing node status to manager")
600
+ await self.command_handler.client.publish(
601
+ "manager/set_node_status",
602
+ NodeStatus(
603
+ status=NodeStatusEnum.DISCONNECTED
604
+ ).SerializeToString(),
605
+ )
606
+
607
+ if self.command_handler is not None:
608
+ self.tracer.info("Cleaning up command handler")
609
+ await self.command_handler.clean()
610
+ finally:
611
+ # Cancel the loops even if publish/clean raised, or they leak.
612
+ if self.command_loop is not None:
613
+ self.tracer.info("Stopping command loop")
614
+ self.command_loop.cancel()
615
+
616
+ if self.light_server_task is not None:
617
+ self.tracer.info("Stopping light server task")
618
+ self.light_server_task.cancel()
619
+ self._stop_done = True
@@ -302,9 +302,15 @@ class TaskManager:
302
302
  return updated
303
303
 
304
304
  async def get_task_status(self, swarm_id: ID, task_id: ID) -> TaskStatus:
305
+ if (swarm_id.tid, task_id.tid) in self.image_task_ids:
306
+ return await self.get_image_task_status(swarm_id, task_id)
305
307
  status = await self._executor.get_status(swarm_id, task_id)
306
308
  return TaskLifecycleService.calculate_status_from_container(status)
307
309
 
310
+ async def get_image_task_status(self, swarm_id: ID, task_id: ID) -> TaskStatus:
311
+ """Exit-code-aware status for image-mode tasks (no SDK inside the container)."""
312
+ return await self._executor.get_image_task_status(swarm_id, task_id)
313
+
308
314
  async def from_pending_to_running(self, task_progression: TaskProgression) -> bool:
309
315
  """
310
316
  Change a task progression from pending status (supposed) to running status
@@ -0,0 +1,115 @@
1
+ Metadata-Version: 2.4
2
+ Name: manta_node
3
+ Version: 0.6b0.dev534
4
+ Summary: Node side software of the Manta platform. It is responsible for the communication with the Manta Core and the execution of the tasks.
5
+ Author-email: Hugo Miralles <hugo.miralles@manta-tech.io>, Matthew Thompson <matthew.thompson@manta-tech.io>
6
+ License-Expression: AGPL-3.0-or-later
7
+ Project-URL: Homepage, https://github.com/mantatech/manta-node-python
8
+ Project-URL: Repository, https://github.com/mantatech/manta-node-python
9
+ Classifier: Programming Language :: JavaScript
10
+ Classifier: Programming Language :: Python
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
15
+ Classifier: Topic :: Software Development :: Embedded Systems
16
+ Requires-Python: >=3.10
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: grpcio-tools
20
+ Requires-Dist: betterproto[compiler]==2.0.0b7
21
+ Requires-Dist: pydantic<3.0.0,>=2.12.5
22
+ Requires-Dist: docker
23
+ Requires-Dist: rich
24
+ Requires-Dist: cryptography>=50.0.0
25
+ Requires-Dist: blake3
26
+ Requires-Dist: aiodocker>=0.26.0
27
+ Requires-Dist: pyyaml
28
+ Requires-Dist: psutil
29
+ Requires-Dist: msgpack
30
+ Requires-Dist: aiomqtt<3.0,>=2.5.1
31
+ Requires-Dist: manta-common-core<=0.6b0,>=0.6b0.dev0
32
+ Requires-Dist: toml
33
+ Requires-Dist: tomli; python_version < "3.11"
34
+ Requires-Dist: tomli-w
35
+ Requires-Dist: keyring
36
+ Requires-Dist: wireguard-tools
37
+ Requires-Dist: pyroute2
38
+ Requires-Dist: icmplib
39
+ Provides-Extra: test
40
+ Requires-Dist: pytest; extra == "test"
41
+ Requires-Dist: pytest-asyncio; extra == "test"
42
+ Provides-Extra: docs
43
+ Requires-Dist: furo; extra == "docs"
44
+ Provides-Extra: code-analytics
45
+ Requires-Dist: ruff; extra == "code-analytics"
46
+ Requires-Dist: pytest-cov; extra == "code-analytics"
47
+ Requires-Dist: coverage-badge; extra == "code-analytics"
48
+ Provides-Extra: all
49
+ Requires-Dist: manta_node[code-analytics,docs,test]; extra == "all"
50
+ Dynamic: license-file
51
+
52
+ # Manta Node Python
53
+
54
+ ![Version](https://img.shields.io/badge/version-0.6b0-orange)
55
+ ![Python version](https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20-blue)
56
+ ![Coverage Badge](.github/coverage/coverage.svg)
57
+ ![Ruff](https://img.shields.io/badge/code_style-ruff-2a1833)
58
+
59
+ ## Overview
60
+
61
+ Distributed edge execution agent for the Manta platform. Manages containerized task execution on compute nodes and provides local services to running tasks.
62
+
63
+ ## Quick Start
64
+
65
+ ```bash
66
+ # Install
67
+ pip install -e ".[all]"
68
+
69
+ # Run node
70
+ python -m manta_node --manager-host localhost --manager-port 50051 --token <jwt_token>
71
+
72
+ # Run multiple nodes
73
+ python -c "from manta_node import start_nodes; import asyncio; asyncio.run(start_nodes(3, 'localhost', 50051, '<jwt_token>'))"
74
+ ```
75
+
76
+ ## Documentation
77
+
78
+ 📚 **Full documentation is available at [docs.manta-tech.io](https://docs.manta-tech.io/)**
79
+
80
+ - [Node Operator Guide](https://docs.manta-tech.io/node-guide/index.html)
81
+ - [Node Configuration](https://docs.manta-tech.io/node-guide/configuration/index.html)
82
+ - [Getting Started](https://docs.manta-tech.io/getting-started/index.html)
83
+ - [Platform Overview](https://docs.manta-tech.io/core-concepts/index.html)
84
+
85
+ For developers working on this component:
86
+
87
+ - **[Node Architecture](https://github.com/mantatech/manta-deploy/blob/main/docs/components/node/ARCHITECTURE.md)** - Container orchestration, service implementation (lives in `mantatech/manta-deploy` per [ADR-0013](https://github.com/mantatech/manta-deploy/blob/main/docs/adr/0013-documentation-organization.md))
88
+ - **[CLAUDE.md](./CLAUDE.md)** - Development guidelines
89
+
90
+ ## Architecture
91
+
92
+ - **Container Management**: Docker-based task execution
93
+ - **gRPC Services**: LocalServicer and WorldServicer for task communication
94
+ - **MQTT Integration**: Asynchronous command reception
95
+ - **Resource Monitoring**: Real-time metrics collection
96
+
97
+ ## Testing
98
+
99
+ ```bash
100
+ python -m pytest tests/ --cov=manta_node
101
+ ```
102
+
103
+ ## Docker Setup
104
+
105
+ For Linux users encountering permission issues:
106
+
107
+ ```bash
108
+ # Follow Docker post-installation steps
109
+ # https://docs.docker.com/engine/install/linux-postinstall/
110
+ sudo usermod -aG docker $USER
111
+ ```
112
+
113
+ ## License
114
+
115
+ GNU Affero General Public License
@@ -1,7 +1,7 @@
1
1
  manta_node/__init__.py,sha256=bgGWXH3yQVhNf0v1ZGUBAy5Y51fqb0Y-EaLnocbcino,153
2
2
  manta_node/__main__.py,sha256=SjrJyuMg_ZFKV6WOVe3MrtWM8Qmu065dkKZYl4n2YLw,1665
3
- manta_node/node_orchestrator.py,sha256=O9xemhDWYzBoFIvOfCmxQlK-2X97xApHhbwe44StsFc,23134
4
- manta_node/task_manager.py,sha256=BkPUGtsEIiJDYhsBd3_qwMOJt7-YgZ6Y7sGqsK3uyDU,33043
3
+ manta_node/node_orchestrator.py,sha256=Y1qOlyrXxk3znBidUagradrjiEVdl8BmgGRmtUYHTL8,24195
4
+ manta_node/task_manager.py,sha256=l8EBQx5Spn2UISUK61WWqanefJF1_p2qGpxP8BeG_7Q,33428
5
5
  manta_node/tasks.py,sha256=o837Hi-KFVJg9LF5iOtE8oD6UuTOfrEPWR-JOdhRGeY,6983
6
6
  manta_node/utils.py,sha256=Hw4Iw2jYQYsfVLVJuBMt-_rMFBeml3nCDE2jiiXc8YM,1155
7
7
  manta_node/cli/__init__.py,sha256=arzO3mXDJ-E2yeeytbZfN7mCswwxdQ43_QjyeL2E5yE,134
@@ -13,7 +13,7 @@ manta_node/cli/commands/cluster.py,sha256=kUVopCN4xkEk-IR1aKpr7bfBSQEtG6pEj_hlWn
13
13
  manta_node/cli/commands/config.py,sha256=BiarCD0S8rcNYbio4RLzDvUS7A50s5dd5F4TiZqLR6M,16577
14
14
  manta_node/cli/commands/logs.py,sha256=cXOSdwhDIJAiKMmJYdzrnpapIxudxVdMzYT-KAWDKVk,5259
15
15
  manta_node/cli/commands/network.py,sha256=QqncD6vbNlg65ptQdFYexEUMALQm8UwcftbW3sfQrjw,42070
16
- manta_node/cli/commands/start.py,sha256=ZvoHP0PG26Um9zS3MIsqDLLLt0iQSsmcdvayalT7xyE,18392
16
+ manta_node/cli/commands/start.py,sha256=8qpOTv4LsCAMaygmPyhC9ZqlH8rkFPko-u2bVYTvyIo,18771
17
17
  manta_node/cli/commands/status.py,sha256=FhlJuFxIRzxv9y8jUJRuWaCLfDBsGBqv6DCHUFQta3A,6401
18
18
  manta_node/cli/commands/stop.py,sha256=8on7NqqaBeHRcbrZ5pGJ3Ms_6E_HNcF22mZ908JVu4A,7695
19
19
  manta_node/domain/__init__.py,sha256=uyJXDf0QgfGCsXLMggqKCB5QV9oneYJ4iM-REaJGXDM,217
@@ -30,16 +30,16 @@ manta_node/infrastructure/container/executor.py,sha256=rl8eDyTVvoPJGnzA8XbY3ee_K
30
30
  manta_node/infrastructure/container/image_executor.py,sha256=ueLYGlMt1xuYCsuwYqf9HcitWgrWfieY0xq1vXZfCco,9987
31
31
  manta_node/infrastructure/container/manager.py,sha256=wJWBU160S6R4-R3B4eIg6p7ik2hCCeAll43wGs8Z8SY,15506
32
32
  manta_node/infrastructure/filesystem/__init__.py,sha256=nf6Fakp3wuFKjSAm_oihI6WE_yyUY6Uelr7A1GwSvXs,145
33
- manta_node/infrastructure/filesystem/dataset_manager.py,sha256=8aexrjrkWZ7OCuS0HkjYXZFtg_8Y5WOJ540inK7BYRs,14968
33
+ manta_node/infrastructure/filesystem/dataset_manager.py,sha256=sW7vPKYBLjwbtju1yzFEob9GlY1v0VI-xu6gxF9KM90,15075
34
34
  manta_node/infrastructure/grpc/__init__.py,sha256=6I-yzQM42gdBfcZ1FPVEKF2-pgJMdW-UssDHgz2EFcc,254
35
- manta_node/infrastructure/grpc/client.py,sha256=8iocMLnGzPaOQmwR3X2sXPLCbOdbLjSZFsLgD1EZcsY,13177
35
+ manta_node/infrastructure/grpc/client.py,sha256=f8z61BYfBChRW0IT5HKbIxypRfsxfCpTkX0Xsmw_vq8,13737
36
36
  manta_node/infrastructure/grpc/local_servicer.py,sha256=9PFAwpKKFGy3P7HZfx2BHwhOgZhWwkwEja-eUTnMfpw,4217
37
37
  manta_node/infrastructure/grpc/world_servicer.py,sha256=nmyrMzYxzGDlZ1-oOeyALgd76mbeOmAOsjzoVN6f0SA,8222
38
38
  manta_node/infrastructure/metrics/__init__.py,sha256=ODGAj9s63F5jba2c3dQRMfNK6I4WvMdcJUS_xApUN5Y,272
39
39
  manta_node/infrastructure/metrics/collector.py,sha256=9ESw__Pc2tV6ldG5yhos2IS7T5Td59KxTIwDRZc_G4w,3067
40
40
  manta_node/infrastructure/metrics/metrics_collector.py,sha256=TI_9tRoIUunGx_BstVavK6VElig7Wc5mJ0kB4bFumVs,11048
41
41
  manta_node/infrastructure/mqtt/__init__.py,sha256=riXo1sXgO4YV6DHCmWRqK61BAmuGLdHiVdQFunAJadA,140
42
- manta_node/infrastructure/mqtt/command_handler.py,sha256=2BP_HuIj6C8quVSLt4SwR4TuPnmpPWztmu0Vzd3RyLM,22975
42
+ manta_node/infrastructure/mqtt/command_handler.py,sha256=WZgcOyzPJ5xgC6rrNumej3dd1LYDaWswlHWNSZJ9fYg,24528
43
43
  manta_node/infrastructure/network/__init__.py,sha256=On3XLgycFQoc-fBCa5hFuFDfEJjmFy7Wl2CK3D2LkdI,478
44
44
  manta_node/infrastructure/network/event_registry.py,sha256=iWEfUJRzDnWjOrDinpYqVyIUpGKJjp7RZkjMDPfpplM,1661
45
45
  manta_node/infrastructure/network/factory.py,sha256=-LvHbBp5nBpQ7fyQT1T0pvK3aczZqWc9QNDW37brBeU,3897
@@ -47,9 +47,9 @@ manta_node/infrastructure/network/protocols.py,sha256=U9AZM_R3Qizz0U-mIwC79jFDGW
47
47
  manta_node/infrastructure/network/wireguard_provider.py,sha256=1U4wbpxG3fQng6d5drqC0clzw26iLSYBlUWRbMyR00c,37923
48
48
  manta_node/infrastructure/process/__init__.py,sha256=MpKkA3k-6ND-Nb7uyzrpw8MdQssQQ6NaiUTLuLnzNbE,53
49
49
  manta_node/infrastructure/process/executor.py,sha256=Ab1XvNuelEGCD5KdZLgYYnpjYZ5dpKRKOzRWL68AxQg,11601
50
- manta_node-0.6b0.dev526.dist-info/licenses/LICENSE,sha256=9mBgLhiB9goQPQjg9XQJ6FjgVxYw9Q8lyOZYkPGwF_c,34484
51
- manta_node-0.6b0.dev526.dist-info/METADATA,sha256=G-hq2vfZiRdqtx2R8CNHFMjedXmZ4c9r1vGMtJFDEP8,43841
52
- manta_node-0.6b0.dev526.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
53
- manta_node-0.6b0.dev526.dist-info/entry_points.txt,sha256=C_zcw6mdmztNxVUZGLZ83UH5TwcSuqb2C-rB4e2CQoc,56
54
- manta_node-0.6b0.dev526.dist-info/top_level.txt,sha256=nbT5J5WETuXM9UPoQckl29uUOq8wMYdRb9QDx5kAFeo,11
55
- manta_node-0.6b0.dev526.dist-info/RECORD,,
50
+ manta_node-0.6b0.dev534.dist-info/licenses/LICENSE,sha256=9mBgLhiB9goQPQjg9XQJ6FjgVxYw9Q8lyOZYkPGwF_c,34484
51
+ manta_node-0.6b0.dev534.dist-info/METADATA,sha256=SXyXZeplD4gYLl_9jqkeXOgv5Q4tGUjanKSFh5WQMpc,4213
52
+ manta_node-0.6b0.dev534.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
53
+ manta_node-0.6b0.dev534.dist-info/entry_points.txt,sha256=C_zcw6mdmztNxVUZGLZ83UH5TwcSuqb2C-rB4e2CQoc,56
54
+ manta_node-0.6b0.dev534.dist-info/top_level.txt,sha256=nbT5J5WETuXM9UPoQckl29uUOq8wMYdRb9QDx5kAFeo,11
55
+ manta_node-0.6b0.dev534.dist-info/RECORD,,