Source code for scitex_container.apptainer._status

#!/usr/bin/env python3
# Timestamp: "2026-02-25"
# File: src/scitex_container/apptainer/_status.py
"""List available containers and their build status."""

from __future__ import annotations

import hashlib
import logging
from datetime import datetime
from pathlib import Path

from scitex_container._compat import supports_return_as

from ._utils import find_containers_dir

logger = logging.getLogger(__name__)


[docs] @supports_return_as def status(containers_dir: str | Path | None = None) -> list[dict]: """List available containers and their status. Parameters ---------- containers_dir : str or Path, optional Directory containing .def files. Auto-detected if not given. Returns ------- list[dict] List of container info dicts with keys: name, def_path, sif_path, sif_size, sif_date, hash_current, hash_stored, needs_rebuild. """ cdir = Path(containers_dir) if containers_dir else find_containers_dir() results = [] for def_path in sorted(cdir.glob("*.def")): name = def_path.stem sif_path = def_path.with_suffix(".sif") hash_file = cdir / ".def-hash" current_hash = _hash_file(def_path) stored_hash = "" if hash_file.exists(): stored_hash = hash_file.read_text().strip() info: dict = { "name": name, "def_path": str(def_path), "sif_path": str(sif_path) if sif_path.exists() else None, "sif_size": None, "sif_date": None, "hash_current": current_hash, "hash_stored": stored_hash or None, "needs_rebuild": True, } if sif_path.exists(): stat = sif_path.stat() info["sif_size"] = _human_size(stat.st_size) info["sif_date"] = datetime.fromtimestamp(stat.st_mtime).strftime( "%Y-%m-%d %H:%M" ) info["needs_rebuild"] = current_hash != stored_hash results.append(info) return results
def _hash_file(path: Path) -> str: """Compute SHA256 hash of a file.""" h = hashlib.sha256() h.update(path.read_bytes()) return h.hexdigest() def _human_size(nbytes: int) -> str: """Convert bytes to human-readable size.""" for unit in ("B", "KB", "MB", "GB", "TB"): if abs(nbytes) < 1024: return f"{nbytes:.1f} {unit}" nbytes /= 1024 return f"{nbytes:.1f} PB" # EOF