homelab infrastructure services
at fix-docker-install 215 lines 5.6 kB view raw
1#!/bin/bash 2 3set -euo pipefail 4 5log() { 6 echo "[Boot Config] $*" 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 24create_env_loader_service() { 25 local env_file="$1" 26 local service_file="/etc/systemd/system/machine-env-loader.service" 27 28 log "Creating systemd service for environment loader..." 29 30 sudo tee "$service_file" > /dev/null << EOF 31[Unit] 32Description=Load machine environment variables 33After=network.target remote-fs.target 34Wants=network-online.target 35 36[Service] 37Type=oneshot 38RemainAfterExit=yes 39ExecStart=/bin/bash -c 'if [[ -f "$env_file" ]]; then source "$env_file" && export -p > /etc/environment.d/99-machine.conf; fi' 40StandardOutput=journal 41 42[Install] 43WantedBy=multi-user.target 44EOF 45 46 sudo mkdir -p /etc/environment.d 47 sudo systemctl daemon-reload 48 sudo systemctl enable machine-env-loader.service 49 50 log "Environment loader service created and enabled" 51} 52 53create_docker_user_service() { 54 local user_service_dir="${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user" 55 56 log "Setting up Docker user service for auto-start..." 57 58 mkdir -p "$user_service_dir" 59 60 cat > "$user_service_dir/docker-rootless.service" << 'EOF' 61[Unit] 62Description=Docker Application Container Engine (Rootless) 63Documentation=https://docs.docker.com/go/rootless/ 64 65[Service] 66Environment="PATH=/usr/local/bin:/usr/bin:/bin" 67ExecStart=/usr/bin/dockerd-rootless.sh 68ExecReload=/bin/kill -s HUP $MAINPID 69TimeoutSec=0 70RestartSec=2 71Restart=always 72StartLimitBurst=3 73StartLimitInterval=60s 74LimitNOFILE=infinity 75LimitNPROC=infinity 76LimitCORE=infinity 77TasksMax=infinity 78Delegate=yes 79Type=simple 80KillMode=mixed 81 82[Install] 83WantedBy=default.target 84EOF 85 86 systemctl --user daemon-reload 87 systemctl --user enable docker-rootless.service 88 89 loginctl enable-linger "$(whoami)" 90 91 log "Docker rootless service configured for auto-start" 92} 93 94configure_mount_verification() { 95 local mount_point="$1" 96 local service_file="/etc/systemd/system/verify-nas-mount.service" 97 98 log "Creating NAS mount verification service..." 99 100 sudo tee "$service_file" > /dev/null << EOF 101[Unit] 102Description=Verify NAS mount is available 103After=network-online.target remote-fs.target 104Wants=network-online.target 105Before=machine-env-loader.service 106 107[Service] 108Type=oneshot 109RemainAfterExit=yes 110ExecStart=/bin/bash -c 'for i in {1..30}; do if mountpoint -q "$mount_point"; then exit 0; fi; sleep 2; done; exit 1' 111Restart=on-failure 112RestartSec=10 113StandardOutput=journal 114 115[Install] 116WantedBy=multi-user.target 117EOF 118 119 sudo systemctl daemon-reload 120 sudo systemctl enable verify-nas-mount.service 121 122 log "NAS mount verification service created and enabled" 123} 124 125create_startup_script() { 126 local startup_script="/usr/local/bin/machine-startup" 127 128 log "Creating machine startup script..." 129 130 sudo tee "$startup_script" > /dev/null << 'EOF' 131#!/bin/bash 132# Machine startup script 133# This script runs at boot to ensure all services are properly initialized 134 135logger -t machine-startup "Starting machine initialization..." 136 137# Wait for network 138for i in {1..30}; do 139 if ping -c 1 -W 1 8.8.8.8 &> /dev/null; then 140 logger -t machine-startup "Network is available" 141 break 142 fi 143 sleep 1 144done 145 146# Verify mounts 147if ! systemctl is-active --quiet remote-fs.target; then 148 logger -t machine-startup "Waiting for remote filesystems..." 149 systemctl start remote-fs.target 150fi 151 152# Start user services 153for user in $(loginctl list-users --no-legend | awk '{print $2}'); do 154 if [[ -f "/home/$user/.config/systemd/user/docker-rootless.service" ]]; then 155 logger -t machine-startup "Starting Docker for user $user" 156 sudo -u "$user" XDG_RUNTIME_DIR="/run/user/$(id -u "$user")" systemctl --user start docker-rootless.service 157 fi 158done 159 160logger -t machine-startup "Machine initialization completed" 161EOF 162 163 sudo chmod +x "$startup_script" 164 165 local service_file="/etc/systemd/system/machine-startup.service" 166 sudo tee "$service_file" > /dev/null << EOF 167[Unit] 168Description=Machine startup initialization 169After=network-online.target remote-fs.target 170Wants=network-online.target 171 172[Service] 173Type=oneshot 174ExecStart=$startup_script 175RemainAfterExit=yes 176StandardOutput=journal 177 178[Install] 179WantedBy=multi-user.target 180EOF 181 182 sudo systemctl daemon-reload 183 sudo systemctl enable machine-startup.service 184 185 log "Machine startup script created and enabled" 186} 187 188main() { 189 log "Starting boot configuration..." 190 191 nas_mount=$(get_nas_mount) 192 193 if [[ ! -d "$nas_mount" ]]; then 194 error "NAS mount point $nas_mount does not exist" 195 fi 196 197 env_file="$nas_mount/.env" 198 199 create_env_loader_service "$env_file" 200 create_docker_user_service 201 configure_mount_verification "$nas_mount" 202 create_startup_script 203 204 log "Boot configuration completed!" 205 log "Services will start automatically on next boot" 206 207 echo 208 log "Created services:" 209 log " - machine-env-loader.service: Loads environment variables" 210 log " - verify-nas-mount.service: Ensures NAS is mounted" 211 log " - docker-rootless.service: Starts Docker in user context" 212 log " - machine-startup.service: Handles boot initialization" 213} 214 215main "$@"