...
Code Block | ||
---|---|---|
| ||
#!/bin/bash # Written by Milton Suen (milton.suen@datacore.com) Oct 31, 2024 # Revision: Update to support running the script in a detachablepersistent session using screen or tmux.. # Define colors RED='\033[0;31m' BOLD_RED='\033[1;31m' GREEN='\033[0;32m' BOLD_GREEN='\033[1;32m' UNDERLINE_BOLD_GREEN='\033[4;32m' YELLOW='\033[0;33m' BOLD_YELLOW='\033[1;33m' BLUE='\033[0;34m' BOLD_BLUE='\033[1;34m' MAGENTA='\033[0;35m' BOLD_MAGENTA='\033[1;35m' CYAN='\033[0;36m' BOLD_CYAN='\033[1;36m' RESET='\033[0m' # Reset color to default # Function to display usage information usage() { echo "Usage: $0 -d swarm_ip -p admin:password -i new_log_level [-t duration_in_seconds] [-D|--detachpersistent] [-v]" echo " -d, --swarm_ip IP address of the Swarm API endpoint (or set SCSP_HOST environment variable)" echo " -p, --credentials Credentials in the format admin:password" echo " -i, --log.level New log level to set" echo " -t, --time Duration in seconds to keep the new log level (optional)" echo " -D, --detachpersistent Run the script in a detachabledetached session using screen or tmux" echo " -v, --verbose Enable verbose mode for debug messages" exit 1 } # Default options detachpersistent=false verbose=false output_log="script_output.log" # Log file for capturing detachablepersistent session output # Function to display debug messages if verbose mode is enabled debug() { if $verbose; then echo "[DEBUG] $1" fi } # Function to check if either 'screen' or 'tmux' is installed check_screen_or_tmux() { if ! command -v tmuxscreen &>/dev/null && ! command -v screentmux &>/dev/null; then echo "Error: Neither 'screen' nor 'tmux' is installed. Cannot run in detachablepersistent mode." detachpersistent=false # Disable detachablepersistent session fi } # Function to format file size format_size() { local size=$1 if (( size >= 1073741824 )); then echo "$(awk "BEGIN {printf \"%.1fGB\", $size/1073741824}")" elif (( size >= 1048576 )); then echo "$(awk "BEGIN {printf \"%.1fMB\", $size/1048576}")" elif (( size >= 1024 )); then echo "$(awk "BEGIN {printf \"%.1fKB\", $size/1024}")" else echo "${size}B" fi } # Function to format duration format_duration() { local duration=$1 local hours=$((duration / 3600)) local minutes=$(( (duration % 3600) / 60 )) local seconds=$((duration % 60)) printf "%02d:%02d:%02d" $hours $minutes $seconds } # Function to check if jq is available and set up JSON parsing method check_jq() { if [[ -x "/usr/local/bin/jq" ]]; then echo "/usr/local/bin/jq" elif [[ -x "$(pwd)/jq" ]]; then echo "$(pwd)/jq" elif command -v jq &>/dev/null; then echo "jq" else echo "grep" fi } jq_or_grep=$(check_jq) # Parse input arguments while [[ "$#" -gt 0 ]]; do case $1 in -d|--swarm_ip) swarm_ip="$2"; shift 2 ;; -p|--credentials) credentials="$2"; shift 2 ;; -i|--log.level) new_log_level="$2"; shift 2 ;; -t|--time) if [[ -n "$2" && "$2" != -* ]]; then duration="$2" shift 2 else read -p "Enter duration in seconds: " duration shift fi ;; -D|--detachpersistent) detachpersistent=true; shift ;; -v|--verbose) verbose=true; shift ;; *) usage ;; esac done # Check if 'screen' or 'tmux' is installed check_screen_or_tmux # If swarm_ip is not provided, try using SCSP_HOST environment variable if [[ -z "$swarm_ip" ]]; then if [[ -n "$SCSP_HOST" ]]; then swarm_ip="$SCSP_HOST" debug "Using Swarm IP from SCSP_HOST: $swarm_ip" else echo "Error: swarm_ip not provided and SCSP_HOST is not set." usage fi fi # Check if required arguments are provided if [[ -z "$credentials" || -z "$new_log_level" ]]; then usage fi # Retrieve cluster name and handle JSON parsing debug "Retrieving the cluster name from Swarm API." if [[ "$jq_or_grep" == "grep" ]]; then clusterName=$(curl --user "$credentials" -sS "http://$swarm_ip:91/api/storage/clusters" | grep -oP '"name":\s*"\K[^"]+') else clusterName=$(curl --user "$credentials" -sS "http://$swarm_ip:91/api/storage/clusters" | "$jq_or_grep" -r '._embedded.clusters[0].name') fi if [[ -z "$clusterName" ]]; then echo "Failed to retrieve the cluster name. Please check your inputs." exit 1 fi debug "Cluster Name: $clusterName" # Main logic function to run the script tasks main_script() { local swarm_ip="$1" local credentials="$2" local new_log_level="$3" local duration="$4" local clusterName="$5" local log_file="/var/log/datacore/castor.log" local initial_size=$(stat -c%s "$log_file" 2>/dev/null || echo 0) local current_log_level local jq_or_grep="$6" # Display initial information echo -e "Swarm IP: ${GREEN}$swarm_ipip${RESET}" echo -e "Credentials: ${GREEN}[hidden for security]${RESET}" echo -e "Cluster Name: $clusterName${GREEN}$clusterName${RESET}" debug "Starting main_script function..." # Retrieve current log level if [[ "$jq_or_grep" == "grep" ]]; then current_log_level=$(curl --user "$credentials" -sS "http://$swarm_ip:91/api/storage/clusters/$clusterName/settings/log.level" | grep -oP '"value":\s*\K[0-9]+') else current_log_level=$(curl --user "$credentials" -sS "http://$swarm_ip:91/api/storage/clusters/$clusterName/settings/log.level" | "$jq_or_grep" -r '.value') fi echo "" echo -e "New log level: : ${BOLD_GREEN}$new_log_levellevel${RESET}" echo -e "Current log level is ${GREEN}$current_log_level.${RESET}" # Skip update if new level matches the current level if [[ "$current_log_level" -eq "$new_log_level" ]]; then echo "" echo -e "Log level is already set to ${BOLD_GREEN}$new_log_levellevel${RESET}. No changes made." return fi # Update the log level using PUT echo -e "Updating log level to ${GREEN}$new_log_levellevel${RESET}..." response=$(curl --user "$credentials" -sS -X PUT -H "Content-Type: application/json" \ "http://$swarm_ip:91/api/storage/clusters/$clusterName/settings/log.level" \ -d "{\"value\": $new_log_level}") if [[ "$jq_or_grep" == "grep" ]]; then updated_log_level=$(echo "$response" | grep -oP '"value":\s*\K[0-9]+') else updated_log_level=$(echo "$response" | "$jq_or_grep" -r '.value') fi if [[ "$updated_log_level" -eq "$new_log_level" ]]; then echo -e "Log level changed successfully from ${GREEN}$current_log_levellevel${RESET} → ${BOLD_GREEN}$new_log_levellevel${RESET}." else echo -e "Failed to update log level. Response: $response: ${RED}$response${RESET}" exit 1 fi # Countdown and revert log level if [[ -n "$duration" && "$duration" -gt 0 ]]; then echo -e "Keeping log level at ${YELLOW}$new_log_levellevel${RESET} for $duration${YELLOW}$duration${RESET} second(s)..." echo -e "" for ((i=duration; i>0; i--)); do printf -v countdown "%02d:%02d:%02d" $((i/3600)) $(( (i%3600) / 60 )) $((i%60)) echo -ne "Countdown: $countdown${YELLOW}$countdown${RESET} remaining...\r" sleep 1 done echo -e "\n\nTime's up! Reverting log level back to ${GREEN}$current_log_levellevel${RESET}..." response=$(curl --user "$credentials" -sS -X PUT -H "Content-Type: application/json" \ "http://$swarm_ip:91/api/storage/clusters/$clusterName/settings/log.level" \ -d "{\"value\": $current_log_level}") if [[ "$jq_or_grep" == "grep" ]]; then reverted_log_level=$(echo "$response" | grep -oP '"value":\s*\K[0-9]+') else reverted_log_level=$(echo "$response" | "$jq_or_grep" -r '.value') fi final_size=$(stat -c%s "$log_file" 2>/dev/null || echo 0) size_diff=$(( final_size - initial_size )) size_diff_formatted=$(format_size "$size_diff") duration_formatted=$(format_duration "$duration") echo -e "Approximate ${BOLD_GREEN}$size_diff_formattedformatted${RESET} new logs were generated at log level ${BOLD_GREEN}$new_log_levellevel${RESET}. Current castor.log size is ${BOLD_GREEN}$(format_size "$final_size")${RESET} after $duration_formatted." if [[ "$reverted_log_level" -eq "$current_log_level" ]]; then echo -e "Log level reverted successfully back to $current_log_level." else echo "Failed to revert log level. Response: $response" exit 1${BOLD_GREEN}$current_log_level${RESET}." else fi else echo -e "Failed to revert echolog "Log level. change is permanent until manually modified.Response: ${RED}$response${RESET}" fi } # Run in detachable or directly ifexit $detach;1 then # Pass the main_script functionfi to the tmux session if available, otherwise use screen else if command -vecho tmux &>/dev/null; then "Log level change is permanent until manually modified." tmux new-session -d -s indexer_script "$(declare -f main_script format_size format_duration check_jq debug); main_script \"$swarm_ip\" \"$credentials\" \"$new_log_level\" \"$duration\" \"$clusterName\" \"$jq_or_grep\" | tee \"$output_log\"" tmux attach-session -t indexer_script eliffi } # Run in persistent or directly if $persistent; then # Pass the main_script function to the screen session and store the output in a file if command -v screen &>/dev/null; then screen -dmS indexer_script bash -c "$(declare -f main_script format_size format_duration check_jq debug); main_script \"$swarm_ip\" \"$credentials\" \"$new_log_level\" \"$duration\" \"$clusterName\" \"$jq_or_grep\" | tee \"$output_log\"" screen -r indexer_script else elif echo "Error: Neithercommand -v tmux nor screen available. Run without --detach."&>/dev/null; then tmux new-session -d -s exit 1 fi # Wait for the tmux or screen session to complete and then display the output log sleep 1 if command -v tmux &>/dev/null; then while tmux list-sessions | grep -q "indexer_script"; doindexer_script "$(declare -f main_script format_size format_duration check_jq debug); main_script \"$swarm_ip\" \"$credentials\" \"$new_log_level\" \"$duration\" \"$clusterName\" \"$jq_or_grep\" | tee \"$output_log\"" tmux attach-session -t indexer_script else echo "Error: Neither screen nor tmux available. Run without --persistent." exit 1 fi sleep 1 # Wait for the screen donesession to complete and then elifdisplay commandthe -voutput screen &>/dev/null; thenlog sleep 1 while screen -list | grep -q "indexer_script"; do sleep 1 done fi echo "" cat "$output_log" else main_script "$swarm_ip" "$credentials" "$new_log_level" "$duration" "$clusterName" "$jq_or_grep" | tee "$output_log" fi |
...