475 lines
No EOL
14 KiB
Bash
475 lines
No EOL
14 KiB
Bash
#!/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
|
|
}
|
|
|
|
# Function to check dependencies
|
|
check_dependencies() {
|
|
print_status "Checking dependencies..."
|
|
|
|
local missing_deps=()
|
|
|
|
# Check for curl or wget
|
|
if ! command -v curl >/dev/null 2>&1 && ! command -v wget >/dev/null 2>&1; then
|
|
missing_deps+=("curl or wget")
|
|
fi
|
|
|
|
# Check for jq
|
|
if ! command -v jq >/dev/null 2>&1; then
|
|
missing_deps+=("jq")
|
|
fi
|
|
|
|
# Check for dos2unix
|
|
if ! command -v dos2unix >/dev/null 2>&1; then
|
|
missing_deps+=("dos2unix")
|
|
fi
|
|
|
|
if [[ ${#missing_deps[@]} -gt 0 ]]; then
|
|
print_error "Missing required dependencies: ${missing_deps[*]}"
|
|
print_status "Installing missing dependencies..."
|
|
|
|
# Try to install dependencies
|
|
if command -v apt-get >/dev/null 2>&1; then
|
|
sudo apt-get update
|
|
sudo apt-get install -y "${missing_deps[@]}"
|
|
elif command -v dnf >/dev/null 2>&1; then
|
|
sudo dnf install -y "${missing_deps[@]}"
|
|
elif command -v yum >/dev/null 2>&1; then
|
|
sudo yum install -y "${missing_deps[@]}"
|
|
else
|
|
print_error "Could not automatically install dependencies. Please install manually:"
|
|
print_error " ${missing_deps[*]}"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
print_success "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 << 'EOF'
|
|
{
|
|
"apt_layer_paths": {
|
|
"description": "apt-layer system path configuration",
|
|
"version": "1.0",
|
|
"main_directories": {
|
|
"workspace": {
|
|
"path": "/var/lib/apt-layer",
|
|
"description": "Main apt-layer workspace directory",
|
|
"permissions": "755",
|
|
"owner": "root:root"
|
|
},
|
|
"logs": {
|
|
"path": "/var/log/apt-layer",
|
|
"description": "apt-layer log files directory",
|
|
"permissions": "755",
|
|
"owner": "root:root"
|
|
},
|
|
"cache": {
|
|
"path": "/var/cache/apt-layer",
|
|
"description": "apt-layer cache directory",
|
|
"permissions": "755",
|
|
"owner": "root:root"
|
|
}
|
|
},
|
|
"workspace_subdirectories": {
|
|
"build": {
|
|
"path": "/var/lib/apt-layer/build",
|
|
"description": "Build artifacts and temporary files",
|
|
"permissions": "755",
|
|
"owner": "root:root"
|
|
},
|
|
"live_overlay": {
|
|
"path": "/var/lib/apt-layer/live-overlay",
|
|
"description": "Live overlay system for temporary changes",
|
|
"permissions": "755",
|
|
"owner": "root:root"
|
|
},
|
|
"composefs": {
|
|
"path": "/var/lib/apt-layer/composefs",
|
|
"description": "ComposeFS layers and metadata",
|
|
"permissions": "755",
|
|
"owner": "root:root"
|
|
},
|
|
"ostree_commits": {
|
|
"path": "/var/lib/apt-layer/ostree-commits",
|
|
"description": "OSTree commit history and metadata",
|
|
"permissions": "755",
|
|
"owner": "root:root"
|
|
},
|
|
"deployments": {
|
|
"path": "/var/lib/apt-layer/deployments",
|
|
"description": "Deployment directories and state",
|
|
"permissions": "755",
|
|
"owner": "root:root"
|
|
},
|
|
"history": {
|
|
"path": "/var/lib/apt-layer/history",
|
|
"description": "Deployment history and rollback data",
|
|
"permissions": "755",
|
|
"owner": "root:root"
|
|
},
|
|
"bootloader": {
|
|
"path": "/var/lib/apt-layer/bootloader",
|
|
"description": "Bootloader state and configuration",
|
|
"permissions": "755",
|
|
"owner": "root:root"
|
|
},
|
|
"transaction_state": {
|
|
"path": "/var/lib/apt-layer/transaction-state",
|
|
"description": "Transaction state and temporary data",
|
|
"permissions": "755",
|
|
"owner": "root:root"
|
|
}
|
|
},
|
|
"files": {
|
|
"deployment_db": {
|
|
"path": "/var/lib/apt-layer/deployments.json",
|
|
"description": "Deployment database file",
|
|
"permissions": "644",
|
|
"owner": "root:root"
|
|
},
|
|
"current_deployment": {
|
|
"path": "/var/lib/apt-layer/current-deployment",
|
|
"description": "Current deployment identifier file",
|
|
"permissions": "644",
|
|
"owner": "root:root"
|
|
},
|
|
"pending_deployment": {
|
|
"path": "/var/lib/apt-layer/pending-deployment",
|
|
"description": "Pending deployment identifier file",
|
|
"permissions": "644",
|
|
"owner": "root:root"
|
|
},
|
|
"transaction_log": {
|
|
"path": "/var/lib/apt-layer/transaction.log",
|
|
"description": "Transaction log file",
|
|
"permissions": "644",
|
|
"owner": "root:root"
|
|
}
|
|
},
|
|
"fallback_paths": {
|
|
"description": "Fallback paths for different environments",
|
|
"wsl": {
|
|
"workspace": "/mnt/wsl/apt-layer",
|
|
"logs": "/mnt/wsl/apt-layer/logs",
|
|
"cache": "/mnt/wsl/apt-layer/cache"
|
|
},
|
|
"container": {
|
|
"workspace": "/tmp/apt-layer",
|
|
"logs": "/tmp/apt-layer/logs",
|
|
"cache": "/tmp/apt-layer/cache"
|
|
},
|
|
"test": {
|
|
"workspace": "/tmp/apt-layer-test",
|
|
"logs": "/tmp/apt-layer-test/logs",
|
|
"cache": "/tmp/apt-layer-test/cache"
|
|
}
|
|
},
|
|
"environment_variables": {
|
|
"description": "Environment variable mappings",
|
|
"APT_LAYER_WORKSPACE": "workspace",
|
|
"APT_LAYER_LOG_DIR": "logs",
|
|
"APT_LAYER_CACHE_DIR": "cache",
|
|
"BUILD_DIR": "workspace_subdirectories.build",
|
|
"LIVE_OVERLAY_DIR": "workspace_subdirectories.live_overlay",
|
|
"COMPOSEFS_DIR": "workspace_subdirectories.composefs",
|
|
"OSTREE_COMMITS_DIR": "workspace_subdirectories.ostree_commits",
|
|
"DEPLOYMENTS_DIR": "workspace_subdirectories.deployments",
|
|
"HISTORY_DIR": "workspace_subdirectories.history",
|
|
"BOOTLOADER_STATE_DIR": "workspace_subdirectories.bootloader",
|
|
"TRANSACTION_STATE": "workspace_subdirectories.transaction_state",
|
|
"DEPLOYMENT_DB": "files.deployment_db",
|
|
"CURRENT_DEPLOYMENT_FILE": "files.current_deployment",
|
|
"PENDING_DEPLOYMENT_FILE": "files.pending_deployment",
|
|
"TRANSACTION_LOG": "files.transaction_log"
|
|
}
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# Set proper permissions
|
|
sudo chmod 644 "$config_dir/paths.json"
|
|
|
|
# Initialize apt-layer system
|
|
print_status "Initializing apt-layer system..."
|
|
if sudo apt-layer --init; then
|
|
print_success "apt-layer system initialized"
|
|
else
|
|
print_warning "apt-layer system initialization failed, but installation completed"
|
|
fi
|
|
|
|
# Clean up temporary file
|
|
rm -f "$temp_file"
|
|
|
|
print_success "apt-layer installed successfully"
|
|
print_status "You can now use 'apt-layer --help' to see available commands"
|
|
}
|
|
|
|
# Function to uninstall apt-layer
|
|
uninstall_apt_layer() {
|
|
print_status "Uninstalling apt-layer..."
|
|
|
|
local install_dir="/usr/local/bin"
|
|
local config_dir="/usr/local/etc/apt-layer"
|
|
|
|
# Remove apt-layer binary
|
|
if [[ -f "$install_dir/apt-layer" ]]; then
|
|
sudo rm -f "$install_dir/apt-layer"
|
|
print_status "Removed apt-layer binary"
|
|
fi
|
|
|
|
# Remove configuration directory
|
|
if [[ -d "$config_dir" ]]; then
|
|
sudo rm -rf "$config_dir"
|
|
print_status "Removed configuration directory"
|
|
fi
|
|
|
|
# Remove apt-layer directories (optional - ask user)
|
|
if [[ -d "/var/lib/apt-layer" ]] || [[ -d "/var/log/apt-layer" ]] || [[ -d "/var/cache/apt-layer" ]]; then
|
|
echo -e "${YELLOW}Do you want to remove all apt-layer data directories? (y/N)${NC}"
|
|
read -r response
|
|
if [[ "$response" =~ ^[Yy]$ ]]; then
|
|
sudo rm -rf "/var/lib/apt-layer" "/var/log/apt-layer" "/var/cache/apt-layer"
|
|
print_status "Removed all apt-layer data directories"
|
|
else
|
|
print_status "Keeping apt-layer data directories"
|
|
fi
|
|
fi
|
|
|
|
print_success "apt-layer uninstalled successfully"
|
|
}
|
|
|
|
# Function to reinstall apt-layer
|
|
reinstall_apt_layer() {
|
|
print_status "Reinstalling apt-layer..."
|
|
|
|
# Uninstall first
|
|
uninstall_apt_layer
|
|
|
|
# Install again
|
|
install_apt_layer
|
|
|
|
print_success "apt-layer reinstalled successfully"
|
|
}
|
|
|
|
# Function to check if apt-layer is installed
|
|
is_apt_layer_installed() {
|
|
command -v apt-layer >/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 "$@" |