#!/usr/bin/env bash # Ignore SC2317 for the entire file # shellcheck disable=SC2317 # Copyright (c) Bacalhau Project Contributors. # SPDX-License-Identifier: Apache-2.0 (or your preferred license) # This script was initially inspired by: # https://raw.githubusercontent.com/SAME-Project/SAME-installer-website/main/install_script.sh # Original copyright: Microsoft Corporation and Dapr Contributors (MIT License) # But has since been substantially rewritten and expanded. #============================================================================= # CONFIGURATION VARIABLES #============================================================================= # BACALHAU CLI location : "${BACALHAU_INSTALL_DIR:="/usr/local/bin"}" # BACALHAU version to install (empty for latest) : "${BACALHAU_VERSION:=""}" # sudo is required to copy binary to BACALHAU_INSTALL_DIR for linux : "${USE_SUDO:="false"}" # Binary naming BACALHAU_CLI_FILENAME=bacalhau BACALHAU_CLI_FILE="${BACALHAU_INSTALL_DIR}/${BACALHAU_CLI_FILENAME}" # Analytics and verification BACALHAU_INSTALLATION_ID="" BACALHAU_INSTALL_SCRIPT_HASH="0f325698169ad4ad61ed7004a7561e0ccb2d8f8e" BACALHAU_HTTP_REQUEST_CLI="curl" # Default http request CLI # PostHog Configuration POSTHOG_ENDPOINT="https://installs.t.bacalhau.org/capture/" POSTHOG_EVENT_NAME="bacalhau.install_v1" # Disable telemetry if needed (default: enabled) : "${BACALHAU_DISABLEANALYTICS:="false"}" # Current time in seconds for tracking duration START_TIME=$(date +%s) # Bacalhau public key for verification BACALHAU_PUBLIC_KEY=$(cat <<-END -----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA7bXxrECk3tQfKox7MDaN OAQ+NATnILQ9XFfYHs+4Q04lK1tHpvUEwm9OwidMJKlr+M1f/9rzLYV6RDrv0FuA xaxGS6xrYwmLiXhDj4KwU3v5e6lHhzupsj+7LNSZ9g+ppCXcw73l5wtNmFojKQDH vpKDzB2KKqRq7/TRenNwvMD02zuDcjGdgXSeSiyIZ6jCn9Y6pX7nPF4rOxpFSL/w oSb5q5tVY3ZqyrNx/Bk9mBoX3a8xDqFtthuC6SjIF1t5arLih2yEpq8hOdGyyX1l uQCYlYuIwsYZL+fj2fFzhqpmrHBB97Npw1bTjnzQ8HQIsxkrMEg9ePFfcRfWw7w6 nWBLD4JOTFOoi9SPB0BdyqvE8B+6FTlT8XbK7/VtheR4yFVHvrnVkGzIm6AnwINc 9yFlS5FbxHh0vzL5G4jTYVZrZ7YaQ/zxgZ/SHE9fcSZv4l+W2vlo1EivtOgy1Ee6 OfDFMvdHyg04qjOGxUzYDxZ4/AL+ywSm1HDXP93Oi8icKXy5OANogW4XZ5hll54g 4EBqSON/HH4eIvyWTfFG+U6DBtD0Qn4gZO9y1KUNbhDQ0Z6LOC/mKgWhPSKRdFJk L9lmeqYFIvAnBx5rmyE7Hlzqk4pSRfggra0D2ydTV79tUQGlX5wpkwch/s4nRmZb rZd9rvTsifOjf2jxGGu5N6ECAwEAAQ== -----END PUBLIC KEY----- END ) #============================================================================= # HELPER FUNCTIONS #============================================================================= # Display usage information usage() { echo "Usage: $0 [VERSION] [options]" echo "or: $0 [options]" echo "" echo "Options:" echo " -v, --version VERSION Specify Bacalhau version to install (with or without 'v' prefix)" echo " -d, --dir DIRECTORY Specify installation directory" echo " -h, --help Show this help message" echo "" echo "If VERSION is provided as the first argument, it will be used as the version to install." } # Check if a command exists command_exists() { command -v "$1" > /dev/null 2>&1 } # Run a command with sudo if needed runAsRoot() { local cmd=( "$@" ) if [ "$EUID" -ne 0 ] && [ "$USE_SUDO" = "true" ]; then cmd=( sudo "${cmd[@]}" ) fi "${cmd[@]}" } # Setup temporary directory and cleanup handler setup_tmp() { BACALHAU_TMP_ROOT=$(mktemp -d 2>/dev/null || mktemp -d -t 'bacalhau-install.XXXXXXXXXX') cleanup_tmp() { code=$? set +e trap - EXIT rm -rf "${BACALHAU_TMP_ROOT}" exit $code } trap cleanup_tmp INT EXIT } # Cleanup temporary files cleanup() { if [[ -d "${BACALHAU_TMP_ROOT:-}" ]]; then rm -rf "$BACALHAU_TMP_ROOT" fi } # Handle failure trap fail_trap() { result=$? if [ "$result" != "0" ]; then echo "Failed to install BACALHAU CLI" echo "For support, go to https://github.com/bacalhau-project/bacalhau" fi # Add standardized failure info to telemetry add_telemetry_property "status" "failed" "string" # Don't override a more specific failure reason if already set if ! [[ "$TELEMETRY_PROPERTIES" =~ \"failure_reason\" ]]; then add_telemetry_property "failure_reason" "unknown_error" "string" fi # Send the single telemetry event before exiting send_telemetry cleanup exit "$result" } #============================================================================= # SYSTEM DETECTION FUNCTIONS #============================================================================= # Get system architecture and OS information getSystemInfo() { # Detect architecture ARCH=$(uname -m) case $ARCH in armv7*) ARCH="arm7" ;; armv6*) ARCH="arm6" ;; aarch64) ARCH="arm64" ;; x86_64) ARCH="amd64" ;; esac # Detect OS OS=$(eval "echo $(uname)|tr '[:upper:]' '[:lower:]'") # Set sudo requirements based on OS and install location if { [ "$OS" == "linux" ] || [ "$OS" == "darwin" ]; } && [ "$BACALHAU_INSTALL_DIR" == "/usr/local/bin" ]; then USE_SUDO="true" fi # Detect Linux distribution if possible if command_exists lsb_release; then DISTRO=$(lsb_release -si) else DISTRO="NOLSB" fi # Add system info to telemetry add_telemetry_property "os_type" "$OS" "string" add_telemetry_property "os_arch" "$ARCH" "string" add_telemetry_property "platform" "$DISTRO" "string" add_telemetry_property "use_sudo" "$USE_SUDO" "string" # Store system info for reference SYSTEM_INFO="operating_system=$OS,architecture=$ARCH,platform=$DISTRO" } # Verify that the system is supported verifySupported() { local supported=(linux-amd64 linux-arm64 linux-arm7 linux-arm6 darwin-amd64 darwin-arm64) local current_osarch="${OS}-${ARCH}" for osarch in "${supported[@]}"; do if [ "$osarch" == "$current_osarch" ]; then echo "Your system is ${OS}_${ARCH}. Your platform is $DISTRO." return fi done echo "No prebuilt binary for ${current_osarch} and platform ${DISTRO}." add_telemetry_property "failure_reason" "unsupported_system" "string" exit 1 } #============================================================================= # HTTP AND DOWNLOAD FUNCTIONS #============================================================================= # Check for HTTP request CLI availability checkHttpRequestCLI() { if command_exists "curl"; then BACALHAU_HTTP_REQUEST_CLI=curl elif command_exists "wget"; then BACALHAU_HTTP_REQUEST_CLI=wget else echo "Either curl or wget is required" exit 1 fi } # Make HTTP requests with retry logic httpRequest() { local url=$1 local max_retries=${2:-3} local retry_delay=${3:-1} local retry_timeout_seconds=${4:-60} local response local http_code if [ "$BACALHAU_HTTP_REQUEST_CLI" == "curl" ]; then # For curl, use a single temp file for the response body local tmp_body tmp_body=$(mktemp -p "$BACALHAU_TMP_ROOT" body.XXXXXXXXXX) # Make the request with curl # Write status code to variable and capture response to file http_code=$(curl \ --retry "$max_retries" \ --retry-delay "$retry_delay" \ --retry-max-time "$retry_timeout_seconds" \ --silent \ --write-out "%{http_code}" \ --output "$tmp_body" \ "$url") response=$(cat "$tmp_body") else # For wget, use separate files for headers and body local tmp_headers local tmp_body tmp_headers=$(mktemp -p "$BACALHAU_TMP_ROOT" headers.XXXXXXXXXX) tmp_body=$(mktemp -p "$BACALHAU_TMP_ROOT" body.XXXXXXXXXX) # Make the request with wget wget \ --tries="$max_retries" \ --wait="$retry_delay" \ --retry-connrefused \ --timeout="$retry_timeout_seconds" \ --server-response \ --quiet \ --output-document="$tmp_body" \ "$url" 2>"$tmp_headers" # Extract HTTP status code from headers http_code=$(awk '/^ HTTP/{print $2}' "$tmp_headers" | tail -n 1) # If no HTTP code was found, set a default failure code if [ -z "$http_code" ]; then http_code=500 fi # Get response content response=$(cat "$tmp_body") fi # Output HTTP code first, then response (to be captured by caller) echo "$http_code" echo "$response" } # Download files with retry logic httpDownload() { local url=$1 local output=$2 local max_retries=${3:-3} local retry_delay=${4:-1} local retry_timeout_seconds=${5:-60} local exit_code=0 if [ "$BACALHAU_HTTP_REQUEST_CLI" == "curl" ]; then curl \ --retry "$max_retries" \ --retry-delay "$retry_delay" \ --retry-max-time "$retry_timeout_seconds" \ --show-error \ --silent \ --location \ --no-buffer \ --output "$output" \ "$url" exit_code=$? else wget \ --tries="$max_retries" \ --wait="$retry_delay" \ --retry-connrefused \ --timeout="$retry_timeout_seconds" \ --quiet \ --output-document="$output" \ "$url" 2>/dev/null # Redirecting stderr to avoid server response output exit_code=$? fi return $exit_code } #============================================================================= # POSTHOG TELEMETRY FUNCTIONS #============================================================================= # Initialize empty telemetry properties TELEMETRY_PROPERTIES="" # Add property to the telemetry collection # This function collects all properties during the installation # but does not send any events until the end add_telemetry_property() { local property_name=$1 local property_value=$2 local property_type=$3 # "string" or "boolean" or "number" # Format property based on type local formatted_property case "$property_type" in "string") formatted_property="\"$property_name\":\"$property_value\"" ;; "boolean"|"number") formatted_property="\"$property_name\":$property_value" ;; *) formatted_property="\"$property_name\":\"$property_value\"" ;; esac # Add to global properties if [ -z "$TELEMETRY_PROPERTIES" ]; then TELEMETRY_PROPERTIES="$formatted_property" else TELEMETRY_PROPERTIES="$TELEMETRY_PROPERTIES,$formatted_property" fi } # Get a distinct ID for telemetry with multiple fallback mechanisms # Returns: ID and source as "id:source" # Get a distinct ID for telemetry with multiple fallback mechanisms # Returns: ID and source as "id:source" get_distinct_id() { local distinct_id="" local id_source="" # Helper function to return result consistently return_result() { local id=$1 local source=$2 echo "${id}:${source}" return 0 } # 1. Try passed installation ID from environment if [ -n "$BACALHAU_INSTALLATION_ID" ] && [[ "$BACALHAU_INSTALLATION_ID" != *REPLACE_ME* ]]; then return_result "$BACALHAU_INSTALLATION_ID" "installation_id_env" return 0 fi # 2. Try to read from installation ID file local config_dir if [[ "$OS" == "mingw"* || "$OS" == "msys"* || "$OS" == "cygwin"* ]]; then config_dir="$APPDATA/bacalhau" else config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/bacalhau" fi local id_file="$config_dir/installation_id" if [ -f "$id_file" ] && [ -r "$id_file" ]; then distinct_id=$(cat "$id_file" 2>/dev/null) if [ -n "$distinct_id" ]; then return_result "$distinct_id" "installation_id_file" return 0 fi fi # 3. Try to read from system metadata local bacalhau_metadata="$HOME/.bacalhau/system_metadata.yaml" if [ -f "$bacalhau_metadata" ] && [ -r "$bacalhau_metadata" ]; then # Try InstanceID first distinct_id=$(grep -E "^InstanceID:" "$bacalhau_metadata" 2>/dev/null | awk '{print $2}' | tr -d '[:space:]') if [ -n "$distinct_id" ]; then return_result "$distinct_id" "instance_id" return 0 fi fi # 4. Try to generate hash from machine-specific components local mac_addr="" hostname="" machine_id="" # Get MAC address if command_exists "ifconfig"; then mac_addr=$(ifconfig 2>/dev/null | grep -E "ether|HWaddr" | head -n 1 | awk '{print $2}' | tr -d ':.-') elif command_exists "ip"; then mac_addr=$(ip link 2>/dev/null | grep -E "link/ether" | head -n 1 | awk '{print $2}' | tr -d ':.-') elif [ -d "/sys/class/net" ]; then local primary_if=$(ls -1 /sys/class/net/ | grep -v "lo" | head -n 1) [ -n "$primary_if" ] && [ -f "/sys/class/net/$primary_if/address" ] && \ mac_addr=$(cat "/sys/class/net/$primary_if/address" | tr -d ':.-') fi # Get hostname hostname=$(hostname 2>/dev/null || echo "unknown") # Get machine-id if [ -f "/etc/machine-id" ] && [ -r "/etc/machine-id" ]; then machine_id=$(cat "/etc/machine-id" 2>/dev/null | tr -d '[:space:]') elif [ -f "/var/lib/dbus/machine-id" ] && [ -r "/var/lib/dbus/machine-id" ]; then machine_id=$(cat "/var/lib/dbus/machine-id" 2>/dev/null | tr -d '[:space:]') fi # Generate hash if we have any components if [ -n "$mac_addr" ] || [ -n "$machine_id" ] || [ -n "$hostname" ]; then local hash_base="${machine_id}${mac_addr}${hostname}" # Try to generate hash with available tools if command_exists "openssl"; then distinct_id=$(echo -n "$hash_base" | openssl sha256 2>/dev/null | awk '{print $2}') if [ -n "$distinct_id" ]; then return_result "$distinct_id" "machine_identifiers" return 0 fi elif command_exists "shasum"; then distinct_id=$(echo -n "$hash_base" | shasum -a 256 2>/dev/null | awk '{print $1}') if [ -n "$distinct_id" ]; then return_result "$distinct_id" "machine_identifiers" return 0 fi elif command_exists "sha256sum"; then distinct_id=$(echo -n "$hash_base" | sha256sum 2>/dev/null | awk '{print $1}') if [ -n "$distinct_id" ]; then return_result "$distinct_id" "machine_identifiers" return 0 fi fi fi # Ultimate fallback return_result "unknown" "unknown" } # Send a single telemetry event at the end send_telemetry() { # Skip if telemetry is disabled if [ "$BACALHAU_DISABLEANALYTICS" = "true" ]; then return 0 fi # Calculate elapsed time local elapsed_time_in_seconds=$(($(date +%s) - START_TIME)) # Get a distinct ID for telemetry and parse the result local result result=$(get_distinct_id) # Split the result into ID and source # The format is "id:source" local telemetry_id local id_source # Extract ID (everything before the colon) telemetry_id=$(echo "$result" | cut -d':' -f1) # Extract source (everything after the colon) id_source=$(echo "$result" | cut -d':' -f2) # Add standard properties add_telemetry_property "distinct_id" "$telemetry_id" "string" add_telemetry_property "id_source" "$id_source" "string" add_telemetry_property "script_git_hash" "$BACALHAU_INSTALL_SCRIPT_HASH" "string" add_telemetry_property "duration_seconds" "$elapsed_time_in_seconds" "number" # Create payload with all collected properties local payload="{\"event\":\"$POSTHOG_EVENT_NAME\",\"properties\":{$TELEMETRY_PROPERTIES}}" # Send telemetry asynchronously (don't block installation) if [ "$BACALHAU_HTTP_REQUEST_CLI" == "curl" ]; then curl -s -X POST "$POSTHOG_ENDPOINT" \ -H "Content-Type: application/json" \ -d "$payload" \ --max-time 5 \ >/dev/null 2>&1 & elif [ "$BACALHAU_HTTP_REQUEST_CLI" == "wget" ]; then # Create a temporary file for the payload local tmp_payload tmp_payload=$(mktemp -p "$BACALHAU_TMP_ROOT" payload.XXXXXXXXXX) echo "$payload" > "$tmp_payload" wget --quiet --post-file="$tmp_payload" \ --header="Content-Type: application/json" \ --timeout=5 \ "$POSTHOG_ENDPOINT" \ -O /dev/null 2>&1 & fi } # Store installation ID on user's system addInstallationID() { # Return early if BACALHAU_INSTALLATION_ID is empty or still has the placeholder value if [ -z "$BACALHAU_INSTALLATION_ID" ] || [[ "$BACALHAU_INSTALLATION_ID" == *REPLACE_ME* ]]; then return 0 # Best effort: if the id is invalid, return early fi # Determine the appropriate config directory based on the OS local id_file if [[ "$OS" == "mingw"* || "$OS" == "msys"* || "$OS" == "cygwin"* ]]; then # Use APPDATA on Windows id_file="$APPDATA/bacalhau/installation_id" else # Use XDG standard or default to ~/.config for Linux and Darwin local config_dir="${XDG_CONFIG_HOME:-$HOME/.config}" id_file="$config_dir/bacalhau/installation_id" fi # Create the directory if it doesn't exist local id_dir id_dir=$(dirname "$id_file") if ! mkdir -p "$id_dir"; then add_telemetry_property "installation_id_failure" "failed_to_create_dir" "string" return 0 # Best effort: if mkdir fails, return early fi # Write the installation ID to the file if ! echo "$BACALHAU_INSTALLATION_ID" > "$id_file"; then add_telemetry_property "installation_id_failure" "failed_to_write_file" "string" return 0 # Best effort: if write fails, return early fi # Set appropriate permissions (readable and writable by user only) if ! chmod 600 "$id_file" 2>/dev/null; then add_telemetry_property "installation_id_failure" "failed_to_set_permissions" "string" return 0 # Best effort: if chmod fails, return early fi return 0 } #============================================================================= # DOWNLOAD AND VERIFICATION FUNCTIONS #============================================================================= # Parse artifact information from API response parseArtifactInfo() { local artifactInfo=$1 local downloadUrl local signatureUrl local version # Extract URLs and version from the response downloadUrl=$(echo "$artifactInfo" | grep -o '"downloadUrl":"[^"]*"' | cut -d'"' -f4) signatureUrl=$(echo "$artifactInfo" | grep -o '"signatureUrl":"[^"]*"' | cut -d'"' -f4) version=$(echo "$artifactInfo" | grep -o '"version":"[^"]*"' | cut -d'"' -f4) if [ -z "$downloadUrl" ] || [ -z "$signatureUrl" ] || [ -z "$version" ]; then echo "Error: Failed to parse artifact information" add_telemetry_property "failure_reason" "artifact_parse_failed" "string" exit 1 fi # Return values as a space-separated string echo "$downloadUrl $signatureUrl $version" } # Get artifact information from Bacalhau API getArtifactInfo() { add_telemetry_property "version_requested" "$BACALHAU_VERSION" "string" # Normalize version string if [ -n "$BACALHAU_VERSION" ]; then case "$BACALHAU_VERSION" in latest) BACALHAU_VERSION="stable" ;; pre-release | pre | pre_release) BACALHAU_VERSION="pre" ;; esac else BACALHAU_VERSION="stable" fi # Get the artifact information from the resolve endpoint local resolveUrl="https://get.bacalhau.org/api/artifacts/resolve?os=${OS}&arch=${ARCH}&release=${BACALHAU_VERSION}" local response_output local http_code local response response_output=$(httpRequest "$resolveUrl") http_code=$(echo "$response_output" | head -n 1) response=$(echo "$response_output" | tail -n +2) if [ "$http_code" != "200" ]; then case "$http_code" in "404") echo "Error: Requested version $BACALHAU_VERSION does not exist. HTTP status code: $http_code" add_telemetry_property "failure_reason" "artifact_not_found" "string" ;; "400") echo "Error: Invalid version $BACALHAU_VERSION. HTTP status code: $http_code" add_telemetry_property "failure_reason" "artifact_invalid_version" "string" ;; *) echo "Error: Failed to fetch version information. HTTP status code: $http_code" add_telemetry_property "failure_reason" "artifact_fetch_failed" "string" ;; esac exit 1 fi if [ -z "$response" ]; then echo "Error: Received empty response from resolve endpoint" add_telemetry_property "failure_reason" "artifact_empty_response" "string" exit 1 fi ret_val=$response } # Download CLI and signature files downloadFile() { local version=$1 local downloadUrl=$2 local signatureUrl=$3 CLI_TMP_FILE="$BACALHAU_TMP_ROOT/bacalhau.tar.gz" SIG_TMP_FILE="$BACALHAU_TMP_ROOT/bacalhau.tar.gz.signature.sha256" echo "Downloading $downloadUrl ..." add_telemetry_property "version_download" "$version" "string" add_telemetry_property "download_url" "$downloadUrl" "string" httpDownload "$downloadUrl" "$CLI_TMP_FILE" if [ ! -f "$CLI_TMP_FILE" ]; then echo "Failed to download $downloadUrl ..." add_telemetry_property "failure_reason" "binary_download_failed" "string" exit 1 fi echo "Downloading sig file $signatureUrl ..." add_telemetry_property "signature_url" "$signatureUrl" "string" httpDownload "$signatureUrl" "$SIG_TMP_FILE" if [ ! -f "$SIG_TMP_FILE" ]; then echo "Failed to download $signatureUrl ..." add_telemetry_property "failure_reason" "signature_download_failed" "string" exit 1 fi } # Verify tarball signature verifyTarBall() { if ! command_exists openssl; then echo "WARNING: openssl could not be found. We are NOT verifying this tarball is correct!" add_telemetry_property "verification_status" "skipped" "string" return fi echo "$BACALHAU_PUBLIC_KEY" > "$BACALHAU_TMP_ROOT/BACALHAU_public_file.pem" openssl base64 -d -in "$SIG_TMP_FILE" -out "$SIG_TMP_FILE".decoded if openssl dgst -sha256 -verify "$BACALHAU_TMP_ROOT/BACALHAU_public_file.pem" -signature "$SIG_TMP_FILE".decoded "$CLI_TMP_FILE"; then add_telemetry_property "verification_status" "success" "string" return else echo "Failed to verify signature of tarball." add_telemetry_property "failure_reason" "verification_failed" "string" add_telemetry_property "verification_status" "failed" "string" exit 1 fi } # Extract the tarball expandTarBall() { echo "Extracting tarball ..." tar xzf "$CLI_TMP_FILE" -C "$BACALHAU_TMP_ROOT" } #============================================================================= # INSTALLATION FUNCTIONS #============================================================================= # Create installation directory if it doesn't exist createInstallDir() { if [ "$USE_SUDO" != "true" ] && [ ! -d "$BACALHAU_INSTALL_DIR" ]; then echo "Custom installation directory $BACALHAU_INSTALL_DIR does not exist. Creating it now..." if mkdir -p "$BACALHAU_INSTALL_DIR"; then echo "Successfully created directory $BACALHAU_INSTALL_DIR" else echo "Failed to create directory $BACALHAU_INSTALL_DIR" add_telemetry_property "failure_reason" "create_dir_failed" "string" exit 1 fi fi } # Check for existing Bacalhau installation checkExistingBacalhau() { if [ -f "$BACALHAU_CLI_FILE" ]; then client_version=$($BACALHAU_CLI_FILE version --client --no-style --output csv --hide-header | cut -d, -f1) echo -e "\nBACALHAU CLI is detected: $client_version" echo -e "Reinstalling BACALHAU CLI - ${BACALHAU_CLI_FILE}..." add_telemetry_property "existing_installation" "true" "boolean" add_telemetry_property "version_existing" "$client_version" "string" else echo -e "No BACALHAU detected. Installing fresh BACALHAU CLI..." add_telemetry_property "existing_installation" "false" "boolean" fi } # Install the Bacalhau binary installFile() { local tmp_root_bacalhau_cli="$BACALHAU_TMP_ROOT/$BACALHAU_CLI_FILENAME" if [ ! -f "$tmp_root_bacalhau_cli" ]; then echo "Failed to unpack BACALHAU CLI executable." add_telemetry_property "failure_reason" "unpacking_failed" "string" exit 1 fi # Set permissions and install chmod o+x "$tmp_root_bacalhau_cli" if [ -f "$BACALHAU_CLI_FILE" ]; then runAsRoot rm -f "$BACALHAU_CLI_FILE" fi if [ ! -d "$BACALHAU_INSTALL_DIR" ]; then runAsRoot mkdir -p "$BACALHAU_INSTALL_DIR" fi runAsRoot cp "$tmp_root_bacalhau_cli" "$BACALHAU_CLI_FILE" # Verify installation and check PATH if [ -f "$BACALHAU_CLI_FILE" ]; then echo "$BACALHAU_CLI_FILENAME installed into $BACALHAU_INSTALL_DIR successfully." $BACALHAU_CLI_FILE version --client --no-style add_telemetry_property "install_dir" "$BACALHAU_INSTALL_DIR" "string" else echo "Failed to install $BACALHAU_CLI_FILENAME" add_telemetry_property "failure_reason" "final_copy_failed" "string" exit 1 fi installed_path=$(which bacalhau 2>/dev/null) if [ -z "$installed_path" ]; then echo "WARNING: $BACALHAU_CLI_FILE is not on your PATH: $PATH" 1>&2 add_telemetry_property "path_status" "not_on_path" "string" elif [ "$installed_path" != "$BACALHAU_CLI_FILE" ]; then echo "WARNING: The Bacalhau CLI found on your PATH ($installed_path) is different from the one we just installed ($BACALHAU_CLI_FILE)." 1>&2 echo "You may want to update your PATH or remove old installations." 1>&2 add_telemetry_property "path_status" "path_conflict" "string" else add_telemetry_property "path_status" "correct" "string" fi } #============================================================================= # MAIN SCRIPT #============================================================================= # Parse command line arguments # Check if the first argument is a version (doesn't start with a dash) if [[ $1 && $1 != -* ]]; then BACALHAU_VERSION="$1" shift fi # Parse command line arguments while [[ $# -gt 0 ]]; do key="$1" case $key in -v|--version) BACALHAU_VERSION="$2" shift 2 ;; -d|--dir) BACALHAU_INSTALL_DIR="$2" BACALHAU_CLI_FILE="${BACALHAU_INSTALL_DIR}/${BACALHAU_CLI_FILENAME}" shift 2 ;; -h|--help) usage exit 0 ;; *) echo "Unknown option: $1" usage exit 1 ;; esac done # Setup error trap trap "fail_trap" EXIT # Display welcome banner cat << EOF ...... :^^^^: ^!!!!^ .?PPP5! .~!!!~: ~555PJ: ^!!!!^ .::::.:~~~~^. :~!!!~. .~!!!~: ____ _____ _ _ _ _ _ ^7!!!~ ^!!!!^ ^!!!!^ | _ \ /\ / ____| /\ | | | | | | /\ | | | | .7PPPP?. .~!!!~: .^~~. .~!!!~: | |_) | / \ | | / \ | | | |__| | / \ | | | | :YPPP5^^!!!!^ ~7777~ .YPPP5. ^!!!!^ | _ < / /\ \| | / /\ \ | | | __ | / /\ \| | | | !5PPPJ::!!!!~. .?PPPP7. 7555?. .~!!!!: | |_) / ____ \ |____ / ____ \| |____| | | |/ ____ \ |__| | :JPPP5! .^!!!!: .?YJJJ^ ... :!!!!~. |____/_/ \_\_____/_/ \_\______|_| |_/_/ \_\____/ :^^^^: :!!!!~. .~!!!!: .~!!!!: :!!!!~. :^^^^: :^^^^: Distributed Compute over Data Bacalhau Repository https://link.cod.dev/bacalhau-repo Please file an issue if you encounter any problems! https://link.cod.dev/bacalhau-new-issue =============================================================================== EOF # Execute installation steps getSystemInfo verifySupported checkExistingBacalhau checkHttpRequestCLI createInstallDir getArtifactInfo if [ -z "$ret_val" ]; then echo 1>&2 "Error getting artifact information... Please file a bug here: https://github.com/bacalhau-project/bacalhau/issues/new" exit 1 fi # Parse artifact information and extract values read -r downloadUrl signatureUrl version <<< "$(parseArtifactInfo "$ret_val")" echo "Installing Bacalhau $version in $BACALHAU_INSTALL_DIR..." # Download and install setup_tmp addInstallationID downloadFile "$version" "$downloadUrl" "$signatureUrl" verifyTarBall expandTarBall installFile # Send the final telemetry event add_telemetry_property "status" "success" "string" send_telemetry # Display thank you message cat << EOF _______ _ _ _ _ _ __ __ ______ _ _ |__ __| | | | /\ | \ | | |/ / \ \ / / __ \| | | | | | | |__| | / \ | \| | / \ \_/ / | | | | | | | | | __ | / /\ \ | | < \ /| | | | | | | | | | | | |/ ____ \| |\ | \ | | | |__| | |__| | |_| |_| |_/_/ \_\_| \_|_|\_\ |_| \____/ \____/ Thanks for installing Bacalhau! We're hoping to unlock an new world of more efficient computation and data, and would really love to hear from you on how we can improve. - ⭐️ Give us a star on GitHub (https://link.cod.dev/bacalhau-repo) - 🧑‍💻 Request a feature! (https://link.cod.dev/bacalhau-new-issue) - 🐛 File a bug! (https://link.cod.dev/bacalhau-file-bug) - ❓ Join our Slack! (https://link.cod.dev/bacalhau-slack) - 📰 Subscribe to our blog! (https://link.cod.dev/bacalhau-blog) - ✉️ Join our mailing list! (https://link.cod.dev/bacalhau-discuss) Thanks again! ~ Team Bacalhau EOF cleanup