Merge main into develop to resolve conflicts before 1.2.2 release PR

# Conflicts:
#	AppImage/ProxMenux-Monitor.AppImage.sha256
#	LICENSE
#	install_proxmenux_beta.sh
This commit is contained in:
MacRimi
2026-05-31 13:24:58 +02:00
6 changed files with 4767 additions and 1445 deletions
+43 -16
View File
@@ -67,9 +67,9 @@ def fetch_all_records(url: str, *, expand: str | None = None, per_page: int = 50
return items return items
def normalize_os_variants(install_methods_json: list[dict[str, Any]]) -> list[str]: def normalize_os_variants(install_methods: list[dict[str, Any]]) -> list[str]:
os_values: list[str] = [] os_values: list[str] = []
for item in install_methods_json: for item in install_methods:
if not isinstance(item, dict): if not isinstance(item, dict):
continue continue
resources = item.get("resources", {}) resources = item.get("resources", {})
@@ -83,6 +83,31 @@ def normalize_os_variants(install_methods_json: list[dict[str, Any]]) -> list[st
return os_values return os_values
def split_notes(notes_raw: list[dict[str, Any]]) -> tuple[list[str], list[str]]:
"""Split PocketBase notes into (info_notes, warnings).
Each entry has shape ``{"text": str, "type": "warning"|...}``. Anything
flagged ``type == "warning"`` lands in the warnings list so the bash
menu can render those in red with a dedicated WARNINGS header. Other
notes go to the regular notes list.
"""
info: list[str] = []
warns: list[str] = []
for note in notes_raw or []:
if not isinstance(note, dict):
continue
text = note.get("text")
if not isinstance(text, str) or not text.strip():
continue
text = text.strip()
ntype = (note.get("type") or "").strip().lower()
if ntype == "warning":
warns.append(text)
else:
info.append(text)
return info, warns
def build_script_path(type_name: str, slug: str) -> str: def build_script_path(type_name: str, slug: str) -> str:
type_name = (type_name or "").strip().lower() type_name = (type_name or "").strip().lower()
slug = (slug or "").strip() slug = (slug or "").strip()
@@ -138,19 +163,19 @@ def main() -> int:
full_script_url = f"{SCRIPT_BASE}/{script_path}" full_script_url = f"{SCRIPT_BASE}/{script_path}"
script_url_mirror = to_mirror_url(full_script_url) script_url_mirror = to_mirror_url(full_script_url)
install_methods_json = raw.get("install_methods_json", []) # Sprint 11.7: PocketBase exposes these as `install_methods` and
if not isinstance(install_methods_json, list): # `notes`, not `install_methods_json` / `notes_json`. The legacy field
install_methods_json = [] # names silently returned [] for every entry, which is why the cache
# had empty notes and missing OS variants for every script.
install_methods = raw.get("install_methods", [])
if not isinstance(install_methods, list):
install_methods = []
notes_json = raw.get("notes_json", []) notes_raw = raw.get("notes", [])
if not isinstance(notes_json, list): if not isinstance(notes_raw, list):
notes_json = [] notes_raw = []
notes = [ notes, warnings = split_notes(notes_raw)
note.get("text", "")
for note in notes_json
if isinstance(note, dict) and isinstance(note.get("text"), str) and note.get("text", "").strip()
]
category_ids = raw.get("categories", []) category_ids = raw.get("categories", [])
if not isinstance(category_ids, list): if not isinstance(category_ids, list):
@@ -193,6 +218,7 @@ def main() -> int:
"categories": category_ids, "categories": category_ids,
"category_names": category_names, "category_names": category_names,
"notes": notes, "notes": notes,
"warnings": warnings,
"port": raw.get("port", 0), "port": raw.get("port", 0),
"website": raw.get("website", ""), "website": raw.get("website", ""),
"documentation": raw.get("documentation", ""), "documentation": raw.get("documentation", ""),
@@ -210,7 +236,7 @@ def main() -> int:
# Emit one entry per install method so the menu shell can offer an # Emit one entry per install method so the menu shell can offer an
# explicit OS choice. When there is only one method (or none), a # explicit OS choice. When there is only one method (or none), a
# single entry is emitted with os="" (script decides at runtime). # single entry is emitted with os="" (script decides at runtime).
os_variants = normalize_os_variants(install_methods_json) os_variants = normalize_os_variants(install_methods)
if len(os_variants) > 1: if len(os_variants) > 1:
for os_name in os_variants: for os_name in os_variants:
@@ -228,11 +254,12 @@ def main() -> int:
with OUTPUT_FILE.open("w", encoding="utf-8") as f: with OUTPUT_FILE.open("w", encoding="utf-8") as f:
json.dump(cache, f, ensure_ascii=False, indent=2) json.dump(cache, f, ensure_ascii=False, indent=2)
total_notes = sum(len(e.get("notes", [])) for e in cache)
total_warns = sum(len(e.get("warnings", [])) for e in cache)
print(f"\n✅ helpers_cache.json → {OUTPUT_FILE}") print(f"\n✅ helpers_cache.json → {OUTPUT_FILE}")
print(f" Guardados: {len(cache)}") print(f" Guardados: {len(cache)} entries, {total_notes} notes, {total_warns} warnings")
return 0 return 0
if __name__ == "__main__": if __name__ == "__main__":
sys.exit(main()) sys.exit(main())
BIN
View File
Binary file not shown.
+2 -2
View File
@@ -3,7 +3,7 @@
### New version ProxMenux v1.2.1 — *SR-IOV Awareness & GPU Passthrough Hardening* ### New version ProxMenux v1.2.1 — *SR-IOV Awareness & GPU Passthrough Hardening*
Targeted release on top of **v1.2.0** addressing three community-reported areas that needed fixing before the next stable cycle: full SR-IOV awareness across the GPU/PCI subsystem, robust handling of GPU + audio companions during passthrough attach and detach (Intel iGPU with chipset audio, discrete cards with HDMI audio, mixed-GPU VMs), and compatibility fixes for the AI notification providers (OpenAI-compatible custom endpoints such as LiteLLM/MLX/LM Studio, OpenAI reasoning models, and Gemini 2.5+/3.x thinking models). Also bundles quality-of-life fixes in the NVIDIA installer, the disk health monitor, and the LXC lifecycle helpers used by the passthrough wizards. Targeted release on top of **v1.2.0** addressing three community-reported areas: complete SR-IOV awareness across the GPU/PCI subsystem, robust handling of GPU + audio companions during passthrough attach and detach (Intel iGPU with chipset audio, discrete cards with HDMI audio, mixed-GPU VMs), and compatibility fixes for AI notification providers (OpenAI-compatible custom endpoints such as LiteLLM/MLX/LM Studio, OpenAI reasoning models, and Gemini 2.5+/3.x thinking models). Also includes quality-of-life improvements in the NVIDIA installer, the disk health monitor, and the LXC lifecycle helpers used by the passthrough wizards.
--- ---
@@ -1062,4 +1062,4 @@ Disks now display tags like ⚠ In use, ⚠ RAID, ⚠ LVM, or ⚠ ZFS, making it
## [1.0.0] - 2024-12-18 ## [1.0.0] - 2024-12-18
### Added ### Added
- Initial release of **ProxMenux**. - Initial release of **ProxMenux**.
- Created a script to add **Coral TPU drivers** to Proxmox. - Created a script to add **Coral TPU drivers** to Proxmox.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

+4721 -1426
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1567,4 +1567,4 @@ main() {
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
main main
fi fi