#!/bin/bash # Hardware Requirements Validation Script # Validates hardware requirements for the infrastructure migration set -euo pipefail # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Function to print colored output print_status() { echo -e "${GREEN}[INFO]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } print_header() { echo -e "${BLUE}[HEADER]${NC} $1" } # Configuration HOSTS=("omv800.local" "jonathan-2518f5u" "surface" "fedora" "audrey") OUTPUT_FILE="${1:-/tmp/hardware_requirements_report.txt}" MIN_RAM_GB=4 MIN_STORAGE_GB=10 MIN_CPU_CORES=2 MIN_DOCKER_VERSION="20.10" MIN_KERNEL_VERSION="4.19" # Function to check CPU requirements check_cpu_requirements() { print_header "Checking CPU Requirements" local cpu_cores=$(nproc) local cpu_model=$(grep "model name" /proc/cpuinfo | head -1 | cut -d':' -f2 | xargs) local cpu_arch=$(uname -m) echo "CPU Cores: $cpu_cores" >> "$OUTPUT_FILE" echo "CPU Model: $cpu_model" >> "$OUTPUT_FILE" echo "CPU Architecture: $cpu_arch" >> "$OUTPUT_FILE" if [ "$cpu_cores" -ge "$MIN_CPU_CORES" ]; then echo "CPU Requirements: PASSED" >> "$OUTPUT_FILE" print_status "CPU Requirements: PASSED ($cpu_cores cores)" else echo "CPU Requirements: FAILED (minimum $MIN_CPU_CORES cores required)" >> "$OUTPUT_FILE" print_error "CPU Requirements: FAILED (minimum $MIN_CPU_CORES cores required)" return 1 fi # Check for virtualization support if grep -q "vmx\|svm" /proc/cpuinfo; then echo "Virtualization Support: AVAILABLE" >> "$OUTPUT_FILE" print_status "Virtualization Support: AVAILABLE" else echo "Virtualization Support: NOT AVAILABLE" >> "$OUTPUT_FILE" print_warning "Virtualization Support: NOT AVAILABLE" fi } # Function to check memory requirements check_memory_requirements() { print_header "Checking Memory Requirements" local total_mem_kb=$(grep MemTotal /proc/meminfo | awk '{print $2}') local total_mem_gb=$((total_mem_kb / 1024 / 1024)) local available_mem_kb=$(grep MemAvailable /proc/meminfo | awk '{print $2}') local available_mem_gb=$((available_mem_kb / 1024 / 1024)) echo "Total Memory: ${total_mem_gb}GB" >> "$OUTPUT_FILE" echo "Available Memory: ${available_mem_gb}GB" >> "$OUTPUT_FILE" if [ "$total_mem_gb" -ge "$MIN_RAM_GB" ]; then echo "Memory Requirements: PASSED" >> "$OUTPUT_FILE" print_status "Memory Requirements: PASSED (${total_mem_gb}GB total)" else echo "Memory Requirements: FAILED (minimum ${MIN_RAM_GB}GB required)" >> "$OUTPUT_FILE" print_error "Memory Requirements: FAILED (minimum ${MIN_RAM_GB}GB required)" return 1 fi # Check available memory if [ "$available_mem_gb" -lt 1 ]; then echo "Available Memory: WARNING (less than 1GB available)" >> "$OUTPUT_FILE" print_warning "Available Memory: WARNING (less than 1GB available)" else echo "Available Memory: SUFFICIENT" >> "$OUTPUT_FILE" print_status "Available Memory: SUFFICIENT (${available_mem_gb}GB available)" fi } # Function to check storage requirements check_storage_requirements() { print_header "Checking Storage Requirements" local root_partition=$(df / | awk 'NR==2 {print $1}') local total_storage_kb=$(df / | awk 'NR==2 {print $2}') local available_storage_kb=$(df / | awk 'NR==2 {print $4}') local total_storage_gb=$((total_storage_kb / 1024 / 1024)) local available_storage_gb=$((available_storage_kb / 1024 / 1024)) echo "Root Partition: $root_partition" >> "$OUTPUT_FILE" echo "Total Storage: ${total_storage_gb}GB" >> "$OUTPUT_FILE" echo "Available Storage: ${available_storage_gb}GB" >> "$OUTPUT_FILE" if [ "$total_storage_gb" -ge "$MIN_STORAGE_GB" ]; then echo "Storage Requirements: PASSED" >> "$OUTPUT_FILE" print_status "Storage Requirements: PASSED (${total_storage_gb}GB total)" else echo "Storage Requirements: FAILED (minimum ${MIN_STORAGE_GB}GB required)" >> "$OUTPUT_FILE" print_error "Storage Requirements: FAILED (minimum ${MIN_STORAGE_GB}GB required)" return 1 fi # Check available storage if [ "$available_storage_gb" -lt 5 ]; then echo "Available Storage: WARNING (less than 5GB available)" >> "$OUTPUT_FILE" print_warning "Available Storage: WARNING (less than 5GB available)" else echo "Available Storage: SUFFICIENT" >> "$OUTPUT_FILE" print_status "Available Storage: SUFFICIENT (${available_storage_gb}GB available)" fi # Check for SSD if grep -q "SSD\|nvme" /proc/mounts || lsblk -d -o name,rota | grep -q "0$"; then echo "SSD Storage: DETECTED" >> "$OUTPUT_FILE" print_status "SSD Storage: DETECTED" else echo "SSD Storage: NOT DETECTED (HDD may impact performance)" >> "$OUTPUT_FILE" print_warning "SSD Storage: NOT DETECTED (HDD may impact performance)" fi } # Function to check network requirements check_network_requirements() { print_header "Checking Network Requirements" # Check network interfaces local interfaces=$(ip link show | grep -E "^[0-9]+:" | cut -d: -f2 | tr -d ' ') echo "Network Interfaces: $interfaces" >> "$OUTPUT_FILE" # Check for Ethernet interface if echo "$interfaces" | grep -q "eth\|en"; then echo "Ethernet Interface: DETECTED" >> "$OUTPUT_FILE" print_status "Ethernet Interface: DETECTED" else echo "Ethernet Interface: NOT DETECTED" >> "$OUTPUT_FILE" print_warning "Ethernet Interface: NOT DETECTED" fi # Check network connectivity if ping -c 1 8.8.8.8 >/dev/null 2>&1; then echo "Internet Connectivity: AVAILABLE" >> "$OUTPUT_FILE" print_status "Internet Connectivity: AVAILABLE" else echo "Internet Connectivity: NOT AVAILABLE" >> "$OUTPUT_FILE" print_warning "Internet Connectivity: NOT AVAILABLE" fi # Check local network connectivity if ping -c 1 192.168.1.1 >/dev/null 2>&1 || ping -c 1 192.168.50.1 >/dev/null 2>&1; then echo "Local Network Connectivity: AVAILABLE" >> "$OUTPUT_FILE" print_status "Local Network Connectivity: AVAILABLE" else echo "Local Network Connectivity: NOT AVAILABLE" >> "$OUTPUT_FILE" print_warning "Local Network Connectivity: NOT AVAILABLE" fi } # Function to check Docker requirements check_docker_requirements() { print_header "Checking Docker Requirements" # Check if Docker is installed if ! command -v docker >/dev/null 2>&1; then echo "Docker: NOT INSTALLED" >> "$OUTPUT_FILE" print_error "Docker: NOT INSTALLED" return 1 fi # Check Docker version local docker_version=$(docker --version | cut -d' ' -f3 | cut -d',' -f1) echo "Docker Version: $docker_version" >> "$OUTPUT_FILE" # Compare versions if [ "$(printf '%s\n' "$MIN_DOCKER_VERSION" "$docker_version" | sort -V | head -n1)" = "$MIN_DOCKER_VERSION" ]; then echo "Docker Version: PASSED" >> "$OUTPUT_FILE" print_status "Docker Version: PASSED ($docker_version)" else echo "Docker Version: FAILED (minimum $MIN_DOCKER_VERSION required)" >> "$OUTPUT_FILE" print_error "Docker Version: FAILED (minimum $MIN_DOCKER_VERSION required)" return 1 fi # Check Docker daemon status if docker info >/dev/null 2>&1; then echo "Docker Daemon: RUNNING" >> "$OUTPUT_FILE" print_status "Docker Daemon: RUNNING" else echo "Docker Daemon: NOT RUNNING" >> "$OUTPUT_FILE" print_error "Docker Daemon: NOT RUNNING" return 1 fi # Check Docker storage driver local storage_driver=$(docker info | grep "Storage Driver" | cut -d: -f2 | xargs) echo "Docker Storage Driver: $storage_driver" >> "$OUTPUT_FILE" if [ "$storage_driver" = "overlay2" ]; then echo "Storage Driver: RECOMMENDED" >> "$OUTPUT_FILE" print_status "Storage Driver: RECOMMENDED ($storage_driver)" else echo "Storage Driver: NOT RECOMMENDED (overlay2 preferred)" >> "$OUTPUT_FILE" print_warning "Storage Driver: NOT RECOMMENDED (overlay2 preferred)" fi } # Function to check kernel requirements check_kernel_requirements() { print_header "Checking Kernel Requirements" local kernel_version=$(uname -r) echo "Kernel Version: $kernel_version" >> "$OUTPUT_FILE" # Extract major.minor version local kernel_major_minor=$(echo "$kernel_version" | cut -d'-' -f1 | cut -d'.' -f1,2) # Compare versions if [ "$(printf '%s\n' "$MIN_KERNEL_VERSION" "$kernel_major_minor" | sort -V | head -n1)" = "$MIN_KERNEL_VERSION" ]; then echo "Kernel Version: PASSED" >> "$OUTPUT_FILE" print_status "Kernel Version: PASSED ($kernel_version)" else echo "Kernel Version: FAILED (minimum $MIN_KERNEL_VERSION required)" >> "$OUTPUT_FILE" print_error "Kernel Version: FAILED (minimum $MIN_KERNEL_VERSION required)" return 1 fi # Check for required kernel modules local required_modules=("overlay" "br_netfilter" "iptable_nat") for module in "${required_modules[@]}"; do if lsmod | grep -q "^$module"; then echo "Kernel Module $module: LOADED" >> "$OUTPUT_FILE" print_status "Kernel Module $module: LOADED" else echo "Kernel Module $module: NOT LOADED" >> "$OUTPUT_FILE" print_warning "Kernel Module $module: NOT LOADED" fi done } # Function to check GPU requirements check_gpu_requirements() { print_header "Checking GPU Requirements" # Check for NVIDIA GPU if command -v nvidia-smi >/dev/null 2>&1; then local nvidia_gpu=$(nvidia-smi --query-gpu=name --format=csv,noheader,nounits | head -1) local nvidia_memory=$(nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits | head -1) echo "NVIDIA GPU: DETECTED ($nvidia_gpu)" >> "$OUTPUT_FILE" echo "NVIDIA Memory: ${nvidia_memory}MB" >> "$OUTPUT_FILE" print_status "NVIDIA GPU: DETECTED ($nvidia_gpu)" # Check Docker GPU support if docker run --rm --gpus all nvidia/cuda:11.0-base-ubuntu20.04 nvidia-smi >/dev/null 2>&1; then echo "Docker GPU Support: WORKING" >> "$OUTPUT_FILE" print_status "Docker GPU Support: WORKING" else echo "Docker GPU Support: NOT WORKING" >> "$OUTPUT_FILE" print_warning "Docker GPU Support: NOT WORKING" fi else echo "NVIDIA GPU: NOT DETECTED" >> "$OUTPUT_FILE" print_status "NVIDIA GPU: NOT DETECTED" fi # Check for Intel GPU if lsmod | grep -q "i915"; then echo "Intel GPU: DETECTED" >> "$OUTPUT_FILE" print_status "Intel GPU: DETECTED" else echo "Intel GPU: NOT DETECTED" >> "$OUTPUT_FILE" print_status "Intel GPU: NOT DETECTED" fi # Check for AMD GPU if lsmod | grep -q "amdgpu"; then echo "AMD GPU: DETECTED" >> "$OUTPUT_FILE" print_status "AMD GPU: DETECTED" else echo "AMD GPU: NOT DETECTED" >> "$OUTPUT_FILE" print_status "AMD GPU: NOT DETECTED" fi } # Function to check system requirements check_system_requirements() { print_header "Checking System Requirements" local os_name=$(grep "PRETTY_NAME" /etc/os-release | cut -d'"' -f2) local os_version=$(grep "VERSION_ID" /etc/os-release | cut -d'"' -f2) echo "Operating System: $os_name" >> "$OUTPUT_FILE" echo "OS Version: $os_version" >> "$OUTPUT_FILE" # Check for supported distributions if echo "$os_name" | grep -q "Ubuntu\|Debian\|CentOS\|Fedora\|RHEL"; then echo "OS Compatibility: SUPPORTED" >> "$OUTPUT_FILE" print_status "OS Compatibility: SUPPORTED ($os_name)" else echo "OS Compatibility: UNKNOWN" >> "$OUTPUT_FILE" print_warning "OS Compatibility: UNKNOWN ($os_name)" fi # Check systemd if command -v systemctl >/dev/null 2>&1; then echo "Systemd: AVAILABLE" >> "$OUTPUT_FILE" print_status "Systemd: AVAILABLE" else echo "Systemd: NOT AVAILABLE" >> "$OUTPUT_FILE" print_warning "Systemd: NOT AVAILABLE" fi # Check for required packages local required_packages=("curl" "wget" "git" "ssh" "rsync") for package in "${required_packages[@]}"; do if command -v "$package" >/dev/null 2>&1; then echo "Package $package: INSTALLED" >> "$OUTPUT_FILE" print_status "Package $package: INSTALLED" else echo "Package $package: NOT INSTALLED" >> "$OUTPUT_FILE" print_warning "Package $package: NOT INSTALLED" fi done } # Function to check security requirements check_security_requirements() { print_header "Checking Security Requirements" # Check for firewall if command -v ufw >/dev/null 2>&1 && ufw status | grep -q "active"; then echo "Firewall (UFW): ACTIVE" >> "$OUTPUT_FILE" print_status "Firewall (UFW): ACTIVE" elif command -v firewall-cmd >/dev/null 2>&1 && firewall-cmd --state | grep -q "running"; then echo "Firewall (firewalld): ACTIVE" >> "$OUTPUT_FILE" print_status "Firewall (firewalld): ACTIVE" else echo "Firewall: NOT ACTIVE" >> "$OUTPUT_FILE" print_warning "Firewall: NOT ACTIVE" fi # Check for SELinux if command -v getenforce >/dev/null 2>&1; then local selinux_status=$(getenforce) echo "SELinux Status: $selinux_status" >> "$OUTPUT_FILE" print_status "SELinux Status: $selinux_status" else echo "SELinux: NOT INSTALLED" >> "$OUTPUT_FILE" print_status "SELinux: NOT INSTALLED" fi # Check for AppArmor if command -v aa-status >/dev/null 2>&1; then echo "AppArmor: INSTALLED" >> "$OUTPUT_FILE" print_status "AppArmor: INSTALLED" else echo "AppArmor: NOT INSTALLED" >> "$OUTPUT_FILE" print_status "AppArmor: NOT INSTALLED" fi } # Function to generate requirements report generate_report() { print_header "Generating Hardware Requirements Report" echo "=== Hardware Requirements Validation Report ===" > "$OUTPUT_FILE" echo "Date: $(date)" >> "$OUTPUT_FILE" echo "Hostname: $(hostname)" >> "$OUTPUT_FILE" echo "" >> "$OUTPUT_FILE" print_status "Requirements report initialized at $OUTPUT_FILE" } # Function to display usage usage() { echo "Usage: $0 [output_file]" echo " output_file: Path to save requirements report (default: /tmp/hardware_requirements_report.txt)" echo "" echo "This script validates hardware requirements for infrastructure migration." echo "It checks CPU, memory, storage, network, Docker, kernel, and security requirements." } # Main execution main() { print_header "Starting Hardware Requirements Validation" # Initialize report generate_report # Run all checks local failed_checks=0 check_cpu_requirements || ((failed_checks++)) check_memory_requirements || ((failed_checks++)) check_storage_requirements || ((failed_checks++)) check_network_requirements || ((failed_checks++)) check_docker_requirements || ((failed_checks++)) check_kernel_requirements || ((failed_checks++)) check_gpu_requirements check_system_requirements check_security_requirements # Summary echo "" >> "$OUTPUT_FILE" echo "=== SUMMARY ===" >> "$OUTPUT_FILE" if [ "$failed_checks" -eq 0 ]; then echo "Overall Status: PASSED" >> "$OUTPUT_FILE" print_status "Hardware requirements validation PASSED" print_status "Report saved to: $OUTPUT_FILE" else echo "Overall Status: FAILED ($failed_checks critical checks failed)" >> "$OUTPUT_FILE" print_error "Hardware requirements validation FAILED ($failed_checks critical checks failed)" print_status "Report saved to: $OUTPUT_FILE" exit 1 fi } # Parse command line arguments if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then usage exit 0 fi # Run main function main "$@"