#!/bin/bash # Deploy a tinsnip service set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SERVICE_DIR="$(dirname "$SCRIPT_DIR")/service" # Use namespace from environment (defaults to dynamicalsystem if not set) TIN_NAMESPACE="${TIN_NAMESPACE:-dynamicalsystem}" log() { echo "[Deploy] $*" } error() { log "ERROR: $*" >&2 exit 1 } deploy_service() { local service_name="$1" local service_dir="$SERVICE_DIR/$service_name" if [[ ! -d "$service_dir" ]]; then error "Service directory not found: $service_dir" fi log "Deploying service: $service_name" # Copy service files to tinsnip user's home local target_dir="/home/tinsnip/service/$service_name" sudo -u tinsnip mkdir -p "$target_dir" # Copy all files sudo cp -r "$service_dir"/* "$target_dir/" sudo chown -R tinsnip:tinsnip "$target_dir" # Make scripts executable sudo find "$target_dir" -name "*.sh" -exec chmod +x {} \; # For LLDAP, we let it run as root to handle initial setup, then it switches to its internal user # Generate secrets for lldap and update docker-compose.yml if [[ "$service_name" == "lldap" ]]; then # Check if secrets are already configured if grep -q "changeme-jwt-secret-32-chars-min" "$target_dir/docker-compose.yml"; then log "Generating LLDAP secrets..." local jwt_secret local key_seed local admin_pass jwt_secret=$(openssl rand -base64 32) key_seed=$(openssl rand -base64 32) read -s -p "Enter LLDAP admin password: " admin_pass echo # Update docker-compose.yml with actual secrets (using | as delimiter to avoid issues with / in base64) sudo sed -i "s|changeme-jwt-secret-32-chars-min|$jwt_secret|" "$target_dir/docker-compose.yml" sudo sed -i "s|changeme-key-seed-32-chars-minimum|$key_seed|" "$target_dir/docker-compose.yml" sudo sed -i "s|changeme-admin-password|$admin_pass|" "$target_dir/docker-compose.yml" log "LLDAP secrets configured" else log "LLDAP secrets already configured, skipping generation" fi fi # Run service-specific setup if it exists if [[ -f "$target_dir/setup.sh" ]]; then log "Running $service_name setup..." sudo -u tinsnip -i bash -c "cd ~/service/$service_name && ./setup.sh" else # Generic docker-compose deployment log "Starting $service_name with docker-compose..." sudo -u tinsnip -i bash -c "cd ~/service/$service_name && docker compose up -d" fi # Create systemd service for auto-start create_systemd_service "$service_name" } create_systemd_service() { local service_name="$1" local systemd_file="/etc/systemd/system/tinsnip-${service_name}.service" log "Creating systemd service for $service_name..." sudo tee "$systemd_file" > /dev/null << EOF [Unit] Description=tinsnip $service_name service After=network-online.target Wants=network-online.target Requires=user@1010.service [Service] Type=simple User=tinsnip WorkingDirectory=/home/tinsnip/service/$service_name ExecStart=/usr/bin/sudo -u tinsnip docker compose up ExecStop=/usr/bin/sudo -u tinsnip docker compose down Restart=on-failure RestartSec=10 [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload sudo systemctl enable "tinsnip-${service_name}.service" log "Systemd service created and enabled: tinsnip-${service_name}.service" } main() { if [[ $# -lt 1 ]]; then error "Usage: $0 " fi local service_name="$1" # Check if tinsnip user exists if ! id "tinsnip" &>/dev/null; then error "tinsnip user does not exist. Run setup.sh first." fi deploy_service "$service_name" log "" log "Service $service_name deployed successfully!" log "To check status: sudo -u tinsnip docker compose -f /home/tinsnip/service/$service_name/docker-compose.yml ps" log "To view logs: sudo -u tinsnip docker compose -f /home/tinsnip/service/$service_name/docker-compose.yml logs" } main "$@"