#!/bin/bash set -e # Whitebox Installation Script # Usage: # curl -fsSL https://install.whitebox.aero | sudo bash # curl -fsSL https://install.whitebox.aero/?branch=feature/my-branch | sudo bash # # On first run, the script will create a .env file from .env.example # Edit the .env file with your configuration and re-run the script # Configuration WHITEBOX_REPO="https://gitlab.com/whitebox-aero/whitebox" BRANCH_FROM_URL="main" BRANCH="${WHITEBOX_BRANCH:-${BRANCH_FROM_URL:-main}}" INSTALL_DIR="/whitebox" ENV_FILE="$INSTALL_DIR/.env" HOSTNAME="whitebox" WHITEBOX_USER="whitebox" WHITEBOX_USER_PASSWORD="whitebox" AP_CONNECTION_NAME="whitebox-ap" AP_SSID="whitebox" AP_PASSWORD="whitebox" AP_INTERFACE="wlan0" AP_GATEWAY="10.42.0.1" # Other variables TEMP_DIR=$(mktemp -d) trap 'rm -rf "$TEMP_DIR"' EXIT # Non-interactive mode # Set NON_INTERACTIVE=1 to skip all prompts and use defaults NON_INTERACTIVE=${NON_INTERACTIVE:-0} # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Functions user_exists() { id "$1" &>/dev/null } # Ensure the script is run with sudo privileges if [ "$EUID" -ne 0 ]; then echo -e "${RED}This script requires sudo privileges. Please run as root.${NC}" exit 1 fi # Install minimal required packages to clone the repository echo -e "${BLUE}Installing git...${NC}" sudo apt update sudo apt install -y git git-lfs # Clone Whitebox repository if [ -d "$INSTALL_DIR" ]; then echo -e "${YELLOW}Whitebox directory already exists at $INSTALL_DIR. Pulling latest changes...${NC}" cd "$INSTALL_DIR" git pull origin "$BRANCH" else echo -e "${BLUE}Cloning Whitebox repository...${NC}" git clone --branch "$BRANCH" "$WHITEBOX_REPO" "$INSTALL_DIR" cd "$INSTALL_DIR" fi # Check if .env file exists (check this FIRST before doing any heavy installation) if [ ! -f "$ENV_FILE" ]; then echo -e "${YELLOW}.env file not found.${NC}" # Copy .env.example to .env cp "$INSTALL_DIR/.env.example" "$ENV_FILE" echo -e "${GREEN}Created .env file from .env.example${NC}" if [ "$NON_INTERACTIVE" -eq 1 ]; then # In non-interactive mode, use .env.example defaults directly echo -e "${BLUE}Non-interactive mode: Using .env.example defaults${NC}" echo -e "${GREEN}.env configured with default values from .env.example${NC}" else echo "" echo -e "${BLUE}========================================${NC}" echo -e "${YELLOW}ACTION REQUIRED:${NC}" echo -e "${BLUE}========================================${NC}" echo "" echo -e "A .env file has been created at: ${GREEN}$ENV_FILE${NC}" echo "" echo -e "Please:" echo -e " 1. Edit ${GREEN}$ENV_FILE${NC} and follow the instructions to configure the required variables" echo "" echo -e " 2. Re-run this installation script:" if [ "$BRANCH" != "main" ]; then echo -e " ${GREEN}curl -fsSL https://install.whitebox.aero/?branch=$BRANCH | sudo bash${NC}" else echo -e " ${GREEN}curl -fsSL https://install.whitebox.aero | sudo bash${NC}" fi echo "" echo -e "${BLUE}========================================${NC}" exit 0 fi fi echo -e "${GREEN}.env file found. Proceeding with installation...${NC}" # Now proceed with full system installation echo -e "${BLUE}Updating package lists and upgrading system...${NC}" sudo apt update && sudo apt full-upgrade -y # Install remaining required packages echo -e "${BLUE}Installing required packages...${NC}" sudo apt install -y jq make network-manager # Check if docker is already installed if command -v docker &>/dev/null; then echo -e "${YELLOW}Docker is already installed.${NC}" # Verify docker compose works (unless IGNORE_EXISTING_DOCKER is set) if [ -z "$IGNORE_EXISTING_DOCKER" ]; then if ! docker compose version &>/dev/null 2>&1; then echo -e "${RED}Docker is installed but 'docker compose' is not available.${NC}" echo -e "${YELLOW}This installer requires Docker with Compose plugin support (Docker 20.10.13+).${NC}" echo "" echo -e "${YELLOW}Options:${NC}" echo " 1. Uninstall Docker and run this script again" echo " 2. Update Docker manually: https://docs.docker.com/engine/install/" echo " 3. Continue at your own risk: IGNORE_EXISTING_DOCKER=1 bash <(curl -fsSL https://install.whitebox.aero)" exit 1 fi echo -e "${GREEN}Docker compose check passed.${NC}" else echo -e "${YELLOW}IGNORE_EXISTING_DOCKER is set. Skipping Docker version checks.${NC}" echo -e "${YELLOW}Warning: Whitebox may not work correctly with older Docker versions.${NC}" fi else # Install docker using official script echo -e "${BLUE}Docker not found. Installing Docker...${NC}" curl -fsSL https://get.docker.com -o "$TEMP_DIR/get-docker.sh" sh "$TEMP_DIR/get-docker.sh" rm "$TEMP_DIR/get-docker.sh" fi # Ensure docker service is running and enabled echo -e "${BLUE}Ensuring Docker service is running...${NC}" sudo systemctl start docker sudo systemctl enable docker # Configure Docker DNS to avoid issues with local DNS resolvers echo -e "${BLUE}Configuring Docker DNS settings...${NC}" if [ -f /etc/docker/daemon.json ]; then sudo jq '.dns=["9.9.9.9","149.112.112.112"]' /etc/docker/daemon.json | sudo tee /etc/docker/daemon.json.tmp > /dev/null sudo mv /etc/docker/daemon.json.tmp /etc/docker/daemon.json else echo '{"dns": ["9.9.9.9", "149.112.112.112"]}' | sudo tee /etc/docker/daemon.json > /dev/null fi # Restart docker to apply DNS changes sudo systemctl restart docker # Set hostname echo -e "${BLUE}Setting hostname to '$HOSTNAME'...${NC}" sudo hostnamectl set-hostname "$HOSTNAME" # Create whitebox user if it doesn't exist if ! user_exists "$WHITEBOX_USER"; then echo -e "${BLUE}Creating user '$WHITEBOX_USER'...${NC}" sudo useradd -m -s /bin/bash -G sudo "$WHITEBOX_USER" # Set default password and expire it to force change on first login echo -e "${BLUE}Setting default password for '$WHITEBOX_USER'...${NC}" echo "$WHITEBOX_USER:$WHITEBOX_USER_PASSWORD" | sudo chpasswd sudo chage -d 0 "$WHITEBOX_USER" echo -e "${YELLOW}Password set to '$WHITEBOX_USER_PASSWORD' - you will be required to change it on first login${NC}" else echo -e "${GREEN}User '$WHITEBOX_USER' already exists, skipping...${NC}" fi # Ensure user is in docker group echo -e "${BLUE}Adding user '$WHITEBOX_USER' to docker group...${NC}" sudo usermod -aG docker "$WHITEBOX_USER" # Ensure ubuntu user is in docker group echo -e "${BLUE}Adding user 'ubuntu' to docker group...${NC}" if user_exists "ubuntu"; then sudo usermod -aG docker "ubuntu" else echo -e "${YELLOW}User 'ubuntu' does not exist, skipping...${NC}" fi # Configure network interface naming (Orange Pi specific) echo -e "${BLUE}Configuring network interface naming...${NC}" make setup-network # Setup udev rules for SDR devices make setup-udev # Setup access point using NetworkManager echo -e "${BLUE}Setting up WiFi access point...${NC}" # Check if the connection already exists if nmcli connection show "$AP_CONNECTION_NAME" &>/dev/null; then echo -e "${YELLOW}Access point '$AP_CONNECTION_NAME' already exists. Deleting and recreating...${NC}" sudo nmcli connection delete "$AP_CONNECTION_NAME" fi # Create Wi-Fi access point using NetworkManager sudo nmcli connection add type wifi ifname "$AP_INTERFACE" con-name "$AP_CONNECTION_NAME" \ autoconnect yes \ ssid "$AP_SSID" \ wifi.mode ap \ wifi.band bg \ ipv4.method shared \ ipv4.addresses "$AP_GATEWAY/24" \ wifi-sec.key-mgmt wpa-psk \ wifi-sec.psk "$AP_PASSWORD" # Return to Whitebox directory cd "$INSTALL_DIR" # Deploy whitebox services echo -e "${BLUE}Deploying Whitebox services...${NC}" sudo -u "$WHITEBOX_USER" docker compose up -d --build # Clean up echo -e "${BLUE}Cleaning up...${NC}" rm -rf "$TEMP_DIR" # Add clear separator and spacing for visibility echo "" echo "" echo -e "${GREEN}========================================${NC}" echo -e "${GREEN} INSTALLATION COMPLETED SUCCESSFULLY ${NC}" echo -e "${GREEN}========================================${NC}" echo "" echo -e "${GREEN}You can now log in as user '$WHITEBOX_USER'.${NC}" echo -e "${GREEN}You can connect to the WiFi access point '${AP_SSID}' using the password '${AP_PASSWORD}'.${NC}" echo "" # Reboot prompt if [ "$NON_INTERACTIVE" -eq 1 ]; then echo -e "${GREEN}Setup complete!${NC}" echo -e "${BLUE}Non-interactive mode: Skipping reboot${NC}" echo -e "${YELLOW}Note: A reboot may be required to apply all changes in production.${NC}" else echo -e "${YELLOW}========================================${NC}" echo -e "${YELLOW} REBOOT REQUIRED ${NC}" echo -e "${YELLOW}========================================${NC}" echo "" echo -e "${YELLOW}A system reboot is required to complete the installation.${NC}" echo "" read -r -p "$(echo -e "${YELLOW}")Do you want to reboot now? (Y/n): $(echo -e "${NC}")" REBOOT_CHOICE