feature/deploy-system #2

Merged
ljp merged 15 commits from feature/deploy-system into main 2025-09-11 17:56:21 +02:00
Showing only changes of commit 63121c71f8 - Show all commits
+87 -276
View File
@@ -1,8 +1,8 @@
#!/usr/bin/env bash
# deploy.sh - Interaktives Deployment-Tool für esn-support-bash-snippets
# deploy.sh - Einfaches Deployment-Tool für esn-support-bash-snippets
# Maintainer: ljp
#
# Erkennt installierte Scripts in ~/bin und ermöglicht interaktive Auswahl
# Erkennt installierte Scripts in ~/bin und ermöglicht einfache Auswahl
set -euo pipefail
# Prüfe LUSER Environment
@@ -16,325 +16,147 @@ usage() {
cat <<'USAGE'
Usage: deploy.sh
INTERAKTIVES DEPLOYMENT:
EINFACHES 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
- Einfache Auswahl mit bash select
- Einfache Server-Auswahl (web, mx, logger, support)
- Optional: bashrc deployment
FEATURES:
- Auto-Detection von Scripts in ~/bin
- Erkennung von Dependencies (lib/ directories)
- Dry-run Modus verfügbar
- Backup von bestehenden Files
- Symlink-basiertes Deployment
- PATH-Setup für target servers
- Dry-run verfügbar
ENVIRONMENT:
LUSER Required: Username für SSH-Verbindungen
USAGE
}
# Detect installierte Scripts in ~/bin (via Symlinks vom Installer)
detect_installed_scripts() {
# Einfache Script-Detection
get_deployable_scripts() {
local scripts=()
if [[ ! -d "$BIN_DIR" ]]; then
echo "Warnung: $BIN_DIR existiert nicht" >&2
return 0
fi
[[ ! -d "$BIN_DIR" ]] && { echo "Warnung: $BIN_DIR existiert nicht" >&2; return 0; }
# 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)
# Finde alle Symlinks die auf unser Repository zeigen
for symlink in "$BIN_DIR"/*; do
[[ -L "$symlink" ]] || continue
local target=$(readlink -f "$symlink" 2>/dev/null || continue)
[[ "$target" == "$SCRIPT_DIR"* ]] || continue
scripts+=("$(basename "$symlink")")
done
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() {
# Einfache Server-Auswahl
select_server() {
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 servers=("web" "mx" "logger" "support")
local server
local target_type=""
local target_number=""
select server in "${servers[@]}"; do
[[ -n "$server" ]] || { echo "Ungültige Auswahl"; continue; }
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: "
case "$server" in
web|mx)
echo -n "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"
[[ "$number" =~ ^[0-9]+$ ]] || { echo "Ungültige Nummer"; continue; }
echo "${LUSER}@${server}${number}.in.easyname.com"
return 0
;;
logger)
echo "${LUSER}@logger.in.nessus.at"
return 0
;;
support)
echo "${LUSER}@support.in.easyname.com"
;;
*)
echo "Unbekanntes Target: $target" >&2
return 1
return 0
;;
esac
done
}
# Deploy single script to target
# Einfaches Script-Deployment
deploy_script() {
local script_name="$1"
local ssh_target="$2"
local dry_run="$3"
# Prüfe ob Script via Symlink installiert ist
# Folge Symlink zum Original
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
[[ -L "$symlink_path" ]] || { echo "Fehler: $script_name ist kein Symlink" >&2; return 1; }
# 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
echo " [DRY-RUN] Würde deployment ausführen:"
echo " Script: $original_script -> ~/$script_name"
echo " Symlink: ~/bin/$script_name -> ~/$script_name"
[[ -d "$script_dir/lib" ]] && echo " Lib: $script_dir/lib/ -> ~/lib_$script_name/"
return 0
fi
# Kopiere das Original-Script
# Deployment ausführen
scp "$original_script" "$ssh_target:$script_name"
ssh "$ssh_target" "chmod +x $script_name"
ssh "$ssh_target" "chmod +x $script_name && mkdir -p ~/bin && ln -sf ~/$script_name ~/bin/$script_name"
# Kopiere lib/ directory falls vorhanden
# Lib-Dependencies 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_<scriptname> zu verwenden
ssh "$ssh_target" "sed -i 's|\$SCRIPT_DIR/lib/|./lib_$script_name/|g' $script_name"
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
# Einfaches bashrc-Deployment
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"
echo " [DRY-RUN] Würde default bashrc mit PATH-Setup erstellen"
return 0
fi
# Erstelle Default .bashrc mit modularer Struktur
# Erstelle einfache .bashrc mit PATH-Setup
ssh "$ssh_target" 'cat > .bashrc << "EOF"
# .bashrc - Optimierte Bash-Konfiguration für easyname Support
# Generated with deployment script
# .bashrc - Einfache Bash-Konfiguration für easyname Support
##### History #####
# 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
# PATH Setup
[[ -d "$HOME/bin" && ":$PATH:" != *":$HOME/bin:"* ]] && PATH="$HOME/bin:$PATH"
##### 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
# Prompt
[[ "$TERM" != "dumb" ]] && PS1="\[\e[01;32m\]\u@\h\[\e[00m\]:\[\e[01;34m\]\w\[\e[00m\]\\$ "
# 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 - Vereinfachte Ausführung
main() {
# Argument parsing für --help
# Argument parsing
local dry_run=0
while [[ $# -gt 0 ]]; do
case "$1" in
-n|--dry-run) dry_run=1; shift ;;
-h|--help) usage; exit 0 ;;
*) echo "Unbekannte Option: $1" >&2; usage; exit 1 ;;
esac
@@ -343,73 +165,62 @@ main() {
echo "=== easyname Support Scripts Deployment ==="
echo
# Schritt 1: Script-Auswahl
local -a selected_scripts
mapfile -t selected_scripts < <(select_scripts)
# Script-Auswahl
local -a available_scripts
mapfile -t available_scripts < <(get_deployable_scripts)
if [[ "${#selected_scripts[@]}" -eq 0 ]]; then
echo "Keine Scripts ausgewählt. Beende."
exit 0
fi
[[ "${#available_scripts[@]}" -eq 0 ]] && {
echo "Keine deployable Scripts in $BIN_DIR gefunden" >&2
exit 1
}
# Schritt 2: Target-Auswahl
local target_info
target_info=$(select_target)
read -r target_type target_number <<< "$target_info"
echo "Verfügbare Scripts:"
local script
select script in "${available_scripts[@]}" "ALL SCRIPTS"; do
[[ -n "$script" ]] && break
echo "Ungültige Auswahl"
done
# Server-Auswahl
local ssh_target
ssh_target=$(build_ssh_target "$target_type" "$target_number")
ssh_target=$(select_server)
# Schritt 3: Optionen
echo "=== Deployment-Optionen ==="
# 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
# Bestätigung
echo
echo "=== Deployment-Zusammenfassung ==="
echo "Target: $ssh_target"
echo "Scripts: ${selected_scripts[*]}"
echo "Scripts: $script"
[[ "$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
[[ "$confirm" =~ ^[yY]$ ]] || { echo "Abgebrochen."; exit 0; }
if [[ ! "$confirm" =~ ^[yY]$ ]]; then
echo "Deployment abgebrochen."
exit 0
fi
# Schritt 5: Deployment ausführen
# Deployment ausführen
echo
echo "=== Deployment wird ausgeführt ==="
# Deploy bashrc if requested
if (( deploy_bashrc )); then
deploy_bashrc "$ssh_target" "$dry_run"
fi
# Bashrc deployment
(( deploy_bashrc )) && deploy_bashrc "$ssh_target" "$dry_run"
# Deploy scripts
for script in "${selected_scripts[@]}"; do
deploy_script "$script" "$ssh_target" "$dry_run" || {
echo "Fehler beim Deployment von $script" >&2
exit 1
}
# Script deployment
if [[ "$script" == "ALL SCRIPTS" ]]; then
for s in "${available_scripts[@]}"; do
deploy_script "$s" "$ssh_target" "$dry_run"
done
else
deploy_script "$script" "$ssh_target" "$dry_run"
fi
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)"
}