diff --git a/README.md b/README.md index fc924b4..76bc5dc 100644 --- a/README.md +++ b/README.md @@ -11,3 +11,22 @@ AtlasOS is an appliance-style storage controller build by Adastra - Prometheus metrics > This repository contains the management plane and appliance tooling. + +## Quick Installation + +### Standard Installation (with internet) +```bash +sudo ./installer/install.sh +``` + +### Airgap Installation (offline) +```bash +# Step 1: Download bundle (on internet-connected system) +sudo ./installer/bundle-downloader.sh ./atlas-bundle + +# Step 2: Transfer bundle to airgap system +# Step 3: Install on airgap system +sudo ./installer/install.sh --offline-bundle /path/to/atlas-bundle +``` + +See `installer/README.md` and `docs/INSTALLATION.md` for detailed instructions. diff --git a/docs/AIRGAP_INSTALLATION.md b/docs/AIRGAP_INSTALLATION.md new file mode 100644 index 0000000..811b16c --- /dev/null +++ b/docs/AIRGAP_INSTALLATION.md @@ -0,0 +1,174 @@ +# Airgap Installation Guide for AtlasOS + +## Overview + +AtlasOS installer supports airgap (offline) installation for data centers without internet access. All required packages and dependencies are bundled into a single directory that can be transferred to the airgap system. + +## Quick Start + +### Step 1: Download Bundle (On System with Internet) + +On a system with internet access and Ubuntu 24.04: + +```bash +# Clone the repository +git clone +cd atlas + +# Run bundle downloader (requires root) +sudo ./installer/bundle-downloader.sh ./atlas-bundle +``` + +This will create a directory `./atlas-bundle` containing: +- All required .deb packages (~100-200 packages) +- All dependencies +- Go binary (fallback) +- Manifest and README files + +**Estimated bundle size:** 500MB - 1GB + +### Step 2: Transfer Bundle to Airgap System + +Transfer the entire bundle directory to your airgap system using: +- USB drive +- Internal network (if available) +- Physical media + +```bash +# Example: Copy to USB drive +cp -r ./atlas-bundle /media/usb/ + +# On airgap system: Copy from USB +cp -r /media/usb/atlas-bundle /tmp/ +``` + +### Step 3: Install on Airgap System + +On the airgap system (Ubuntu 24.04): + +```bash +# Navigate to bundle directory +cd /tmp/atlas-bundle + +# Run installer with offline bundle +cd /path/to/atlas +sudo ./installer/install.sh --offline-bundle /tmp/atlas-bundle +``` + +## Bundle Contents + +The bundle includes: + +### Main Packages +- **Build Tools**: build-essential, git, curl, wget +- **ZFS**: zfsutils-linux, zfs-zed, zfs-initramfs +- **Storage Services**: samba, samba-common-bin, nfs-kernel-server, rpcbind +- **iSCSI**: targetcli-fb +- **Database**: sqlite3, libsqlite3-dev +- **Go Compiler**: golang-go +- **Utilities**: openssl, net-tools, iproute2 + +### Dependencies +All transitive dependencies are automatically included. + +## Verification + +Before transferring, verify the bundle: + +```bash +# Count .deb files (should be 100-200) +find ./atlas-bundle -name "*.deb" | wc -l + +# Check manifest +cat ./atlas-bundle/MANIFEST.txt + +# Check total size +du -sh ./atlas-bundle +``` + +## Troubleshooting + +### Missing Dependencies + +If installation fails with dependency errors: + +1. Ensure all .deb files are present in bundle +2. Check that bundle was created on Ubuntu 24.04 +3. Verify system architecture matches (amd64/arm64) + +### Go Installation Issues + +If Go is not found after installation: + +1. Check if `golang-go` package is installed: `dpkg -l | grep golang-go` +2. If missing, the bundle includes `go.tar.gz` as fallback +3. Installer will automatically extract it if needed + +### Package Conflicts + +If you encounter package conflicts: + +```bash +# Fix broken packages +sudo apt-get install -f -y + +# Or manually install specific packages +sudo dpkg -i /path/to/bundle/*.deb +sudo apt-get install -f -y +``` + +## Bundle Maintenance + +### Updating Bundle + +To update the bundle with newer packages: + +1. Run `./installer/bundle-downloader.sh` again on internet-connected system +2. This will download latest versions +3. Transfer new bundle to airgap system + +### Bundle Size Optimization + +To reduce bundle size (optional): + +```bash +# Remove unnecessary packages (be careful!) +# Only remove if you're certain they're not needed +``` + +## Security Considerations + +- Verify bundle integrity before transferring +- Use secure transfer methods (encrypted USB, secure network) +- Keep bundle in secure location on airgap system +- Verify package signatures if possible + +## Advanced Usage + +### Custom Bundle Location + +```bash +# Download to custom location +sudo ./installer/bundle-downloader.sh /opt/atlas-bundles/ubuntu24.04 + +# Install from custom location +sudo ./installer/install.sh --offline-bundle /opt/atlas-bundles/ubuntu24.04 +``` + +### Partial Bundle (if some packages already installed) + +If some packages are already installed on airgap system: + +```bash +# Installer will skip already-installed packages +# Missing packages will be installed from bundle +sudo ./installer/install.sh --offline-bundle /path/to/bundle +``` + +## Support + +For issues with airgap installation: +1. Check installation logs +2. Verify bundle completeness +3. Ensure Ubuntu 24.04 compatibility +4. Review MANIFEST.txt for package list diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index 8ca1e59..289486f 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -35,7 +35,7 @@ The easiest way to install AtlasOS is using the provided installer script: cd /path/to/atlas # Run installer (requires root) -sudo ./install.sh +sudo ./installer/install.sh ``` The installer will: @@ -50,22 +50,22 @@ The installer will: ```bash # Custom installation directory -sudo ./install.sh --install-dir /opt/custom-atlas +sudo ./installer/install.sh --install-dir /opt/custom-atlas # Custom data directory -sudo ./install.sh --data-dir /mnt/atlas-data +sudo ./installer/install.sh --data-dir /mnt/atlas-data # Skip dependency installation (if already installed) -sudo ./install.sh --skip-deps +sudo ./installer/install.sh --skip-deps # Skip building binaries (use pre-built) -sudo ./install.sh --skip-build +sudo ./installer/install.sh --skip-build # Custom HTTP address -sudo ./install.sh --http-addr :8443 +sudo ./installer/install.sh --http-addr :8443 # Show help -sudo ./install.sh --help +sudo ./installer/install.sh --help ``` ## Manual Installation diff --git a/installer/README.md b/installer/README.md new file mode 100644 index 0000000..d3eab3d --- /dev/null +++ b/installer/README.md @@ -0,0 +1,51 @@ +# AtlasOS Installer + +This directory contains installation scripts for AtlasOS on Ubuntu 24.04. + +## Files + +- **`install.sh`** - Main installation script +- **`bundle-downloader.sh`** - Downloads all packages for airgap installation +- **`README.md`** - This file + +## Quick Start + +### Standard Installation (with internet) + +```bash +# From repository root +sudo ./installer/install.sh +``` + +### Airgap Installation (offline) + +**Step 1: Download bundle (on internet-connected system)** +```bash +sudo ./installer/bundle-downloader.sh ./atlas-bundle +``` + +**Step 2: Transfer bundle to airgap system** + +**Step 3: Install on airgap system** +```bash +sudo ./installer/install.sh --offline-bundle /path/to/atlas-bundle +``` + +## Options + +See help for all options: +```bash +sudo ./installer/install.sh --help +``` + +## Documentation + +- **Installation Guide**: `../docs/INSTALLATION.md` +- **Airgap Installation**: `../docs/AIRGAP_INSTALLATION.md` + +## Requirements + +- Ubuntu 24.04 (Noble Numbat) +- Root/sudo access +- Internet connection (for standard installation) +- Or offline bundle (for airgap installation) diff --git a/installer/bundle-downloader.sh b/installer/bundle-downloader.sh new file mode 100755 index 0000000..ec8e372 --- /dev/null +++ b/installer/bundle-downloader.sh @@ -0,0 +1,223 @@ +#!/bin/bash +# +# AtlasOS Bundle Downloader for Ubuntu 24.04 +# Downloads all required packages and dependencies for airgap installation +# +# Usage: sudo ./installer/bundle-downloader.sh [output-dir] +# or: sudo ./bundle-downloader.sh [output-dir] (if run from installer/ directory) +# +# This script must be run on a system with internet access and Ubuntu 24.04 +# The downloaded packages can then be transferred to airgap systems +# +# Example: +# sudo ./installer/bundle-downloader.sh ./atlas-bundle +# # Transfer ./atlas-bundle to airgap system +# # On airgap: sudo ./installer/install.sh --offline-bundle ./atlas-bundle +# + +set -e +set -o pipefail + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Default output directory +OUTPUT_DIR="${1:-./atlas-bundle-ubuntu24.04}" +OUTPUT_DIR=$(realpath "$OUTPUT_DIR") + +echo -e "${GREEN}========================================${NC}" +echo -e "${GREEN}AtlasOS Bundle Downloader${NC}" +echo -e "${GREEN}For Ubuntu 24.04 (Noble Numbat)${NC}" +echo -e "${GREEN}========================================${NC}" +echo "" + +# Check if running on Ubuntu 24.04 +if [[ ! -f /etc/os-release ]]; then + echo -e "${RED}Error: Cannot detect Linux distribution${NC}" + exit 1 +fi + +. /etc/os-release + +if [[ "$ID" != "ubuntu" ]] || [[ "$VERSION_ID" != "24.04" ]]; then + echo -e "${YELLOW}Warning: This script is designed for Ubuntu 24.04${NC}" + echo " Detected: $ID $VERSION_ID" + read -p "Continue anyway? (y/n) " -n 1 -r + echo "" + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit 1 + fi +fi + +# Check if running as root (needed for apt operations) +if [[ $EUID -ne 0 ]]; then + echo -e "${RED}Error: This script must be run as root (use sudo)${NC}" + exit 1 +fi + +# Create output directory +echo "Creating output directory: $OUTPUT_DIR" +mkdir -p "$OUTPUT_DIR" + +# Update package lists +echo "Updating package lists..." +apt-get update -qq + +# List of packages to download (all dependencies will be included) +PACKAGES=( + # Build essentials + "build-essential" + "git" + "curl" + "wget" + "ca-certificates" + "software-properties-common" + "apt-transport-https" + + # ZFS utilities + "zfsutils-linux" + "zfs-zed" + "zfs-initramfs" + + # Storage services + "samba" + "samba-common-bin" + "nfs-kernel-server" + "rpcbind" + + # iSCSI target + "targetcli-fb" + + # Database + "sqlite3" + "libsqlite3-dev" + + # Go compiler + "golang-go" + + # Additional utilities + "openssl" + "net-tools" + "iproute2" +) + +echo "" +echo -e "${GREEN}Downloading packages and all dependencies...${NC}" +echo "" + +# Download all packages with dependencies +cd "$OUTPUT_DIR" + +# Use apt-get download to get all packages including dependencies +for pkg in "${PACKAGES[@]}"; do + echo -n " Downloading $pkg... " + if apt-get download "$pkg" 2>/dev/null; then + echo -e "${GREEN}✓${NC}" + else + echo -e "${YELLOW}⚠ (may not be available)${NC}" + fi +done + +# Download all dependencies recursively +echo "" +echo "Downloading all dependencies..." +apt-get download $(apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances "${PACKAGES[@]}" | grep "^\w" | sort -u) 2>/dev/null || { + echo -e "${YELLOW}Warning: Some dependencies may have been skipped${NC}" +} + +# Download Go binary (if golang-go package is not sufficient) +echo "" +echo "Downloading Go binary (fallback)..." +GO_VERSION="1.22.0" +if ! wget -q "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" -O "$OUTPUT_DIR/go.tar.gz" 2>/dev/null; then + echo -e "${YELLOW}Warning: Could not download Go binary${NC}" + echo " You may need to download it manually from https://go.dev/dl/" +fi + +# Create manifest file +echo "" +echo "Creating manifest..." +cat > "$OUTPUT_DIR/MANIFEST.txt" < "$OUTPUT_DIR/README.md" <<'EOF' +# AtlasOS Offline Bundle for Ubuntu 24.04 + +This bundle contains all required packages and dependencies for installing AtlasOS on an airgap (offline) Ubuntu 24.04 system. + +## Contents + +- All required .deb packages with dependencies +- Go binary (fallback, if needed) +- Installation manifest + +## Usage + +1. Transfer this entire directory to your airgap system +2. On the airgap system, run: + ```bash + sudo ./installer/install.sh --offline-bundle /path/to/this/directory + ``` + +## Bundle Size + +The bundle typically contains: +- ~100-200 .deb packages (including dependencies) +- Total size: ~500MB - 1GB (depending on architecture) + +## Verification + +Before transferring, verify the bundle: +```bash +# Count .deb files +find . -name "*.deb" | wc -l + +# Check manifest +cat MANIFEST.txt +``` + +## Troubleshooting + +If installation fails: +1. Check that all .deb files are present +2. Verify you're on Ubuntu 24.04 +3. Check disk space (need at least 2GB free) +4. Review installation logs +EOF + +# Summary +echo "" +echo -e "${GREEN}========================================${NC}" +echo -e "${GREEN}Bundle Download Complete!${NC}" +echo -e "${GREEN}========================================${NC}" +echo "" +echo "Output directory: $OUTPUT_DIR" +echo "Total .deb files: $(find "$OUTPUT_DIR" -name "*.deb" | wc -l)" +echo "Total size: $(du -sh "$OUTPUT_DIR" | cut -f1)" +echo "" +echo "Manifest: $OUTPUT_DIR/MANIFEST.txt" +echo "README: $OUTPUT_DIR/README.md" +echo "" +echo -e "${YELLOW}Next Steps:${NC}" +echo "1. Transfer this directory to your airgap system" +echo "2. On airgap system, run:" +echo " sudo ./installer/install.sh --offline-bundle \"$OUTPUT_DIR\"" +echo "" diff --git a/install.sh b/installer/install.sh similarity index 86% rename from install.sh rename to installer/install.sh index 7093cb4..0cf8c9c 100755 --- a/install.sh +++ b/installer/install.sh @@ -3,9 +3,11 @@ # AtlasOS Installation Script for Ubuntu 24.04 # Installs AtlasOS storage controller with infrastructure gap consideration # -# Usage: sudo ./install.sh [options] +# Usage: sudo ./installer/install.sh [options] +# or: sudo ./install.sh [options] (if run from installer/ directory) # # Note: Run this script from the atlas repository root directory +# or ensure REPO_DIR points to the repository root # set -e @@ -30,6 +32,8 @@ BUILD_BINARIES=true SKIP_DEPS=false REPO_DIR="" FIREWALL_ACTIVE=false +OFFLINE_BUNDLE_DIR="" +OFFLINE_MODE=false # Parse command line arguments while [[ $# -gt 0 ]]; do @@ -58,8 +62,13 @@ while [[ $# -gt 0 ]]; do REPO_DIR="$2" shift 2 ;; + --offline-bundle) + OFFLINE_BUNDLE_DIR="$2" + OFFLINE_MODE=true + shift 2 + ;; -h|--help) - echo "AtlasOS Installation Script" + echo "AtlasOS Installation Script for Ubuntu 24.04" echo "" echo "Usage: sudo ./install.sh [options]" echo "" @@ -70,7 +79,16 @@ while [[ $# -gt 0 ]]; do echo " --skip-build Skip building binaries (use existing)" echo " --http-addr ADDR HTTP address (default: :8080)" echo " --repo-dir DIR Repository directory (if not in current dir)" + echo " --offline-bundle DIR Use offline bundle directory (for airgap installs)" + echo " Example: --offline-bundle ./atlas-bundle" echo " -h, --help Show this help message" + echo "" + echo "Airgap Installation:" + echo " 1. On internet-connected system: sudo ./installer/bundle-downloader.sh" + echo " 2. Transfer bundle to airgap system" + echo " 3. On airgap: sudo ./installer/install.sh --offline-bundle /path/to/bundle" + echo "" + echo "See docs/AIRGAP_INSTALLATION.md for detailed instructions" exit 0 ;; *) @@ -88,6 +106,12 @@ fi # Get script directory early (for path resolution) SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# If script is in installer/ subdirectory, get parent (repo root) +if [[ "$(basename "$SCRIPT_DIR")" == "installer" ]]; then + REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +else + REPO_ROOT="$SCRIPT_DIR" +fi # Detect distribution and validate Ubuntu 24.04 detect_distro() { @@ -269,8 +293,105 @@ fix_infrastructure_gaps() { echo "" } +# Install dependencies from offline bundle (airgap mode) +install_from_bundle() { + if [[ -z "$OFFLINE_BUNDLE_DIR" ]] || [[ ! -d "$OFFLINE_BUNDLE_DIR" ]]; then + echo -e "${RED}Error: Offline bundle directory not found: $OFFLINE_BUNDLE_DIR${NC}" + exit 1 + fi + + echo -e "${GREEN}Installing dependencies from offline bundle...${NC}" + echo " Bundle directory: $OFFLINE_BUNDLE_DIR" + + # Check if bundle directory contains .deb files + DEB_COUNT=$(find "$OFFLINE_BUNDLE_DIR" -name "*.deb" 2>/dev/null | wc -l) + if [[ $DEB_COUNT -eq 0 ]]; then + echo -e "${RED}Error: No .deb files found in bundle directory${NC}" + echo " Please ensure the bundle directory contains downloaded .deb packages" + exit 1 + fi + + echo " Found $DEB_COUNT .deb package(s)" + + # Install all .deb files from bundle directory + echo " Installing packages from bundle..." + cd "$OFFLINE_BUNDLE_DIR" + + # Install packages using dpkg, handling dependencies + # First pass: install all packages (may fail due to missing deps) + dpkg -i *.deb 2>/dev/null || true + + # Second pass: fix dependencies (if any packages are already installed, this will work) + apt-get install -f -y -qq --no-install-recommends || { + echo -e "${YELLOW}Warning: Some dependencies may need manual resolution${NC}" + } + + # Verify critical packages + echo " Verifying installations..." + MISSING_PACKAGES=() + + for pkg in zfsutils-linux samba nfs-kernel-server sqlite3 golang-go build-essential; do + if ! dpkg -l | grep -q "^ii.*$pkg"; then + MISSING_PACKAGES+=("$pkg") + fi + done + + if [[ ${#MISSING_PACKAGES[@]} -gt 0 ]]; then + echo -e "${YELLOW}Warning: Some packages may be missing: ${MISSING_PACKAGES[*]}${NC}" + echo " Attempting to install from bundle..." + + # Try to find and install missing packages + for pkg in "${MISSING_PACKAGES[@]}"; do + DEB_FILE=$(find "$OFFLINE_BUNDLE_DIR" -name "${pkg}*.deb" | head -1) + if [[ -n "$DEB_FILE" ]]; then + dpkg -i "$DEB_FILE" 2>/dev/null || true + fi + done + + # Fix dependencies again + apt-get install -f -y -qq --no-install-recommends || true + fi + + # Check for targetcli-fb or targetcli + if ! command -v targetcli &>/dev/null && ! command -v targetcli-fb &>/dev/null; then + TARGETCLI_DEB=$(find "$OFFLINE_BUNDLE_DIR" -name "*targetcli*.deb" | head -1) + if [[ -n "$TARGETCLI_DEB" ]]; then + dpkg -i "$TARGETCLI_DEB" 2>/dev/null || true + apt-get install -f -y -qq --no-install-recommends || true + fi + fi + + # Create symlink for targetcli if needed + if ! command -v targetcli &>/dev/null && command -v targetcli-fb &>/dev/null; then + ln -sf $(which targetcli-fb) /usr/local/bin/targetcli 2>/dev/null || true + fi + + # Verify Go installation (may need to install from bundle or binary) + if ! command -v go &>/dev/null; then + # Check if Go binary is in bundle + if [[ -f "$OFFLINE_BUNDLE_DIR/go.tar.gz" ]]; then + echo " Installing Go from bundle..." + rm -rf /usr/local/go + tar -C /usr/local -xzf "$OFFLINE_BUNDLE_DIR/go.tar.gz" + ln -sf /usr/local/go/bin/go /usr/local/bin/go + ln -sf /usr/local/go/bin/gofmt /usr/local/bin/gofmt + else + echo -e "${YELLOW}Warning: Go not found in bundle, checking for golang-go package...${NC}" + fi + fi + + echo -e "${GREEN}Offline bundle installation complete${NC}" + echo "" +} + # Install dependencies for Ubuntu 24.04 install_dependencies() { + # If offline mode, use bundle installation + if [[ "$OFFLINE_MODE" == "true" ]]; then + install_from_bundle + return + fi + echo -e "${GREEN}Installing dependencies for Ubuntu 24.04...${NC}" # Update package lists @@ -439,6 +560,9 @@ build_binaries() { # Try REPO_DIR first if [[ -n "$REPO_DIR" ]] && is_repo_root "$REPO_DIR"; then BUILD_DIR="$(cd "$REPO_DIR" && pwd)" + # Try REPO_ROOT (if script is in installer/ subdirectory) + elif [[ -n "$REPO_ROOT" ]] && is_repo_root "$REPO_ROOT"; then + BUILD_DIR="$REPO_ROOT" # Try current directory elif is_repo_root "."; then BUILD_DIR="$(pwd)" @@ -1103,6 +1227,10 @@ main() { # Step 4: Install dependencies if [[ "$SKIP_DEPS" == "false" ]]; then + if [[ "$OFFLINE_MODE" == "true" ]]; then + echo -e "${GREEN}Offline mode: Installing from bundle${NC}" + echo "" + fi install_dependencies else echo -e "${YELLOW}Skipping dependency installation${NC}"