- 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
238 lines
No EOL
8.6 KiB
Bash
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
|
|
} |