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