feat: storage pool dropdown populated from /etc/pve/storage.cfg
- New GET /api/v1/storage/pools returns available lvmthin/zfspool/rbd/dir pools - Analysis result template now shows dropdown when >1 pool available - Falls back to text input with single pool or on discovery failure
This commit is contained in:
parent
878bc66da8
commit
7eb2d6bb45
4 changed files with 65 additions and 2 deletions
|
|
@ -94,6 +94,49 @@ def health() -> HealthResponse:
|
|||
return HealthResponse(status="ok")
|
||||
|
||||
|
||||
@app.get(f"{API_PREFIX}/storage/pools")
|
||||
def storage_pools():
|
||||
"""Return available Proxmox storage pools that support disk images."""
|
||||
pools = []
|
||||
try:
|
||||
cfg = Path("/etc/pve/storage.cfg")
|
||||
if cfg.exists():
|
||||
lines = cfg.read_text()
|
||||
current = {}
|
||||
for line in lines.split("\n"):
|
||||
line = line.strip()
|
||||
if not line or line.startswith("#"):
|
||||
continue
|
||||
if ":" in line and not line.startswith(" "):
|
||||
if current and current.get("name"):
|
||||
pools.append(current)
|
||||
parts = line.split(":", 1)
|
||||
stype = parts[0].strip()
|
||||
sname = parts[1].strip() if len(parts) > 1 else ""
|
||||
current = {"name": sname, "type": stype}
|
||||
elif line.startswith(" ") and current:
|
||||
if " " in line:
|
||||
key, val = line.strip().split(" ", 1)
|
||||
current[key] = val
|
||||
if current and current.get("name"):
|
||||
pools.append(current)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
result = []
|
||||
for p in pools:
|
||||
if p.get("type") in ("lvmthin", "zfspool", "rbd", "dir"):
|
||||
result.append({
|
||||
"name": p["name"],
|
||||
"type": p["type"],
|
||||
})
|
||||
|
||||
if not result:
|
||||
result.append({"name": "local-lvm", "type": "lvmthin"})
|
||||
|
||||
return {"pools": result}
|
||||
|
||||
|
||||
@app.post(f"{API_PREFIX}/analyze", response_model=AnalyzeStatusResponse, status_code=202)
|
||||
def analyze(req: AnalyzeRequest) -> AnalyzeStatusResponse:
|
||||
"""Analyze a source file asynchronously: extraction + disk probing + OS detection."""
|
||||
|
|
|
|||
|
|
@ -54,6 +54,10 @@ class ApiClient:
|
|||
"""GET /api/v1/analyze/{analysis_id} — poll analysis status."""
|
||||
return self._get(f"/api/v1/analyze/{analysis_id}")
|
||||
|
||||
def get_storage_pools(self) -> dict:
|
||||
"""GET /api/v1/storage/pools — list available Proxmox storage pools."""
|
||||
return self._get("/api/v1/storage/pools")
|
||||
|
||||
def create_job(self, payload: dict) -> dict:
|
||||
"""POST /api/v1/jobs — submit conversion job."""
|
||||
return self._post("/api/v1/jobs", payload)
|
||||
|
|
|
|||
|
|
@ -356,6 +356,13 @@ async def session_analyze_result(
|
|||
return render("_analysis.html", request=request,
|
||||
error=f"Failed to fetch analysis: {exc.detail}")
|
||||
|
||||
pools = []
|
||||
try:
|
||||
sp = api.get_storage_pools()
|
||||
pools = sp.get("pools", [])
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
analysis = result
|
||||
name = vm_name.strip()
|
||||
if not name:
|
||||
|
|
@ -363,7 +370,7 @@ async def session_analyze_result(
|
|||
|
||||
return render("_analysis.html", request=request,
|
||||
vmid=vmid, source_filename=source_filename,
|
||||
vm_name=name, analysis=analysis)
|
||||
vm_name=name, analysis=analysis, storage_pools=pools)
|
||||
|
||||
|
||||
@app.post("/session/confirm", response_class=HTMLResponse)
|
||||
|
|
|
|||
|
|
@ -63,7 +63,16 @@
|
|||
<div class="pve-row">
|
||||
<div class="pve-form-group">
|
||||
<label>Storage Pool</label>
|
||||
<input type="text" name="target_storage" class="pve-input" value="local-lvm">
|
||||
{% if storage_pools and storage_pools|length > 1 %}
|
||||
<select name="target_storage" class="pve-select">
|
||||
{% for pool in storage_pools %}
|
||||
<option value="{{ pool.name }}">{{ pool.name }} ({{ pool.type }})</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% else %}
|
||||
<input type="text" name="target_storage" class="pve-input"
|
||||
value="{{ storage_pools[0].name if storage_pools else 'local-lvm' }}">
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="pve-form-group">
|
||||
<label>Boot Detection</label>
|
||||
|
|
|
|||
Loading…
Reference in a new issue