#!/bin/bash # Setup a complete service environment with NFS and rootless Docker # Implements DEPLOYMENT_STRATEGY.md conventions set -euo pipefail # Required parameters TIN_SERVICE_NAME="${1:-}" TIN_SERVICE_ENVIRONMENT="${2:-}" NAS_SERVER="${3:-}" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Source shared library functions source "$SCRIPT_DIR/lib.sh" log() { log_with_prefix "Service Setup" "$@" } error() { error_with_prefix "Service Setup" "$@" } usage() { echo "Usage: $0 " echo "" echo "Sets up a complete service environment with:" echo " - Service user with UID convention" echo " - NFS mount to /mnt/-" echo " - XDG directory integration" echo " - Rootless Docker with privileged ports" echo "" echo "Parameters:" echo " service_name: tinsnip, gazette, etc." echo " service_env: prod, test" echo " nas_server: NAS hostname or IP" echo "" echo "Example: $0 tinsnip test DS412plus" exit 1 } # calculate_service_uid is now provided by lib.sh check_prerequisites() { # Check Ubuntu if [[ ! -f /etc/os-release ]] || ! grep -q "Ubuntu" /etc/os-release; then error "This script requires Ubuntu" fi # Check sudo access if ! groups | grep -q sudo; then error "Current user must have sudo access" fi # Check not running as root or service user if [[ $EUID -eq 0 ]]; then error "Do not run as root. Run as a regular user with sudo access." fi local service_user="${TIN_SERVICE_NAME}-${TIN_SERVICE_ENVIRONMENT}" if [[ "$USER" == "$service_user" ]]; then error "Do not run as the service user ($service_user). Run as a regular admin user." fi } copy_service_definition() { local service_name="$1" local service_user="$2" local mount_point="$3" # Look for service definition in common locations local service_catalog_dirs=( "$HOME/.local/opt/dynamicalsystem.service" "/opt/dynamicalsystem/service" "$(dirname "$SCRIPT_DIR")/../service" ) local found_service="" for catalog_dir in "${service_catalog_dirs[@]}"; do if [[ -d "$catalog_dir/$service_name" ]]; then found_service="$catalog_dir/$service_name" log "Found service definition: $found_service" break fi done if [[ -n "$found_service" ]]; then # Copy service definition to NFS mount log "Copying service definition to $mount_point/service/$service_name/" mkdir -p "$mount_point/service/$service_name" cp -r "$found_service"/* "$mount_point/service/$service_name/" chown -R "$service_user:$service_user" "$mount_point/service/$service_name" log "Service definition ready for deployment" else log "No service definition found for $service_name" log "You can manually add docker-compose.yml to $mount_point/service/$service_name/" fi } main() { # Validate parameters if [[ -z "$TIN_SERVICE_NAME" || -z "$TIN_SERVICE_ENVIRONMENT" || -z "$NAS_SERVER" ]]; then usage fi # Guard against explicit station creation if [[ "$TIN_SERVICE_NAME" == "station" ]]; then error "Station is infrastructure and cannot be created as a service. It will be automatically created when needed." fi # Calculate service details TIN_SERVICE_UID=$(calculate_service_uid "$TIN_SERVICE_NAME" "$TIN_SERVICE_ENVIRONMENT") SERVICE_USER="${TIN_SERVICE_NAME}-${TIN_SERVICE_ENVIRONMENT}" log "Service Environment Setup" log "=========================" log "Service: $TIN_SERVICE_NAME" log "Environment: $TIN_SERVICE_ENVIRONMENT" log "User: $SERVICE_USER (UID: $TIN_SERVICE_UID)" log "NAS: $NAS_SERVER" echo # Check prerequisites check_prerequisites # Ensure station exists first local namespace="${TIN_NAMESPACE:-dynamicalsystem}" log "Checking $namespace station..." if ! "$SCRIPT_DIR/setup_station.sh" "$NAS_SERVER"; then error "Failed to setup namespace station" fi # Proceeding with setup # Step 1: Mount NFS and create service user log "Step 1: Setting up NFS mount and service user..." if ! "$SCRIPT_DIR/mount_nas.sh" "$TIN_SERVICE_NAME" "$TIN_SERVICE_ENVIRONMENT" "$NAS_SERVER"; then error "Failed to setup NFS mount" fi # Step 2: Install rootless Docker log "Step 2: Installing rootless Docker..." if ! "$SCRIPT_DIR/install_docker_simple.sh" "$SERVICE_USER"; then error "Failed to install Docker" fi # Step 3: Copy service definition if available log "Step 3: Setting up service definition..." copy_service_definition "$TIN_SERVICE_NAME" "$SERVICE_USER" "/mnt/${TIN_SERVICE_NAME}-${TIN_SERVICE_ENVIRONMENT}" log "" log "Service setup complete!" log "" log "Environment details:" log " Service: $TIN_SERVICE_NAME ($TIN_SERVICE_ENVIRONMENT)" log " User: $SERVICE_USER (UID: $TIN_SERVICE_UID)" log " NFS mount: /mnt/${TIN_SERVICE_NAME}-${TIN_SERVICE_ENVIRONMENT}" log " XDG integration: ~/.local/{state,share,config}/${TIN_NAMESPACE:-dynamicalsystem}/@$TIN_SERVICE_NAME" log "" log "To use this environment:" log " sudo -u $SERVICE_USER -i" log " cd /mnt/${TIN_SERVICE_NAME}-${TIN_SERVICE_ENVIRONMENT}" log " docker run hello-world" log "" log "To deploy the $TIN_SERVICE_NAME service:" log " sudo -u $SERVICE_USER -i" log " cd /mnt/${TIN_SERVICE_NAME}-${TIN_SERVICE_ENVIRONMENT}/service/$TIN_SERVICE_NAME" log " ./setup.sh # If available" log " docker compose up -d" } main "$@"