#!/bin/bash # tin sheet rm - Remove sheet and all its machines set -euo pipefail # Get tinsnip root and source libraries SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" TINSNIP_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")" source "$TINSNIP_ROOT/lib/core.sh" source "$TINSNIP_ROOT/lib/uid.sh" source "$TINSNIP_ROOT/lib/registry.sh" # Remove sheet and cascade to machines remove_sheet() { local sheet="$1" local delete_data="${2:-false}" log_with_prefix "Sheet Remove" "Removing sheet: $sheet" echo # Check if sheet exists local sheet_num if ! sheet_num=$(get_sheet_number "$sheet" 2>/dev/null); then error_with_prefix "Sheet Remove" "Sheet '$sheet' is not registered" echo "Available sheets:" >&2 list_sheets | while IFS='=' read -r name number; do echo " $name (sheet $number)" >&2 done exit 1 fi echo "Sheet Details:" echo " Name: $sheet" echo " Number: $sheet_num" echo # Find all machines on this sheet local machines=() for user_entry in $(getent passwd | grep "^[^:]*:[^:]*:[0-9]\{5\}:"); do local username=$(echo "$user_entry" | cut -d: -f1) local uid=$(echo "$user_entry" | cut -d: -f3) # Extract sheet number from UID (first digit) local user_sheet_num="${uid:0:1}" # Check if this user belongs to this sheet if [[ "$user_sheet_num" == "$sheet_num" ]]; then machines+=("$username") fi done if [[ ${#machines[@]} -gt 0 ]]; then echo "WARNING: Found ${#machines[@]} machine(s) on this sheet:" for machine in "${machines[@]}"; do echo " - $machine" done echo read -p "Remove all machines first? [Y/n]: " remove_machines case "${remove_machines:-y}" in [Yy]*|"") for machine in "${machines[@]}"; do log_with_prefix "Sheet Remove" "Removing machine: $machine" if [[ "$delete_data" == "true" ]]; then # Use --no-confirm to skip prompts but keep stdin as terminal for NAS deletion "$TINSNIP_ROOT/cmd/machine/rm.sh" "$machine" --delete-data --no-confirm else "$TINSNIP_ROOT/cmd/machine/rm.sh" "$machine" --no-confirm fi done echo ;; *) log_with_prefix "Sheet Remove" "Removal cancelled" exit 0 ;; esac fi # Remove sheet from registry echo log_with_prefix "Sheet Remove" "Removing from sheet registry..." # Check if we're removing topsheet if [[ "$sheet" == "topsheet" ]]; then error_with_prefix "Sheet Remove" "Cannot remove topsheet (infrastructure sheet)" echo "The topsheet contains the station machine and registry." >&2 exit 1 fi # Remove from station registry (as station-prod) if [[ -f "$SHEET_REGISTRY" ]]; then sudo -u station-prod sed -i "/^${sheet}=/d" "$SHEET_REGISTRY" echo " SUCCESS: Removed from sheet registry" fi # Remove per-sheet machine registry file (as station-prod) local machine_registry="$MACHINE_REGISTRY_DIR/$sheet" if [[ -f "$machine_registry" ]]; then log_with_prefix "Sheet Remove" "Removing machine registry for sheet..." sudo -u station-prod rm -f "$machine_registry" echo " SUCCESS: Removed machine registry" fi echo log_with_prefix "Sheet Remove" "SUCCESS: Sheet '$sheet' removed successfully" if [[ "$delete_data" != "true" ]]; then echo echo "NAS data preserved. To restore:" echo " tin sheet create $sheet" echo " tin machine create " fi } show_help() { cat << EOF tin sheet rm - Remove sheet and all its machines USAGE: tin sheet rm [--delete-data] DESCRIPTION: Remove a sheet including all its machines and catalog services. By default, NAS data is PRESERVED for recovery. Automatically removes all machines (which cascade to catalog services). ARGUMENTS: Sheet to remove (e.g., infrastructure) OPTIONS: --delete-data Also delete ALL data on NAS for this sheet (DANGEROUS!) EXAMPLES: tin sheet rm infrastructure # Remove sheet, keep NAS data tin sheet rm infrastructure --delete-data # Remove sheet AND delete ALL NAS data NOTES: - Automatically removes all machines on the sheet (with confirmation) - Each machine removal cascades to its catalog services - Default behavior preserves NAS data (CD-friendly) - Sheet can be recreated and machines restored from preserved data - Use --delete-data only when permanently decommissioning entire sheet WARNING: --delete-data will PERMANENTLY DELETE all data for all catalog services on this sheet! Cannot remove 'topsheet' (infrastructure sheet containing station registry) EOF } # Handle help flags case "${1:-}" in --help|-h|help) show_help exit 0 ;; esac # Main execution if [[ $# -eq 0 ]]; then error_with_prefix "Sheet Remove" "Sheet name required" echo "Usage: tin sheet rm [--delete-data]" >&2 exit 1 fi sheet="$1" delete_data="false" if [[ "${2:-}" == "--delete-data" ]]; then delete_data="true" fi remove_sheet "$sheet" "$delete_data"