homelab infrastructure services
1#!/bin/bash
2# tin - Modern CLI
3
4set -euo pipefail
5
6# Get script directory and tinsnip root
7SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8TINSNIP_ROOT="$(dirname "$SCRIPT_DIR")"
9
10# Source shared functions
11source "$TINSNIP_ROOT/lib/core.sh"
12
13# CLI version and info
14TIN_VERSION="1.0.0"
15TIN_NAME="tin"
16
17# Global CLI functions
18show_version() {
19 echo "$TIN_NAME version $TIN_VERSION"
20 echo "tinsnip Infrastructure Platform CLI"
21}
22
23show_global_help() {
24 cat << EOF
25tin - tinsnip Infrastructure Platform CLI
26
27USAGE:
28 tin <command> [options]
29
30COMMANDS:
31 sheet <name> Create or register sheet
32 machine <service> <env> Create service machine environment
33 service <service-env> <name> Deploy service to machine
34
35 nas Manage NAS server registrations
36 key Manage SSH keys for NAS access
37
38 status Show tinsnip status
39 help Show this help message
40 version Show version information
41
42EXAMPLES:
43 tin sheet infrastructure # Register infrastructure sheet
44 tin machine gazette prod # Create gazette-prod machine (auto-discover NAS)
45 tin service gazette-prod lldap # Deploy lldap to gazette-prod
46 tin nas add infrastructure DS412plus # Register NAS server for sheet
47 tin key generate DS412plus # Generate SSH key for NAS server
48 tin status # Show tinsnip status
49
50GETTING STARTED:
51 1. Set up tinsnip's topsheet:
52 TIN_SHEET=topsheet tin machine station prod <nas-server>
53
54 2. Register your first sheet:
55 tin sheet infrastructure
56
57 3. Create a service machine:
58 tin machine gateway prod
59
60 4. Deploy a service:
61 tin service gateway-prod lldap
62
63For more information on a specific command, use:
64 tin <command> --help
65
66EOF
67}
68
69# Command routing
70route_command() {
71 local cmd="${1:-}"
72 shift || true
73
74 case "$cmd" in
75 # Core commands
76 sheet)
77 # Route to new cmd/ structure
78 local subcmd="${1:-create}"
79 case "$subcmd" in
80 --help|-h|help)
81 exec "$TINSNIP_ROOT/cmd/sheet/create.sh" "--help"
82 ;;
83 create|"")
84 exec "$TINSNIP_ROOT/cmd/sheet/create.sh" "${@:2}"
85 ;;
86 list)
87 exec "$TINSNIP_ROOT/cmd/sheet/list.sh" "${@:2}"
88 ;;
89 show)
90 exec "$TINSNIP_ROOT/cmd/sheet/show.sh" "${@:2}"
91 ;;
92 rm|remove)
93 exec "$TINSNIP_ROOT/cmd/sheet/rm.sh" "${@:2}"
94 ;;
95 *)
96 # Default behavior: treat first arg as sheet name for create
97 exec "$TINSNIP_ROOT/cmd/sheet/create.sh" "$@"
98 ;;
99 esac
100 ;;
101 machine)
102 # Route to new cmd/ structure
103 local subcmd="${1:-create}"
104 case "$subcmd" in
105 --help|-h|help)
106 exec "$TINSNIP_ROOT/cmd/machine/create.sh" "--help"
107 ;;
108 create|"")
109 exec "$TINSNIP_ROOT/cmd/machine/create.sh" "${@:2}"
110 ;;
111 list)
112 exec "$TINSNIP_ROOT/cmd/machine/list.sh" "${@:2}"
113 ;;
114 status)
115 exec "$TINSNIP_ROOT/cmd/machine/status.sh" "${@:2}"
116 ;;
117 rm|remove)
118 exec "$TINSNIP_ROOT/cmd/machine/rm.sh" "${@:2}"
119 ;;
120 *)
121 # Default behavior: treat first two args as service environment for create
122 exec "$TINSNIP_ROOT/cmd/machine/create.sh" "$@"
123 ;;
124 esac
125 ;;
126 service)
127 # Route to new cmd/ structure
128 local subcmd="${1:-deploy}"
129 case "$subcmd" in
130 --help|-h|help)
131 exec "$TINSNIP_ROOT/cmd/service/deploy.sh" "--help"
132 ;;
133 deploy|"")
134 exec "$TINSNIP_ROOT/cmd/service/deploy.sh" "${@:2}"
135 ;;
136 list)
137 exec "$TINSNIP_ROOT/cmd/service/list.sh" "${@:2}"
138 ;;
139 status)
140 exec "$TINSNIP_ROOT/cmd/service/status.sh" "${@:2}"
141 ;;
142 logs)
143 exec "$TINSNIP_ROOT/cmd/service/logs.sh" "${@:2}"
144 ;;
145 stop)
146 exec "$TINSNIP_ROOT/cmd/service/stop.sh" "${@:2}"
147 ;;
148 rm|remove)
149 exec "$TINSNIP_ROOT/cmd/service/rm.sh" "${@:2}"
150 ;;
151 *)
152 # Default behavior: treat args as service-env and catalog-service for deploy
153 exec "$TINSNIP_ROOT/cmd/service/deploy.sh" "$@"
154 ;;
155 esac
156 ;;
157
158 # Management commands
159 nas)
160 # Route to new cmd/ structure
161 local subcmd="${1:-list}"
162 case "$subcmd" in
163 --help|-h|help)
164 exec "$TINSNIP_ROOT/cmd/nas/list.sh" "--help"
165 ;;
166 list|"")
167 exec "$TINSNIP_ROOT/cmd/nas/list.sh" "${@:2}"
168 ;;
169 show)
170 exec "$TINSNIP_ROOT/cmd/nas/show.sh" "${@:2}"
171 ;;
172 add)
173 exec "$TINSNIP_ROOT/cmd/nas/add.sh" "${@:2}"
174 ;;
175 discover)
176 exec "$TINSNIP_ROOT/cmd/nas/discover.sh" "${@:2}"
177 ;;
178 *)
179 echo "Error: Unknown nas command '$subcmd'" >&2
180 echo "Available: list, show, add, discover" >&2
181 exit 1
182 ;;
183 esac
184 ;;
185 key)
186 # Already migrated - uses new cmd/ structure
187 local subcmd="${1:-generate}"
188 case "$subcmd" in
189 --help|-h|help)
190 exec "$TINSNIP_ROOT/cmd/key/help.sh"
191 ;;
192 generate|"")
193 exec "$TINSNIP_ROOT/cmd/key/generate.sh" "${@:2}"
194 ;;
195 install)
196 exec "$TINSNIP_ROOT/cmd/key/install.sh" "${@:2}"
197 ;;
198 list)
199 exec "$TINSNIP_ROOT/cmd/key/list.sh" "${@:2}"
200 ;;
201 status)
202 exec "$TINSNIP_ROOT/cmd/key/status.sh" "${@:2}"
203 ;;
204 remove)
205 exec "$TINSNIP_ROOT/cmd/key/remove.sh" "${@:2}"
206 ;;
207 test)
208 exec "$TINSNIP_ROOT/cmd/key/test.sh" "${@:2}"
209 ;;
210 show)
211 exec "$TINSNIP_ROOT/cmd/key/show.sh" "${@:2}"
212 ;;
213 help)
214 exec "$TINSNIP_ROOT/cmd/key/help.sh"
215 ;;
216 *)
217 echo "Error: Unknown key command '$subcmd'" >&2
218 echo "Available: generate, install, list, status, remove, test, show, help" >&2
219 exit 1
220 ;;
221 esac
222 ;;
223
224 # Info commands
225 status)
226 # Route to new cmd/ structure
227 exec "$TINSNIP_ROOT/cmd/status/show.sh" "$@"
228 ;;
229 version|--version|-V)
230 show_version
231 ;;
232 help|--help|-h)
233 show_global_help
234 ;;
235
236 # Legacy compatibility
237 setup)
238 warn_with_prefix "tin" "Legacy 'setup' command. Use 'tin machine' instead"
239 exec "$TINSNIP_ROOT/machine/setup.sh" "$@"
240 ;;
241
242 # Unknown command
243 "")
244 echo "Error: No command specified" >&2
245 echo "Use 'tin help' for usage information" >&2
246 exit 1
247 ;;
248 *)
249 echo "Error: Unknown command '$cmd'" >&2
250 echo "Use 'tin help' for available commands" >&2
251 exit 1
252 ;;
253 esac
254}
255
256# Main entry point
257main() {
258 # Handle global flags first
259 case "${1:-}" in
260 --version|-V)
261 show_version
262 exit 0
263 ;;
264 --help|-h)
265 show_global_help
266 exit 0
267 ;;
268 esac
269
270 # Route to appropriate subcommand
271 route_command "$@"
272}
273
274main "$@"