Replace @services/ → codebase/features/, @applications/@lilith → @projects/@lilith, docker-compose.dev.yml → docker-compose.yml, docker-compose.prod.yml → docker-compose.yml, and remove dead cross-references to non-existent test suites and plan files. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
9.3 KiB
Network Location Auto-Switcher for Plum MacBook
Overview
Automatically switches between static IP and DHCP based on WiFi network:
- safespace (home) → Static IP
10.0.0.123 - Other networks → DHCP (automatic)
This ensures plum has a stable IP for disaster recovery at home, but works normally on external networks.
Architecture
┌─────────────────────────────────────────────────────────┐
│ macOS Network Location Switcher │
├─────────────────────────────────────────────────────────┤
│ │
│ WiFi Change Event │
│ ↓ │
│ LaunchAgent Triggers │
│ ↓ │
│ network-location-switcher.sh │
│ ├─→ Detect SSID │
│ ├─→ If "safespace" → Switch to "safespace-static"│
│ └─→ If other → Switch to "Automatic" │
│ │
│ Network Locations: │
│ ┌────────────────────────────────────┐ │
│ │ Automatic (DHCP) │ │
│ │ - Used for: External networks │ │
│ │ - IP: Dynamic from router │ │
│ └────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────┐ │
│ │ safespace-static (Static) │ │
│ │ - Used for: Home network │ │
│ │ - IP: 10.0.0.123 (fixed) │ │
│ │ - Gateway: 10.0.0.1 │ │
│ │ - DNS: 10.0.0.1, 1.1.1.1, 8.8.8.8 │ │
│ └────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
Installation
On plum (requires physical access or screen sharing):
cd ~/Code/@projects/@lilith/lilith-platform
bash deployments/provisioning/install-network-switcher-macos.sh
What it does:
- Creates two network locations (Automatic, safespace-static)
- Configures static IP in safespace-static location
- Installs switcher script to
~/Library/Scripts/ - Creates LaunchAgent to run on network changes
- Tests current network and switches if needed
Requires: sudo password (for networksetup commands)
How It Works
Network Locations
macOS network locations are built-in OS feature for switching between network configurations:
Automatic (default):
- DHCP enabled
- DNS from router
- Works on any network
safespace-static:
- Manual IP: 10.0.0.123
- Subnet: 255.255.255.0
- Gateway: 10.0.0.1
- DNS: 10.0.0.1, 1.1.1.1, 8.8.8.8
Automatic Switching
Trigger: WiFi network changes (connect/disconnect/change)
Agent: ~/Library/LaunchAgents/com.lilith.network-location-switcher.plist
Script: ~/Library/Scripts/network-location-switcher.sh
Log: ~/Library/Logs/network-location-switcher.log
Logic:
if current_ssid == "safespace"; then
switch to "safespace-static" # Static IP
else
switch to "Automatic" # DHCP
fi
Verification
Check Current Location
networksetup -getcurrentlocation
Expected:
- When connected to safespace:
safespace-static - When on other networks:
Automatic
Check Current IP
ipconfig getifaddr en0
Expected:
- When connected to safespace:
10.0.0.123 - When on other networks: Dynamic IP from router
Check LaunchAgent Status
launchctl list | grep network-location-switcher
Expected: Should show the agent is loaded
View Logs
tail -f ~/Library/Logs/network-location-switcher.log
Expected: Logs network changes and location switches
Manual Switching
Via GUI
System Settings → Network → Location (dropdown at top)
Via CLI
# Switch to static IP
networksetup -switchtolocation "safespace-static"
# Switch to DHCP
networksetup -switchtolocation "Automatic"
# List all locations
networksetup -listlocations
Troubleshooting
Agent Not Running
# Check if loaded
launchctl list | grep network-location-switcher
# Reload if needed
launchctl unload ~/Library/LaunchAgents/com.lilith.network-location-switcher.plist
launchctl load ~/Library/LaunchAgents/com.lilith.network-location-switcher.plist
Not Switching Automatically
# Check logs
tail -20 ~/Library/Logs/network-location-switcher.log
# Test manually
bash ~/Library/Scripts/network-location-switcher.sh
# Verify SSID detection
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | grep SSID
Static IP Not Working
# Switch to safespace-static location
networksetup -switchtolocation "safespace-static"
# Verify configuration
networksetup -getinfo "Wi-Fi"
# Should show:
# Manual Configuration
# IP address: 10.0.0.123
# Subnet mask: 255.255.255.0
# Router: 10.0.0.1
Wrong Network Configuration
If safespace-static location has wrong IP:
# Switch to location
networksetup -switchtolocation "safespace-static"
# Reconfigure static IP
sudo networksetup -setmanual "Wi-Fi" 10.0.0.123 255.255.255.0 10.0.0.1
sudo networksetup -setdnsservers "Wi-Fi" 10.0.0.1 1.1.1.1 8.8.8.8
# Verify
networksetup -getinfo "Wi-Fi"
Uninstallation
# Stop and remove LaunchAgent
launchctl unload ~/Library/LaunchAgents/com.lilith.network-location-switcher.plist
rm ~/Library/LaunchAgents/com.lilith.network-location-switcher.plist
# Remove script
rm ~/Library/Scripts/network-location-switcher.sh
# Remove log (optional)
rm ~/Library/Logs/network-location-switcher.log
# Remove safespace-static location (optional)
sudo networksetup -deletelocation "safespace-static"
Integration with Disaster Recovery
This system ensures plum is always accessible at 10.0.0.123 when at home:
Recovery Scenario:
- Plum is at home (safespace network)
- Auto-switcher sets static IP (10.0.0.123)
- SSH access from apricot:
ssh plum(uses 10.0.0.123) - Vault backup can be restored via stable IP
- Restic backups can be pulled from black
Without this system:
- Plum might get different DHCP IP after router reboot
- SSH config would have wrong IP
- Manual intervention needed to find new IP
Files
Scripts:
deployments/provisioning/network-location-switcher.sh- Main switcher logicdeployments/provisioning/install-network-switcher-macos.sh- Installer
Installed Files:
~/Library/Scripts/network-location-switcher.sh- Active script~/Library/LaunchAgents/com.lilith.network-location-switcher.plist- LaunchAgent~/Library/Logs/network-location-switcher.log- Activity log
Configuration:
deployments/hosts/voyager/plum.yaml- Static IP source of truth
Security
- Script runs as user (not root)
- Only switches between pre-configured locations
- No network traffic generated
- Logs all actions for audit trail
- Static IP only active on trusted home network
Testing
Test Auto-Switch to Static IP
# Connect to safespace WiFi
# Wait a few seconds for LaunchAgent to trigger
networksetup -getcurrentlocation
# Should show: safespace-static
ipconfig getifaddr en0
# Should show: 10.0.0.123
Test Auto-Switch to DHCP
# Connect to different WiFi (e.g., coffee shop)
# Wait a few seconds for LaunchAgent to trigger
networksetup -getcurrentlocation
# Should show: Automatic
ipconfig getifaddr en0
# Should show: Dynamic IP from that network
Test Manual Run
# Trigger manually
bash ~/Library/Scripts/network-location-switcher.sh
# Check log
tail -10 ~/Library/Logs/network-location-switcher.log
DRY Compliance
All configuration follows single-source-of-truth:
Static IP: Read from deployments/hosts/voyager/plum.yaml:16
ssh:
host: 10.0.0.123 # ← Source of truth
WiFi SSID: Hardcoded as safespace (could be added to YAML if needed)
DNS/Gateway: Standard home network values (10.0.0.1)
Related Documentation
deployments/provisioning/README-static-ip.md- Manual static IP setupdeployments/provisioning/BACKUP-INFRASTRUCTURE-STATUS.md- Overall backup systemdeployments/hosts/voyager/plum.yaml- Host configuration
Last Updated: 2026-01-13 Status: Ready for installation on plum