portacode 1.4.15.dev9__py3-none-any.whl → 1.4.15.dev11__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 +15 -47
- {portacode-1.4.15.dev9.dist-info → portacode-1.4.15.dev11.dist-info}/METADATA +1 -1
- {portacode-1.4.15.dev9.dist-info → portacode-1.4.15.dev11.dist-info}/RECORD +8 -8
- {portacode-1.4.15.dev9.dist-info → portacode-1.4.15.dev11.dist-info}/WHEEL +0 -0
- {portacode-1.4.15.dev9.dist-info → portacode-1.4.15.dev11.dist-info}/entry_points.txt +0 -0
- {portacode-1.4.15.dev9.dist-info → portacode-1.4.15.dev11.dist-info}/licenses/LICENSE +0 -0
- {portacode-1.4.15.dev9.dist-info → portacode-1.4.15.dev11.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.dev11'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 4, 15, 'dev11')
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -47,9 +47,7 @@ UNIT_DIR = Path("/etc/systemd/system")
|
|
|
47
47
|
_MANAGED_CONTAINERS_CACHE_TTL_S = 30.0
|
|
48
48
|
_MANAGED_CONTAINERS_CACHE: Dict[str, Any] = {"timestamp": 0.0, "summary": None}
|
|
49
49
|
_MANAGED_CONTAINERS_CACHE_LOCK = threading.Lock()
|
|
50
|
-
|
|
51
|
-
_STARTUP_TEMPLATE_KEY: tuple[Any, ...] | None = None
|
|
52
|
-
_STARTUP_TEMPLATES_LOCK = threading.Lock()
|
|
50
|
+
_STARTUP_TEMPLATES_REFRESHED = False
|
|
53
51
|
|
|
54
52
|
ProgressCallback = Callable[[int, int, Dict[str, Any], str, Optional[Dict[str, Any]]], None]
|
|
55
53
|
|
|
@@ -182,16 +180,6 @@ def _list_templates(client: Any, node: str, storages: Iterable[Dict[str, Any]])
|
|
|
182
180
|
return templates
|
|
183
181
|
|
|
184
182
|
|
|
185
|
-
def _template_key(config: Dict[str, Any]) -> tuple[Any, ...]:
|
|
186
|
-
return (
|
|
187
|
-
config.get("host"),
|
|
188
|
-
config.get("node"),
|
|
189
|
-
config.get("user"),
|
|
190
|
-
config.get("token_name"),
|
|
191
|
-
config.get("verify_ssl"),
|
|
192
|
-
)
|
|
193
|
-
|
|
194
|
-
|
|
195
183
|
def _build_proxmox_client_from_config(config: Dict[str, Any]):
|
|
196
184
|
user = config.get("user")
|
|
197
185
|
token_name = config.get("token_name")
|
|
@@ -209,41 +197,22 @@ def _build_proxmox_client_from_config(config: Dict[str, Any]):
|
|
|
209
197
|
)
|
|
210
198
|
|
|
211
199
|
|
|
212
|
-
def
|
|
213
|
-
global
|
|
214
|
-
if not config:
|
|
215
|
-
|
|
216
|
-
_STARTUP_TEMPLATES = []
|
|
217
|
-
_STARTUP_TEMPLATE_KEY = None
|
|
200
|
+
def _ensure_templates_refreshed_on_startup(config: Dict[str, Any]) -> None:
|
|
201
|
+
global _STARTUP_TEMPLATES_REFRESHED
|
|
202
|
+
if _STARTUP_TEMPLATES_REFRESHED or not config or not config.get("token_value"):
|
|
203
|
+
_STARTUP_TEMPLATES_REFRESHED = True
|
|
218
204
|
return
|
|
219
|
-
with _STARTUP_TEMPLATES_LOCK:
|
|
220
|
-
if _STARTUP_TEMPLATE_KEY == _template_key(config) and _STARTUP_TEMPLATES is not None:
|
|
221
|
-
return
|
|
222
|
-
key = _template_key(config)
|
|
223
|
-
templates: List[str] = []
|
|
224
205
|
try:
|
|
225
206
|
client = _build_proxmox_client_from_config(config)
|
|
226
207
|
node = config.get("node") or _pick_node(client)
|
|
227
208
|
storages = client.nodes(node).storage.get()
|
|
228
209
|
templates = _list_templates(client, node, storages)
|
|
210
|
+
if templates:
|
|
211
|
+
config["templates"] = templates
|
|
229
212
|
except Exception as exc:
|
|
230
|
-
logger.warning("Unable to refresh Proxmox templates: %s", exc)
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
_STARTUP_TEMPLATE_KEY = key
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
def _get_startup_templates(config: Dict[str, Any]) -> List[str]:
|
|
237
|
-
_ensure_startup_templates(config)
|
|
238
|
-
with _STARTUP_TEMPLATES_LOCK:
|
|
239
|
-
return list(_STARTUP_TEMPLATES or [])
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
def _clear_startup_templates() -> None:
|
|
243
|
-
global _STARTUP_TEMPLATES, _STARTUP_TEMPLATE_KEY
|
|
244
|
-
with _STARTUP_TEMPLATES_LOCK:
|
|
245
|
-
_STARTUP_TEMPLATES = None
|
|
246
|
-
_STARTUP_TEMPLATE_KEY = None
|
|
213
|
+
logger.warning("Unable to refresh Proxmox templates on startup: %s", exc)
|
|
214
|
+
finally:
|
|
215
|
+
_STARTUP_TEMPLATES_REFRESHED = True
|
|
247
216
|
|
|
248
217
|
|
|
249
218
|
def _pick_storage(storages: Iterable[Dict[str, Any]]) -> str:
|
|
@@ -756,7 +725,7 @@ def _remove_container_record(vmid: int) -> None:
|
|
|
756
725
|
|
|
757
726
|
|
|
758
727
|
def _build_container_payload(message: Dict[str, Any], config: Dict[str, Any]) -> Dict[str, Any]:
|
|
759
|
-
templates =
|
|
728
|
+
templates = config.get("templates") or []
|
|
760
729
|
default_template = templates[0] if templates else ""
|
|
761
730
|
template = message.get("template") or default_template
|
|
762
731
|
if not template:
|
|
@@ -1177,6 +1146,7 @@ def build_snapshot(config: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
1177
1146
|
}
|
|
1178
1147
|
if not config:
|
|
1179
1148
|
return {"configured": False, "network": base_network}
|
|
1149
|
+
_ensure_templates_refreshed_on_startup(config)
|
|
1180
1150
|
return {
|
|
1181
1151
|
"configured": True,
|
|
1182
1152
|
"host": config.get("host"),
|
|
@@ -1184,14 +1154,13 @@ def build_snapshot(config: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
1184
1154
|
"user": config.get("user"),
|
|
1185
1155
|
"token_name": config.get("token_name"),
|
|
1186
1156
|
"default_storage": config.get("default_storage"),
|
|
1187
|
-
"templates":
|
|
1157
|
+
"templates": config.get("templates") or [],
|
|
1188
1158
|
"last_verified": config.get("last_verified"),
|
|
1189
1159
|
"network": base_network,
|
|
1190
1160
|
}
|
|
1191
1161
|
|
|
1192
1162
|
|
|
1193
1163
|
def configure_infrastructure(token_identifier: str, token_value: str, verify_ssl: bool = False) -> Dict[str, Any]:
|
|
1194
|
-
_clear_startup_templates()
|
|
1195
1164
|
ProxmoxAPI = _ensure_proxmoxer()
|
|
1196
1165
|
user, token_name = _parse_token(token_identifier)
|
|
1197
1166
|
client = ProxmoxAPI(
|
|
@@ -1227,12 +1196,12 @@ def configure_infrastructure(token_identifier: str, token_value: str, verify_ssl
|
|
|
1227
1196
|
"token_value": token_value,
|
|
1228
1197
|
"verify_ssl": verify_ssl,
|
|
1229
1198
|
"default_storage": default_storage,
|
|
1199
|
+
"templates": templates,
|
|
1230
1200
|
"last_verified": datetime.utcnow().isoformat() + "Z",
|
|
1231
1201
|
"network": network,
|
|
1232
1202
|
"node_status": status,
|
|
1233
1203
|
}
|
|
1234
1204
|
_save_config(config)
|
|
1235
|
-
_ensure_startup_templates(config)
|
|
1236
1205
|
snapshot = build_snapshot(config)
|
|
1237
1206
|
snapshot["node_status"] = status
|
|
1238
1207
|
snapshot["managed_containers"] = _get_managed_containers_summary(force=True)
|
|
@@ -1252,7 +1221,6 @@ def revert_infrastructure() -> Dict[str, Any]:
|
|
|
1252
1221
|
_revert_bridge()
|
|
1253
1222
|
if CONFIG_PATH.exists():
|
|
1254
1223
|
CONFIG_PATH.unlink()
|
|
1255
|
-
_clear_startup_templates()
|
|
1256
1224
|
snapshot = build_snapshot({})
|
|
1257
1225
|
snapshot["network"] = snapshot.get("network", {})
|
|
1258
1226
|
snapshot["network"]["applied"] = False
|
|
@@ -1314,7 +1282,7 @@ class CreateProxmoxContainerHandler(SyncHandler):
|
|
|
1314
1282
|
device_private_key = (message.get("device_private_key") or "").strip()
|
|
1315
1283
|
has_device_keypair = bool(device_public_key and device_private_key)
|
|
1316
1284
|
config_guess = _load_config()
|
|
1317
|
-
template_candidates =
|
|
1285
|
+
template_candidates = config_guess.get("templates") or []
|
|
1318
1286
|
template_hint = (message.get("template") or (template_candidates[0] if template_candidates else "")).strip()
|
|
1319
1287
|
package_manager = _guess_package_manager_from_template(template_hint)
|
|
1320
1288
|
bootstrap_user, bootstrap_password, bootstrap_ssh_key = _get_provisioning_user_info(message)
|
|
@@ -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=xmWnbzztE5Rc80b-QMEet19V4hm80qIDp1evukvT-mY,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=GX2IE1J0YX5GHnqqn__e_wpag_Lsa-cWVRQ82MZnbjU,67267
|
|
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.dev11.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.dev11.dist-info/METADATA,sha256=YjU_cRf0I5P6zz-KmGOslg3APj4CL8IgOHbP13Z6T1U,13052
|
|
95
|
+
portacode-1.4.15.dev11.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
96
|
+
portacode-1.4.15.dev11.dist-info/entry_points.txt,sha256=lLUUL-BM6_wwe44Xv0__5NQ1BnAz6jWjSMFvZdWW3zU,48
|
|
97
|
+
portacode-1.4.15.dev11.dist-info/top_level.txt,sha256=TGhTYUxfW8SyVZc_zGgzjzc24gGT7nSw8Qf73liVRKM,41
|
|
98
|
+
portacode-1.4.15.dev11.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|