homelab infrastructure services
1#!/bin/bash
2
3# Setup a complete service environment with NFS and rootless Docker
4# Implements DEPLOYMENT_STRATEGY.md conventions
5
6set -euo pipefail
7
8# Required parameters
9TIN_SERVICE_NAME="${1:-}"
10TIN_SERVICE_ENVIRONMENT="${2:-}"
11NAS_SERVER="${3:-}"
12
13SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
14
15# Source shared library functions
16source "$SCRIPT_DIR/lib.sh"
17
18log() {
19 log_with_prefix "Service Setup" "$@"
20}
21
22error() {
23 error_with_prefix "Service Setup" "$@"
24}
25
26usage() {
27 echo "Usage: $0 <service_name> <service_env> <nas_server>"
28 echo ""
29 echo "Sets up a complete service environment with:"
30 echo " - Service user with UID convention"
31 echo " - NFS mount to /mnt/<service>-<environment>"
32 echo " - XDG directory integration"
33 echo " - Rootless Docker with privileged ports"
34 echo ""
35 echo "Parameters:"
36 echo " service_name: tinsnip, gazette, etc."
37 echo " service_env: prod, test"
38 echo " nas_server: NAS hostname or IP"
39 echo ""
40 echo "Example: $0 tinsnip test DS412plus"
41 exit 1
42}
43
44# calculate_service_uid is now provided by lib.sh
45
46check_prerequisites() {
47 # Check Ubuntu
48 if [[ ! -f /etc/os-release ]] || ! grep -q "Ubuntu" /etc/os-release; then
49 error "This script requires Ubuntu"
50 fi
51
52 # Check sudo access
53 if ! groups | grep -q sudo; then
54 error "Current user must have sudo access"
55 fi
56
57 # Check not running as root or service user
58 if [[ $EUID -eq 0 ]]; then
59 error "Do not run as root. Run as a regular user with sudo access."
60 fi
61
62 local service_user="${TIN_SERVICE_NAME}-${TIN_SERVICE_ENVIRONMENT}"
63 if [[ "$USER" == "$service_user" ]]; then
64 error "Do not run as the service user ($service_user). Run as a regular admin user."
65 fi
66}
67
68copy_service_definition() {
69 local service_name="$1"
70 local service_user="$2"
71 local mount_point="$3"
72
73 # Look for service definition in common locations
74 local service_catalog_dirs=(
75 "$HOME/.local/opt/dynamicalsystem.service"
76 "/opt/dynamicalsystem/service"
77 "$(dirname "$SCRIPT_DIR")/../service"
78 )
79
80 local found_service=""
81 for catalog_dir in "${service_catalog_dirs[@]}"; do
82 if [[ -d "$catalog_dir/$service_name" ]]; then
83 found_service="$catalog_dir/$service_name"
84 log "Found service definition: $found_service"
85 break
86 fi
87 done
88
89 if [[ -n "$found_service" ]]; then
90 # Copy service definition to NFS mount
91 log "Copying service definition to $mount_point/service/$service_name/"
92 mkdir -p "$mount_point/service/$service_name"
93 cp -r "$found_service"/* "$mount_point/service/$service_name/"
94 chown -R "$service_user:$service_user" "$mount_point/service/$service_name"
95 log "Service definition ready for deployment"
96 else
97 log "No service definition found for $service_name"
98 log "You can manually add docker-compose.yml to $mount_point/service/$service_name/"
99 fi
100}
101
102main() {
103 # Validate parameters
104 if [[ -z "$TIN_SERVICE_NAME" || -z "$TIN_SERVICE_ENVIRONMENT" || -z "$NAS_SERVER" ]]; then
105 usage
106 fi
107
108 # Guard against explicit station creation
109 if [[ "$TIN_SERVICE_NAME" == "station" ]]; then
110 error "Station is infrastructure and cannot be created as a service. It will be automatically created when needed."
111 fi
112
113 # Calculate service details
114 TIN_SERVICE_UID=$(calculate_service_uid "$TIN_SERVICE_NAME" "$TIN_SERVICE_ENVIRONMENT")
115 SERVICE_USER="${TIN_SERVICE_NAME}-${TIN_SERVICE_ENVIRONMENT}"
116
117 log "Service Environment Setup"
118 log "========================="
119 log "Service: $TIN_SERVICE_NAME"
120 log "Environment: $TIN_SERVICE_ENVIRONMENT"
121 log "User: $SERVICE_USER (UID: $TIN_SERVICE_UID)"
122 log "NAS: $NAS_SERVER"
123 echo
124
125 # Check prerequisites
126 check_prerequisites
127
128 # Ensure station exists first
129 local namespace="${TIN_NAMESPACE:-dynamicalsystem}"
130 log "Checking $namespace station..."
131 if ! "$SCRIPT_DIR/setup_station.sh" "$NAS_SERVER"; then
132 error "Failed to setup namespace station"
133 fi
134
135 # Proceeding with setup
136
137 # Step 1: Mount NFS and create service user
138 log "Step 1: Setting up NFS mount and service user..."
139 if ! "$SCRIPT_DIR/mount_nas.sh" "$TIN_SERVICE_NAME" "$TIN_SERVICE_ENVIRONMENT" "$NAS_SERVER"; then
140 error "Failed to setup NFS mount"
141 fi
142
143 # Step 2: Install rootless Docker
144 log "Step 2: Installing rootless Docker..."
145 if ! "$SCRIPT_DIR/install_docker_simple.sh" "$SERVICE_USER"; then
146 error "Failed to install Docker"
147 fi
148
149 # Step 3: Copy service definition if available
150 log "Step 3: Setting up service definition..."
151 copy_service_definition "$TIN_SERVICE_NAME" "$SERVICE_USER" "/mnt/${TIN_SERVICE_NAME}-${TIN_SERVICE_ENVIRONMENT}"
152
153 log ""
154 log "Service setup complete!"
155 log ""
156 log "Environment details:"
157 log " Service: $TIN_SERVICE_NAME ($TIN_SERVICE_ENVIRONMENT)"
158 log " User: $SERVICE_USER (UID: $TIN_SERVICE_UID)"
159 log " NFS mount: /mnt/${TIN_SERVICE_NAME}-${TIN_SERVICE_ENVIRONMENT}"
160 log " XDG integration: ~/.local/{state,share,config}/${TIN_NAMESPACE:-dynamicalsystem}/@$TIN_SERVICE_NAME"
161 log ""
162 log "To use this environment:"
163 log " sudo -u $SERVICE_USER -i"
164 log " cd /mnt/${TIN_SERVICE_NAME}-${TIN_SERVICE_ENVIRONMENT}"
165 log " docker run hello-world"
166 log ""
167 log "To deploy the $TIN_SERVICE_NAME service:"
168 log " sudo -u $SERVICE_USER -i"
169 log " cd /mnt/${TIN_SERVICE_NAME}-${TIN_SERVICE_ENVIRONMENT}/service/$TIN_SERVICE_NAME"
170 log " ./setup.sh # If available"
171 log " docker compose up -d"
172}
173
174main "$@"