#!/usr/bin/env bash # deploy.sh - Interaktives Deployment-Tool für esn-support-bash-snippets # Maintainer: ljp # # Erkennt installierte Scripts in ~/bin und ermöglicht interaktive Auswahl set -euo pipefail # Prüfe LUSER Environment LUSER="${LUSER:?Bitte LUSER setzen! (siehe go-Script)}" # Script directory SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" BIN_DIR="$HOME/bin" usage() { cat <<'USAGE' Usage: deploy.sh INTERAKTIVES DEPLOYMENT: - Erkennt automatisch installierte Scripts in ~/bin - Interaktive Auswahl der zu deployenden Scripts - Interaktive Server-Auswahl (web, mx, logger, support) - Optional: bashrc + modulare Configs deployment FEATURES: - Auto-Detection von Scripts in ~/bin - Erkennung von Dependencies (lib/ directories) - Dry-run Modus verfügbar - Backup von bestehenden Files ENVIRONMENT: LUSER Required: Username für SSH-Verbindungen USAGE } # Detect installierte Scripts in ~/bin (via Symlinks vom Installer) detect_installed_scripts() { local scripts=() if [[ ! -d "$BIN_DIR" ]]; then echo "Warnung: $BIN_DIR existiert nicht" >&2 return 0 fi # Alle Symlinks in ~/bin die auf dieses Repository zeigen while IFS= read -r -d '' script; do local script_name=$(basename "$script") # Nur Symlinks betrachten if [[ -L "$script" ]]; then local target=$(readlink "$script") # Prüfe ob Symlink auf unser Repository zeigt if [[ "$target" == "$SCRIPT_DIR"* ]]; then scripts+=("$script_name") fi fi done < <(find "$BIN_DIR" -maxdepth 1 -type l -print0 2>/dev/null || true) printf '%s\n' "${scripts[@]}" | sort } # Finde Source-Pfad für Script-Namen find_script_source() { local script_name="$1" # Suche in legacy/ if [[ -f "$SCRIPT_DIR/legacy/$script_name/$script_name.sh" ]]; then echo "$SCRIPT_DIR/legacy/$script_name" return 0 fi # Suche in wh20/ if [[ -f "$SCRIPT_DIR/wh20/$script_name/$script_name.sh" ]]; then echo "$SCRIPT_DIR/wh20/$script_name" return 0 fi return 1 } # Interaktive Script-Auswahl select_scripts() { local -a available_scripts mapfile -t available_scripts < <(detect_installed_scripts) if [[ "${#available_scripts[@]}" -eq 0 ]]; then echo "Keine deployable Scripts in $BIN_DIR gefunden" >&2 return 1 fi echo "=== Verfügbare Scripts in $BIN_DIR ===" for i in "${!available_scripts[@]}"; do printf "%2d) %s\n" $((i+1)) "${available_scripts[i]}" done echo local selected_scripts=() while true; do echo -n "Script auswählen (Nummer, 'all' für alle, 'done' zum Beenden): " read -r choice case "$choice" in done|q|quit|exit) break ;; all) selected_scripts=("${available_scripts[@]}") echo "Alle Scripts ausgewählt: ${selected_scripts[*]}" break ;; ''|*[!0-9]*) echo "Ungültige Eingabe. Bitte Nummer eingeben." ;; *) local idx=$((choice - 1)) if [[ $idx -ge 0 && $idx -lt ${#available_scripts[@]} ]]; then local script="${available_scripts[idx]}" if [[ ! " ${selected_scripts[*]} " =~ " ${script} " ]]; then selected_scripts+=("$script") echo "✓ $script hinzugefügt" else echo "Script bereits ausgewählt: $script" fi else echo "Ungültige Nummer: $choice" fi ;; esac if [[ "${#selected_scripts[@]}" -gt 0 ]]; then echo "Aktuell ausgewählt: ${selected_scripts[*]}" fi done printf '%s\n' "${selected_scripts[@]}" } # Interaktive Target-Auswahl select_target() { echo "=== Server-Auswahl ===" echo "1) web server" echo "2) mx server" echo "3) logger.in.nessus.at" echo "4) support.in.easyname.com" echo local target_type="" local target_number="" while [[ -z "$target_type" ]]; do echo -n "Server-Typ auswählen (1-4): " read -r choice case "$choice" in 1) target_type="web" ;; 2) target_type="mx" ;; 3) target_type="logger" ;; 4) target_type="support" ;; *) echo "Ungültige Auswahl" ;; esac done if [[ "$target_type" == "web" || "$target_type" == "mx" ]]; then while [[ -z "$target_number" ]]; do echo -n "${target_type} Server-Nummer eingeben: " read -r number if [[ "$number" =~ ^[0-9]+$ ]]; then target_number="$number" else echo "Ungültige Nummer" fi done fi echo "$target_type${target_number:+ $target_number}" } # Build SSH target from arguments build_ssh_target() { local target="$1" local number="${2:-}" case "$target" in web) [[ -n "$number" ]] || { echo "Fehler: 'web' benötigt Server-Nummer" >&2; return 1; } echo "${LUSER}@web${number}.in.easyname.com" ;; mx) [[ -n "$number" ]] || { echo "Fehler: 'mx' benötigt Server-Nummer" >&2; return 1; } echo "${LUSER}@mx${number}.in.easyname.com" ;; logger) echo "${LUSER}@logger.in.nessus.at" ;; support) echo "${LUSER}@support.in.easyname.com" ;; *) echo "Unbekanntes Target: $target" >&2 return 1 ;; esac } # Deploy single script to target deploy_script() { local script_name="$1" local ssh_target="$2" local dry_run="$3" # Prüfe ob Script via Symlink installiert ist local symlink_path="$BIN_DIR/$script_name" if [[ ! -L "$symlink_path" ]]; then echo "Fehler: $script_name ist nicht via Installer-Symlink installiert" >&2 return 1 fi # Folge dem Symlink zum Original-Script local original_script=$(readlink -f "$symlink_path") local script_dir=$(dirname "$original_script") echo "=== Deploying $script_name to $ssh_target ===" echo " Source: $original_script" if (( dry_run )); then echo " [DRY-RUN] Würde kopieren:" echo " $original_script -> ~/$script_name" # Check für lib/ directory if [[ -d "$script_dir/lib" ]]; then echo " $script_dir/lib/ -> ~/lib_$script_name/" fi return 0 fi # Kopiere das Original-Script scp "$original_script" "$ssh_target:$script_name" ssh "$ssh_target" "chmod +x $script_name" # Kopiere lib/ directory falls vorhanden if [[ -d "$script_dir/lib" ]]; then echo " Deploying lib dependencies..." scp -r "$script_dir/lib" "$ssh_target:lib_$script_name" # Update Script um lib_ zu verwenden ssh "$ssh_target" "sed -i 's|\$SCRIPT_DIR/lib/|./lib_$script_name/|g' $script_name" fi echo " ✓ $script_name deployed successfully" } # Deploy bashrc and modular configs deploy_bashrc() { local ssh_target="$1" local dry_run="$2" local force="$3" echo "=== Deploying bashrc to $ssh_target ===" # Suche nach verfügbaren bashrc profiles local profiles=() while IFS= read -r -d '' profile_dir; do profiles+=("$(basename "$profile_dir")") done < <(find "$SCRIPT_DIR/bashprofiles" -mindepth 1 -maxdepth 1 -type d -print0 2>/dev/null || true) if [[ "${#profiles[@]}" -eq 0 ]]; then echo " Keine bashprofiles gefunden - erstelle Default-Profile..." if (( dry_run )); then echo " [DRY-RUN] Würde Default-.bashrc mit modularer Struktur erstellen" return 0 fi # Erstelle Default .bashrc mit modularer Struktur ssh "$ssh_target" 'cat > .bashrc << "EOF" # .bashrc - Optimierte Bash-Konfiguration für easyname Support # Generated with deployment script ##### History ##### HISTCONTROL=ignoredups:erasedups HISTSIZE=50000 HISTFILESIZE=100000 HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S " shopt -s histappend shopt -s cmdhist ##### Prompt ##### if [[ "$TERM" != "dumb" ]]; then PS1="\[\e[01;32m\]\u@\h\[\e[00m\]:\[\e[01;34m\]\w\[\e[00m\]\\$ " fi ##### Modular configs ##### [[ -f ~/.bash_aliases ]] && source ~/.bash_aliases [[ -f ~/.bash_env ]] && source ~/.bash_env [[ -f ~/.bash_paths ]] && source ~/.bash_paths ##### Standard settings ##### if [[ -f /etc/bash_completion ]]; then source /etc/bash_completion fi if [[ -x /usr/bin/dircolors ]]; then eval "$(dircolors -b)" fi # Built with the help of Claude Code EOF' # Erstelle modulare Config-Files ssh "$ssh_target" 'touch .bash_aliases .bash_env .bash_paths' ssh "$ssh_target" 'echo "# Add your environment variables here" > .bash_env' ssh "$ssh_target" 'echo "# Add your custom aliases here" > .bash_aliases' ssh "$ssh_target" 'echo "# Add your PATH extensions here" > .bash_paths' echo " ✓ Default bashrc mit modularer Struktur deployed" return 0 fi # Verwende erstes verfügbares Profil local profile="${profiles[0]}" echo " Using profile: $profile" if (( dry_run )); then echo " [DRY-RUN] Würde bashrc-Profile '$profile' kopieren" return 0 fi # Deploy bashrc profile scp "$SCRIPT_DIR/bashprofiles/$profile/.bashrc" "$ssh_target:.bashrc" echo " ✓ bashrc deployed successfully" } # MAIN - Interaktiver Modus main() { # Argument parsing für --help while [[ $# -gt 0 ]]; do case "$1" in -h|--help) usage; exit 0 ;; *) echo "Unbekannte Option: $1" >&2; usage; exit 1 ;; esac done echo "=== easyname Support Scripts Deployment ===" echo # Schritt 1: Script-Auswahl local -a selected_scripts mapfile -t selected_scripts < <(select_scripts) if [[ "${#selected_scripts[@]}" -eq 0 ]]; then echo "Keine Scripts ausgewählt. Beende." exit 0 fi # Schritt 2: Target-Auswahl local target_info target_info=$(select_target) read -r target_type target_number <<< "$target_info" local ssh_target ssh_target=$(build_ssh_target "$target_type" "$target_number") # Schritt 3: Optionen echo "=== Deployment-Optionen ===" echo -n "Bashrc auch deployen? [y/N]: " read -r deploy_bashrc_choice local deploy_bashrc=0 [[ "$deploy_bashrc_choice" =~ ^[yY]$ ]] && deploy_bashrc=1 echo -n "Dry-run (nur anzeigen was gemacht würde)? [y/N]: " read -r dry_run_choice local dry_run=0 [[ "$dry_run_choice" =~ ^[yY]$ ]] && dry_run=1 # Schritt 4: Zusammenfassung echo echo "=== Deployment-Zusammenfassung ===" echo "Target: $ssh_target" echo "Scripts: ${selected_scripts[*]}" [[ "$deploy_bashrc" -eq 1 ]] && echo "Bashrc: Ja" [[ "$dry_run" -eq 1 ]] && echo "Modus: DRY-RUN" echo echo -n "Deployment starten? [y/N]: " read -r confirm if [[ ! "$confirm" =~ ^[yY]$ ]]; then echo "Deployment abgebrochen." exit 0 fi # Schritt 5: Deployment ausführen echo echo "=== Deployment wird ausgeführt ===" # Deploy bashrc if requested if (( deploy_bashrc )); then deploy_bashrc "$ssh_target" "$dry_run" fi # Deploy scripts for script in "${selected_scripts[@]}"; do deploy_script "$script" "$ssh_target" "$dry_run" || { echo "Fehler beim Deployment von $script" >&2 exit 1 } done echo echo "=== Deployment abgeschlossen ===" echo "Target: $ssh_target" [[ "$deploy_bashrc" -eq 1 ]] && echo "✓ bashrc deployed" echo "✓ Scripts deployed: ${selected_scripts[*]}" [[ "$dry_run" -eq 1 ]] && echo "(DRY-RUN - nichts wurde tatsächlich deployed)" } # Script starten main "$@" # Built with the help of Claude Code