homelab infrastructure services
1#!/bin/bash
2
3# Create dedicated tinsnip user for running infrastructure services
4
5set -euo pipefail
6
7log() {
8 echo "[User Setup] $*"
9}
10
11create_tinsnip_user() {
12 local username="tinsnip"
13 local uid=1010
14
15 log "Creating dedicated user '$username' with UID $uid..."
16
17 if id "$username" &>/dev/null; then
18 log "User $username already exists"
19 return 0
20 fi
21
22 # Create regular user (not system user) for rootless Docker
23 sudo useradd -m -u "$uid" -s /bin/bash -c "tinsnip Infrastructure Services" "$username"
24 log "Created user $username with UID $uid"
25
26 # Add subuid/subgid ranges for rootless Docker
27 echo "$username:100000:65536" | sudo tee -a /etc/subuid
28 echo "$username:100000:65536" | sudo tee -a /etc/subgid
29 log "Added subuid/subgid mappings for rootless containers"
30
31 # Enable lingering for systemd user sessions
32 sudo loginctl enable-linger "$username"
33 log "Enabled systemd lingering for $username"
34
35 # Create directory structure
36 sudo -u "$username" mkdir -p /home/"$username"/{services,config,data}
37 log "Created directory structure"
38}
39
40find_available_uid() {
41 local start_uid=995
42 local end_uid=998
43
44 for uid in $(seq $start_uid $end_uid); do
45 if ! getent passwd "$uid" >/dev/null 2>&1; then
46 echo "$uid"
47 return 0
48 fi
49 done
50
51 # If no UID in preferred range, let system assign
52 echo ""
53}
54
55create_system_users() {
56 log "Creating system users for services..."
57
58 # Create lldap system user (will be used inside containers)
59 if ! id "lldap" &>/dev/null; then
60 local lldap_uid
61 lldap_uid=$(find_available_uid)
62
63 if [[ -n "$lldap_uid" ]]; then
64 sudo useradd -r -u "$lldap_uid" -s /bin/false -d /nonexistent -c "LLDAP Service" lldap
65 log "Created system user 'lldap' with UID $lldap_uid"
66 else
67 sudo useradd -r -s /bin/false -d /nonexistent -c "LLDAP Service" lldap
68 lldap_uid=$(id -u lldap)
69 log "Created system user 'lldap' with auto-assigned UID $lldap_uid"
70 fi
71
72 # Update docker-compose.yml with the actual UID
73 update_lldap_uid "$lldap_uid"
74 else
75 local existing_uid
76 existing_uid=$(id -u lldap)
77 log "System user 'lldap' already exists with UID $existing_uid"
78 update_lldap_uid "$existing_uid"
79 fi
80}
81
82update_lldap_uid() {
83 local uid="$1"
84 local compose_file="/home/tinsnip/service/lldap/docker-compose.yml"
85
86 # This will be updated after the service files are copied
87 # Store the UID for later use with proper permissions
88 local temp_file="/tmp/lldap-uid-$$"
89 echo "$uid" > "$temp_file"
90 sudo mv "$temp_file" /tmp/lldap-uid
91 sudo chmod 644 /tmp/lldap-uid
92}
93
94main() {
95 log "Setting up tinsnip user environment..."
96
97 create_tinsnip_user
98 create_system_users
99
100 log "User setup complete!"
101 log ""
102 log "Created users:"
103 log " - tinsnip (UID 1010): Runs rootless Docker and all services"
104 if [[ -f /tmp/lldap-uid ]]; then
105 local lldap_uid
106 lldap_uid=$(cat /tmp/lldap-uid)
107 log " - lldap (UID $lldap_uid): System user for LLDAP container"
108 fi
109}
110
111main "$@"