# Sheet Configuration Sheets are tinsnip's organizational unit for isolating different service deployments. Each sheet provides complete isolation with its own UID ranges, storage paths, and service deployments. ## Architecture Overview **Key Design Principles:** - **One Global Station**: Only topsheet has a station (UID 50000) that manages registries for ALL sheets - **Explicit Registration**: Sheet numbers (1-4) are explicitly assigned via `tin sheet create` - **Shared Registry Access**: All machines mount `/mnt/station-prod` to access registries - **UID Isolation**: Each sheet's services use unique UID ranges based on the sheet number ## Sheet Number Assignment Sheets are assigned numbers when registered: - **Sheet 1-4**: User sheets assigned sequentially via `tin sheet create` - **Sheet 5**: Reserved for topsheet (default/infrastructure sheet) The sheet number becomes the first digit in the SMEP UID scheme: - Sheet 1 services: UIDs 10000-19999 - Sheet 2 services: UIDs 20000-29999 - Sheet 3 services: UIDs 30000-39999 - Sheet 4 services: UIDs 40000-49999 - Sheet 5 (topsheet): UIDs 50000-59999 ## Quick Start: Working with Sheets ### Default Setup (Single Sheet) Most users only need topsheet: ```bash # First-time setup: Create topsheet station (only needed once) tin machine station prod # Create machines on topsheet (no TIN_SHEET needed - topsheet is default) tin machine create myservice prod tin machine create myservice dev ``` ### Multi-Sheet Setup For multi-tenant or organization isolation: ```bash # Step 1: Ensure topsheet station exists (only needed once for all sheets) tin machine station prod # Step 2: Register a new sheet tin sheet create company-a # Output: Sheet 'company-a' registered as sheet number 1 # Step 3: Create machines on the new sheet TIN_SHEET=company-a tin machine create app prod TIN_SHEET=company-a tin machine create app dev # Step 4: Register another sheet tin sheet create company-b # Output: Sheet 'company-b' registered as sheet number 2 # Step 5: Create machines on second sheet TIN_SHEET=company-b tin machine create app prod ``` ## Registry Architecture The station (at `/mnt/station-prod`) maintains three registries accessible to all sheets: ### 1. Sheet Registry **Location**: `/mnt/station-prod/data/sheets` Maps sheet names to numbers (1-4 for user sheets, 5 for topsheet): ``` topsheet=5 company-a=1 company-b=2 ``` **Management**: ```bash tin sheet create # Register new sheet (auto-assigns next number) tin sheet list # Show all registered sheets tin sheet show # Show sheet details tin sheet rm # Remove sheet (cascades to all machines) ``` ### 2. Machine Registries **Location**: `/mnt/station-prod/data/machines/` Each sheet has its own machine registry file mapping machine names to 2-digit numbers: ``` # /mnt/station-prod/data/machines/company-a app=01 database=02 cache=03 ``` Services are auto-registered when machines are created. ### 3. NAS Registry **Location**: `/mnt/station-prod/data/nas-credentials/nas-servers` Maps sheets to their NAS servers for convenience: ``` topsheet=DS412plus.local company-a=nas1.company-a.com company-b=nas2.company-b.com ``` Allows omitting NAS server from commands after initial setup. ## Sheet Detection Sheet is determined in this priority order: 1. **Environment variable**: `TIN_SHEET=company-a` 2. **System file**: `/etc/tinsnip-sheet` 3. **Default**: `topsheet` ### Setting Sheet Context **Per-command** (recommended for multi-sheet): ```bash TIN_SHEET=company-a tin machine create app prod nas1.example.com ``` **Environment variable** (for session): ```bash export TIN_SHEET=company-a tin machine create app prod nas1.example.com tin machine create app dev nas1.example.com ``` **System-wide** (for single sheet setups): ```bash echo "company-a" | sudo tee /etc/tinsnip-sheet tin machine create app prod nas1.example.com # Uses company-a automatically ``` ## Storage Isolation Each sheet uses separate NFS paths on the NAS: **Sheet 'company-a' (number 1):** ``` NAS paths: /volume1/tinsnip/company-a/station/prod (if creating per-sheet station) /volume1/tinsnip/company-a/app/prod /volume1/tinsnip/company-a/app/dev Machine mount points: /mnt/station-prod → topsheet station (shared) /mnt/app-prod → /volume1/tinsnip/company-a/app/prod /mnt/app-dev → /volume1/tinsnip/company-a/app/dev ``` **Sheet 'company-b' (number 2):** ``` NAS paths: /volume1/tinsnip/company-b/app/prod /volume1/tinsnip/company-b/app/dev Machine mount points: /mnt/station-prod → topsheet station (shared) /mnt/app-prod → /volume1/tinsnip/company-b/app/prod /mnt/app-dev → /volume1/tinsnip/company-b/app/dev ``` ## UID and Port Isolation The SMEP scheme ensures complete UID/port isolation: **Format**: `S-M-E-P` where: - `S` = Sheet number (1-5) - `M` = Machine number (00-99, auto-assigned) - `E` = Environment (0=prod, 1=test, 2=dev, etc.) - `P` = Port index (0-9) **Examples**: Sheet 1 (company-a): - `app-prod` user: UID 10100 (sheet=1, service=01, env=0, port=0) - `app-dev` user: UID 10120 (sheet=1, service=01, env=2, port=0) - Ports: 10100-10109 for app-prod, 10120-10129 for app-dev Sheet 2 (company-b): - `app-prod` user: UID 20100 (sheet=2, service=01, env=0, port=0) - `app-dev` user: UID 20120 (sheet=2, service=01, env=2, port=0) - Ports: 20100-20109 for app-prod, 20120-20129 for app-dev Topsheet (sheet 5): - `app-prod` user: UID 50100 (sheet=5, service=01, env=0, port=0) - Ports: 50100-50109 for app-prod ## Complete Multi-Sheet Example Setting up two isolated organizations: ```bash # === Initial Setup (Once) === # Create topsheet station for registry infrastructure tin machine station prod DS412plus.local # === Company A Setup === # Register sheet tin sheet create company-a # Create machines TIN_SHEET=company-a tin machine create web prod nas-a.example.com TIN_SHEET=company-a tin machine create api prod nas-a.example.com TIN_SHEET=company-a tin machine create db prod nas-a.example.com # Deploy services TIN_SHEET=company-a tin service deploy web-prod nginx TIN_SHEET=company-a tin service deploy api-prod myapi TIN_SHEET=company-a tin service deploy db-prod postgres # === Company B Setup === # Register sheet tin sheet create company-b # Create machines (different NAS, same service names - no conflict!) TIN_SHEET=company-b tin machine create web prod nas-b.example.com TIN_SHEET=company-b tin machine create api prod nas-b.example.com TIN_SHEET=company-b tin machine create db prod nas-b.example.com # Deploy services TIN_SHEET=company-b tin service deploy web-prod nginx TIN_SHEET=company-b tin service deploy api-prod myapi TIN_SHEET=company-b tin service deploy db-prod postgres ``` **Result**: - Company A: UIDs 10100, 10200, 10300 / Ports 10100+, 10200+, 10300+ - Company B: UIDs 20100, 20200, 20300 / Ports 20100+, 20200+, 20300+ - Complete storage, UID, and port isolation - Both can have services with identical names without conflict ## Sheet Limits - **Maximum sheets**: 4 user sheets + 1 topsheet = 5 total - **Rationale**: Single-digit sheet number in SMEP scheme - **Workaround**: For >4 sheets, deploy separate tinsnip infrastructure ## NAS Configuration tinsnip automatically creates NFS exports with correct permissions during `tin machine create`. No manual NAS configuration required. **Behind the scenes** (for reference): ```bash # On NAS, tinsnip creates exports like: /volume1/tinsnip/company-a/app/prod host(rw,async,no_subtree_check,all_squash,anonuid=10100,anongid=10100) /volume1/tinsnip/company-b/app/prod host(rw,async,no_subtree_check,all_squash,anonuid=20100,anongid=20100) ``` The `all_squash` with `anonuid` ensures all writes from the machine appear as the correct service UID on the NAS. ## Troubleshooting ### "Sheet not registered" error ```bash [ERROR] Sheet 'mysheet' not registered ``` **Solution**: Register the sheet first: ```bash tin sheet create mysheet ``` ### "Service registry not found" error ```bash [ERROR] Machine registry not found: /mnt/station-prod/data/machines/mysheet ``` **Solution**: Ensure topsheet station exists and sheet is registered: ```bash # Check if station mounted mount | grep station-prod # If not, create it tin machine station prod # Then register sheet tin sheet create mysheet ``` ### UID conflicts between sheets UIDs should never conflict if sheets are properly registered. Verify sheet numbers: ```bash tin sheet list ``` ### Cannot access registries All machines need `/mnt/station-prod` mounted. Verify: ```bash mount | grep station-prod ls -la /mnt/station-prod/data/ ``` If missing, ensure topsheet station was created with `tin machine station prod `.