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 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.dev9'
32
- __version_tuple__ = version_tuple = (1, 4, 16, 'dev9')
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 _extract_storage(value: Any) -> str:
263
- if not value:
264
- return "unknown"
265
- text = str(value).strip()
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"), cfg.get("disk")):
403
- if candidate in (None, 0):
405
+ for candidate in (entry.get("maxdisk"), entry.get("disk")):
406
+ if candidate in {None, 0}:
404
407
  continue
405
- return _bytes_to_gib(candidate)
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 = disk_gib_override if disk_gib_override is not None else _pick_disk_gib(entry_type, cfg, ct)
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 = storage_override or _pick_storage(entry_type, cfg, ct)
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 False
722
- storage = _extract_storage(storage_name)
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: portacode
3
- Version: 1.4.16.dev9
3
+ Version: 1.4.16.dev10
4
4
  Summary: Portacode CLI client and SDK
5
5
  Home-page: https://github.com/portacode/portacode
6
6
  Author: Meena Erian
@@ -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=MiVkLaI5JqUCo1IS8Z-ZuJxS2iDsMOn2RV8qQYxQ5kE,719
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=CcPTFTM5TMJ9uX4-Ndrfao6Xx_8zdMMPlvze08SHWgU,88344
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.dev9.dist-info/licenses/LICENSE,sha256=2FGbCnUDgRYuQTkB1O1dUUpu5CVAjK1j4_p6ack9Z54,1066
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.dev9.dist-info/METADATA,sha256=IwtVePxyAtqCsSSOTisxusWv8gBIvL1DSCoT96cNDj0,13051
95
- portacode-1.4.16.dev9.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
96
- portacode-1.4.16.dev9.dist-info/entry_points.txt,sha256=lLUUL-BM6_wwe44Xv0__5NQ1BnAz6jWjSMFvZdWW3zU,48
97
- portacode-1.4.16.dev9.dist-info/top_level.txt,sha256=TGhTYUxfW8SyVZc_zGgzjzc24gGT7nSw8Qf73liVRKM,41
98
- portacode-1.4.16.dev9.dist-info/RECORD,,
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,,