# Embedded dependencies.json APT_LAYER_DEPENDENCIES_JSON=$(cat << 'EOF' { "core": [ "chroot", "apt-get", "dpkg", "jq", "mount", "umount", "findmnt", "numfmt" ], "container": [ "podman", "docker" ], "oci": [ "skopeo" ], "composefs": [ "mkcomposefs", "composefs-info", "mount.composefs", "mksquashfs", "unsquashfs" ], "composefs_packages": [ "composefs", "libcomposefs1" ], "bootloader": [ "efibootmgr", "grub-install", "update-grub", "bootctl" ], "security": [ "curl", "wget", "gpg" ], "package_install_commands": { "debian": { "composefs": "apt install -y composefs libcomposefs1", "container": "apt install -y podman docker.io", "oci": "apt install -y skopeo", "bootloader": "apt install -y efibootmgr grub-common systemd-boot", "core": "apt install -y squashfs-tools jq coreutils util-linux" }, "fedora": { "composefs": "dnf install -y composefs composefs-libs", "container": "dnf install -y podman docker", "oci": "dnf install -y skopeo", "bootloader": "dnf install -y efibootmgr grub2-tools systemd-boot", "core": "dnf install -y squashfs-tools jq coreutils util-linux" } } } EOF ) #!/bin/bash # apt-layer Installation Script # This script installs the apt-layer tool, its dependencies, creates necessary directories and files, # and sets up the system to use apt-layer. If already installed, it will update the tool. # # Usage: # ./install-apt-layer.sh # Install or update apt-layer # ./install-apt-layer.sh --uninstall # Remove apt-layer and all its files # ./install-apt-layer.sh --reinstall # Remove and reinstall (reset to default state) # ./install-apt-layer.sh --help # Show this help message set -euo pipefail # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' # Function to print colored output print_status() { echo -e "${GREEN}[INFO]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } print_header() { echo -e "${BLUE}================================${NC}" echo -e "${BLUE}$1${NC}" echo -e "${BLUE}================================${NC}" } # Function to show help show_help() { cat << 'EOF' apt-layer Installation Script This script installs the apt-layer tool, its dependencies, creates necessary directories and files, and sets up the system to use apt-layer. Usage: ./install-apt-layer.sh # Install or update apt-layer ./install-apt-layer.sh --uninstall # Remove apt-layer and all its files ./install-apt-layer.sh --reinstall # Remove and reinstall (reset to default state) ./install-apt-layer.sh --help # Show this help message What this script does: - Downloads the latest apt-layer.sh from the repository - Installs required dependencies (jq, dos2unix, etc.) - Creates necessary directories (/var/lib/apt-layer, /var/log/apt-layer, etc.) - Sets up configuration files - Makes apt-layer executable and available system-wide - Initializes the apt-layer system Dependencies: - curl or wget (for downloading) - jq (for JSON processing) - dos2unix (for Windows line ending conversion) - sudo (for system installation) EOF } # Function to check if running as root check_root() { if [[ $EUID -eq 0 ]]; then print_error "This script should not be run as root. Use sudo for specific commands." exit 1 fi } # --- BEGIN DEPENDENCY JSON LOADING --- # The dependencies JSON will be embedded as APT_LAYER_DEPENDENCIES_JSON in the compiled script. APT_LAYER_DEPENDENCIES_JSON="${APT_LAYER_DEPENDENCIES_JSON:-} { \"core\": [\"chroot\", \"apt-get\", \"dpkg\", \"jq\", \"mount\", \"umount\", \"findmnt\", \"numfmt\"], \"container\": [\"podman\", \"docker\"], \"oci\": [\"skopeo\"], \"composefs\": [\"mkcomposefs\", \"composefs-info\", \"mount.composefs\", \"mksquashfs\", \"unsquashfs\"], \"bootloader\": [\"efibootmgr\", \"grub-install\", \"update-grub\", \"bootctl\"], \"security\": [\"curl\", \"wget\", \"gpg\"] }" get_deps_for_type() { local type="$1" local json="$APT_LAYER_DEPENDENCIES_JSON" case "$type" in core) echo "$json" | jq -r '.core[]' ;; security) echo "$json" | jq -r '.security[]' ;; all) echo "$json" | jq -r '.core[], .security[]' ;; *) echo "$json" | jq -r '.core[]' ;; esac } print_install_instructions() { local json="$APT_LAYER_DEPENDENCIES_JSON" echo " Quick fix for common dependencies:" echo " sudo apt install -y squashfs-tools jq coreutils util-linux skopeo" echo "" echo " For container support (choose one):" echo " sudo apt install -y podman # or" echo " sudo apt install -y docker.io" echo "" echo " For bootloader support:" echo " sudo apt install -y efibootmgr grub-common systemd-boot" echo "" echo " For more information, run: apt-layer --help" echo "" } # Function to check dependencies check_dependencies() { print_status "Checking dependencies..." local missing_deps=() # Installer-specific dependencies local installer_deps=("sudo" "dos2unix") # Use JSON to get core and security deps local deps=( $(get_deps_for_type all) ) # Add installer deps deps+=("sudo" "dos2unix") # Check for curl or wget (at least one) if ! command -v curl >/dev/null 2>&1 && ! command -v wget >/dev/null 2>&1; then missing_deps+=("curl or wget") fi # Check all other deps for dep in "${deps[@]}"; do if [[ "$dep" == "curl" || "$dep" == "wget" ]]; then continue # already checked above fi if ! command -v "$dep" >/dev/null 2>&1; then missing_deps+=("$dep") fi done if [[ ${#missing_deps[@]} -gt 0 ]]; then print_error "Missing required dependencies: ${missing_deps[*]}" print_install_instructions print_error "Please install missing dependencies and re-run the installer." exit 1 fi print_status "All dependencies satisfied" } # Function to download apt-layer download_apt_layer() { print_status "Downloading apt-layer..." local download_url="https://git.raines.xyz/robojerk/particle-os-tools/raw/branch/main/apt-layer.sh" local temp_file="/tmp/apt-layer.sh" # Download using curl or wget if command -v curl >/dev/null 2>&1; then if curl -L -o "$temp_file" "$download_url"; then print_success "Downloaded apt-layer using curl" else print_error "Failed to download apt-layer using curl" return 1 fi elif command -v wget >/dev/null 2>&1; then if wget -O "$temp_file" "$download_url"; then print_success "Downloaded apt-layer using wget" else print_error "Failed to download apt-layer using wget" return 1 fi else print_error "No download tool available (curl or wget)" return 1 fi # Verify the downloaded file if [[ ! -f "$temp_file" ]] || [[ ! -s "$temp_file" ]]; then print_error "Downloaded file is empty or missing" return 1 fi # Convert line endings if needed if command -v dos2unix >/dev/null 2>&1; then dos2unix "$temp_file" 2>/dev/null || true fi # Make executable chmod +x "$temp_file" print_success "apt-layer downloaded and prepared" } # Function to install apt-layer install_apt_layer() { print_status "Installing apt-layer..." local temp_file="/tmp/apt-layer.sh" local install_dir="/usr/local/bin" local config_dir="/usr/local/etc/apt-layer" # Create installation directory if it doesn't exist sudo mkdir -p "$install_dir" # Install apt-layer sudo cp "$temp_file" "$install_dir/apt-layer" sudo chmod +x "$install_dir/apt-layer" # Create configuration directory sudo mkdir -p "$config_dir" # Create paths.json configuration sudo tee "$config_dir/paths.json" >/dev/null </dev/null 2>&1 } # Function to check if apt-layer is up to date check_for_updates() { print_status "Checking for updates..." if ! is_apt_layer_installed; then return 0 # Not installed, so no update needed fi # For now, we'll always download the latest version # In the future, this could check version numbers or timestamps return 1 # Update needed } # Main installation function main_install() { print_header "apt-layer Installation" # Check if running as root check_root # Check dependencies check_dependencies # Check if already installed if is_apt_layer_installed; then print_status "apt-layer is already installed" if check_for_updates; then print_status "apt-layer is up to date" return 0 else print_status "Updating apt-layer..." fi else print_status "Installing apt-layer..." fi # Download and install if download_apt_layer && install_apt_layer; then print_success "apt-layer installation completed successfully" print_status "You can now use 'apt-layer --help' to see available commands" return 0 else print_error "apt-layer installation failed" return 1 fi } # Main function main() { case "${1:-}" in --help|-h) show_help exit 0 ;; --uninstall) print_header "apt-layer Uninstallation" uninstall_apt_layer exit 0 ;; --reinstall) print_header "apt-layer Reinstallation" reinstall_apt_layer exit 0 ;; "") main_install exit $? ;; *) print_error "Unknown option: $1" show_help exit 1 ;; esac } # Run main function with all arguments main "$@"