portacode 1.4.16.dev9__py3-none-any.whl → 1.4.16.dev10__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/proxmox_infra.py +32 -85
- {portacode-1.4.16.dev9.dist-info → portacode-1.4.16.dev10.dist-info}/METADATA +1 -1
- {portacode-1.4.16.dev9.dist-info → portacode-1.4.16.dev10.dist-info}/RECORD +8 -8
- {portacode-1.4.16.dev9.dist-info → portacode-1.4.16.dev10.dist-info}/WHEEL +0 -0
- {portacode-1.4.16.dev9.dist-info → portacode-1.4.16.dev10.dist-info}/entry_points.txt +0 -0
- {portacode-1.4.16.dev9.dist-info → portacode-1.4.16.dev10.dist-info}/licenses/LICENSE +0 -0
- {portacode-1.4.16.dev9.dist-info → portacode-1.4.16.dev10.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.16.
|
|
32
|
-
__version_tuple__ = version_tuple = (1, 4, 16, '
|
|
31
|
+
__version__ = version = '1.4.16.dev10'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 4, 16, 'dev10')
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -259,16 +259,10 @@ def _bytes_to_gib(value: Any) -> int:
|
|
|
259
259
|
return int(round(_normalize_bytes(value) / (1024**3)))
|
|
260
260
|
|
|
261
261
|
|
|
262
|
-
def
|
|
263
|
-
if not
|
|
264
|
-
return "
|
|
265
|
-
|
|
266
|
-
if not text:
|
|
267
|
-
return "unknown"
|
|
268
|
-
primary = text.split(",", 1)[0]
|
|
269
|
-
storage = primary.split(":", 1)[0].strip()
|
|
270
|
-
return storage or "unknown"
|
|
271
|
-
|
|
262
|
+
def _normalize_storage_name(name: Any) -> str:
|
|
263
|
+
if not name:
|
|
264
|
+
return ""
|
|
265
|
+
return str(name).strip().lower()
|
|
272
266
|
|
|
273
267
|
def _size_token_to_gib(token: str) -> float:
|
|
274
268
|
match = re.match(r"^\s*([0-9]+(?:\.[0-9]+)?)\s*([KMGTP])?([iI]?[bB])?\s*$", token)
|
|
@@ -278,11 +272,11 @@ def _size_token_to_gib(token: str) -> float:
|
|
|
278
272
|
unit = (match.group(2) or "").upper()
|
|
279
273
|
scale = {
|
|
280
274
|
"": 1,
|
|
281
|
-
"K": 1024**1,
|
|
282
|
-
"M": 1024**2,
|
|
283
|
-
"G": 1024**3,
|
|
284
|
-
"T": 1024**4,
|
|
285
|
-
"P": 1024**5,
|
|
275
|
+
"K": 1024 ** 1,
|
|
276
|
+
"M": 1024 ** 2,
|
|
277
|
+
"G": 1024 ** 3,
|
|
278
|
+
"T": 1024 ** 4,
|
|
279
|
+
"P": 1024 ** 5,
|
|
286
280
|
}.get(unit, 1)
|
|
287
281
|
return (number * scale) / 1024**3
|
|
288
282
|
|
|
@@ -298,6 +292,15 @@ def _extract_size_gib(value: Any) -> float:
|
|
|
298
292
|
return _size_token_to_gib(text)
|
|
299
293
|
|
|
300
294
|
|
|
295
|
+
def _extract_storage(value: Any) -> str:
|
|
296
|
+
if not value:
|
|
297
|
+
return "unknown"
|
|
298
|
+
text = str(value)
|
|
299
|
+
if ":" in text:
|
|
300
|
+
return text.split(":", 1)[0].strip() or "unknown"
|
|
301
|
+
return text.strip() or "unknown"
|
|
302
|
+
|
|
303
|
+
|
|
301
304
|
def _storage_from_lxc(cfg: Dict[str, Any], entry: Dict[str, Any]) -> str:
|
|
302
305
|
rootfs = cfg.get("rootfs") or entry.get("rootfs")
|
|
303
306
|
storage = _extract_storage(rootfs)
|
|
@@ -312,10 +315,10 @@ def _storage_from_lxc(cfg: Dict[str, Any], entry: Dict[str, Any]) -> str:
|
|
|
312
315
|
|
|
313
316
|
|
|
314
317
|
def _storage_from_qemu(cfg: Dict[str, Any]) -> str:
|
|
315
|
-
preferred_keys = []
|
|
318
|
+
preferred_keys: List[str] = []
|
|
316
319
|
for prefix in ("scsi", "virtio", "sata", "ide"):
|
|
317
320
|
preferred_keys.extend(f"{prefix}{idx}" for idx in range(0, 6))
|
|
318
|
-
seen = set()
|
|
321
|
+
seen: Set[str] = set()
|
|
319
322
|
for key in preferred_keys:
|
|
320
323
|
value = cfg.get(key)
|
|
321
324
|
if value is None:
|
|
@@ -353,10 +356,10 @@ def _primary_lxc_disk(cfg: Dict[str, Any], entry: Dict[str, Any]) -> str:
|
|
|
353
356
|
|
|
354
357
|
|
|
355
358
|
def _primary_qemu_disk(cfg: Dict[str, Any]) -> str:
|
|
356
|
-
preferred_keys = []
|
|
359
|
+
preferred_keys: List[str] = []
|
|
357
360
|
for prefix in ("scsi", "virtio", "sata", "ide"):
|
|
358
361
|
preferred_keys.extend(f"{prefix}{idx}" for idx in range(0, 6))
|
|
359
|
-
seen = set()
|
|
362
|
+
seen: Set[str] = set()
|
|
360
363
|
for key in preferred_keys:
|
|
361
364
|
value = cfg.get(key)
|
|
362
365
|
if value is None:
|
|
@@ -399,19 +402,16 @@ def _pick_disk_gib(kind: str, cfg: Dict[str, Any], entry: Dict[str, Any]) -> flo
|
|
|
399
402
|
size = _extract_size_gib(_primary_qemu_disk(cfg))
|
|
400
403
|
if size:
|
|
401
404
|
return size
|
|
402
|
-
for candidate in (entry.get("maxdisk"), entry.get("disk")
|
|
403
|
-
if candidate in
|
|
405
|
+
for candidate in (entry.get("maxdisk"), entry.get("disk")):
|
|
406
|
+
if candidate in {None, 0}:
|
|
404
407
|
continue
|
|
405
|
-
return
|
|
408
|
+
return _normalize_bytes(candidate) / 1024**3
|
|
409
|
+
cfg_disk = cfg.get("disk")
|
|
410
|
+
if cfg_disk not in (None, 0):
|
|
411
|
+
return _normalize_bytes(cfg_disk) / 1024**3
|
|
406
412
|
return 0.0
|
|
407
413
|
|
|
408
414
|
|
|
409
|
-
def _normalize_storage_name(name: Any) -> str:
|
|
410
|
-
if not name:
|
|
411
|
-
return ""
|
|
412
|
-
return str(name).strip().lower()
|
|
413
|
-
|
|
414
|
-
|
|
415
415
|
def _parse_bool_flag(value: Any) -> bool:
|
|
416
416
|
if isinstance(value, bool):
|
|
417
417
|
return value
|
|
@@ -611,43 +611,16 @@ def _extract_host_totals(node_status: Dict[str, Any] | None) -> Tuple[Optional[i
|
|
|
611
611
|
return host_ram, host_disk, host_cpu
|
|
612
612
|
|
|
613
613
|
|
|
614
|
-
def _parse_disk_reference(value: Any) -> Tuple[str | None, int]:
|
|
615
|
-
if not value:
|
|
616
|
-
return None, 0
|
|
617
|
-
text = str(value)
|
|
618
|
-
primary = text.split(",", 1)[0]
|
|
619
|
-
if ":" not in primary:
|
|
620
|
-
return primary.strip() or None, 0
|
|
621
|
-
storage_name, size_part = primary.split(":", 1)
|
|
622
|
-
storage_name = storage_name.strip() or None
|
|
623
|
-
size_text = size_part.strip()
|
|
624
|
-
if not size_text:
|
|
625
|
-
return storage_name, 0
|
|
626
|
-
unit = size_text[-1].upper()
|
|
627
|
-
number = size_text[:-1] if unit in {"G", "M"} else size_text
|
|
628
|
-
try:
|
|
629
|
-
value_num = float(number)
|
|
630
|
-
except ValueError:
|
|
631
|
-
return storage_name, 0
|
|
632
|
-
if unit == "M":
|
|
633
|
-
gib = value_num / 1024.0
|
|
634
|
-
else:
|
|
635
|
-
gib = value_num
|
|
636
|
-
return storage_name, int(round(gib))
|
|
637
|
-
|
|
638
|
-
|
|
639
614
|
def _build_unmanaged_container_entry(
|
|
640
615
|
ct: Dict[str, Any],
|
|
641
616
|
cfg: Dict[str, Any],
|
|
642
617
|
vmid: str,
|
|
643
618
|
default_storage: str | None,
|
|
644
619
|
*,
|
|
645
|
-
disk_gib_override: int | None = None,
|
|
646
|
-
storage_override: str | None = None,
|
|
647
620
|
entry_type: str = "lxc",
|
|
648
621
|
) -> Dict[str, Any]:
|
|
649
622
|
ram_mib = _to_int(cfg.get("memory")) or _bytes_to_mib(ct.get("maxmem"))
|
|
650
|
-
disk_gib =
|
|
623
|
+
disk_gib = int(round(_pick_disk_gib(entry_type, cfg, ct)))
|
|
651
624
|
cpu_share = _to_float(
|
|
652
625
|
cfg.get("cpulimit")
|
|
653
626
|
or cfg.get("cpus")
|
|
@@ -656,7 +629,7 @@ def _build_unmanaged_container_entry(
|
|
|
656
629
|
or ct.get("cpu")
|
|
657
630
|
)
|
|
658
631
|
hostname = ct.get("name") or cfg.get("hostname") or f"ct{vmid}"
|
|
659
|
-
storage =
|
|
632
|
+
storage = _pick_storage(entry_type, cfg, ct)
|
|
660
633
|
status = (ct.get("status") or "unknown").lower()
|
|
661
634
|
reserved = _parse_bool_flag(cfg.get("onboot"))
|
|
662
635
|
storage_matches_default = _storage_matches_default(storage, default_storage)
|
|
@@ -695,33 +668,10 @@ def _get_storage_snapshot(proxmox: Any, node: str, storage_name: str | None) ->
|
|
|
695
668
|
}
|
|
696
669
|
|
|
697
670
|
|
|
698
|
-
def _extract_qemu_disk_info(cfg: Dict[str, Any]) -> Tuple[str | None, int]:
|
|
699
|
-
disk_keys = sorted(
|
|
700
|
-
key
|
|
701
|
-
for key in cfg.keys()
|
|
702
|
-
if (
|
|
703
|
-
key.startswith("ide")
|
|
704
|
-
or key.startswith("sata")
|
|
705
|
-
or key.startswith("scsi")
|
|
706
|
-
or key.startswith("virtio")
|
|
707
|
-
or key.startswith("efidisk")
|
|
708
|
-
or key.startswith("raid")
|
|
709
|
-
)
|
|
710
|
-
and cfg.get(key)
|
|
711
|
-
)
|
|
712
|
-
for key in disk_keys:
|
|
713
|
-
storage_name, size_gib = _parse_disk_reference(cfg.get(key))
|
|
714
|
-
if storage_name or size_gib:
|
|
715
|
-
return storage_name, size_gib
|
|
716
|
-
return None, 0
|
|
717
|
-
|
|
718
|
-
|
|
719
671
|
def _storage_matches_default(storage_name: Any, default_storage: str | None) -> bool:
|
|
720
672
|
if not default_storage:
|
|
721
|
-
return
|
|
722
|
-
|
|
723
|
-
default = str(default_storage).strip()
|
|
724
|
-
return storage.lower() == default.lower()
|
|
673
|
+
return True
|
|
674
|
+
return _normalize_storage_name(storage_name) == _normalize_storage_name(default_storage)
|
|
725
675
|
|
|
726
676
|
|
|
727
677
|
def _build_managed_containers_summary(
|
|
@@ -864,15 +814,12 @@ def _get_managed_containers_summary(force: bool = False) -> Dict[str, Any]:
|
|
|
864
814
|
description = (cfg.get("description") or "")
|
|
865
815
|
if MANAGED_MARKER in description:
|
|
866
816
|
continue
|
|
867
|
-
storage_name, disk_gib_override = _extract_qemu_disk_info(cfg)
|
|
868
817
|
unmanaged.append(
|
|
869
818
|
_build_unmanaged_container_entry(
|
|
870
819
|
vm,
|
|
871
820
|
cfg,
|
|
872
821
|
vmid_key,
|
|
873
822
|
default_storage,
|
|
874
|
-
disk_gib_override=disk_gib_override,
|
|
875
|
-
storage_override=storage_name,
|
|
876
823
|
entry_type="qemu",
|
|
877
824
|
)
|
|
878
825
|
)
|
|
@@ -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=xQIvOHyr77yXKzNXQJL1rE01nrJdvUnM7LX3jaSU684,721
|
|
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
|
|
@@ -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=5XUUzr24bs-QOMpuVPq071ZDAmhadKiMs2E-wO62kMw,86709
|
|
26
26
|
portacode/connection/handlers/registry.py,sha256=qXGE60sYEWg6ZtVQzFcZ5YI2XWR6lMgw4hAL9x5qR1I,6181
|
|
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.16.
|
|
68
|
+
portacode-1.4.16.dev10.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.16.
|
|
95
|
-
portacode-1.4.16.
|
|
96
|
-
portacode-1.4.16.
|
|
97
|
-
portacode-1.4.16.
|
|
98
|
-
portacode-1.4.16.
|
|
94
|
+
portacode-1.4.16.dev10.dist-info/METADATA,sha256=CYVCSXxYLiRseul0OVvOLRWWp2-Lv1u737bm-qT1hVk,13052
|
|
95
|
+
portacode-1.4.16.dev10.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
96
|
+
portacode-1.4.16.dev10.dist-info/entry_points.txt,sha256=lLUUL-BM6_wwe44Xv0__5NQ1BnAz6jWjSMFvZdWW3zU,48
|
|
97
|
+
portacode-1.4.16.dev10.dist-info/top_level.txt,sha256=TGhTYUxfW8SyVZc_zGgzjzc24gGT7nSw8Qf73liVRKM,41
|
|
98
|
+
portacode-1.4.16.dev10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|