Created
December 23, 2022 23:24
-
-
Save grischard/2cafeaa0073c45d74d4260c16b565f57 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -Eeuo pipefail | |
# This script fetches various Prometheus exporters from GitHub. | |
# It checks if the latest release has already been downloaded for each repository | |
# in the list. If there is a new release, it downloads it, and performs standard | |
# steps like compilation or copying, depending on the options specified. | |
# It depends on the exporters being stored in the following structure: | |
# | |
# $EXPORTER_DIR | |
# $exporter | |
# version.txt - latest version | |
# repo.txt - repository url, like https://github.com/prometheus/node_exporter/releases | |
# process_assets - shell script to process the assets, like turning | |
# node_exporter-1.5.0.linux-amd64.tar.gz into | |
# node_exporter-amd64 | |
# Set the destination directory for the exporters and the working directory | |
EXPORTER_DIR="/usr/local/prometheus/exporters" | |
WORKING_DIR="/root/prometheus/exporters" | |
# Check if the required dependencies are installed | |
for dependency in git curl go jq; do | |
if ! command -v "$dependency" >/dev/null; then | |
printf "Error: %s is required but not installed. Aborting.\n" "$dependency" | |
exit 1 | |
fi | |
done | |
# Check if the exporter directory exists and is writable | |
for dir in $EXPORTER_DIR $WORKING_DIR; do | |
if [[ ! -d "$dir" || ! -w "$dir" ]]; then | |
printf "Error: %s does not exist or is not writable.\n" "$dir" | |
exit 1 | |
fi | |
done | |
# Find the list of exporters and their repositories from the directory structure, and iterate over them | |
for exporter_repo in $EXPORTER_DIR/*/repo.txt; do | |
exporter="$(echo "$exporter_repo" | rev | cut -d / -f 2 | rev)" | |
repo=$(cat "$EXPORTER_DIR/$exporter/repo.txt") | |
# Check if the required metadata files exist for the exporter | |
for metafile in patterns.txt process_assets; do | |
if [[ ! -f "$metafile" ]]; then | |
echo "Error: $exporter/$metafile does not exist." | |
exit 1 | |
fi | |
done | |
# Check if the directory for the repository exists | |
if [[ -f "$EXPORTER_DIR/$exporter/version.txt" ]]; then | |
# The directory and version file exist, so check the version of the downloaded release | |
downloaded_version=$(cat "$EXPORTER_DIR/$exporter/version.txt") | |
else | |
# The directory or version file does not exist, so set the downloaded version to an empty string | |
downloaded_version="" | |
fi | |
# Get the latest version from GitHub | |
latest_release_api_response=$(curl -s https://api.github.com/repos/$repo/releases/latest) | |
if [[ $? -ne 0 ]]; then | |
# Curl encountered an error when fetching the latest release API response | |
echo "Error: Failed to fetch latest release for $exporter from GitHub." | |
exit 1 | |
fi | |
latest_version=$(echo "$latest_release_api_response" | jq -r '.tag_name' 2>/dev/null) | |
if [[ $? -ne 0 ]]; then | |
# Jq encountered an error when parsing the latest release API response | |
echo "Error: Failed to parse latest release for $exporter from GitHub." | |
exit 1 | |
fi | |
# Compare the versions | |
if [[ "$downloaded_version" != "$latest_version" ]]; then | |
# The downloaded version is older, so download the latest release | |
printf "Info: %s has updates available (current: %s, latest: %s).\n" "$exporter" "$downloaded_version" "$latest_version" | |
assets=$(echo "$latest_release_api_response" | jq -r '.assets[].name' 2>/dev/null) | |
if [[ $? -ne 0 ]]; then | |
# Jq encountered an error when parsing the list of assets from the latest release API response | |
echo "Error: Failed to parse list of assets for $exporter from GitHub at $repo." | |
exit 1 | |
fi | |
if [[ -z "$assets" ]]; then | |
# The list of assets is empty | |
echo "Error: No assets found for latest release of $exporter on GitHub at $repo." | |
exit 1 | |
fi | |
# Loop through the list of assets | |
for asset in $assets; do | |
# Loop through the list of patterns | |
matched=false | |
while IFS='' read -r pattern || [[ -n "$pattern" ]]; do | |
# Check if the asset's filename matches the pattern | |
if [[ $asset =~ $pattern ]]; then | |
# The asset's filename matches the pattern, so download it | |
matched=true | |
break | |
fi | |
done < "$EXPORTER_DIR/$exporter/patterns.txt" | |
if [[ "$matched" = true ]]; then | |
# The asset's filename matches a pattern in the list, so download it | |
# Get the URL of the asset | |
asset_url=$(echo "$latest_release_api_response" | jq -r ".assets[] | select(.name == \"$asset\") | .browser_download_url" 2>/dev/null) | |
if [[ $? -ne 0 ]]; then | |
# Jq encountered an error when parsing the URL of the asset from the latest release API response | |
echo "Error: Failed to parse URL for asset $asset for $exporter from GitHub." | |
exit 1 | |
fi | |
# Download the asset | |
mkdir -p $WORKING_DIR/$exporter | |
if [[ $? -ne 0 ]]; then | |
# Mkdir encountered an error when creating the working directory for the exporter | |
echo "Error: Failed to create working directory for $exporter." | |
exit 1 | |
fi | |
curl -L "$asset_url" -o "$WORKING_DIR/$exporter/$asset" | |
if [[ $? -ne 0 ]]; then | |
# Curl encountered an error when downloading the asset | |
echo "Error: Failed to download asset $asset for $exporter from GitHub." | |
exit 1 | |
fi | |
# Process the asset | |
"$EXPORTER_DIR/$exporter/process_assets" "$WORKING_DIR/$exporter/$asset" | |
if [[ $? -ne 0 ]]; then | |
# The process_assets script encountered an error | |
echo "Error: Failed to process asset $asset for $exporter." | |
exit 1 | |
fi | |
fi | |
done | |
# Update the version file | |
echo "$latest_version" > "$EXPORTER_DIR/$exporter/version.txt" | |
else | |
# The downloaded version is up to date | |
printf "Info: %s is up to date (current: %s, latest: %s).\n" "$exporter" "$downloaded_version" "$latest_version" | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment