portacode 1.4.19__py3-none-any.whl → 1.4.19.dev0__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.
- portacode/_version.py +2 -2
- portacode/connection/handlers/WEBSOCKET_PROTOCOL.md +3 -4
- portacode/connection/handlers/proxmox_infra.py +17 -156
- {portacode-1.4.19.dist-info → portacode-1.4.19.dev0.dist-info}/METADATA +1 -1
- {portacode-1.4.19.dist-info → portacode-1.4.19.dev0.dist-info}/RECORD +9 -9
- {portacode-1.4.19.dist-info → portacode-1.4.19.dev0.dist-info}/WHEEL +0 -0
- {portacode-1.4.19.dist-info → portacode-1.4.19.dev0.dist-info}/entry_points.txt +0 -0
- {portacode-1.4.19.dist-info → portacode-1.4.19.dev0.dist-info}/licenses/LICENSE +0 -0
- {portacode-1.4.19.dist-info → portacode-1.4.19.dev0.dist-info}/top_level.txt +0 -0
portacode/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '1.4.19'
|
|
32
|
-
__version_tuple__ = version_tuple = (1, 4, 19)
|
|
31
|
+
__version__ = version = '1.4.19.dev0'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 4, 19, 'dev0')
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -380,7 +380,7 @@ Starts a previously provisioned, Portacode-managed LXC container. Handled by [`S
|
|
|
380
380
|
|
|
381
381
|
**Payload Fields:**
|
|
382
382
|
|
|
383
|
-
* `ctid` (string,
|
|
383
|
+
* `ctid` (string, required): Identifier of the container to start.
|
|
384
384
|
* `child_device_id` (string, required): Dashboard `Device.id` of the container that triggered the request; the handler validates the CT belongs to that device before issuing the start.
|
|
385
385
|
|
|
386
386
|
**Responses:**
|
|
@@ -394,7 +394,7 @@ Stops a running Portacode-managed container. Handled by [`StopProxmoxContainerHa
|
|
|
394
394
|
|
|
395
395
|
**Payload Fields:**
|
|
396
396
|
|
|
397
|
-
* `ctid` (string,
|
|
397
|
+
* `ctid` (string, required): Identifier of the container to stop.
|
|
398
398
|
* `child_device_id` (string, required): Dashboard `Device.id` that owns the container; the handler rejects the request if the CT is mapped to another device.
|
|
399
399
|
|
|
400
400
|
**Responses:**
|
|
@@ -408,13 +408,12 @@ Deletes a managed container from Proxmox (stopping it first if necessary) and re
|
|
|
408
408
|
|
|
409
409
|
**Payload Fields:**
|
|
410
410
|
|
|
411
|
-
* `ctid` (string, optional): Identifier of the container to delete. If omitted, the handler resolves the CTID from managed container records
|
|
411
|
+
* `ctid` (string, optional): Identifier of the container to delete. If omitted, the handler resolves the CTID from the managed container records using `child_device_id`.
|
|
412
412
|
* `child_device_id` (string, required): Dashboard `Device.id` that should own the container metadata being purged.
|
|
413
413
|
|
|
414
414
|
**Responses:**
|
|
415
415
|
|
|
416
416
|
* Emits a [`proxmox_container_action`](#proxmox_container_action-event) event with `action="remove"` and the refreshed infra snapshot after deletion.
|
|
417
|
-
* If no managed container matches the requested `child_device_id`, emits a `proxmox_container_action` event with `success=false`, `status="not_found"`, and a human-readable message (no error event).
|
|
418
417
|
* Emits an [`error`](#error) event on failure.
|
|
419
418
|
|
|
420
419
|
### `proxmox_container_created`
|
|
@@ -17,7 +17,6 @@ import sys
|
|
|
17
17
|
import tempfile
|
|
18
18
|
import time
|
|
19
19
|
import threading
|
|
20
|
-
import random
|
|
21
20
|
from datetime import datetime, timezone
|
|
22
21
|
from pathlib import Path
|
|
23
22
|
from typing import Any, Callable, Dict, Iterable, List, Optional, Sequence, Tuple
|
|
@@ -34,44 +33,6 @@ REPO_ROOT = Path(__file__).resolve().parents[3]
|
|
|
34
33
|
NET_SETUP_SCRIPT = REPO_ROOT / "proxmox_management" / "net_setup.py"
|
|
35
34
|
CONTAINERS_DIR = CONFIG_DIR / "containers"
|
|
36
35
|
MANAGED_MARKER = "portacode-managed:true"
|
|
37
|
-
DEVICE_ID_MARKER = "device_id="
|
|
38
|
-
PROVISIONING_ID_MARKER = "provisioning_id="
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def _sanitize_description_value(value: Any) -> str:
|
|
42
|
-
return str(value).strip().replace(";", "_")
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def _build_managed_description(
|
|
46
|
-
base: Optional[str],
|
|
47
|
-
*,
|
|
48
|
-
device_id: Optional[str] = None,
|
|
49
|
-
provisioning_id: Optional[str] = None,
|
|
50
|
-
) -> str:
|
|
51
|
-
parts = [part for part in (base or "").split(";") if part]
|
|
52
|
-
if MANAGED_MARKER not in parts:
|
|
53
|
-
parts.insert(0, MANAGED_MARKER)
|
|
54
|
-
if device_id:
|
|
55
|
-
device_id_value = _sanitize_description_value(device_id)
|
|
56
|
-
if not any(part.startswith(DEVICE_ID_MARKER) for part in parts):
|
|
57
|
-
parts.append(f"{DEVICE_ID_MARKER}{device_id_value}")
|
|
58
|
-
if provisioning_id:
|
|
59
|
-
provisioning_value = _sanitize_description_value(provisioning_id)
|
|
60
|
-
if not any(part.startswith(PROVISIONING_ID_MARKER) for part in parts):
|
|
61
|
-
parts.append(f"{PROVISIONING_ID_MARKER}{provisioning_value}")
|
|
62
|
-
return ";".join(parts)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def _extract_marker_value(description: str, prefix: str) -> Optional[str]:
|
|
66
|
-
for part in description.split(";"):
|
|
67
|
-
part = part.strip()
|
|
68
|
-
if part.startswith(prefix):
|
|
69
|
-
return part[len(prefix) :].strip()
|
|
70
|
-
return None
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def _parse_device_id_from_description(description: str) -> Optional[str]:
|
|
74
|
-
return _extract_marker_value(description, DEVICE_ID_MARKER)
|
|
75
36
|
|
|
76
37
|
DEFAULT_HOST = "localhost"
|
|
77
38
|
DEFAULT_NODE_NAME = os.uname().nodename.split(".", 1)[0]
|
|
@@ -1296,21 +1257,12 @@ def _validate_positive_number(value: Any, default: float) -> float:
|
|
|
1296
1257
|
|
|
1297
1258
|
|
|
1298
1259
|
def _wait_for_task(proxmox: Any, node: str, upid: str) -> Tuple[Dict[str, Any], float]:
|
|
1299
|
-
from proxmoxer.core import ResourceException
|
|
1300
1260
|
start = time.time()
|
|
1301
|
-
poll = 2.0
|
|
1302
1261
|
while True:
|
|
1303
|
-
|
|
1304
|
-
status = proxmox.nodes(node).tasks(upid).status.get()
|
|
1305
|
-
except ResourceException as e:
|
|
1306
|
-
if str(e).startswith("599 "):
|
|
1307
|
-
# transient proxy glitch; task may still be running
|
|
1308
|
-
time.sleep(poll + random.random() * 0.5) # small jitter
|
|
1309
|
-
continue
|
|
1310
|
-
raise
|
|
1262
|
+
status = proxmox.nodes(node).tasks(upid).status.get()
|
|
1311
1263
|
if status.get("status") == "stopped":
|
|
1312
1264
|
return status, time.time() - start
|
|
1313
|
-
time.sleep(
|
|
1265
|
+
time.sleep(1)
|
|
1314
1266
|
|
|
1315
1267
|
|
|
1316
1268
|
def _list_running_managed(proxmox: Any, node: str) -> List[Tuple[str, Dict[str, Any]]]:
|
|
@@ -1448,10 +1400,6 @@ def _parse_ctid(message: Dict[str, Any]) -> int:
|
|
|
1448
1400
|
raise ValueError("ctid is required")
|
|
1449
1401
|
|
|
1450
1402
|
|
|
1451
|
-
class _DeviceLookupError(ValueError):
|
|
1452
|
-
pass
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
1403
|
def _resolve_vmid_for_device(device_id: str) -> int:
|
|
1456
1404
|
_initialize_managed_containers_state()
|
|
1457
1405
|
records = list(_MANAGED_CONTAINERS_STATE.get("records", {}).values())
|
|
@@ -1468,77 +1416,21 @@ def _resolve_vmid_for_device(device_id: str) -> int:
|
|
|
1468
1416
|
return int(str(vmid).strip())
|
|
1469
1417
|
except ValueError:
|
|
1470
1418
|
raise ValueError("ctid must be an integer") from None
|
|
1471
|
-
raise
|
|
1472
|
-
f"No managed container record found for device_id {device_id!r}."
|
|
1473
|
-
)
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
def _resolve_vmid_for_device_in_proxmox(
|
|
1477
|
-
proxmox: Any, node: str, device_id: str
|
|
1478
|
-
) -> int:
|
|
1479
|
-
device_id_value = str(device_id).strip()
|
|
1480
|
-
matches: List[int] = []
|
|
1481
|
-
try:
|
|
1482
|
-
containers = proxmox.nodes(node).lxc.get()
|
|
1483
|
-
except Exception as exc: # pragma: no cover - proxmox failure
|
|
1484
|
-
raise _DeviceLookupError(
|
|
1485
|
-
f"Unable to query Proxmox containers for device_id {device_id_value!r}: {exc}"
|
|
1486
|
-
) from exc
|
|
1487
|
-
for entry in containers or []:
|
|
1488
|
-
vmid = entry.get("vmid")
|
|
1489
|
-
if vmid is None:
|
|
1490
|
-
continue
|
|
1491
|
-
try:
|
|
1492
|
-
cfg = proxmox.nodes(node).lxc(str(vmid)).config.get()
|
|
1493
|
-
except Exception:
|
|
1494
|
-
continue
|
|
1495
|
-
description = (cfg or {}).get("description") or ""
|
|
1496
|
-
if MANAGED_MARKER not in description:
|
|
1497
|
-
continue
|
|
1498
|
-
desc_device_id = _parse_device_id_from_description(description)
|
|
1499
|
-
if desc_device_id is None:
|
|
1500
|
-
continue
|
|
1501
|
-
if str(desc_device_id) != device_id_value:
|
|
1502
|
-
continue
|
|
1503
|
-
matches.append(int(str(vmid).strip()))
|
|
1504
|
-
if not matches:
|
|
1505
|
-
raise _DeviceLookupError(
|
|
1506
|
-
f"No managed container found for device_id {device_id_value!r}. It may already be deleted."
|
|
1507
|
-
)
|
|
1508
|
-
if len(matches) > 1:
|
|
1509
|
-
raise _DeviceLookupError(
|
|
1510
|
-
f"Multiple managed containers found for device_id {device_id_value!r}: {matches}."
|
|
1511
|
-
)
|
|
1512
|
-
return matches[0]
|
|
1419
|
+
raise ValueError("ctid is required for remove_proxmox_container")
|
|
1513
1420
|
|
|
1514
1421
|
|
|
1515
1422
|
def _ensure_container_managed(
|
|
1516
1423
|
proxmox: Any, node: str, vmid: int, *, device_id: Optional[str] = None
|
|
1517
1424
|
) -> Tuple[Dict[str, Any], Dict[str, Any]]:
|
|
1518
|
-
|
|
1519
|
-
record = _read_container_record(vmid)
|
|
1520
|
-
except FileNotFoundError:
|
|
1521
|
-
record = {}
|
|
1425
|
+
record = _read_container_record(vmid)
|
|
1522
1426
|
ct_cfg = proxmox.nodes(node).lxc(str(vmid)).config.get()
|
|
1523
|
-
|
|
1524
|
-
if not ct_cfg or MANAGED_MARKER not in description:
|
|
1427
|
+
if not ct_cfg or MANAGED_MARKER not in (ct_cfg.get("description") or ""):
|
|
1525
1428
|
raise RuntimeError(f"Container {vmid} is not managed by Portacode.")
|
|
1526
1429
|
record_device_id = record.get("device_id")
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
raise RuntimeError(
|
|
1532
|
-
f"Container {vmid} is managed for device {description_device_id!r}, not {device_id_value!r}."
|
|
1533
|
-
)
|
|
1534
|
-
if record_device_id and str(record_device_id) != device_id_value:
|
|
1535
|
-
raise RuntimeError(
|
|
1536
|
-
f"Container {vmid} is managed for device {record_device_id!r}, not {device_id_value!r}."
|
|
1537
|
-
)
|
|
1538
|
-
if not description_device_id and not record_device_id:
|
|
1539
|
-
raise RuntimeError(
|
|
1540
|
-
f"Container {vmid} is missing a device_id marker; refusing to operate without ctid."
|
|
1541
|
-
)
|
|
1430
|
+
if device_id and str(record_device_id or "") != str(device_id):
|
|
1431
|
+
raise RuntimeError(
|
|
1432
|
+
f"Container {vmid} is managed for device {record_device_id!r}, not {device_id!r}."
|
|
1433
|
+
)
|
|
1542
1434
|
return record, ct_cfg
|
|
1543
1435
|
|
|
1544
1436
|
|
|
@@ -2223,11 +2115,7 @@ class CreateProxmoxContainerHandler(SyncHandler):
|
|
|
2223
2115
|
payload, device_id=device_id, request_id=request_id
|
|
2224
2116
|
)
|
|
2225
2117
|
provisioning_id = secrets.token_hex(6)
|
|
2226
|
-
payload["description"] =
|
|
2227
|
-
payload.get("description"),
|
|
2228
|
-
device_id=device_id,
|
|
2229
|
-
provisioning_id=provisioning_id,
|
|
2230
|
-
)
|
|
2118
|
+
payload["description"] = f"{payload.get('description', MANAGED_MARKER)};provisioning_id={provisioning_id}"
|
|
2231
2119
|
|
|
2232
2120
|
def _provision_background() -> None:
|
|
2233
2121
|
nonlocal current_step_index
|
|
@@ -2617,19 +2505,13 @@ class StartProxmoxContainerHandler(SyncHandler):
|
|
|
2617
2505
|
return "start_proxmox_container"
|
|
2618
2506
|
|
|
2619
2507
|
def execute(self, message: Dict[str, Any]) -> Dict[str, Any]:
|
|
2508
|
+
vmid = _parse_ctid(message)
|
|
2620
2509
|
child_device_id = (message.get("child_device_id") or "").strip()
|
|
2621
2510
|
if not child_device_id:
|
|
2622
2511
|
raise ValueError("child_device_id is required for start_proxmox_container")
|
|
2623
2512
|
config = _ensure_infra_configured()
|
|
2624
2513
|
proxmox = _connect_proxmox(config)
|
|
2625
2514
|
node = _get_node_from_config(config)
|
|
2626
|
-
try:
|
|
2627
|
-
vmid = _parse_ctid(message)
|
|
2628
|
-
except ValueError:
|
|
2629
|
-
try:
|
|
2630
|
-
vmid = _resolve_vmid_for_device(child_device_id)
|
|
2631
|
-
except _DeviceLookupError:
|
|
2632
|
-
vmid = _resolve_vmid_for_device_in_proxmox(proxmox, node, child_device_id)
|
|
2633
2515
|
_ensure_container_managed(proxmox, node, vmid, device_id=child_device_id)
|
|
2634
2516
|
|
|
2635
2517
|
status, elapsed = _start_container(proxmox, node, vmid)
|
|
@@ -2656,19 +2538,13 @@ class StopProxmoxContainerHandler(SyncHandler):
|
|
|
2656
2538
|
return "stop_proxmox_container"
|
|
2657
2539
|
|
|
2658
2540
|
def execute(self, message: Dict[str, Any]) -> Dict[str, Any]:
|
|
2541
|
+
vmid = _parse_ctid(message)
|
|
2659
2542
|
child_device_id = (message.get("child_device_id") or "").strip()
|
|
2660
2543
|
if not child_device_id:
|
|
2661
2544
|
raise ValueError("child_device_id is required for stop_proxmox_container")
|
|
2662
2545
|
config = _ensure_infra_configured()
|
|
2663
2546
|
proxmox = _connect_proxmox(config)
|
|
2664
2547
|
node = _get_node_from_config(config)
|
|
2665
|
-
try:
|
|
2666
|
-
vmid = _parse_ctid(message)
|
|
2667
|
-
except ValueError:
|
|
2668
|
-
try:
|
|
2669
|
-
vmid = _resolve_vmid_for_device(child_device_id)
|
|
2670
|
-
except _DeviceLookupError:
|
|
2671
|
-
vmid = _resolve_vmid_for_device_in_proxmox(proxmox, node, child_device_id)
|
|
2672
2548
|
_ensure_container_managed(proxmox, node, vmid, device_id=child_device_id)
|
|
2673
2549
|
|
|
2674
2550
|
status, elapsed = _stop_container(proxmox, node, vmid)
|
|
@@ -2704,30 +2580,14 @@ class RemoveProxmoxContainerHandler(SyncHandler):
|
|
|
2704
2580
|
child_device_id = (message.get("child_device_id") or "").strip()
|
|
2705
2581
|
if not child_device_id:
|
|
2706
2582
|
raise ValueError("child_device_id is required for remove_proxmox_container")
|
|
2583
|
+
try:
|
|
2584
|
+
vmid = _parse_ctid(message)
|
|
2585
|
+
except ValueError:
|
|
2586
|
+
vmid = _resolve_vmid_for_device(child_device_id)
|
|
2707
2587
|
request_id = message.get("request_id")
|
|
2708
2588
|
config = _ensure_infra_configured()
|
|
2709
2589
|
proxmox = _connect_proxmox(config)
|
|
2710
2590
|
node = _get_node_from_config(config)
|
|
2711
|
-
try:
|
|
2712
|
-
vmid = _parse_ctid(message)
|
|
2713
|
-
except ValueError:
|
|
2714
|
-
try:
|
|
2715
|
-
vmid = _resolve_vmid_for_device(child_device_id)
|
|
2716
|
-
except _DeviceLookupError:
|
|
2717
|
-
try:
|
|
2718
|
-
vmid = _resolve_vmid_for_device_in_proxmox(proxmox, node, child_device_id)
|
|
2719
|
-
except _DeviceLookupError as exc:
|
|
2720
|
-
infra = get_infra_snapshot()
|
|
2721
|
-
return {
|
|
2722
|
-
"event": "proxmox_container_action",
|
|
2723
|
-
"action": "remove",
|
|
2724
|
-
"success": False,
|
|
2725
|
-
"message": str(exc),
|
|
2726
|
-
"status": "not_found",
|
|
2727
|
-
"child_device_id": child_device_id,
|
|
2728
|
-
"request_id": request_id,
|
|
2729
|
-
"infra": infra,
|
|
2730
|
-
}
|
|
2731
2591
|
_ensure_container_managed(proxmox, node, vmid, device_id=child_device_id)
|
|
2732
2592
|
|
|
2733
2593
|
stop_status, stop_elapsed = _stop_container(proxmox, node, vmid)
|
|
@@ -2747,6 +2607,7 @@ class RemoveProxmoxContainerHandler(SyncHandler):
|
|
|
2747
2607
|
},
|
|
2748
2608
|
"status": "deleted",
|
|
2749
2609
|
"child_device_id": child_device_id,
|
|
2610
|
+
"on_behalf_of_device": child_device_id,
|
|
2750
2611
|
"request_id": request_id,
|
|
2751
2612
|
"infra": infra,
|
|
2752
2613
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
portacode/README.md,sha256=4dKtpvR8LNgZPVz37GmkQCMWIr_u25Ao63iW56s7Ke4,775
|
|
2
2
|
portacode/__init__.py,sha256=oB3sV1wXr-um-RXio73UG8E5Xx6cF2ZVJveqjNmC-vQ,1086
|
|
3
3
|
portacode/__main__.py,sha256=jmHTGC1hzmo9iKJLv-SSYe9BSIbPPZ2IOpecI03PlTs,296
|
|
4
|
-
portacode/_version.py,sha256=
|
|
4
|
+
portacode/_version.py,sha256=Mg7-aZdTDXntrWHuweCpOdxOGlkCkhdNJGq-1P_CTYQ,719
|
|
5
5
|
portacode/cli.py,sha256=mGLKoZ-T2FBF7IA9wUq0zyG0X9__-A1ao7gajjcVRH8,21828
|
|
6
6
|
portacode/data.py,sha256=5-s291bv8J354myaHm1Y7CQZTZyRzMU3TGe5U4hb-FA,1591
|
|
7
7
|
portacode/keypair.py,sha256=0OO4vHDcF1XMxCDqce61xFTlFwlTcmqe5HyGsXFEt7s,5838
|
|
@@ -14,7 +14,7 @@ portacode/connection/client.py,sha256=jtLb9_YufqPkzi9t8VQH3iz_JEMisbtY6a8L9U5wei
|
|
|
14
14
|
portacode/connection/multiplex.py,sha256=L-TxqJ_ZEbfNEfu1cwxgJ5vUdyRzZjsMy2Kx1diiZys,5237
|
|
15
15
|
portacode/connection/terminal.py,sha256=n1Uu92JacV5K6d1Qwx94Tw9OB2Tpke5HqsW2NDn76Ls,49032
|
|
16
16
|
portacode/connection/handlers/README.md,sha256=HsLZG1QK1JNm67HsgL6WoDg9nxzKXxwkc5fJPFJdX5g,12169
|
|
17
|
-
portacode/connection/handlers/WEBSOCKET_PROTOCOL.md,sha256=
|
|
17
|
+
portacode/connection/handlers/WEBSOCKET_PROTOCOL.md,sha256=Btbt3UVUvXG5t2HB0_ani0eQNnUPUCLWaqlvCHTaWfo,103727
|
|
18
18
|
portacode/connection/handlers/__init__.py,sha256=WSeBmi65GWFQPYt9M3E10rn0uZ_EPCJzNJOzSf2HZyw,2921
|
|
19
19
|
portacode/connection/handlers/base.py,sha256=tMsKJmnNhXA3a4YZA55a0WO2e8-4Uh4BsG9lWAr3Ris,10829
|
|
20
20
|
portacode/connection/handlers/chunked_content.py,sha256=h6hXRmxSeOgnIxoU8CkmvEf2Odv-ajPrpHIe_W3GKcA,9251
|
|
@@ -22,7 +22,7 @@ portacode/connection/handlers/diff_handlers.py,sha256=iYTIRCcpEQ03vIPKZCsMTE5aZb
|
|
|
22
22
|
portacode/connection/handlers/file_handlers.py,sha256=nAJH8nXnX07xxD28ngLpgIUzcTuRwZBNpEGEKdRqohw,39507
|
|
23
23
|
portacode/connection/handlers/project_aware_file_handlers.py,sha256=AqgMnDqX2893T2NsrvUSCwjN5VKj4Pb2TN0S_SuboOE,9803
|
|
24
24
|
portacode/connection/handlers/project_state_handlers.py,sha256=v6ZefGW9i7n1aZLq2jOGumJIjYb6aHlPI4m1jkYewm8,1686
|
|
25
|
-
portacode/connection/handlers/proxmox_infra.py,sha256=
|
|
25
|
+
portacode/connection/handlers/proxmox_infra.py,sha256=rO7y9TGC2_u5Qazi3ukiXhiA0-nC_Gyi_FuXJSvVX80,100875
|
|
26
26
|
portacode/connection/handlers/registry.py,sha256=elISoWpIXapMuY28x1hzXV-uErtAklsFzMb8yVgp7NU,6456
|
|
27
27
|
portacode/connection/handlers/session.py,sha256=uNGfiO_1B9-_yjJKkpvmbiJhIl6b-UXlT86UTfd6WYE,42219
|
|
28
28
|
portacode/connection/handlers/system_handlers.py,sha256=fr12QpOr_Z8KYGUU-AYrTQwRPAcrLK85hvj3SEq1Kw8,14757
|
|
@@ -65,7 +65,7 @@ portacode/utils/__init__.py,sha256=NgBlWTuNJESfIYJzP_3adI1yJQJR0XJLRpSdVNaBAN0,3
|
|
|
65
65
|
portacode/utils/diff_apply.py,sha256=4Oi7ft3VUCKmiUE4VM-OeqO7Gk6H7PF3WnN4WHXtjxI,15157
|
|
66
66
|
portacode/utils/diff_renderer.py,sha256=S76StnQ2DLfsz4Gg0m07UwPfRp8270PuzbNaQq-rmYk,13850
|
|
67
67
|
portacode/utils/ntp_clock.py,sha256=VqCnWCTehCufE43W23oB-WUdAZGeCcLxkmIOPwInYHc,2499
|
|
68
|
-
portacode-1.4.19.dist-info/licenses/LICENSE,sha256=2FGbCnUDgRYuQTkB1O1dUUpu5CVAjK1j4_p6ack9Z54,1066
|
|
68
|
+
portacode-1.4.19.dev0.dist-info/licenses/LICENSE,sha256=2FGbCnUDgRYuQTkB1O1dUUpu5CVAjK1j4_p6ack9Z54,1066
|
|
69
69
|
test_modules/README.md,sha256=Do_agkm9WhSzueXjRAkV_xEj6Emy5zB3N3VKY5Roce8,9274
|
|
70
70
|
test_modules/__init__.py,sha256=1LcbHodIHsB0g-g4NGjSn6AMuCoGbymvXPYLOb6Z7F0,53
|
|
71
71
|
test_modules/test_device_online.py,sha256=QtYq0Dq9vME8Gp2O4fGSheqVf8LUtpsSKosXXk56gGM,1654
|
|
@@ -91,8 +91,8 @@ testing_framework/core/playwright_manager.py,sha256=Tw46qwxIhOFkS48C2IWIQHHNpEe-
|
|
|
91
91
|
testing_framework/core/runner.py,sha256=j2QwNJmAxVBmJvcbVS7DgPJUKPNzqfLmt_4NNdaKmZU,19297
|
|
92
92
|
testing_framework/core/shared_cli_manager.py,sha256=BESSNtyQb7BOlaOvZmm04T8Uezjms4KCBs2MzTxvzYQ,8790
|
|
93
93
|
testing_framework/core/test_discovery.py,sha256=2FZ9fJ8Dp5dloA-fkgXoJ_gCMC_nYPBnA3Hs2xlagzM,4928
|
|
94
|
-
portacode-1.4.19.dist-info/METADATA,sha256=
|
|
95
|
-
portacode-1.4.19.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
96
|
-
portacode-1.4.19.dist-info/entry_points.txt,sha256=lLUUL-BM6_wwe44Xv0__5NQ1BnAz6jWjSMFvZdWW3zU,48
|
|
97
|
-
portacode-1.4.19.dist-info/top_level.txt,sha256=TGhTYUxfW8SyVZc_zGgzjzc24gGT7nSw8Qf73liVRKM,41
|
|
98
|
-
portacode-1.4.19.dist-info/RECORD,,
|
|
94
|
+
portacode-1.4.19.dev0.dist-info/METADATA,sha256=Wb-KIopzQn0baUy96Wah9IBrH12vzbNys9K0qkastxw,13051
|
|
95
|
+
portacode-1.4.19.dev0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
96
|
+
portacode-1.4.19.dev0.dist-info/entry_points.txt,sha256=lLUUL-BM6_wwe44Xv0__5NQ1BnAz6jWjSMFvZdWW3zU,48
|
|
97
|
+
portacode-1.4.19.dev0.dist-info/top_level.txt,sha256=TGhTYUxfW8SyVZc_zGgzjzc24gGT7nSw8Qf73liVRKM,41
|
|
98
|
+
portacode-1.4.19.dev0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|