portacode 1.4.15.dev8__py3-none-any.whl → 1.4.15.dev9__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 +130 -33
- {portacode-1.4.15.dev8.dist-info → portacode-1.4.15.dev9.dist-info}/METADATA +1 -1
- {portacode-1.4.15.dev8.dist-info → portacode-1.4.15.dev9.dist-info}/RECORD +8 -8
- {portacode-1.4.15.dev8.dist-info → portacode-1.4.15.dev9.dist-info}/WHEEL +0 -0
- {portacode-1.4.15.dev8.dist-info → portacode-1.4.15.dev9.dist-info}/entry_points.txt +0 -0
- {portacode-1.4.15.dev8.dist-info → portacode-1.4.15.dev9.dist-info}/licenses/LICENSE +0 -0
- {portacode-1.4.15.dev8.dist-info → portacode-1.4.15.dev9.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.15.
|
|
32
|
-
__version_tuple__ = version_tuple = (1, 4, 15, '
|
|
31
|
+
__version__ = version = '1.4.15.dev9'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 4, 15, 'dev9')
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -504,48 +504,119 @@ def _friendly_step_label(step_name: str) -> str:
|
|
|
504
504
|
return normalized.capitalize()
|
|
505
505
|
|
|
506
506
|
|
|
507
|
+
_PACKAGE_MANAGER_PROFILES: Dict[str, Dict[str, Any]] = {
|
|
508
|
+
"apt": {
|
|
509
|
+
"update_cmd": "apt-get update -y",
|
|
510
|
+
"update_step_name": "apt_update",
|
|
511
|
+
"install_cmd": "apt-get install -y python3 python3-pip sudo --fix-missing",
|
|
512
|
+
"install_step_name": "install_deps",
|
|
513
|
+
"update_retries": 4,
|
|
514
|
+
"install_retries": 5,
|
|
515
|
+
},
|
|
516
|
+
"dnf": {
|
|
517
|
+
"update_cmd": "dnf check-update || true",
|
|
518
|
+
"update_step_name": "dnf_update",
|
|
519
|
+
"install_cmd": "dnf install -y python3 python3-pip sudo",
|
|
520
|
+
"install_step_name": "install_deps",
|
|
521
|
+
"update_retries": 3,
|
|
522
|
+
"install_retries": 5,
|
|
523
|
+
},
|
|
524
|
+
"yum": {
|
|
525
|
+
"update_cmd": "yum makecache",
|
|
526
|
+
"update_step_name": "yum_update",
|
|
527
|
+
"install_cmd": "yum install -y python3 python3-pip sudo",
|
|
528
|
+
"install_step_name": "install_deps",
|
|
529
|
+
"update_retries": 3,
|
|
530
|
+
"install_retries": 5,
|
|
531
|
+
},
|
|
532
|
+
"apk": {
|
|
533
|
+
"update_cmd": "apk update",
|
|
534
|
+
"update_step_name": "apk_update",
|
|
535
|
+
"install_cmd": "apk add --no-cache python3 py3-pip sudo",
|
|
536
|
+
"install_step_name": "install_deps",
|
|
537
|
+
"update_retries": 3,
|
|
538
|
+
"install_retries": 5,
|
|
539
|
+
},
|
|
540
|
+
"pacman": {
|
|
541
|
+
"update_cmd": "pacman -Sy --noconfirm",
|
|
542
|
+
"update_step_name": "pacman_update",
|
|
543
|
+
"install_cmd": "pacman -S --noconfirm python python-pip sudo",
|
|
544
|
+
"install_step_name": "install_deps",
|
|
545
|
+
"update_retries": 3,
|
|
546
|
+
"install_retries": 5,
|
|
547
|
+
},
|
|
548
|
+
"zypper": {
|
|
549
|
+
"update_cmd": "zypper refresh",
|
|
550
|
+
"update_step_name": "zypper_update",
|
|
551
|
+
"install_cmd": "zypper install -y python3 python3-pip sudo",
|
|
552
|
+
"install_step_name": "install_deps",
|
|
553
|
+
"update_retries": 3,
|
|
554
|
+
"install_retries": 5,
|
|
555
|
+
},
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
_UPDATE_RETRY_ON = [
|
|
559
|
+
"Temporary failure resolving",
|
|
560
|
+
"Could not resolve",
|
|
561
|
+
"Failed to fetch",
|
|
562
|
+
]
|
|
563
|
+
|
|
564
|
+
_INSTALL_RETRY_ON = [
|
|
565
|
+
"lock-frontend",
|
|
566
|
+
"Unable to acquire the dpkg frontend lock",
|
|
567
|
+
"Temporary failure resolving",
|
|
568
|
+
"Could not resolve",
|
|
569
|
+
"Failed to fetch",
|
|
570
|
+
]
|
|
571
|
+
|
|
572
|
+
|
|
507
573
|
def _build_bootstrap_steps(
|
|
508
574
|
user: str,
|
|
509
575
|
password: str,
|
|
510
576
|
ssh_key: str,
|
|
511
577
|
include_portacode_connect: bool = True,
|
|
578
|
+
package_manager: str = "apt",
|
|
512
579
|
) -> List[Dict[str, Any]]:
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
"
|
|
521
|
-
"
|
|
522
|
-
"
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
"
|
|
532
|
-
"
|
|
533
|
-
"
|
|
534
|
-
"
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
580
|
+
profile = _PACKAGE_MANAGER_PROFILES.get(package_manager, _PACKAGE_MANAGER_PROFILES["apt"])
|
|
581
|
+
steps: List[Dict[str, Any]] = []
|
|
582
|
+
update_cmd = profile.get("update_cmd")
|
|
583
|
+
if update_cmd:
|
|
584
|
+
steps.append(
|
|
585
|
+
{
|
|
586
|
+
"name": profile.get("update_step_name", "package_update"),
|
|
587
|
+
"cmd": update_cmd,
|
|
588
|
+
"retries": profile.get("update_retries", 3),
|
|
589
|
+
"retry_delay_s": 5,
|
|
590
|
+
"retry_on": _UPDATE_RETRY_ON,
|
|
591
|
+
}
|
|
592
|
+
)
|
|
593
|
+
install_cmd = profile.get("install_cmd")
|
|
594
|
+
if install_cmd:
|
|
595
|
+
steps.append(
|
|
596
|
+
{
|
|
597
|
+
"name": profile.get("install_step_name", "install_deps"),
|
|
598
|
+
"cmd": install_cmd,
|
|
599
|
+
"retries": profile.get("install_retries", 5),
|
|
600
|
+
"retry_delay_s": 5,
|
|
601
|
+
"retry_on": _INSTALL_RETRY_ON,
|
|
602
|
+
}
|
|
603
|
+
)
|
|
604
|
+
steps.extend(
|
|
605
|
+
[
|
|
606
|
+
{"name": "user_exists", "cmd": f"id -u {user} >/dev/null 2>&1 || adduser --disabled-password --gecos '' {user}", "retries": 0},
|
|
607
|
+
{"name": "add_sudo", "cmd": f"usermod -aG sudo {user}", "retries": 0},
|
|
608
|
+
]
|
|
609
|
+
)
|
|
541
610
|
if password:
|
|
542
611
|
steps.append({"name": "set_password", "cmd": f"echo '{user}:{password}' | chpasswd", "retries": 0})
|
|
543
612
|
if ssh_key:
|
|
544
|
-
steps.append(
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
613
|
+
steps.append(
|
|
614
|
+
{
|
|
615
|
+
"name": "add_ssh_key",
|
|
616
|
+
"cmd": f"install -d -m 700 /home/{user}/.ssh && echo '{ssh_key}' >> /home/{user}/.ssh/authorized_keys && chown -R {user}:{user} /home/{user}/.ssh",
|
|
617
|
+
"retries": 0,
|
|
618
|
+
}
|
|
619
|
+
)
|
|
549
620
|
steps.extend(
|
|
550
621
|
[
|
|
551
622
|
{"name": "pip_upgrade", "cmd": "python3 -m pip install --upgrade pip", "retries": 0},
|
|
@@ -557,6 +628,27 @@ def _build_bootstrap_steps(
|
|
|
557
628
|
return steps
|
|
558
629
|
|
|
559
630
|
|
|
631
|
+
def _guess_package_manager_from_template(template: str) -> str:
|
|
632
|
+
normalized = (template or "").lower()
|
|
633
|
+
if "alpine" in normalized:
|
|
634
|
+
return "apk"
|
|
635
|
+
if "archlinux" in normalized:
|
|
636
|
+
return "pacman"
|
|
637
|
+
if "centos-7" in normalized:
|
|
638
|
+
return "yum"
|
|
639
|
+
if any(keyword in normalized for keyword in ("centos-8", "centos-9", "centos-9-stream", "centos-8-stream")):
|
|
640
|
+
return "dnf"
|
|
641
|
+
if any(keyword in normalized for keyword in ("rockylinux", "almalinux", "fedora")):
|
|
642
|
+
return "dnf"
|
|
643
|
+
if "opensuse" in normalized or "suse" in normalized:
|
|
644
|
+
return "zypper"
|
|
645
|
+
if any(keyword in normalized for keyword in ("debian", "ubuntu", "devuan", "turnkeylinux")):
|
|
646
|
+
return "apt"
|
|
647
|
+
if normalized.startswith("system/") and "linux" in normalized:
|
|
648
|
+
return "apt"
|
|
649
|
+
return "apt"
|
|
650
|
+
|
|
651
|
+
|
|
560
652
|
def _get_storage_type(storages: Iterable[Dict[str, Any]], storage_name: str) -> str:
|
|
561
653
|
for entry in storages:
|
|
562
654
|
if entry.get("storage") == storage_name:
|
|
@@ -1221,12 +1313,17 @@ class CreateProxmoxContainerHandler(SyncHandler):
|
|
|
1221
1313
|
device_public_key = (message.get("device_public_key") or "").strip()
|
|
1222
1314
|
device_private_key = (message.get("device_private_key") or "").strip()
|
|
1223
1315
|
has_device_keypair = bool(device_public_key and device_private_key)
|
|
1316
|
+
config_guess = _load_config()
|
|
1317
|
+
template_candidates = _get_startup_templates(config_guess)
|
|
1318
|
+
template_hint = (message.get("template") or (template_candidates[0] if template_candidates else "")).strip()
|
|
1319
|
+
package_manager = _guess_package_manager_from_template(template_hint)
|
|
1224
1320
|
bootstrap_user, bootstrap_password, bootstrap_ssh_key = _get_provisioning_user_info(message)
|
|
1225
1321
|
bootstrap_steps = _build_bootstrap_steps(
|
|
1226
1322
|
bootstrap_user,
|
|
1227
1323
|
bootstrap_password,
|
|
1228
1324
|
bootstrap_ssh_key,
|
|
1229
1325
|
include_portacode_connect=not has_device_keypair,
|
|
1326
|
+
package_manager=package_manager,
|
|
1230
1327
|
)
|
|
1231
1328
|
total_steps = 3 + len(bootstrap_steps) + 2
|
|
1232
1329
|
current_step_index = 1
|
|
@@ -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=YbH9Im7cDkYWkWFiH-JGJ5BzJGjRVMg1TyCC8DAh1fE,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
|
|
@@ -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=g3AXQ_SQ5-WDH0ixDMtowqPtod6ruTrPd7_6FkMp1ts,68206
|
|
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.15.
|
|
68
|
+
portacode-1.4.15.dev9.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.15.
|
|
95
|
-
portacode-1.4.15.
|
|
96
|
-
portacode-1.4.15.
|
|
97
|
-
portacode-1.4.15.
|
|
98
|
-
portacode-1.4.15.
|
|
94
|
+
portacode-1.4.15.dev9.dist-info/METADATA,sha256=6lnCia50lWblHLbiGKsxzaOVohX8yzayZgrAB8Hz-CY,13051
|
|
95
|
+
portacode-1.4.15.dev9.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
96
|
+
portacode-1.4.15.dev9.dist-info/entry_points.txt,sha256=lLUUL-BM6_wwe44Xv0__5NQ1BnAz6jWjSMFvZdWW3zU,48
|
|
97
|
+
portacode-1.4.15.dev9.dist-info/top_level.txt,sha256=TGhTYUxfW8SyVZc_zGgzjzc24gGT7nSw8Qf73liVRKM,41
|
|
98
|
+
portacode-1.4.15.dev9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|