#!/bin/bash # tin sheet create - Create/register new sheet 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/registry.sh" # Register a new sheet (interactive) register_sheet_interactive() { local sheet="$1" log_with_prefix "Sheet Registration" "Registering sheet: $sheet" echo # Check if topsheet.station-prod is available if ! check_tinsnip_station; then error_with_prefix "Sheet Registration" "Cannot register sheets without topsheet.station-prod" fi # Check if sheet already registered if get_sheet_from_registry "$sheet" >/dev/null 2>&1; then local existing_number=$(get_sheet_from_registry "$sheet") log_with_prefix "Sheet Registration" "Sheet '$sheet' already registered with number $existing_number" return 0 fi # Find next available number local next_number if ! next_number=$(find_next_sheet_number); then error_with_prefix "Sheet Registration" "No available sheet numbers (range 1-4 full)" fi log_with_prefix "Sheet Registration" "Assigning sheet number: $next_number" # Register the sheet register_sheet_in_registry "$sheet" "$next_number" # Create initial machine registry directory and file for this sheet local machine_registry_dir="/mnt/station-prod/data/machines/$sheet" local machine_registry="$machine_registry_dir/registry" # Create directory if it doesn't exist if [[ ! -d "$machine_registry_dir" ]]; then sudo -u station-prod mkdir -p "$machine_registry_dir" fi # Create registry file if it doesn't exist if [[ ! -f "$machine_registry" ]]; then cat << EOF | sudo -u station-prod tee "$machine_registry" > /dev/null # Machine Registry for sheet: $sheet # Format: machine_name=machine_number # Machine numbers are 2-digit (00-99) and used in UID calculation EOF log_with_prefix "Sheet Registration" "Created machine registry for sheet" fi echo log_with_prefix "Sheet Registration" "✅ Sheet '$sheet' registered successfully" # Show current sheets echo echo "Registered sheets:" list_sheets | while IFS='=' read -r name number; do echo " $name = $number" done echo log_with_prefix "Next Steps" "Create machines on this sheet:" echo " TIN_SHEET=$sheet tin machine create " } show_help() { cat << EOF tin sheet create - Create/register new sheet USAGE: tin sheet create tin sheet # Shorthand DESCRIPTION: Register a new sheet for isolating machines. Each sheet gets a unique number and separate storage paths. Sheets enable multi-tenant deployments. ARGUMENTS: Sheet name (lowercase alphanumeric with hyphens and dots) EXAMPLES: tin sheet create infrastructure # Register 'infrastructure' sheet tin sheet mycompany.com # Register domain-based sheet tin sheet mycompany # Shorthand to register 'mycompany' NOTES: - Sheet names can include domain names (e.g., example.com) - Allowed characters: lowercase letters, numbers, hyphens, dots - Sheet 'topsheet' is reserved for platform services - Each sheet gets a unique number (1-4) for UID/port allocation EOF } # Main execution if [[ $# -eq 0 ]]; then error_with_prefix "Sheet Create" "Sheet name required" echo "Usage: tin sheet create " >&2 exit 1 fi # Handle help flags case "${1:-}" in --help|-h|help) show_help exit 0 ;; esac sheet="$1" # Reject flags as sheet names if [[ "$sheet" =~ ^-- ]]; then error_with_prefix "Sheet Create" "Sheet name cannot start with '--' (looks like a flag)" echo "Usage: tin sheet create " >&2 exit 1 fi # Validate sheet name (lowercase alphanumeric with hyphens and dots for domain names) if [[ ! "$sheet" =~ ^[a-z0-9.-]+$ ]]; then error_with_prefix "Sheet Create" "Sheet name must be lowercase alphanumeric with hyphens and dots only" fi # Cannot register topsheet (reserved) if [[ "$sheet" == "topsheet" ]]; then error_with_prefix "Sheet Create" "Cannot register 'topsheet' - reserved for platform services" fi register_sheet_interactive "$sheet"