#!/bin/bash # This script automates the backporting of ostree packages for Ubuntu Noble and Debian Trixie. # Ubuntu: Pulls source from Ubuntu Questing # Debian: Pulls source from Debian sid # # ⚠️ WARNING: This script modifies system libraries. Use with caution! # - Test in a VM first # - Have a system backup # - Be prepared for potential side effects with Flatpak and other ostree-dependent software # Exit immediately if a command exits with a non-zero status. set -e # --- Configuration --- OSTREE_VERSION="2025.2" OSTREE_DEBIAN_REVISION="1" # Distribution-specific configurations declare -A DISTRO_CONFIGS DISTRO_CONFIGS["noble"]="ubuntu|questing|noble|~noble1|http://archive.ubuntu.com/ubuntu/pool/universe/o/ostree/" DISTRO_CONFIGS["trixie"]="debian|sid|trixie|~trixie1|http://deb.debian.org/debian/pool/main/o/ostree/" # Default to noble if no distribution specified TARGET_DISTRO=${1:-noble} # Validate target distribution if [[ ! ${DISTRO_CONFIGS[$TARGET_DISTRO]} ]]; then echo "Error: Unsupported distribution '$TARGET_DISTRO'" echo "Supported distributions: ${!DISTRO_CONFIGS[@]}" exit 1 fi # Parse distribution config IFS='|' read -r DISTRO_TYPE SOURCE_RELEASE TARGET_RELEASE BACKPORT_SUFFIX POOL_URL <<< "${DISTRO_CONFIGS[$TARGET_DISTRO]}" # Set working directory based on distribution BACKPORT_DIR="${BACKPORT_DIR:-/opt/Projects/ostree-backport-${TARGET_DISTRO}}" # --- Functions --- log_info() { echo -e "\n\e[1;34m[INFO]\e[0m $1" } log_success() { echo -e "\n\e[1;32m[SUCCESS]\e[0m $1" } log_warning() { echo -e "\n\e[1;33m[WARNING]\e[0m $1" } log_error() { echo -e "\n\e[1;31m[ERROR]\e[0m $1" >&2 exit 1 } cleanup() { log_info "Cleaning up temporary files..." # Remove the added source list file sudo rm -f /etc/apt/sources.list.d/${TARGET_RELEASE}-sources.list # Remove the entire backport working directory sudo rm -rf "${BACKPORT_DIR}" sudo apt update >/dev/null 2>&1 || true log_success "Cleanup completed." } # Safety check function safety_check() { log_info "Performing safety checks..." # Check if we're running as root (shouldn't be) if [ "$EUID" -eq 0 ]; then log_error "This script should not be run as root. Please run as a regular user with sudo privileges." fi # Check if we're in a VM (recommended) if ! grep -q "VMware\|VirtualBox\|QEMU\|KVM" /sys/class/dmi/id/product_name 2>/dev/null; then log_warning "This doesn't appear to be running in a VM. Consider testing in a VM first." read -p "Continue anyway? (y/N): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then log_info "Aborted by user." exit 0 fi fi # Check if we have enough disk space (rough estimate: 500MB) AVAILABLE_SPACE=$(df /opt | awk 'NR==2 {print $4}') if [ "$AVAILABLE_SPACE" -lt 500000 ]; then log_error "Insufficient disk space. Need at least 500MB available in /opt" fi log_success "Safety checks passed." } # Set trap to ensure cleanup runs on exit # Commented out for debugging - uncomment when script is working # trap cleanup EXIT # --- Main Script --- log_info "Starting ostree backport process for ${DISTRO_TYPE^} ${TARGET_RELEASE}..." log_info "Source: ${SOURCE_RELEASE} → Target: ${TARGET_RELEASE}" # Safety checks safety_check # Step 0: Clean up any existing backport directory log_info "Step 0: Cleaning up any existing backport directory..." if [ -d "${BACKPORT_DIR}" ]; then log_info "Removing existing backport directory: ${BACKPORT_DIR}" sudo rm -rf "${BACKPORT_DIR}" fi log_success "Cleanup completed." # Step 1: Install Required Tools log_info "Step 1: Installing essential build tools (devscripts, build-essential)..." sudo apt update || log_error "Failed to update apt cache." sudo apt install -y devscripts build-essential || log_error "Failed to install build tools." log_success "Build tools installed." # Step 1.5: Add Source Repositories log_info "Step 1.5: Adding source repositories for build dependencies..." if [[ "$DISTRO_TYPE" == "ubuntu" ]]; then echo "deb-src http://us.archive.ubuntu.com/ubuntu/ ${TARGET_RELEASE} main universe" | sudo tee /etc/apt/sources.list.d/${TARGET_RELEASE}-sources.list else echo "deb-src http://deb.debian.org/debian/ ${TARGET_RELEASE} main contrib non-free" | sudo tee /etc/apt/sources.list.d/${TARGET_RELEASE}-sources.list fi sudo apt update || log_error "Failed to update apt cache with source repositories." log_success "Source repositories added." # Step 2: Create Backport Directory Structure log_info "Step 2: Creating backport directory structure at ${BACKPORT_DIR}..." mkdir -p "${BACKPORT_DIR}" || log_error "Failed to create directory ${BACKPORT_DIR}." cd "${BACKPORT_DIR}" || log_error "Failed to change directory to ${BACKPORT_DIR}." log_success "Directory structure created." # Step 3: Download Source log_info "Step 3: Downloading ostree ${OSTREE_VERSION}-${OSTREE_DEBIAN_REVISION} source from ${SOURCE_RELEASE}..." # Construct the full filenames DSC_FILE="ostree_${OSTREE_VERSION}-${OSTREE_DEBIAN_REVISION}.dsc" ORIG_TAR_XZ_FILE="ostree_${OSTREE_VERSION}.orig.tar.xz" DEBIAN_TAR_XZ_FILE="ostree_${OSTREE_VERSION}-${OSTREE_DEBIAN_REVISION}.debian.tar.xz" # Check if files already exist to avoid re-downloading for file in "${DSC_FILE}" "${ORIG_TAR_XZ_FILE}" "${DEBIAN_TAR_XZ_FILE}"; do if [ ! -f "$file" ]; then wget "${POOL_URL}${file}" || log_error "Failed to download ${file}." else log_info "File ${file} already exists, skipping download." fi done log_success "Source files downloaded." # Step 4: Extract and Modify Source log_info "Step 4: Extracting source and modifying debian/changelog..." dpkg-source -x "${DSC_FILE}" || log_error "Failed to extract source package." cd "ostree-${OSTREE_VERSION}" || log_error "Failed to change directory to ostree-${OSTREE_VERSION}." # Create backport version entry in changelog # For backports, we need to manually set the version and distribution # Use -b to force the version change since backport versions are "less than" original if ! dch --newversion "${OSTREE_VERSION}-${OSTREE_DEBIAN_REVISION}${BACKPORT_SUFFIX}" \ --distribution "${TARGET_RELEASE}-backports" \ -b \ "Backport ostree ${OSTREE_VERSION}-${OSTREE_DEBIAN_REVISION} from ${SOURCE_RELEASE} for ${TARGET_RELEASE} compatibility."; then log_info "dch failed, attempting manual changelog update..." log_error "Manual changelog update not implemented. Please check debian/changelog format." fi log_success "Source extracted and changelog updated." # Step 5: Install Build Dependencies log_info "Step 5: Installing build dependencies for ostree..." # This command relies on the debian/control file in the extracted source sudo apt build-dep ./ || log_error "Failed to install build dependencies. Check debian/control or your ${TARGET_RELEASE} repositories." log_success "Build dependencies installed." # Step 6: Build the Backport log_info "Step 6: Building the ostree backport for ${TARGET_RELEASE}..." dpkg-buildpackage -us -uc -b || log_error "Failed to build the Debian package." log_success "ostree backport built successfully." # Step 7: Install the Backport log_info "Step 7: Installing the built ostree packages..." cd .. # Go back to the directory where the .deb files are # Find all .deb files from the current build (more flexible) OSTREE_DEBS=$(find . -maxdepth 1 -name "*ostree*${BACKPORT_SUFFIX}*.deb" -o -name "*libostree*${BACKPORT_SUFFIX}*.deb") if [ -z "$OSTREE_DEBS" ]; then log_error "No .deb packages found to install. Build might have failed or naming is unexpected." log_info "Available .deb files:" ls -la *.deb 2>/dev/null || echo "No .deb files found" exit 1 fi log_info "Found packages to install: $OSTREE_DEBS" sudo dpkg -i ${OSTREE_DEBS} || log_error "Failed to install the backported .deb packages." log_success "Backported ostree packages installed." # Run apt --fix-broken install to handle any missed dependencies if dpkg -i failed to resolve them log_info "Running apt --fix-broken install to resolve any lingering dependencies..." sudo apt --fix-broken install -y || log_error "apt --fix-broken install failed." log_success "Dependency resolution attempted." # Step 8: Verify Installation log_info "Step 8: Verifying installation..." if dpkg -l | grep -q "ostree.*${BACKPORT_SUFFIX}"; then log_success "ostree backport successfully installed." else log_warning "ostree backport installation verification failed, but continuing..." fi # Step 9: Test with bootc log_info "Step 9: Now you can try building bootc with the newly installed ostree." log_info "Example: (assuming bootc source is in /opt/Projects/bootc-deb/bootc)" echo "cd /opt/Projects/bootc-deb/bootc" echo "cargo build --release" log_info "Remember to monitor for AppArmor denials during bootc operation if issues arise." log_success "ostree backport process completed for ${DISTRO_TYPE^} ${TARGET_RELEASE}." log_warning "⚠️ IMPORTANT: Please reboot your system if you experience any issues with applications that use ostree (e.g., Flatpak)." log_info "If you encounter problems, you can revert by reinstalling the original ostree packages from the ${TARGET_RELEASE} repositories."