homelab infrastructure services

Implementation Plan: tinsnip CLI Evolution#

Overview#

Transform tinsnip from script-based to modern CLI with centralized sheet management, automated NAS credential handling, and improved UX.

Phase 1: Bootstrap topsheet (Foundation)#

1.1 Create topsheet Infrastructure#

Goal: Establish reserved sheet 5 (topsheet) for tinsnip infrastructure services

Tasks:

  • Update lib/uid.sh to reserve sheet 5 for topsheet
  • Modify sheet number calculation to handle reserved sheet
  • Create topsheet bootstrap capability

Files modified:

  • lib/uid.sh: Added get_sheet_number() reservation logic for topsheet
  • Machine setup: Added special handling for topsheet

Implementation:

# In lib/uid.sh
get_sheet_number() {
    local sheet="${1:-${TIN_SHEET:-topsheet}}"
    if [[ "$sheet" == "topsheet" ]]; then
        echo "5"  # Reserved for topsheet
        return
    fi
    # Registry lookup for user sheets (1-4)
}

1.2 Create topsheet.station-prod Service#

Goal: Deploy the special station with global registries

Tasks:

  • Create service/station/ directory structure
  • Create docker-compose.yml for station service
  • Add registry initialization scripts
  • Set up NAS credential storage structure

Files to create:

  • service/station/docker-compose.yml
  • service/station/setup.sh
  • service/station/scripts/init-registries.sh

Registry Structure:

/volume1/topsheet/station/prod/data/
├── sheets               # Global sheet registry
├── services/            # Per-sheet service registries
│   └── topsheet        # topsheet services registry
└── nas-credentials/     # SSH keys for NAS access
    ├── DS412plus.key
    └── authorized_keys

Phase 2: Sheet Registry Implementation#

2.1 Collision Detection and Registry#

Goal: Prevent sheet number collisions

Tasks:

  • Create sheet collision detection in lib.sh
  • Implement registry consultation before assignment
  • Add registry update functions
  • Create sheet registration workflow

Files to modify:

  • machine/scripts/lib.sh: Add registry functions
  • machine/setup.sh: Add collision checking

Implementation:

# In lib/registry.sh
register_sheet_in_registry() {
    local sheet="$1"
    local number="$2"
    local registry="/mnt/station-prod/data/sheets"

    # Check if already registered
    if grep -q "^${sheet}=" "$registry" 2>/dev/null; then
        error "Sheet already registered"
        return 1
    fi

    # Add to registry (user sheets use 1-4, topsheet is 5)
    echo "${sheet}=${number}" >> "$registry"
}

2.2 Update Existing Sheet Functions#

Goal: Make all sheet operations registry-aware

Tasks:

  • Modify get_sheet_number() to consult registry
  • Update all scripts to use registry-based assignment
  • Add validation for sheet conflicts

Phase 3: NAS Credential Management#

3.1 SSH Key Infrastructure#

Goal: Eliminate interactive password prompts

Tasks:

  • Create SSH key generation and distribution system
  • Modify NAS setup scripts to use stored keys
  • Add key management functions to tinsnip.station-prod

Files to modify:

  • machine/scripts/mount_nas.sh: Replace password logic with key-based auth
  • service/station/scripts/manage-nas-keys.sh: New key management script

Implementation:

# In mount_nas.sh
setup_nas_exports() {
    local nas_server="$1"
    local ssh_key="/volume1/tinsnip/station-prod/data/nas-credentials/${nas_server}.key"
    
    # Use stored SSH key instead of prompting for password
    ssh -i "$ssh_key" "$nas_server" "sudo mkdir -p '$nfs_export'"
}

3.2 Automated NAS Discovery#

Goal: Remove NAS parameter from machine setup

Tasks:

  • Create NAS server registry in tinsnip.station-prod
  • Implement NAS auto-discovery based on sheet
  • Update machine setup to query NAS from registry

Registry Structure:

/volume1/topsheet/station/prod/data/nas-credentials/nas-servers
# Format: sheet=nas_server
topsheet=DS412plus.local
infrastructure=DS412plus.local
mycompany=nas2.company.com

