-
Notifications
You must be signed in to change notification settings - Fork 0
AiMLops Project 3.4 Bash Script analysis
This document analyzes the errors found in your deployment script and explains the key topics you should understand to fix and prevent similar issues.
set -eoa pipefailProblem: -eoa is invalid. Likely a typo for -eo pipefail.
Fix:
set -eo pipefailcp "$SCRIPT_DIR/config.env" $PLATFORM_CONFIG
source $PLATFORM_CONFIGProblem: $PLATFORM_CONFIG should be quoted.
Fix:
cp "$SCRIPT_DIR/config.env" "$PLATFORM_CONFIG"
source "$PLATFORM_CONFIG"read -p "Enter the number of your choice [1-6] (default is [1]): " choiceProblem: If run in a non-interactive environment, read will hang or fail silently.
Fix: Add timeouts or allow non-interactive execution:
read -t 60 -p "Enter the number of your choice [1-6] (default is [1]): " choice || trueecho -e "\nDEPLOYMENT_OPTION=$DEPLOYMENT_OPTION" >> $PLATFORM_CONFIGProblem: Repeated runs of the script will keep appending to .config, causing duplicate/conflicting keys.
Fix: Use sed to update or create keys cleanly:
grep -q '^DEPLOYMENT_OPTION=' "$PLATFORM_CONFIG" && \
sed -i "s|^DEPLOYMENT_OPTION=.*|DEPLOYMENT_OPTION=$DEPLOYMENT_OPTION|" "$PLATFORM_CONFIG" || \
echo "DEPLOYMENT_OPTION=$DEPLOYMENT_OPTION" >> "$PLATFORM_CONFIG"DISK_SPACE=$(df -k . | awk -F ' ' '{print $4}' | sed -n '2 p')Problem: This might break on systems with localized or differently formatted df.
Fix: More robust parsing:
DISK_SPACE=$(df -Pk . | awk 'NR==2 {print $4}')kind delete cluster --name $CLUSTER_NAMEProblem: Could destroy a production cluster by accident if variables are wrong.
Fix: Add confirmation and validation before deletion:
echo "About to delete cluster: $CLUSTER_NAME"
read -p "Are you sure you want to proceed? (y/N): " confirm
if [[ "$confirm" == [yY] ]]; then
kind delete cluster --name "$CLUSTER_NAME"
else
echo "Cluster deletion cancelled"
exit 1
fikubectl cluster-info --context kind-$CLUSTER_NAMEProblem: Might fail if the cluster was renamed or created with a different config.
Fix: Consider dynamically determining context:
kubectl config get-contexts -o name | grep "$CLUSTER_NAME" | xargs kubectl cluster-info --contextif [ "$INSTALL_TYPE" = "cloud" ]; thenProblem: INSTALL_TYPE is never set in the script, causing this condition to always fail.
Fix: Either define INSTALL_TYPE from config.env or remove the block.
tmp_file=$(mktemp)
# later rm "$tmp_file"Problem: rm is only called on success.
Fix: Use trap to clean up:
tmp_file=$(mktemp)
trap 'rm -f "$tmp_file"' EXIT- Why it matters: Unquoted variables can lead to word splitting, empty values causing unexpected behavior, or even command injection.
-
Best practices:
- Always quote variables in commands:
"$VAR"not$VAR - Use
${VAR:-default}for variables that might be unset - Consider using
set -uto catch unset variables
- Always quote variables in commands:
-
Options:
-
set -e: Exit immediately if a command fails -
set -o pipefail: Fail if any command in a pipe fails -
set -u: Treat unset variables as errors -
set -x: Print commands before execution (debugging)
-
-
Usage: Put
set -euo pipefailat the top of your scripts for safer execution
-
Understanding:
- How to properly handle stdin/stdout/stderr
- Using traps for cleanup
- Process substitution and subshells
-
Example:
# Redirect stderr to stdout command 2>&1 # Capture output while allowing it to display output=$(command | tee /dev/tty) # Ensure cleanup with trap trap 'rm -f "$TMP_FILE"' EXIT
-
Approaches:
- Use
grep/sedto update config files instead of appending - Consider using a proper key-value parser/editor
- Use namespaces in config files to avoid collisions
- Use
-
Example:
# Update or add a key update_config() { local key="$1" local value="$2" local file="$3" if grep -q "^$key=" "$file"; then sed -i "s|^$key=.*|$key=$value|" "$file" else echo "$key=$value" >> "$file" fi }
-
Principles:
- Always validate user input
- Provide timeouts for interactive prompts
- Have non-interactive fallbacks
-
Example:
# Safe input with validation, timeout, and default get_user_choice() { local prompt="$1" local default="$2" local response read -t 30 -p "$prompt" response || true response=${response:-$default} if [[ ! "$response" =~ ^[1-6]$ ]]; then echo "$default" else echo "$response" fi }
-
Strategies:
- Test commands for existence before using them
- Use POSIX-compatible alternatives when possible
- Document system requirements
-
Example:
# Check for command existence check_command() { command -v "$1" >/dev/null 2>&1 || { echo >&2 "Required command '$1' not found. Aborting."; exit 1; } } check_command kubectl
-
Key concepts:
- Context-aware operations
- Safe cluster deletion procedures
- Proper resource application order
-
Best practices:
- Always verify cluster name before deletion
- Use wait conditions for resources to be ready
- Implement proper retry logic with backoff