242 lines
6.3 KiB
Bash
Executable File
242 lines
6.3 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Main Deployment Script
|
|
# Uses script framework for professional deployment automation
|
|
#
|
|
|
|
set -euo pipefail
|
|
|
|
# Determine script directory
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
# Source libraries
|
|
# shellcheck source=./lib/common.sh
|
|
source "${SCRIPT_DIR}/lib/common.sh"
|
|
# shellcheck source=./lib/ansible.sh
|
|
source "${SCRIPT_DIR}/lib/ansible.sh"
|
|
|
|
# Configuration
|
|
readonly DEPLOYMENT_NAME="Framework Production Deployment"
|
|
readonly START_TIME=$(date +%s)
|
|
|
|
# Usage information
|
|
usage() {
|
|
cat << EOF
|
|
Usage: $0 [OPTIONS] [GIT_REPO_URL]
|
|
|
|
Professional deployment automation using Ansible.
|
|
|
|
OPTIONS:
|
|
-h, --help Show this help message
|
|
-c, --check Run in check mode (dry-run)
|
|
-v, --verbose Enable verbose output
|
|
-d, --debug Enable debug logging
|
|
-f, --force Skip confirmation prompts
|
|
--no-health-check Skip health checks
|
|
|
|
EXAMPLES:
|
|
# Deploy from existing code on server
|
|
$0
|
|
|
|
# Deploy from specific Git repository
|
|
$0 https://github.com/user/repo.git
|
|
|
|
# Dry-run to see what would happen
|
|
$0 --check
|
|
|
|
# Debug mode
|
|
$0 --debug
|
|
|
|
EOF
|
|
exit 0
|
|
}
|
|
|
|
# Parse command line arguments
|
|
parse_args() {
|
|
local git_repo_url=""
|
|
local check_mode=false
|
|
local force=false
|
|
local health_check=true
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
-h|--help)
|
|
usage
|
|
;;
|
|
-c|--check)
|
|
check_mode=true
|
|
shift
|
|
;;
|
|
-v|--verbose)
|
|
set -x
|
|
shift
|
|
;;
|
|
-d|--debug)
|
|
export DEBUG=1
|
|
shift
|
|
;;
|
|
-f|--force)
|
|
force=true
|
|
shift
|
|
;;
|
|
--no-health-check)
|
|
health_check=false
|
|
shift
|
|
;;
|
|
*)
|
|
if [[ -z "$git_repo_url" ]]; then
|
|
git_repo_url="$1"
|
|
else
|
|
log_error "Unknown argument: $1"
|
|
usage
|
|
fi
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
echo "$check_mode|$force|$health_check|$git_repo_url"
|
|
}
|
|
|
|
# Pre-deployment checks
|
|
pre_deployment_checks() {
|
|
log_step "Running pre-deployment checks..."
|
|
|
|
# Check Ansible
|
|
check_ansible || die "Ansible check failed"
|
|
|
|
# Test connectivity
|
|
test_ansible_connectivity || die "Connectivity check failed"
|
|
|
|
# Check playbook syntax
|
|
local playbook="${ANSIBLE_PLAYBOOK_DIR}/deploy.yml"
|
|
if [[ -f "$playbook" ]]; then
|
|
check_playbook_syntax "$playbook" || log_warning "Playbook syntax check failed"
|
|
fi
|
|
|
|
log_success "Pre-deployment checks passed"
|
|
}
|
|
|
|
# Deployment summary
|
|
show_deployment_summary() {
|
|
local git_repo_url="$1"
|
|
local check_mode="$2"
|
|
|
|
echo ""
|
|
echo "========================================="
|
|
echo " ${DEPLOYMENT_NAME}"
|
|
echo "========================================="
|
|
echo ""
|
|
echo "Mode: $([ "$check_mode" = "true" ] && echo "CHECK (Dry-Run)" || echo "PRODUCTION")"
|
|
echo "Target: 94.16.110.151 (production)"
|
|
echo "Services: framework_web, framework_queue-worker"
|
|
|
|
if [[ -n "$git_repo_url" ]]; then
|
|
echo "Git Repo: $git_repo_url"
|
|
else
|
|
echo "Source: Existing code on server"
|
|
fi
|
|
|
|
echo "Ansible: $(ansible --version | head -1)"
|
|
echo "Timestamp: $(timestamp)"
|
|
echo ""
|
|
}
|
|
|
|
# Post-deployment health check
|
|
post_deployment_health_check() {
|
|
log_step "Running post-deployment health checks..."
|
|
|
|
log_info "Checking service status..."
|
|
if ansible_adhoc production_server shell "docker stack services framework" &> /dev/null; then
|
|
log_success "Services are running"
|
|
else
|
|
log_warning "Could not verify service status"
|
|
fi
|
|
|
|
log_info "Testing website availability..."
|
|
if ansible_adhoc production_server shell "curl -k -s -o /dev/null -w '%{http_code}' https://michaelschiemer.de/" | grep -q "200\|302"; then
|
|
log_success "Website is responding"
|
|
else
|
|
log_warning "Website health check failed"
|
|
fi
|
|
|
|
log_success "Health checks completed"
|
|
}
|
|
|
|
# Main deployment function
|
|
main() {
|
|
# Parse arguments
|
|
IFS='|' read -r check_mode force health_check git_repo_url <<< "$(parse_args "$@")"
|
|
|
|
# Show summary
|
|
show_deployment_summary "$git_repo_url" "$check_mode"
|
|
|
|
# Confirm deployment
|
|
if [[ "$force" != "true" ]] && [[ "$check_mode" != "true" ]]; then
|
|
if ! confirm "Proceed with deployment?" "n"; then
|
|
log_warning "Deployment cancelled by user"
|
|
exit 0
|
|
fi
|
|
echo ""
|
|
fi
|
|
|
|
# Pre-deployment checks
|
|
pre_deployment_checks
|
|
|
|
# Run deployment
|
|
log_step "Starting deployment..."
|
|
echo ""
|
|
|
|
if [[ "$check_mode" = "true" ]]; then
|
|
local playbook="${ANSIBLE_PLAYBOOK_DIR}/deploy.yml"
|
|
ansible_dry_run "$playbook" ${git_repo_url:+-e "git_repo_url=$git_repo_url"}
|
|
else
|
|
run_deployment "$git_repo_url"
|
|
fi
|
|
|
|
local deployment_exit_code=$?
|
|
|
|
if [[ $deployment_exit_code -eq 0 ]]; then
|
|
echo ""
|
|
log_success "Deployment completed successfully!"
|
|
|
|
# Post-deployment health check
|
|
if [[ "$health_check" = "true" ]] && [[ "$check_mode" != "true" ]]; then
|
|
echo ""
|
|
post_deployment_health_check
|
|
fi
|
|
|
|
# Show deployment stats
|
|
local end_time=$(date +%s)
|
|
local elapsed=$(duration "$START_TIME" "$end_time")
|
|
|
|
echo ""
|
|
echo "========================================="
|
|
echo " Deployment Summary"
|
|
echo "========================================="
|
|
echo "Status: SUCCESS ✅"
|
|
echo "Duration: $elapsed"
|
|
echo "Website: https://michaelschiemer.de"
|
|
echo "Timestamp: $(timestamp)"
|
|
echo "========================================="
|
|
echo ""
|
|
|
|
return 0
|
|
else
|
|
echo ""
|
|
log_error "Deployment failed!"
|
|
echo ""
|
|
log_info "Troubleshooting:"
|
|
log_info " 1. Check Ansible logs above"
|
|
log_info " 2. SSH to server: ssh -i ~/.ssh/production deploy@94.16.110.151"
|
|
log_info " 3. Check services: docker stack services framework"
|
|
log_info " 4. View logs: docker service logs framework_web --tail 50"
|
|
echo ""
|
|
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Execute main function
|
|
main "$@"
|