Update oci_manager.py

This commit is contained in:
MacRimi
2026-03-16 17:58:04 +01:00
parent b6780ba876
commit b7c800b550

View File

@@ -271,64 +271,82 @@ def get_available_storages() -> List[Dict[str, Any]]:
storages = []
try:
# Use pvesm status to get all storages
rc, out, err = _run_pve_cmd(["pvesm", "status", "--output-format", "json"])
# Use pvesm status to get all storages (parse text output for compatibility)
rc, out, err = _run_pve_cmd(["pvesm", "status"])
if rc != 0:
logger.error(f"Failed to get storage status: {err}")
return storages
storage_list = json.loads(out) if out.strip() else []
for storage in storage_list:
storage_name = storage.get("storage", "")
storage_type = storage.get("type", "")
# Skip if storage is not active
if storage.get("active", 0) != 1:
# Parse text output: Name Type Status Total Used Available %
# Example: local-lvm lvmthin active 464031744 15491072 448540672 3.34%
lines = out.strip().split('\n')
for line in lines[1:]: # Skip header
parts = line.split()
if len(parts) < 4:
continue
# Check if storage supports rootdir content (for LXC)
rc2, out2, _ = _run_pve_cmd(["pvesm", "show", storage_name, "--output-format", "json"])
if rc2 == 0 and out2.strip():
try:
config = json.loads(out2)
content = config.get("content", "")
# Storage must support "images" or "rootdir" for LXC rootfs
# - "rootdir" is for directory-based storage (ZFS, BTRFS, NFS, etc.)
# - "images" is for block storage (LVM, LVM-thin, etc.)
if "images" in content or "rootdir" in content:
total_bytes = storage.get("total", 0)
used_bytes = storage.get("used", 0)
avail_bytes = storage.get("avail", total_bytes - used_bytes)
# Determine recommendation priority
# Prefer: zfspool > lvmthin > btrfs > lvm > others
priority = 99
if storage_type == "zfspool":
priority = 1
elif storage_type == "lvmthin":
priority = 2
elif storage_type == "btrfs":
priority = 3
elif storage_type == "lvm":
priority = 4
elif storage_type in ("dir", "nfs", "cifs"):
priority = 10
storages.append({
"name": storage_name,
"type": storage_type,
"total": total_bytes,
"used": used_bytes,
"avail": avail_bytes,
"active": True,
"enabled": storage.get("enabled", 0) == 1,
"priority": priority,
"recommended": False # Will be set after sorting
})
except json.JSONDecodeError:
pass
storage_name = parts[0]
storage_type = parts[1]
status = parts[2]
# Skip if storage is not active
if status != "active":
continue
# Get capacity info
total_bytes = int(parts[3]) * 1024 if len(parts) > 3 and parts[3].isdigit() else 0
used_bytes = int(parts[4]) * 1024 if len(parts) > 4 and parts[4].isdigit() else 0
avail_bytes = int(parts[5]) * 1024 if len(parts) > 5 and parts[5].isdigit() else total_bytes - used_bytes
# Check if storage supports rootdir/images content (for LXC)
# Read from /etc/pve/storage.cfg directly for compatibility
content = ""
try:
with open("/etc/pve/storage.cfg", "r") as f:
cfg_content = f.read()
# Find the storage section
import re
pattern = rf'{storage_type}:\s*{re.escape(storage_name)}\s*\n((?:\s+[^\n]+\n)*)'
match = re.search(pattern, cfg_content)
if match:
section = match.group(1)
content_match = re.search(r'content\s+(\S+)', section)
if content_match:
content = content_match.group(1)
except Exception:
# Fallback: assume block storages support images
if storage_type in ("lvm", "lvmthin", "zfspool", "rbd"):
content = "images,rootdir"
elif storage_type in ("dir", "nfs", "cifs", "btrfs"):
content = "rootdir,images"
# Storage must support "images" or "rootdir" for LXC rootfs
if "images" in content or "rootdir" in content:
# Determine recommendation priority
# Prefer: zfspool > lvmthin > btrfs > lvm > others
priority = 99
if storage_type == "zfspool":
priority = 1
elif storage_type == "lvmthin":
priority = 2
elif storage_type == "btrfs":
priority = 3
elif storage_type == "lvm":
priority = 4
elif storage_type in ("dir", "nfs", "cifs"):
priority = 10
storages.append({
"name": storage_name,
"type": storage_type,
"total": total_bytes,
"used": used_bytes,
"avail": avail_bytes,
"active": True,
"enabled": True,
"priority": priority,
"recommended": False # Will be set after sorting
})
# Sort by priority (lower = better), then by available space
storages.sort(key=lambda s: (s.get("priority", 99), -s.get("avail", 0)))