homelab infrastructure services
1#!/bin/bash
2# Registry management functions for tinsnip
3
4# Source core functions
5LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6source "$LIB_DIR/core.sh"
7
8# Registry paths
9TINSNIP_STATION_DATA="/mnt/station-prod/data"
10SHEET_REGISTRY="$TINSNIP_STATION_DATA/sheets"
11MACHINE_REGISTRY_DIR="$TINSNIP_STATION_DATA/machines"
12NAS_CREDENTIALS_DIR="$TINSNIP_STATION_DATA/nas-credentials"
13
14# Check if tinsnip.station-prod is available
15check_tinsnip_station() {
16 if [[ ! -d "$TINSNIP_STATION_DATA" ]]; then
17 error_with_prefix "Registry" "tinsnip.station-prod not found at $TINSNIP_STATION_DATA"
18 error_with_prefix "Registry" "Run: TIN_SHEET=topsheet tin machine station prod <nas-server>"
19 return 1
20 fi
21 return 0
22}
23
24# Sheet registry functions
25list_sheets() {
26 check_tinsnip_station || return 1
27 if [[ -f "$SHEET_REGISTRY" ]]; then
28 grep -v '^#' "$SHEET_REGISTRY" | grep -v '^$'
29 fi
30}
31
32get_sheet_from_registry() {
33 local sheet="$1"
34 check_tinsnip_station || return 1
35
36 if [[ -f "$SHEET_REGISTRY" ]]; then
37 grep "^${sheet}=" "$SHEET_REGISTRY" | cut -d= -f2
38 fi
39}
40
41register_sheet_in_registry() {
42 local sheet="$1"
43 local number="$2"
44 check_tinsnip_station || return 1
45
46 # Check if already registered
47 if get_sheet_from_registry "$sheet" >/dev/null 2>&1; then
48 error_with_prefix "Sheet Registry" "Sheet '$sheet' already registered"
49 return 1
50 fi
51
52 # Check if number already used
53 if grep -q "=${number}$" "$SHEET_REGISTRY" 2>/dev/null; then
54 error_with_prefix "Sheet Registry" "Sheet number '$number' already in use"
55 return 1
56 fi
57
58 # Add to registry (must write as station-prod user)
59 echo "${sheet}=${number}" | sudo -u station-prod tee -a "$SHEET_REGISTRY" > /dev/null
60 log_with_prefix "Sheet Registry" "Registered sheet: $sheet = $number"
61}
62
63find_next_sheet_number() {
64 check_tinsnip_station || return 1
65
66 # Create registry if it doesn't exist
67 if [[ ! -f "$SHEET_REGISTRY" ]]; then
68 cat > "$SHEET_REGISTRY" << EOF
69# Sheet Registry
70# Format: sheet_name=sheet_number
71# Sheet 5 (topsheet) is reserved for platform services
72# User sheets use numbers 1-4
73
74topsheet=5
75EOF
76 fi
77
78 # Find next available number (1-4)
79 for num in {1..4}; do
80 if ! grep -q "=${num}$" "$SHEET_REGISTRY" 2>/dev/null; then
81 echo "$num"
82 return 0
83 fi
84 done
85
86 # No available numbers
87 error_with_prefix "Sheet Registry" "Sheet registry full (range 1-4, 5 reserved for topsheet)"
88 return 1
89}
90
91# Machine registry functions
92list_machines() {
93 local sheet="${1:-topsheet}"
94 local machine_registry="$MACHINE_REGISTRY_DIR/$sheet/registry"
95
96 if [[ -f "$machine_registry" ]]; then
97 grep -v '^#' "$machine_registry" | grep -v '^$'
98 else
99 # Return empty - no machines registered yet for this sheet
100 return 0
101 fi
102}
103
104get_machine_number() {
105 local machine="$1"
106 local sheet="${2:-topsheet}"
107 local machine_registry="$MACHINE_REGISTRY_DIR/$sheet/registry"
108
109 if [[ -f "$machine_registry" ]]; then
110 grep "^${machine}=" "$machine_registry" | cut -d= -f2
111 fi
112}
113
114register_machine() {
115 local machine="$1"
116 local machine_number="$2"
117 local sheet="${3:-${TIN_SHEET:-topsheet}}"
118 local machine_registry="$MACHINE_REGISTRY_DIR/$sheet/registry"
119
120 check_tinsnip_station || return 1
121
122 # Create sheet directory if needed (as station-prod)
123 sudo -u station-prod mkdir -p "$MACHINE_REGISTRY_DIR/$sheet"
124
125 # Create registry file if needed (as station-prod)
126 if [[ ! -f "$machine_registry" ]]; then
127 cat << EOF | sudo -u station-prod tee "$machine_registry" > /dev/null
128# Machine Registry for sheet: $sheet
129# Format: machine_name=machine_number
130# Machine numbers are 2-digit (00-99) and used in UID calculation
131EOF
132 fi
133
134 # Add or update machine entry (as station-prod)
135 if grep -q "^${machine}=" "$machine_registry" 2>/dev/null; then
136 sudo -u station-prod sed -i "s/^${machine}=.*/${machine}=${machine_number}/" "$machine_registry"
137 else
138 echo "${machine}=${machine_number}" | sudo -u station-prod tee -a "$machine_registry" > /dev/null
139 fi
140
141 log_with_prefix "Machine Registry" "Registered $machine = $machine_number (sheet: $sheet)"
142}
143
144unregister_machine() {
145 local machine="$1"
146 local sheet="${2:-${TIN_SHEET:-topsheet}}"
147 local machine_registry="$MACHINE_REGISTRY_DIR/$sheet/registry"
148
149 check_tinsnip_station || return 1
150
151 if [[ ! -f "$machine_registry" ]]; then
152 return 1
153 fi
154
155 # Remove machine entry (as station-prod)
156 sudo -u station-prod sed -i "/^${machine}=/d" "$machine_registry"
157 log_with_prefix "Machine Registry" "Unregistered $machine (sheet: $sheet)"
158}
159
160# NAS credential functions
161list_nas_servers() {
162 check_tinsnip_station || return 1
163 if [[ -f "$NAS_CREDENTIALS_DIR/nas-servers" ]]; then
164 grep -v '^#' "$NAS_CREDENTIALS_DIR/nas-servers" | grep -v '^$'
165 fi
166}
167
168get_nas_server() {
169 local sheet="$1"
170 check_tinsnip_station || return 1
171
172 if [[ -f "$NAS_CREDENTIALS_DIR/nas-servers" ]]; then
173 grep "^${sheet}=" "$NAS_CREDENTIALS_DIR/nas-servers" | cut -d= -f2
174 fi
175}
176
177register_nas_server() {
178 local sheet="$1"
179 local nas_server="$2"
180 check_tinsnip_station || return 1
181
182 # Create nas-servers file if it doesn't exist (as station-prod)
183 local nas_servers_file="$NAS_CREDENTIALS_DIR/nas-servers"
184 sudo -u station-prod mkdir -p "$NAS_CREDENTIALS_DIR"
185
186 if [[ ! -f "$nas_servers_file" ]]; then
187 cat << EOF | sudo -u station-prod tee "$nas_servers_file" > /dev/null
188# NAS Server Registry
189# Format: sheet=nas_server_hostname
190# Used for automatic NAS discovery during machine setup
191
192EOF
193 fi
194
195 # Update or add entry (as station-prod)
196 if grep -q "^${sheet}=" "$nas_servers_file" 2>/dev/null; then
197 sudo -u station-prod sed -i "s/^${sheet}=.*/${sheet}=${nas_server}/" "$nas_servers_file"
198 log_with_prefix "NAS Registry" "Updated NAS server for $sheet: $nas_server"
199 else
200 echo "${sheet}=${nas_server}" | sudo -u station-prod tee -a "$nas_servers_file" > /dev/null
201 log_with_prefix "NAS Registry" "Registered NAS server for $sheet: $nas_server"
202 fi
203}
204
205# Auto-discover NAS server for a sheet
206discover_nas_server() {
207 local sheet="$1"
208 check_tinsnip_station || return 1
209
210 # First check if explicitly registered for this sheet
211 local nas_server=$(get_nas_server "$sheet")
212 if [[ -n "$nas_server" ]]; then
213 echo "$nas_server"
214 return 0
215 fi
216
217 # Fall back to default sheet server if no specific entry
218 nas_server=$(get_nas_server "default")
219 if [[ -n "$nas_server" ]]; then
220 echo "$nas_server"
221 return 0
222 fi
223
224 # No NAS server found
225 return 1
226}
227
228# SSH key management functions
229has_nas_key() {
230 local nas_server="$1"
231 check_tinsnip_station || return 1
232 [[ -f "$NAS_CREDENTIALS_DIR/${nas_server}.key" ]]
233}
234
235get_nas_key_path() {
236 local nas_server="$1"
237 check_tinsnip_station || return 1
238 echo "$NAS_CREDENTIALS_DIR/${nas_server}.key"
239}
240
241# Usage examples
242show_registry_usage() {
243 cat << EOF
244Registry Management Functions
245
246Sheet Registry:
247 list_sheets # Show all registered sheets
248 get_sheet_from_registry <sheet> # Get number for sheet
249 register_sheet_in_registry <name> <number> # Register new sheet
250 find_next_sheet_number # Find next available sheet number
251
252Machine Registry:
253 list_machines [sheet] # Show machines in sheet
254 get_machine_number <machine> [sheet] # Get machine number
255
256NAS Management:
257 list_nas_servers # Show registered NAS servers
258 get_nas_server <sheet> # Get NAS server for sheet
259 register_nas_server <sheet> <server> # Register NAS server
260 discover_nas_server <sheet> # Auto-discover NAS server
261
262SSH Keys:
263 has_nas_key <server> # Check if SSH key exists
264 get_nas_key_path <server> # Get path to SSH key
265
266Example Usage:
267 source "\$TINSNIP_ROOT/lib/registry.sh"
268 list_sheets
269 register_sheet_in_registry infrastructure 2
270 register_nas_server infrastructure DS412plus.local
271EOF
272}