homelab infrastructure services
1#!/bin/bash
2
3set -euo pipefail
4
5log() {
6 echo "[Env Manager] $*"
7}
8
9error() {
10 log "ERROR: $*" >&2
11 exit 1
12}
13
14get_nas_mount() {
15 if [[ -f ${DYNAMICALSYSTEM_TEMP_DIR:-/tmp/dynamicalsystem}/nas_mount.env ]]; then
16 source ${DYNAMICALSYSTEM_TEMP_DIR:-/tmp/dynamicalsystem}/nas_mount.env
17 echo "${NAS_MOUNT_POINT}"
18 else
19 read -p "Enter NAS mount point: " mount_point
20 echo "$mount_point"
21 fi
22}
23
24prompt_for_env_value() {
25 local var_name="$1"
26 local prompt="$2"
27 local is_secret="${3:-false}"
28
29 if [[ "$is_secret" == "true" ]]; then
30 read -s -p "$prompt: " value
31 echo
32 else
33 read -p "$prompt: " value
34 fi
35
36 echo "$value"
37}
38
39create_env_template() {
40 cat > "$1" << 'EOF'
41# Machine Environment Configuration
42# Generated on: $(date)
43
44DYNAMICAL_SYSTEM_FOLDER=
45ENVIRONMENT=
46EOF
47}
48
49load_or_create_env() {
50 local env_file="$1"
51 local env_vars=()
52
53 if [[ -f "$env_file" ]]; then
54 log "Found existing .env file at $env_file"
55
56 while IFS='=' read -r key value; do
57 if [[ ! "$key" =~ ^[[:space:]]*# ]] && [[ -n "$key" ]]; then
58 key=$(echo "$key" | xargs)
59 value=$(echo "$value" | xargs)
60
61 if [[ -n "$value" ]]; then
62 export "$key=$value"
63 env_vars+=("$key")
64 fi
65 fi
66 done < "$env_file"
67
68 log "Loaded ${#env_vars[@]} environment variables"
69 else
70 log "No .env file found. Creating new configuration..."
71
72 create_env_template "$env_file"
73
74 echo
75 log "Please provide values for the following environment variables:"
76 log "(Press Enter to skip optional variables)"
77 echo
78
79 # Setup XDG variables for proper expansion
80 export XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
81
82 declare -A prompts=(
83 ["DYNAMICAL_SYSTEM_FOLDER"]="$XDG_DATA_HOME/dynamicalsystem/"
84 ["ENVIRONMENT"]="$(whoami)"
85 )
86
87 declare -A secrets=(
88 ["DYNAMICAL_SYSTEM_FOLDER"]=false
89 ["ENVIRONMENT"]=false
90 )
91
92 > "$env_file"
93 echo "# Machine Environment Configuration" >> "$env_file"
94 echo "# Generated on: $(date)" >> "$env_file"
95 echo >> "$env_file"
96
97 for var in ENVIRONMENT DYNAMICAL_SYSTEM_FOLDER; do
98 is_secret="${secrets[$var]:-false}"
99 default_value="${prompts[$var]}"
100 value=$(prompt_for_env_value "$var" "$var [${default_value}]" "$is_secret")
101
102 # Use default if empty
103 if [[ -z "$value" ]]; then
104 value="$default_value"
105 fi
106
107 if [[ -n "$value" ]]; then
108 echo "$var=$value" >> "$env_file"
109 export "$var=$value"
110 env_vars+=("$var")
111 fi
112 done
113
114 echo >> "$env_file"
115 echo "# Custom Configuration" >> "$env_file"
116 echo "# Add your custom environment variables below" >> "$env_file"
117
118 log "Created .env file with ${#env_vars[@]} variables"
119 fi
120
121 # Try to set secure permissions, but don't fail if on NFS
122 if ! chmod 600 "$env_file" 2>/dev/null; then
123 log "Note: Could not change permissions on $env_file (may be on NFS mount)"
124 fi
125
126 echo "${env_vars[@]}" > ${DYNAMICALSYSTEM_TEMP_DIR:-/tmp/dynamicalsystem}/env_vars.list
127}
128
129create_profile_script() {
130 local env_file="$1"
131 local profile_dir="/etc/profile.d"
132 local profile_script="$profile_dir/machine-env.sh"
133
134 log "Creating system-wide profile script..."
135
136 sudo tee "$profile_script" > /dev/null << 'EOF'
137#!/bin/bash
138# Machine environment variables loader
139# Auto-generated by machine setup
140
141# Determine environment name - default to username
142ENVIRONMENT="${ENVIRONMENT:-$(whoami)}"
143CONFIG_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/dynamicalsystem/config"
144ENV_FILE="$CONFIG_DIR/machine.$ENVIRONMENT.env"
145
146if [[ -f "$ENV_FILE" ]]; then
147 set -a
148 source "$ENV_FILE"
149 set +a
150fi
151EOF
152
153 sudo chmod 644 "$profile_script"
154}
155
156main() {
157 log "Starting environment variable management..."
158
159 # Use the symlink structure instead of raw mount point
160 local config_dir="${XDG_DATA_HOME:-$HOME/.local/share}/dynamicalsystem/config"
161
162 # Create config directory if it doesn't exist
163 if [[ ! -d "$config_dir" ]]; then
164 mkdir -p "$config_dir"
165 fi
166
167 # Determine environment name - default to username
168 local environment="${ENVIRONMENT:-$(whoami)}"
169
170 # Check for existing env files or prompt for environment
171 local existing_files=($(ls "$config_dir"/machine.*.env 2>/dev/null))
172 if [[ ${#existing_files[@]} -gt 0 ]] && [[ -z "$ENVIRONMENT" ]]; then
173 log "Found existing environment files:"
174 for i in "${!existing_files[@]}"; do
175 local fname=$(basename "${existing_files[$i]}")
176 local env_name=${fname#machine.}
177 env_name=${env_name%.env}
178 echo "$((i+1))) $env_name"
179 done
180 echo "$((${#existing_files[@]}+1))) Create new environment"
181
182 read -p "Select environment [1]: " selection
183 selection="${selection:-1}"
184
185 if [[ "$selection" -le "${#existing_files[@]}" ]]; then
186 local fname=$(basename "${existing_files[$((selection-1))]}")
187 environment=${fname#machine.}
188 environment=${environment%.env}
189 else
190 read -p "Enter new environment name [$(whoami)]: " environment
191 environment="${environment:-$(whoami)}"
192 fi
193 fi
194
195 local env_file="$config_dir/machine.$environment.env"
196
197 load_or_create_env "$env_file"
198 create_profile_script "$env_file"
199
200 log "Environment variables configured successfully!"
201 log "Variables are stored in: $env_file"
202 log "They will be automatically loaded on login via /etc/profile.d/machine-env.sh"
203}
204
205main "$@"