diff --git a/envs/deployed/docker-compose.yml b/envs/deployed/docker-compose.yml new file mode 100644 index 0000000..0153614 --- /dev/null +++ b/envs/deployed/docker-compose.yml @@ -0,0 +1,13 @@ +services: + hello-world: + image: alpine:latest + restart: unless-stopped + command: sh -c "while true; do echo 'hello world'; sleep 1; done" + env_file: + - .env + hello-world2: + image: alpine:latest + restart: unless-stopped + command: sh -c "while true; do echo 'hello world2'; sleep 1; done" + env_file: + - .env \ No newline at end of file diff --git a/installer/README.md b/installer/README.md new file mode 100644 index 0000000..5e8c6e1 --- /dev/null +++ b/installer/README.md @@ -0,0 +1,59 @@ +# Test Validator Installer + +This directory contains scripts to install and maintain a test validator node. + +## Quick Installation + +You can install the test validator with a single command: + +```bash +curl -s https://raw.githubusercontent.com/backend-developers-ltd/installer-test/refs/heads/deploy-config-prod/installer/install.sh | bash +``` + +This will: +1. Create a working directory at `~/test-validator/` (default) +2. Prompt you for configuration values if needed +3. Set up a cron job to automatically update your validator when changes are published +4. Download and start the validator services using Docker Compose + +## Custom Installation + +If you want to customize the installation, you can pass arguments to the script: + +```bash +curl -s https://raw.githubusercontent.com/backend-developers-ltd/installer-test/refs/heads/deploy-config-prod/installer/install.sh | bash -s -- [ENV_NAME] [WORKING_DIRECTORY] +``` + +Where: +- `ENV_NAME`: The environment to use (defaults to "prod") +- `WORKING_DIRECTORY`: The directory where the validator will be installed (defaults to "~/test-validator/") + +Example with custom working directory: + +```bash +curl -s https://raw.githubusercontent.com/backend-developers-ltd/installer-test/refs/heads/deploy-config-prod/installer/install.sh | bash -s -- prod /opt/test-validator +``` + +## Prerequisites + +- Docker and Docker Compose installed +- cron running +- curl installed +- bash shell +- Internet access to GitHub + +## What the Installer Does + +1. Creates a working directory +2. Sets up a .env file with your configuration +3. Downloads the latest docker-compose.yml file +4. Sets up a cron job to check for updates every 15 minutes +5. Starts the validator services + +## Manual Update + +If you want to manually update your validator, you can run: + +```bash +curl -s https://raw.githubusercontent.com/backend-developers-ltd/installer-test/refs/heads/deploy-config-prod/installer/update_compose.sh | bash -s -- [ENV_NAME] [WORKING_DIRECTORY] +``` diff --git a/installer/install.sh b/installer/install.sh new file mode 100755 index 0000000..3116660 --- /dev/null +++ b/installer/install.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash +# Script to install a cron job that fetches and runs the updater script + +set -euo pipefail + +# Default values for arguments +ENV_NAME="${1:-prod}" +WORKING_DIRECTORY="${2:-$HOME/test-validator/}" + +# Ensure the working directory exists +mkdir -p "${WORKING_DIRECTORY}" + +WORKING_DIRECTORY=$(realpath "${WORKING_DIRECTORY}") + +# Check if .env file exists in the working directory +ENV_FILE="${WORKING_DIRECTORY}/.env" +if [ ! -f "${ENV_FILE}" ]; then + echo "Creating .env file..." + + # Prompt for user inputs with default values + read -p "Enter BITTENSOR_NETUID [9999]: " BITTENSOR_NETUID "${ENV_FILE}" << EOL +BITTENSOR_NETUID=${BITTENSOR_NETUID} +BITTENSOR_NETWORK=${BITTENSOR_NETWORK} +HOST_WALLET_DIR=${HOST_WALLET_DIR} +BITTENSOR_WALLET_NAME=${BITTENSOR_WALLET_NAME} +BITTENSOR_WALLET_HOTKEY_NAME=${BITTENSOR_WALLET_HOTKEY_NAME} +POSTGRES_PASSWORD=123456789 +SECRET_KEY=${SECRET_KEY} +EOL + + echo ".env file created successfully." +fi + +# Hardcoded GitHub raw URL +GITHUB_URL="https://raw.githubusercontent.com/backend-developers-ltd/installer-test/refs/heads" + +# Run update_compose.sh once to ensure it works +echo "Running update_compose.sh once to ensure it works..." +curl -s "${GITHUB_URL}/deploy-config-${ENV_NAME}/installer/update_compose.sh" > /tmp/update_compose.sh +chmod +x /tmp/update_compose.sh +if ! /tmp/update_compose.sh "${ENV_NAME}" "${WORKING_DIRECTORY}"; then + echo "Error: update_compose.sh failed. Not adding cronline." + exit 1 +fi +echo "update_compose.sh ran successfully." + +# Create the cron job command with a unique identifier comment +# This will fetch the updater script from GitHub and run it with the provided arguments +CRON_CMD="*/15 * * * * cd ${WORKING_DIRECTORY} && curl -s ${GITHUB_URL}/deploy-config-${ENV_NAME}/installer/update_compose.sh > /tmp/update_compose.sh && chmod +x /tmp/update_compose.sh && /tmp/update_compose.sh ${ENV_NAME} ${WORKING_DIRECTORY} # TEST_VALIDATOR_UPDATE" + +# Install the cron job +(crontab -l 2>/dev/null || echo "") | grep -v "TEST_VALIDATOR_UPDATE" | { cat; echo "${CRON_CMD}"; } | crontab - + +echo "Cron job installed successfully. It will run every 15 minutes." +echo "Environment: ${ENV_NAME}" +echo "Working directory: ${WORKING_DIRECTORY}" diff --git a/installer/update_compose.sh b/installer/update_compose.sh new file mode 100755 index 0000000..3bee094 --- /dev/null +++ b/installer/update_compose.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +# Script to update docker-compose.yml and restart services if needed + +set -euo pipefail +set -x + +# Default values for arguments +ENV_NAME="${1:-prod}" +WORKING_DIRECTORY="${2:-$HOME/test-validator/}" + +mkdir -p "${WORKING_DIRECTORY}" + +# Ensure we're in the working directory +cd "${WORKING_DIRECTORY}" + +# Hardcoded GitHub raw URL +GITHUB_URL="https://raw.githubusercontent.com/backend-developers-ltd/installer-test/refs/heads" + +# Use a fixed temporary file for the remote docker-compose.yml +TEMP_FILE="/tmp/test_compose_update.yml" +curl -s "${GITHUB_URL}/deploy-config-${ENV_NAME}/envs/deployed/docker-compose.yml" > "${TEMP_FILE}" + +# Path to the local docker-compose.yml file +LOCAL_FILE="${WORKING_DIRECTORY}/docker-compose.yml" + +# Check if the local file exists +if [ ! -f "${LOCAL_FILE}" ]; then + echo "Local docker-compose.yml does not exist. Creating it." + cat "${TEMP_FILE}" > "${LOCAL_FILE}" + UPDATED=true +else + # Compare the files + if diff -q "${TEMP_FILE}" "${LOCAL_FILE}" > /dev/null; then + echo "No changes detected in docker-compose.yml" + UPDATED=false + else + echo "Changes detected in docker-compose.yml. Updating..." + cat "${TEMP_FILE}" > "${LOCAL_FILE}" + UPDATED=true + fi +fi + +# We're using a fixed temporary file, so we don't need to clean it up + +# If the file was updated, restart the services +if [ "${UPDATED}" = true ]; then + echo "Updating services..." + + # Check if docker compose or docker-compose should be used + if command -v docker &> /dev/null && docker compose version &> /dev/null; then + # Docker Compose V2 (docker compose) + docker compose up -d --remove-orphans + elif command -v docker-compose &> /dev/null; then + # Docker Compose V1 (docker-compose) + docker-compose up -d --remove-orphans + else + echo "Error: Neither docker compose nor docker-compose is available." + exit 1 + fi + + echo "Services updated successfully." +fi + +echo "Update process completed."