#!/usr/bin/env bash # Human-readable container RSS when rootless podman stats shows 0B / host RAM. # Cause on openSUSE: user@.service Delegate= (20-defaults-SUSE.conf) clears # memory/cpu controllers → no memory.current. CPU% from podman stats still works. # Usage: podman-rss.sh [--json] [NAME_FILTER…] set -euo pipefail JSON=0 FILTERS=() for a in "$@"; do case "$a" in --json|-j) JSON=1 ;; -h|--help) echo "usage: $0 [--json] [NAME_FILTER…]" >&2 exit 0 ;; *) FILTERS+=("$a") ;; esac done human() { # stdin: kibibytes integer awk ' { k=$1+0 if (k >= 1048576) printf "%.1f GiB", k/1048576 else if (k >= 1024) printf "%.0f MiB", k/1024 else printf "%d KiB", k }' } # CPU map: name -> cpu% declare -A CPU=() while IFS=$'\t' read -r name cpu; do [ -n "$name" ] || continue CPU["$name"]="$cpu" done < <(podman stats --no-stream --format '{{.Name}}\t{{.CPUPerc}}' 2>/dev/null || true) rows=() total_kib=0 while IFS= read -r cid; do [ -n "$cid" ] || continue name=$(podman inspect -f '{{.Name}}' "$cid" 2>/dev/null || true) [ -n "$name" ] || continue if [ ${#FILTERS[@]} -gt 0 ]; then ok=0 for f in "${FILTERS[@]}"; do case "$name" in *"$f"*) ok=1; break ;; esac done [ "$ok" -eq 1 ] || continue fi # podman top rss is KiB per process; sum kib=$(podman top "$cid" -o rss 2>/dev/null | awk 'NR>1{s+=$1} END{print s+0}') cpu="${CPU[$name]:-?}" rows+=("${kib}|${name}|${cpu}") total_kib=$((total_kib + kib)) done < <(podman ps -q) IFS=$'\n' sorted=($(printf '%s\n' "${rows[@]:-}" | sort -t'|' -k1,1nr)) unset IFS if [ "$JSON" -eq 1 ]; then python3 - "$total_kib" "${sorted[@]:-}" <<'PY' import json, sys total = int(sys.argv[1]) if len(sys.argv) > 1 else 0 items = [] for row in sys.argv[2:]: if not row.strip(): continue kib, name, cpu = row.split("|", 2) items.append({"name": name, "rss_kib": int(kib), "cpu": cpu}) print(json.dumps({"ok": True, "total_rss_kib": total, "containers": items}, indent=2)) PY exit 0 fi printf '%-44s %10s %8s\n' "NAME" "RSS" "CPU%" printf '%-44s %10s %8s\n' "----" "---" "----" for row in "${sorted[@]:-}"; do [ -n "$row" ] || continue kib="${row%%|*}" rest="${row#*|}" name="${rest%%|*}" cpu="${rest##*|}" hum=$(printf '%s' "$kib" | human) printf '%-44s %10s %8s\n' "$name" "$hum" "$cpu" done printf '%-44s %10s\n' "TOTAL" "$(printf '%s' "$total_kib" | human)" echo "# note: RSS via podman top (no memory cgroup); CPU via podman stats" >&2