mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-04-29 19:06:37 +00:00
Update oci_manager.py
This commit is contained in:
@@ -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)))
|
||||||
|
|||||||
Reference in New Issue
Block a user