Skip to content

Commit

Permalink
more wip
Browse files Browse the repository at this point in the history
  • Loading branch information
morga471 committed May 13, 2025
1 parent 692671c commit e992d71
Show file tree
Hide file tree
Showing 7 changed files with 679 additions and 40 deletions.
6 changes: 0 additions & 6 deletions .github/platform-tg-infra.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,6 @@
},
{
"path": "../../243219719746-lab-gov-management-nonprod"
},
{
"path": "../../../terraform-modules/aws-s3"
},
{
"path": "../../karpenter-provider-aws"
}
]
}
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ deploy-to-pipeline:
exit 1; \
fi

@echo "Copy buildspecs from tfmod-pipeline"
cp -r ../tfmod-pipeline/buildspecs/* ./buildspecs

@echo "Creating zip file..."
zip -r platform-tg-infra.zip . -x "*.git*" "*.github*" "*.terragrunt-cache*" "*.terraform*"

Expand All @@ -82,7 +85,7 @@ deploy-to-pipeline:
$(eval OBJECT_KEY=clusters/$(CLUSTER_NAME)/platform-tg-infra.zip)

@echo "Uploading to S3 bucket $(S3_BUCKET)..."
aws s3 cp platform-tg-infra.zip s3://$(S3_BUCKET)/$(OBJECT_KEY) --profile $(AWS_PROFILE)
aws s3 cp platform-tg-infra.zip s3://$(S3_BUCKET)/$(OBJECT_KEY) --profile $(AWS_PROFILE) --sse aws:kms
@echo "Upload complete. Pipeline should trigger automatically."

@echo "Calculating pipeline URL..."
Expand Down
220 changes: 220 additions & 0 deletions buildspecs/scripts/manage_tools.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
#!/bin/bash
set -e # Exit immediately if a command exits with a non-zero status.

echo "--- Starting Tool Management Script (manage_tools.sh) ---"

# --- Configuration & Environment Variables ---
# Required environment variables:
# - TOOL_DEFINITIONS: JSON string defining tools (name, s3_key, checksum, archive_format, executable_path_in_archive)
# - ARTIFACTS_BUCKET: S3 bucket name for downloading tool archives
# - REQUIRED_TOOLS: Space-separated list of tool names to install (e.g., "terraform terragrunt")
# - CODEBUILD_SRC_DIR: Base directory for caching (CodeBuild specific, but adaptable)

TOOL_CACHE_DIR="${CODEBUILD_SRC_DIR}/.tool_cache"
INSTALL_DIR="/usr/local/bin" # Standard installation directory for executables

# --- Sanity Checks ---
if [ -z "$TOOL_DEFINITIONS" ]; then
echo "ERROR: TOOL_DEFINITIONS environment variable is not set or is empty." >&2
exit 1
fi

if ! echo "$TOOL_DEFINITIONS" | jq empty > /dev/null 2>&1; then
echo "ERROR: TOOL_DEFINITIONS does not contain valid JSON." >&2
echo "TOOL_DEFINITIONS content: $TOOL_DEFINITIONS" >&2
exit 1
fi

if [ -z "$ARTIFACTS_BUCKET" ]; then
echo "ERROR: ARTIFACTS_BUCKET environment variable is not set or is empty." >&2
exit 1
fi

if [ -z "$REQUIRED_TOOLS" ]; then
echo "WARNING: REQUIRED_TOOLS environment variable is not set or is empty. No tools will be installed by this script." >&2
# exit 0 # or exit 1 depending on desired strictness
fi

if [ -z "$CODEBUILD_SRC_DIR" ]; then
echo "ERROR: CODEBUILD_SRC_DIR environment variable is not set or is empty." >&2
exit 1
fi

# --- Ensure jq is available ---
if ! command -v jq &> /dev/null; then
echo "jq not found, attempting to install..."
if apt-get update -y && apt-get install -y jq; then
echo "jq installed successfully via apt-get."
elif yum install -y jq; then
echo "jq installed successfully via yum."
else
echo "ERROR: Failed to install jq. Please ensure jq is available in the CodeBuild image or install it manually." >&2
exit 1
fi
fi
echo "jq is available."

# --- Create necessary directories ---
mkdir -p "$TOOL_CACHE_DIR"
mkdir -p "$INSTALL_DIR"
export PATH="$INSTALL_DIR:$PATH" # Add install dir to PATH for this script's session

echo "Tool Cache Directory: $TOOL_CACHE_DIR"
echo "Installation Directory: $INSTALL_DIR"
echo "Updated PATH: $PATH"
echo "Required tools to process: $REQUIRED_TOOLS"
echo "TOOL_DEFINITIONS (first 200 chars): $(echo "$TOOL_DEFINITIONS" | cut -c 1-200)..."

# --- Tool Installation Loop ---
for tool_name_var in $REQUIRED_TOOLS; do
# Use a subshell for per-tool variables to avoid conflicts and ensure clean state
(
tool_name="$tool_name_var"
echo "--------------------------------------------------"
echo "Processing tool: $tool_name"

tool_info=$(echo "$TOOL_DEFINITIONS" | jq -r --arg tn "$tool_name" '.[$tn]')

if [ -z "$tool_info" ] || [ "$tool_info" == "null" ] || [ "$tool_info" == "{}" ] ; then
echo "ERROR: Tool '$tool_name' not found or has null/empty definition in TOOL_DEFINITIONS." >&2
exit 1 # Exit subshell, which will cause the main script to exit due to \`set -e\` if subshell fails
fi

# Extract tool details
# version=$(echo "$tool_info" | jq -r '.version // empty') # Version not strictly needed by script but good for logging
s3_key=$(echo "$tool_info" | jq -r '.s3_key // empty')
expected_checksum=$(echo "$tool_info" | jq -r '.checksum // empty') # SHA256
archive_format=$(echo "$tool_info" | jq -r '.archive_format // empty')
# executable_path_in_archive is the path *inside* the archive to the executable file itself.
# If archive_format is 'binary', this is ignored.
# If archive_format is 'zip' or 'tar.gz' and this is empty/null, script defaults to tool_name.
executable_path_in_archive=$(echo "$tool_info" | jq -r '.executable_path_in_archive // empty')

# Validate extracted details
if [ -z "$s3_key" ] || [ -z "$expected_checksum" ] || [ -z "$archive_format" ]; then
echo "ERROR: Missing one or more critical fields (s3_key, checksum, archive_format) for tool '$tool_name'." >&2
echo "Tool Info Found: $tool_info" >&2
exit 1
fi

# Determine the actual executable name within the archive if not specified
effective_executable_path_in_archive="$executable_path_in_archive"
if [[ "$archive_format" == "zip" || "$archive_format" == "tar.gz" ]] && \
[[ -z "$executable_path_in_archive" || "$executable_path_in_archive" == "null" ]]; then
effective_executable_path_in_archive="$tool_name"
fi

archive_filename=$(basename "$s3_key")
cached_archive_path="$TOOL_CACHE_DIR/$archive_filename"
s3_source_path="s3://${ARTIFACTS_BUCKET}/${s3_key}"
target_executable_path="$INSTALL_DIR/$tool_name" # Final destination of the executable

echo "Details for $tool_name:"
# echo " Version: $version"
echo " S3 Key: $s3_key"
echo " Expected SHA256: $expected_checksum"
echo " Archive Format: $archive_format"
echo " Executable path in archive (effective): $effective_executable_path_in_archive"
echo " Archive filename: $archive_filename"
echo " Cached archive path: $cached_archive_path"
echo " Target executable path: $target_executable_path"

# --- Cache Check & Download ---
needs_download=true
if [ -f "$cached_archive_path" ]; then
echo "Cached archive $cached_archive_path found. Verifying checksum..."
actual_checksum=$(sha256sum "$cached_archive_path" | awk '{print $1}')
if [ "$actual_checksum" == "$expected_checksum" ]; then
echo "Checksum for cached $archive_filename is VALID."
needs_download=false
else
echo "Checksum MISMATCH for cached $archive_filename. Expected: $expected_checksum, Got: $actual_checksum. Re-downloading."
rm -f "$cached_archive_path"
fi
else
echo "Archive $archive_filename not found in cache: $cached_archive_path. Downloading."
fi

if [ "$needs_download" == true ]; then
echo "Downloading $tool_name from $s3_source_path to $cached_archive_path..."
if ! aws s3 cp "$s3_source_path" "$cached_archive_path"; then
echo "ERROR: Failed to download $tool_name from S3." >&2
exit 1
fi
echo "Download complete. Verifying checksum of downloaded file..."
actual_checksum=$(sha256sum "$cached_archive_path" | awk '{print $1}')
if [ "$actual_checksum" != "$expected_checksum" ]; then
echo "ERROR: Checksum MISMATCH for downloaded $archive_filename. Expected: $expected_checksum, Got: $actual_checksum." >&2
rm -f "$cached_archive_path"
exit 1
fi
echo "Checksum for downloaded $archive_filename is VALID."
fi

# --- Extraction & Installation ---
echo "Installing $tool_name from $cached_archive_path to $target_executable_path..."
# Ensure target is clean for binary moves/copies
rm -f "$target_executable_path"
# Create a temporary directory for extraction to keep $TOOL_CACHE_DIR clean from extracted files
temp_extract_dir=$(mktemp -d -p "$TOOL_CACHE_DIR" "tmp_extract_${tool_name}_XXXXXX")

extracted_executable_source_path="" # Path to the executable *after* extraction

if [ "$archive_format" == "zip" ]; then
unzip -o "$cached_archive_path" -d "$temp_extract_dir" > /dev/null
extracted_executable_source_path="$temp_extract_dir/$effective_executable_path_in_archive"
elif [ "$archive_format" == "tar.gz" ]; then
# tar -xzf "$cached_archive_path" -C "$temp_extract_dir" "$effective_executable_path_in_archive" # This only extracts the specific file
tar -xzf "$cached_archive_path" -C "$temp_extract_dir" > /dev/null # Extract all
extracted_executable_source_path="$temp_extract_dir/$effective_executable_path_in_archive"
elif [ "$archive_format" == "binary" ]; then
# For binary, the "archive" is the executable itself. Copy it to the temp dir first for consistency.
cp "$cached_archive_path" "$temp_extract_dir/$tool_name"
extracted_executable_source_path="$temp_extract_dir/$tool_name"
else
echo "ERROR: Unknown archive format '$archive_format' for $tool_name." >&2
rm -rf "$temp_extract_dir"
exit 1
fi

if [ ! -f "$extracted_executable_source_path" ]; then
echo "ERROR: Executable for $tool_name not found at '$extracted_executable_source_path' after extraction." >&2
echo "Contents of $temp_extract_dir:" >&2
ls -lR "$temp_extract_dir" >&2
rm -rf "$temp_extract_dir"
exit 1
fi

echo "Moving '$extracted_executable_source_path' to '$target_executable_path'"
mv "$extracted_executable_source_path" "$target_executable_path"
chmod +x "$target_executable_path"

# Clean up temporary extraction directory
rm -rf "$temp_extract_dir"

echo "$tool_name installed successfully to $target_executable_path."

# --- Verification (Optional but Recommended) ---
echo "Verifying $tool_name installation..."
if command -v $tool_name &> /dev/null; then
echo "Attempting to get version for $tool_name..."
# Try common version flags, redirect stderr to stdout for capture, take first line
if $tool_name --version &> /dev/null; then
echo "$($tool_name --version 2>&1 | head -n 1)"
elif $tool_name version &> /dev/null; then
echo "$($tool_name version 2>&1 | head -n 1)"
elif $tool_name -version &> /dev/null; then # e.g. Java
echo "$($tool_name -version 2>&1 | head -n 1)"
elif $tool_name -v &> /dev/null; then # e.g. Go
echo "$($tool_name -v 2>&1 | head -n 1)"
else
echo "$tool_name is callable, but version command is unknown or failed. Assuming successful installation."
fi
else
echo "ERROR: $tool_name command not found in PATH after installation attempt to $target_executable_path." >&2
exit 1
fi
) || exit 1 # If subshell fails, exit the main script
done

echo "--- Tool Management Script (manage_tools.sh) Finished Successfully ---"
Loading

0 comments on commit e992d71

Please sign in to comment.