diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57221df --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +logs/ +*.log + +backups/ +*.tar.gz + diff --git a/run_all.sh b/run_all.sh new file mode 100644 index 0000000..1c781fe --- /dev/null +++ b/run_all.sh @@ -0,0 +1,225 @@ +#!/bin/bash + +# Interactive menu runner for all scripts + +set -euo pipefail + +# Check for batch mode +if [[ "${1:-}" == "--batch" ]]; then + LOG_FILE="logs/app.log" + mkdir -p "$(dirname "$LOG_FILE")" + log_message() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE" + } + # Run all scripts in batch + log_message "=== Batch Mode: Running All Scripts ===" + echo "Running System Check..." + bash scripts/system_check.sh 2>/dev/null || log_message "ERROR: system_check.sh failed" + echo "System Check done." + echo "Running User Info (skipped in batch mode)..." + log_message "User Info script skipped in batch mode" + echo "Running Process Monitor..." + bash scripts/process_monitor.sh 2>/dev/null || log_message "ERROR: process_monitor.sh failed" + echo "Process Monitor done." + log_message "=== Batch Mode Completed ===" + echo "All scripts executed in batch mode." + exit 0 +fi + +LOG_FILE="logs/app.log" + +mkdir -p "$(dirname "$LOG_FILE")" + +log_message() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE" +} + +show_header() { + clear + echo "DEVOPS BASH TOOLKIT" + echo "Interactive Automation Menu" + echo "" +} + +show_menu() { + show_header + echo "Select an option:" + echo "" + echo " 1) Run All Scripts" + echo " 2) System Check" + echo " 3) User Information" + echo " 4) File Manager" + echo " 5) Backup System" + echo " 6) Process Monitor" + echo " 7) View Logs" + echo " 8) Exit" + echo "" +} + +run_user_info() { + log_message "Executing: User Info Script" + echo "" + echo "=== User Information Script ===" + + if [[ -x "scripts/user_info.sh" ]]; then + bash scripts/user_info.sh + else + echo "Error: scripts/user_info.sh not found or not executable" + log_message "ERROR: scripts/user_info.sh not executable" + fi + + echo "" + read -p "Press Enter to continue..." +} + +run_system_check() { + log_message "Executing: System Check Script" + echo "" + echo "=== System Check Report ===" + + if [[ -x "scripts/system_check.sh" ]]; then + bash scripts/system_check.sh + else + echo "Error: scripts/system_check.sh not found or not executable" + log_message "ERROR: scripts/system_check.sh not executable" + fi + + echo "" + read -p "Press Enter to continue..." +} + +run_file_manager() { + log_message "Executing: File Manager Script" + echo "" + echo "=== File Manager ===" + + if [[ -x "scripts/file_manager.sh" ]]; then + read -p "Enter file manager command (e.g., list, create file.txt): " -r cmd + bash scripts/file_manager.sh $cmd + else + echo "Error: scripts/file_manager.sh not found or not executable" + log_message "ERROR: scripts/file_manager.sh not executable" + fi + + echo "" + read -p "Press Enter to continue..." +} + +run_backup() { + log_message "Executing: Backup Script" + echo "" + echo "=== Backup System ===" + + if [[ -x "scripts/backup.sh" ]]; then + read -p "Enter directory to backup (e.g., .): " -r dir + bash scripts/backup.sh "$dir" + else + echo "Error: scripts/backup.sh not found or not executable" + log_message "ERROR: scripts/backup.sh not executable" + fi + + echo "" + read -p "Press Enter to continue..." +} + + +run_process_monitor() { + log_message "Executing: Process Monitor Script" + echo "" + echo "=== Process Monitor ===" + + if [[ -x "scripts/process_monitor.sh" ]]; then + read -p "Enter process name to monitor (leave blank for all): " -r process + if [[ -z "$process" ]]; then + bash scripts/process_monitor.sh + else + bash scripts/process_monitor.sh "$process" + fi + else + echo "Error: scripts/process_monitor.sh not found or not executable" + log_message "ERROR: scripts/process_monitor.sh not executable" + fi + + echo "" + read -p "Press Enter to continue..." +} + +run_all_scripts() { + log_message "Executing: All Scripts" + + echo "" + echo "Running all scripts in sequence..." + echo "" + + echo "Running System Check..." + bash scripts/system_check.sh 2>/dev/null || log_message "ERROR: system_check.sh failed" + echo "" + + echo "Running User Info (skipped - requires user input)..." + log_message "User Info script skipped in batch mode" + echo "" + + echo "Running Process Monitor (all services)..." + bash scripts/process_monitor.sh 2>/dev/null || log_message "ERROR: process_monitor.sh failed" + echo "" + + log_message "All scripts executed" + read -p "Press Enter to continue..." +} + +view_logs() { + show_header + echo "=== Application Log ===" + echo "" + + if [[ -f "$LOG_FILE" ]]; then + tail -n 30 "$LOG_FILE" + else + echo "No logs found yet" + fi + + echo "" + read -p "Press Enter to continue..." +} + +log_message "=== Application Started ===" + +while true; do + show_menu + read -p "Enter your choice [1-8]: " -r choice + + case "$choice" in + 1) + run_all_scripts + ;; + 2) + run_system_check + ;; + 3) + run_user_info + ;; + 4) + run_file_manager + ;; + 5) + run_backup + ;; + 6) + run_process_monitor + ;; + 7) + view_logs + ;; + 8) + log_message "=== Application Terminated ===" + echo "Exiting... Goodbye!" + exit 0 + ;; + *) + echo "Invalid choice. Please try again." + read -p "Press Enter to continue..." + ;; + esac +done + +exit 0 diff --git a/scripts/backup.sh b/scripts/backup.sh new file mode 100644 index 0000000..fb75108 --- /dev/null +++ b/scripts/backup.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +# Backup management + +set -euo pipefail + +LOG_FILE="logs/backup.log" +BACKUP_DIR="backups" +MAX_BACKUPS=5 + +mkdir -p "$(dirname "$LOG_FILE")" +mkdir -p "$BACKUP_DIR" + +log_message() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" +} + +show_usage() { + echo "Usage: $0 " + echo "" + echo "Example:" + echo " $0 /home/user/documents" + echo "" + echo "Options:" + echo " Backups are stored in: $BACKUP_DIR/" + echo " Latest 5 backups are kept, older ones are deleted" + echo "" +} + +# Check if directory argument is provided +if [[ $# -lt 1 ]]; then + echo "Error: No directory specified" + show_usage + exit 1 +fi + +SOURCE_DIR="$1" + +# Validate directory exists +if [[ ! -d "$SOURCE_DIR" ]]; then + log_message "ERROR: Directory does not exist: $SOURCE_DIR" + echo "Error: Directory '$SOURCE_DIR' does not exist." + exit 1 +fi + +log_message "=== Backup Process Started ===" +log_message "Source Directory: $SOURCE_DIR" + +# Create backup with timestamp +TIMESTAMP=$(date '+%Y%m%d_%H%M%S') +BACKUP_FILENAME="backup_${TIMESTAMP}.tar.gz" +BACKUP_PATH="${BACKUP_DIR}/${BACKUP_FILENAME}" + + +DIR_NAME=$(basename "$SOURCE_DIR") + +echo "Creating backup of: $SOURCE_DIR" +echo "Backup file: $BACKUP_FILENAME" + +# Create the compressed backup +if tar -czf "$BACKUP_PATH" -C "$(dirname "$SOURCE_DIR")" "$(basename "$SOURCE_DIR")" 2>/dev/null; then + BACKUP_SIZE=$(du -h "$BACKUP_PATH" | cut -f1) + log_message "SUCCESS: Backup created - $BACKUP_FILENAME ($BACKUP_SIZE)" + echo "✓ Backup created successfully: $BACKUP_FILENAME ($BACKUP_SIZE)" +else + log_message "ERROR: Failed to create backup" + echo "Error: Failed to create backup" + exit 1 +fi + +log_message "--- Backup Rotation ---" + + +BACKUP_COUNT=$(ls -1 "$BACKUP_DIR"/backup_*.tar.gz 2>/dev/null | wc -l) +log_message "Total backups available: $BACKUP_COUNT" + +if [[ $BACKUP_COUNT -gt $MAX_BACKUPS ]]; then + echo "Rotating backups (keeping last $MAX_BACKUPS)..." + + # Remove oldest backups + ls -t "$BACKUP_DIR"/backup_*.tar.gz 2>/dev/null | tail -n "+$((MAX_BACKUPS + 1))" | while read -r old_backup; do + log_message "DELETED (rotation): $(basename "$old_backup")" + rm -f "$old_backup" + echo " Removed: $(basename "$old_backup")" + done +fi + +log_message "--- Current Backups ---" +echo "" +echo "Current backups in $BACKUP_DIR:" +ls -lh "$BACKUP_DIR"/backup_*.tar.gz 2>/dev/null | awk '{print " " $9 " (" $5 ")"}' + +log_message "=== Backup Process Completed ===" + +exit 0 diff --git a/scripts/file_manager.sh b/scripts/file_manager.sh new file mode 100644 index 0000000..ed58ed1 --- /dev/null +++ b/scripts/file_manager.sh @@ -0,0 +1,120 @@ +#!/bin/bash + +set -euo pipefail + +LOG_FILE="logs/file_manager.log" + +mkdir -p "$(dirname "$LOG_FILE")" + +log_message() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE" + echo "$1" +} + +show_usage() { + echo "Usage: $0 [arguments]" + echo "" + echo "Commands:" + echo " create - Create a new file" + echo " delete - Delete a file" + echo " list [directory] - List files in directory (default: current)" + echo " rename - Rename a file" + echo "" +} + +# Check if command is provided +if [[ $# -lt 1 ]]; then + echo "Error: No command provided" + show_usage + exit 1 +fi + +COMMAND="$1" + +case "$COMMAND" in + create) + if [[ $# -lt 2 ]]; then + echo "Error: Filename required for create command" + exit 1 + fi + + FILENAME="$2" + + if [[ -e "$FILENAME" ]]; then + log_message "ERROR: File already exists: $FILENAME" + echo "Error: File '$FILENAME' already exists. Use a different name." + exit 1 + fi + + touch "$FILENAME" + log_message "SUCCESS: Created file: $FILENAME" + echo "✓ File created: $FILENAME" + ;; + + delete) + if [[ $# -lt 2 ]]; then + echo "Error: Filename required for delete command" + exit 1 + fi + + FILENAME="$2" + + if [[ ! -e "$FILENAME" ]]; then + log_message "ERROR: File not found: $FILENAME" + echo "Error: File '$FILENAME' not found." + exit 1 + fi + + rm "$FILENAME" + log_message "SUCCESS: Deleted file: $FILENAME" + echo "✓ File deleted: $FILENAME" + ;; + + list) + DIRECTORY="${2:-.}" + + if [[ ! -d "$DIRECTORY" ]]; then + log_message "ERROR: Directory not found: $DIRECTORY" + echo "Error: Directory '$DIRECTORY' not found." + exit 1 + fi + + log_message "SUCCESS: Listed files in: $DIRECTORY" + echo "Files in $DIRECTORY:" + ls -lh "$DIRECTORY" || true + ;; + + rename) + if [[ $# -lt 3 ]]; then + echo "Error: Old name and new name required for rename command" + exit 1 + fi + + OLD_NAME="$2" + NEW_NAME="$3" + + if [[ ! -e "$OLD_NAME" ]]; then + log_message "ERROR: File not found: $OLD_NAME" + echo "Error: File '$OLD_NAME' not found." + exit 1 + fi + + if [[ -e "$NEW_NAME" ]]; then + log_message "ERROR: Target file already exists: $NEW_NAME" + echo "Error: File '$NEW_NAME' already exists. Choose a different name." + exit 1 + fi + + mv "$OLD_NAME" "$NEW_NAME" + log_message "SUCCESS: Renamed '$OLD_NAME' to '$NEW_NAME'" + echo "✓ File renamed: $OLD_NAME → $NEW_NAME" + ;; + + *) + echo "Error: Unknown command: $COMMAND" + show_usage + exit 1 + ;; +esac + +exit 0 diff --git a/scripts/process_monitor.sh b/scripts/process_monitor.sh new file mode 100644 index 0000000..5bdbf1a --- /dev/null +++ b/scripts/process_monitor.sh @@ -0,0 +1,115 @@ +#!/bin/bash + +# process_monitor.sh - Process monitoring and restart script (Optional Bonus) +# Monitors running processes and attempts restart if stopped +# Uses an array to manage services + +set -euo pipefail + +LOG_FILE="logs/process_monitor.log" + +# Initialize log file +mkdir -p "$(dirname "$LOG_FILE")" + +# Function to log messages +log_message() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" +} + +# Function to display usage +show_usage() { + echo "Usage: $0 " + echo "" + echo "Examples:" + echo " $0 nginx" + echo " $0 sshd" + echo " $0 docker" + echo "" + echo "Predefined services to monitor: nginx, ssh, docker" + echo "" +} + +# Array of default services +declare -a services=("nginx" "ssh" "docker") + +log_message "=== Process Monitor Started ===" + +# Check if process name is provided +if [[ $# -lt 1 ]]; then + echo "Error: No process name provided" + show_usage + + echo "Monitoring all default services..." + echo "" + + # Monitor all default services + for service in "${services[@]}"; do + log_message "Checking service: $service" + + if pgrep -f "$service" > /dev/null 2>&1; then + log_message " Status: Running" + echo "✓ $service: Running" + else + log_message " Status: Stopped - Attempting restart" + echo "⚠️ $service: Stopped - Attempting restart..." + + # Simulate restart (actual restart would require sudo/permissions) + log_message " Simulating restart for: $service" + echo " [SIMULATED] systemctl restart $service" + echo "✓ $service: Restarted (simulated)" + fi + echo "" + done + + log_message "=== Process Monitor Completed ===" + exit 0 +fi + +PROCESS_NAME="$1" + +log_message "Monitoring process: $PROCESS_NAME" + +# Check if process is running +if pgrep -f "$PROCESS_NAME" > /dev/null 2>&1; then + log_message "Status: Running" + echo "================================" + echo "Process: $PROCESS_NAME" + echo "Status: ✓ Running" + echo "================================" + + # Show process details + echo "" + echo "Process Details:" + pgrep -a -f "$PROCESS_NAME" | head -5 + +else + log_message "Status: Stopped - Attempting restart" + echo "================================" + echo "Process: $PROCESS_NAME" + echo "Status: ⚠️ Stopped" + echo "================================" + echo "" + echo "Attempting to restart..." + + # Simulate restart (actual restart would require sudo/permissions) + echo "Simulating restart command:" + echo " systemctl restart $PROCESS_NAME" + + log_message "Simulated restart: systemctl restart $PROCESS_NAME" + + # Check if systemctl command exists + if command -v systemctl &> /dev/null; then + echo "" + echo "Note: Restart requires sudo permissions" + echo "To actually restart, run:" + echo " sudo systemctl restart $PROCESS_NAME" + fi + + echo "" + echo "Status: ✓ Restarted (simulated)" + log_message "Status: Restarted (simulated)" +fi + +log_message "=== Process Monitor Completed ===" + +exit 0 diff --git a/scripts/system_check.sh b/scripts/system_check.sh new file mode 100644 index 0000000..ef0014c --- /dev/null +++ b/scripts/system_check.sh @@ -0,0 +1,73 @@ +#!/bin/bash + +# Displays system data +# Shows disk usage, memory usage, CPU load, running processes + +set -euo pipefail + +LOG_FILE="logs/system_report_$(date '+%Y-%m-%d_%H-%M-%S').log" + + +mkdir -p "$(dirname "$LOG_FILE")" + + +log_message() { + echo "$1" | tee -a "$LOG_FILE" +} + +log_message "=== System Check Report ===" +log_message "Generated: $(date '+%Y-%m-%d %H:%M:%S')" +log_message "" + +# Disk usage +log_message "--- DISK USAGE ---" +df -h | tee -a "$LOG_FILE" +log_message "" + +# Disk usage exceeding 805 +log_message "--- DISK USAGE ALERTS ---" +df -h | awk 'NR>1 {gsub(/%/,"",$5); if ($5 > 80) print " WARNING: " $6 " is " $5 "% full"}' | tee -a "$LOG_FILE" +log_message "" + +#memory usage +log_message "--- MEMORY USAGE ---" +if command -v free &> /dev/null; then + free -m | tee -a "$LOG_FILE" +else + MEM_INFO=$(wmic OS get TotalVisibleMemorySize,FreePhysicalMemory) + TOTAL_KB=$(echo "$MEM_INFO" | awk 'NR==2 {print $2}') + FREE_KB=$(echo "$MEM_INFO" | awk 'NR==2 {print $1}') + TOTAL_MB=$((TOTAL_KB / 1024)) + FREE_MB=$((FREE_KB / 1024)) + USED_MB=$((TOTAL_MB - FREE_MB)) + echo "Total Memory: ${TOTAL_MB} MB" | tee -a "$LOG_FILE" + echo "Used Memory: ${USED_MB} MB" | tee -a "$LOG_FILE" + echo "Free Memory: ${FREE_MB} MB" | tee -a "$LOG_FILE" +fi +log_message "" + +# CPU load +log_message "--- CPU LOAD ---" +if command -v uptime &> /dev/null; then + uptime | tee -a "$LOG_FILE" +else + # Windows alternative + CPU_LOAD=$(wmic cpu get loadpercentage | awk 'NR==2 {print $1}') + echo "CPU Load: ${CPU_LOAD}%" | tee -a "$LOG_FILE" +fi +log_message "" + +# Process count +log_message "--- RUNNING PROCESSES ---" +process_count=$(ps aux | wc -l) +log_message "Total Running Processes: $((process_count - 1))" +log_message "" + +log_message "--- TOP 5 MEMORY-CONSUMING PROCESSES ---" +ps aux | sort -k4 -nr | head -6 | tee -a "$LOG_FILE" +log_message "" + +log_message "=== System Check Report Complete ===" +log_message "Report saved to: $LOG_FILE" + +exit 0 diff --git a/scripts/user_info.sh b/scripts/user_info.sh new file mode 100644 index 0000000..71da2e4 --- /dev/null +++ b/scripts/user_info.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +# Collects user information with validation + +set -euo pipefail + +LOG_FILE="logs/user_info.log" + +mkdir -p "$(dirname "$LOG_FILE")" + +log_message() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" +} + +is_numeric() { + [[ "$1" =~ ^[0-9]+$ ]] +} + +get_age_category() { + local age=$1 + if (( age < 18 )); then + echo "Minor" + elif (( age >= 18 && age <= 65 )); then + echo "Adult" + else + echo "Senior" + fi +} + +log_message "=== User Info Script Started ===" + +read -p "Enter your name: " -r name || { log_message "ERROR: Failed to read name"; exit 1; } + +if [[ -z "$name" ]]; then + log_message "ERROR: Name cannot be empty" + echo "Error: Name cannot be empty" + exit 1 +fi + +read -p "Enter your age: " -r age || { log_message "ERROR: Failed to read age"; exit 1; } + +if ! is_numeric "$age"; then + log_message "ERROR: Age must be numeric (received: $age)" + echo "Error: Age must be numeric" + exit 1 +fi + +read -p "Enter your country: " -r country || { log_message "ERROR: Failed to read country"; exit 1; } + +if [[ -z "$country" ]]; then + log_message "ERROR: Country cannot be empty" + echo "Error: Country cannot be empty" + exit 1 +fi + +age_category=$(get_age_category "$age") + +# Output +echo "================================" +echo "Hello, $name!" +echo "Age: $age" +echo "Country: $country" +echo "Age Category: $age_category" +echo "================================" + +# Output logs +log_message "User Info Collected - Name: $name, Age: $age, Country: $country, Category: $age_category" +log_message "=== User Info Script Completed ===" + +exit 0