@@ -714,113 +714,26 @@ async def list_vbox_assets():
714714_download_tasks : dict [str , dict [str , Any ]] = {}
715715_download_lock = threading .Lock ()
716716
717- # Common Ubuntu releases (amd64 live-server)
718- ISO_CATEGORIES = [
719- {
720- "id" : "ubuntu" ,
721- "label" : "Ubuntu" ,
722- "items" : [
723- {
724- "version" : "24.04 LTS Server" ,
725- "url" : "https://releases.ubuntu.com/24.04/ubuntu-24.04.4-live-server-amd64.iso" ,
726- "description" : "Ubuntu Server 24.04 LTS — recommended for VMs" ,
727- "size" : "~2.6 GB" ,
728- },
729- {
730- "version" : "24.04 LTS Desktop" ,
731- "url" : "https://releases.ubuntu.com/24.04/ubuntu-24.04.4-desktop-amd64.iso" ,
732- "description" : "Ubuntu Desktop 24.04 LTS — full GUI" ,
733- "size" : "~5.7 GB" ,
734- },
735- {
736- "version" : "22.04 LTS Server" ,
737- "url" : "https://releases.ubuntu.com/22.04/ubuntu-22.04.5-live-server-amd64.iso" ,
738- "description" : "Ubuntu Server 22.04 LTS — stable, long support" ,
739- "size" : "~2.6 GB" ,
740- },
741- {
742- "version" : "22.04 LTS Desktop" ,
743- "url" : "https://releases.ubuntu.com/22.04/ubuntu-22.04.5-desktop-amd64.iso" ,
744- "description" : "Ubuntu Desktop 22.04 LTS" ,
745- "size" : "~4.6 GB" ,
746- },
747- {
748- "version" : "25.04 Server" ,
749- "url" : "https://releases.ubuntu.com/25.04/ubuntu-25.04-live-server-amd64.iso" ,
750- "description" : "Ubuntu Server 25.04 — latest release" ,
751- "size" : "~2.8 GB" ,
752- },
753- ],
754- },
755- {
756- "id" : "debian" ,
757- "label" : "Debian" ,
758- "items" : [
759- {
760- "version" : "Debian 12 Bookworm" ,
761- "url" : "https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-12.10.0-amd64-netinst.iso" ,
762- "description" : "Debian 12 netinstall — minimal, rock-solid" ,
763- "size" : "~700 MB" ,
764- },
765- {
766- "version" : "Debian 12 Live XFCE" ,
767- "url" : "https://cdimage.debian.org/debian-cd/current-live/amd64/iso-hybrid/debian-live-12.10.0-amd64-xfce.iso" ,
768- "description" : "Debian 12 with XFCE desktop" ,
769- "size" : "~3.1 GB" ,
770- },
771- ],
772- },
773- {
774- "id" : "windows" ,
775- "label" : "Windows" ,
776- "items" : [
777- {
778- "version" : "Windows 11 24H2 (eval)" ,
779- "url" : "https://go.microsoft.com/fwlink/?linkid=2294090" ,
780- "description" : "Windows 11 Enterprise Evaluation — 90-day trial (redirects to latest)" ,
781- "size" : "~6.4 GB" ,
782- "filename" : "Win11_24H2_Eval.iso" ,
783- },
784- {
785- "version" : "Windows Server 2025 (eval)" ,
786- "url" : "https://go.microsoft.com/fwlink/?linkid=2294501" ,
787- "description" : "Windows Server 2025 Evaluation — 180-day trial" ,
788- "size" : "~6.0 GB" ,
789- "filename" : "WinServer2025_Eval.iso" ,
790- },
791- ],
792- },
793- {
794- "id" : "utilities" ,
795- "label" : "Utilities" ,
796- "items" : [
797- {
798- "version" : "GParted Live" ,
799- "url" : "https://downloads.sourceforge.net/gparted/gparted-live-1.6.0-1-amd64.iso" ,
800- "description" : "Partition manager — resize, repair, recover disks" ,
801- "size" : "~550 MB" ,
802- },
803- ],
804- },
805- {
806- "id" : "safety" ,
807- "label" : "Safety Tools" ,
808- "items" : [
809- {
810- "version" : "Kali Linux 2025" ,
811- "url" : "https://cdimage.kali.org/kali-2025.1/kali-linux-2025.1-installer-amd64.iso" ,
812- "description" : "Penetration testing and security auditing distro" ,
813- "size" : "~4.6 GB" ,
814- },
815- {
816- "version" : "Kali Linux Live (2025)" ,
817- "url" : "https://cdimage.kali.org/kali-2025.1/kali-linux-2025.1-live-amd64.iso" ,
818- "description" : "Kali live environment — no install needed" ,
819- "size" : "~4.2 GB" ,
820- },
821- ],
822- },
823- ]
717+ # ISO categories loaded from external JSON (editable, extensible), fallback to empty list
718+ ISO_CATEGORIES_FILE = os .path .join (_repo_root , "config" , "iso_categories.json" )
719+ ISO_CATEGORIES : list [dict [str , Any ]] = []
720+
721+
722+ def _load_iso_categories () -> list [dict [str , Any ]]:
723+ """Load ISO categories from config/iso_categories.json, with cache."""
724+ try :
725+ if os .path .isfile (ISO_CATEGORIES_FILE ):
726+ with open (ISO_CATEGORIES_FILE , encoding = "utf-8" ) as f :
727+ return json .load (f )
728+ except Exception as e :
729+ logger .warning ("Failed to load %s: %s" , ISO_CATEGORIES_FILE , e )
730+ return []
731+
732+
733+ def _get_iso_categories () -> list [dict [str , Any ]]:
734+ """Return ISO categories, reloaded on each call so edits take effect without restart."""
735+ # Reload from JSON on every call
736+ return _load_iso_categories ()
824737
825738
826739def _download_iso_worker (task_id : str , url : str , dest : str ) -> None :
@@ -907,8 +820,12 @@ def _derive_filename(url: str, fallback: str = "download.iso") -> str:
907820
908821@app .get ("/api/v1/iso/candidates" )
909822async def iso_candidates ():
910- """List downloadable Ubuntu ISO candidates."""
911- return {"categories" : ISO_CATEGORIES , "assets_vbox" : ASSETS_VBOX }
823+ """List downloadable ISO candidates from config/iso_categories.json (reloaded on each call).
824+
825+ Edit config/iso_categories.json and refresh to see changes immediately.
826+ """
827+ cats = _get_iso_categories ()
828+ return {"categories" : cats , "assets_vbox" : ASSETS_VBOX , "config_file" : ISO_CATEGORIES_FILE }
912829
913830
914831@app .post ("/api/v1/iso/download" )
0 commit comments