Phase 4: Modern CLI Implementation#

4.1 Create tin Command Structure#

Goal: Replace script-based workflow with modern CLI

Tasks:

  • Create bin/tin main CLI script
  • Implement subcommand routing
  • Add verbless command pattern
  • Create help system

Files to create:

  • bin/tin: Main CLI entry point
  • bin/tin-sheet: Sheet management subcommand
  • bin/tin-machine: Machine setup subcommand
  • bin/tin-service: Service deployment subcommand

CLI Structure:

#!/bin/bash
# bin/tin
case "$1" in
    sheet) shift; exec tin-sheet "$@" ;;
    machine)   shift; exec tin-machine "$@" ;;
    service)   shift; exec tin-service "$@" ;;
    *) tin-help ;;
esac

4.2 Implement Subcommands#

Goal: Create intuitive verbless commands

Tasks:

  • tin sheet <name>: Register new sheet
  • tin machine <service> <env>: Create service environment
  • tin service <service-env> <catalog-entry>: Deploy service
  • Add list, status, remove variations

Command Examples:

# Most users just use topsheet (default)
tin machine gazette prod DS412plus   # Create gazette-prod in topsheet
tin service gazette-prod lldap       # Deploy lldap to gazette-prod

# Advanced: Register additional sheets for multi-tenant
tin sheet infrastructure             # Register user sheet
TIN_SHEET=infrastructure tin machine gazette prod

Phase 5: Service Catalog Integration#

5.1 Move Service Catalog to topsheet.station-prod#

Goal: Centralize service definitions

Tasks:

  • Migrate service catalog from separate repo to topsheet.station-prod
  • Update service deployment to use centralized catalog
  • Add catalog management commands

Structure:

/volume1/topsheet/station/prod/data/catalog/
├── lldap/
│   ├── docker-compose.yml
│   └── setup.sh
├── redis/
└── prometheus/

5.2 Service Deployment Automation#

Goal: Streamline service deployment

Tasks:

  • Implement automatic service copying from catalog
  • Add environment variable generation
  • Create service status monitoring

Phase 6: Migration and Documentation#

6.1 Backward Compatibility#

Goal: Ensure existing deployments continue working

Tasks:

  • Create migration script for existing installations
  • Add legacy command compatibility layer
  • Update all documentation

6.2 Documentation Updates#

Goal: Document new CLI and architecture

Tasks:

  • Update CLAUDE.md with new workflow
  • Create CLI reference documentation
  • Add migration guide from script-based to CLI-based workflow

Implementation Order#

  1. ✅ Phase 1 COMPLETED: Bootstrap topsheet and station infrastructure
  2. ✅ Phase 2 COMPLETED: Registry functionality to prevent collisions
  3. ✅ Phase 3 COMPLETED: NAS credential management infrastructure
  4. ✅ Phase 4 COMPLETED: Modern CLI interface
  5. Phase 5 IN PROGRESS: Service catalog integration
  6. Phase 6 PENDING: Migration and documentation

Each phase builds on the previous and can be tested independently. Most users will deploy all services to topsheet (the default). Advanced multi-tenant setups can use additional sheets (1-4).

Architecture Summary#

Before (Current)#

  • Script-based workflow with manual NAS parameter
  • Hash-based sheet numbers (collision-prone)
  • Interactive password prompts for NAS access
  • Separate service catalog repository
  • Manual service deployment

After (Current Implementation)#

  • ✅ Modern CLI with verbless commands
  • ✅ Registry-based sheet management (collision-free)
  • ✅ SSH key infrastructure for NAS access
  • 🚧 Centralized service catalog in topsheet.station-prod (in progress)
  • 🚧 Automated service deployment with auto-discovery (in progress)

Key Benefits Achieved#

  • UX: Simple commands with sensible defaults
  • Security: SSH key infrastructure available
  • Reliability: Registry prevents UID/port collisions
  • Flexibility: topsheet for most users, additional sheets for advanced multi-tenant scenarios
  • Consistency: Standardized SMEP UID scheme across all deployments