particle-os-tools/src/composefs/scriptlets/05-listing.sh
robojerk 74c7bede5f Initial commit: Particle-OS tools repository
- Complete Particle-OS rebranding from uBlue-OS
- Professional installation system with standardized paths
- Self-initialization system with --init and --reset commands
- Enhanced error messages and dependency checking
- Comprehensive testing infrastructure
- All source scriptlets updated with runtime improvements
- Clean codebase with redundant files moved to archive
- Complete documentation suite
2025-07-11 21:14:33 -07:00

238 lines
No EOL
8.6 KiB
Bash

# Listing and reporting functions for Ubuntu uBlue ComposeFS Alternative
# List composefs images
list_images() {
log_info "Currently available Composefs Images:" "composefs-alternative"
if [[ ! -d "$COMPOSEFS_DIR/images" ]]; then
log_info "No images found" "composefs-alternative"
return 0
fi
for image_dir in "$COMPOSEFS_DIR/images"/*; do
if [[ -d "$image_dir" ]]; then
local image_name
image_name=$(basename "$image_dir")
local metadata_file="$image_dir/metadata.json"
if [[ -f "$metadata_file" ]]; then
local created
local layers
local layer_ids=()
created=$(jq -r '.created' "$metadata_file")
layers=$(jq -r '.layers | length' "$metadata_file")
# Collect layer IDs for size calculation
while IFS= read -r layer_id; do
layer_ids+=("$layer_id")
done < <(jq -r '.layers[]' "$metadata_file")
# Calculate actual disk usage (accounting for deduplication)
local actual_size
actual_size=$(calculate_layer_disk_usage "${layer_ids[@]}")
local actual_size_mb=$((actual_size / 1024 / 1024))
# Calculate total size (including duplicates for reference)
local total_size=0
for layer_id in "${layer_ids[@]}"; do
local layer_dir="$COMPOSEFS_DIR/layers/$layer_id"
local layer_metadata="$layer_dir/metadata.json"
if [[ -f "$layer_metadata" ]]; then
local layer_size
layer_size=$(jq -r '.size' "$layer_metadata")
total_size=$((total_size + layer_size))
fi
done
local total_size_mb=$((total_size / 1024 / 1024))
# Show both actual and total sizes
if [[ $actual_size -eq $total_size ]]; then
echo " $image_name (created: $created, layers: $layers, size: ${actual_size_mb}MB)"
else
local savings_mb=$((total_size_mb - actual_size_mb))
echo " $image_name (created: $created, layers: $layers, size: ${actual_size_mb}MB, total: ${total_size_mb}MB, saved: ${savings_mb}MB via deduplication)"
fi
else
echo " $image_name (incomplete)"
fi
fi
done
}
# List mounted composefs images
list_mounts() {
log_info "Currently Mounted Composefs Images:" "composefs-alternative"
if [[ ! -d "$COMPOSEFS_DIR/mounts" ]]; then
log_info "No mounts found" "composefs-alternative"
return 0
fi
local mount_count=0
for mount_info in "$COMPOSEFS_DIR/mounts"/*.json; do
if [[ -f "$mount_info" ]]; then
local mount_point
local image_name
local mounted_at
mount_point=$(jq -r '.mount_point' "$mount_info")
image_name=$(jq -r '.image' "$mount_info")
mounted_at=$(jq -r '.mounted_at' "$mount_info")
echo " $image_name -> $mount_point (mounted: $mounted_at)"
mount_count=$((mount_count + 1))
fi
done
if [[ $mount_count -eq 0 ]]; then
log_info "No active mounts" "composefs-alternative"
fi
}
# PERFORMANCE: Optimized layer listing with caching
list_layers() {
log_info "Available Composefs Layers:" "composefs-alternative"
if [[ ! -d "$COMPOSEFS_DIR/layers" ]]; then
log_info "No layers found" "composefs-alternative"
return 0
fi
local layer_count=0
local total_size=0
# Pre-calculate layer references for better performance
local -A layer_references
for image_dir in "$COMPOSEFS_DIR/images"/*; do
if [[ -d "$image_dir" ]]; then
local image_metadata="$image_dir/metadata.json"
if [[ -f "$image_metadata" ]]; then
while IFS= read -r layer_id; do
layer_references["$layer_id"]=$((layer_references["$layer_id"] + 1))
done < <(jq -r '.layers[]' "$image_metadata")
fi
fi
done
for layer_dir in "$COMPOSEFS_DIR/layers"/*; do
if [[ -d "$layer_dir" ]]; then
local layer_id
layer_id=$(basename "$layer_dir")
local metadata_file="$layer_dir/metadata.json"
if [[ -f "$metadata_file" ]]; then
local created
local size
local source
local reference_count=${layer_references["$layer_id"]:-0}
created=$(jq -r '.created' "$metadata_file")
size=$(jq -r '.size' "$metadata_file")
source=$(jq -r '.source' "$metadata_file")
local size_mb=$((size / 1024 / 1024))
total_size=$((total_size + size))
if [[ $reference_count -eq 0 ]]; then
echo " $layer_id (created: $created, size: ${size_mb}MB, source: $source, references: 0 - UNREFERENCED)"
elif [[ $reference_count -eq 1 ]]; then
echo " $layer_id (created: $created, size: ${size_mb}MB, source: $source, references: $reference_count)"
else
echo " $layer_id (created: $created, size: ${size_mb}MB, source: $source, references: $reference_count - SHARED)"
fi
layer_count=$((layer_count + 1))
else
echo " $layer_id (incomplete)"
fi
fi
done
local total_size_mb=$((total_size / 1024 / 1024))
echo
log_info "Layer Summary: $layer_count layers, total size: ${total_size_mb}MB" "composefs-alternative"
}
# Show comprehensive system status
show_status() {
echo "=== Composefs Alternative Status ==="
echo
# System information
echo "System Information:"
get_system_info
echo
# Storage information
echo "Storage Information:"
local composefs_size
composefs_size=$(du -sb "$COMPOSEFS_DIR" 2>/dev/null | cut -f1 || echo "0")
local composefs_size_mb=$((composefs_size / 1024 / 1024))
echo " Composefs directory size: ${composefs_size_mb}MB"
local available_space_mb
available_space_mb=$(get_available_space "$COMPOSEFS_DIR")
local available_space_gb=$((available_space_mb / 1024))
echo " Available space: ${available_space_gb}GB"
echo
# Images and layers
list_images
echo
list_mounts
echo
list_layers
echo
# Health check
echo "Health Check:"
local health_issues=0
# Check for orphaned mounts
for mount_info in "$COMPOSEFS_DIR/mounts"/*.json; do
if [[ -f "$mount_info" ]]; then
local mount_point
mount_point=$(jq -r '.mount_point' "$mount_info" 2>/dev/null)
if [[ -n "$mount_point" && "$mount_point" != "null" ]]; then
if ! mountpoint -q "$mount_point" 2>/dev/null; then
echo " ⚠️ Orphaned mount info: $mount_info"
health_issues=$((health_issues + 1))
fi
fi
fi
done
# Check for unreferenced layers
local unreferenced_count=0
for layer_dir in "$COMPOSEFS_DIR/layers"/*; do
if [[ -d "$layer_dir" ]]; then
local layer_id
layer_id=$(basename "$layer_dir")
local is_referenced=false
for image_dir in "$COMPOSEFS_DIR/images"/*; do
if [[ -d "$image_dir" ]]; then
local metadata_file="$image_dir/metadata.json"
if [[ -f "$metadata_file" ]]; then
if jq -e --arg layer "$layer_id" '.layers[] | select(. == $layer)' "$metadata_file" >/dev/null 2>&1; then
is_referenced=true
break
fi
fi
fi
done
if [[ "$is_referenced" == false ]]; then
unreferenced_count=$((unreferenced_count + 1))
fi
fi
done
if [[ $unreferenced_count -gt 0 ]]; then
echo " ⚠️ $unreferenced_count unreferenced layers found (run 'cleanup' to remove)"
health_issues=$((health_issues + 1))
fi
if [[ $health_issues -eq 0 ]]; then
echo " ✓ System healthy"
else
echo " ⚠️ $health_issues health issues found"
fi
}