# apt-ostree OSTree Implementation ## Overview apt-ostree implements OSTree as its core filesystem management system, providing atomic, immutable deployments with APT/DEB package layering capabilities. This document explains how apt-ostree implements and extends OSTree functionality for Debian/Ubuntu systems. ## Core OSTree Integration ### Repository Management apt-ostree maintains an OSTree repository at `/ostree/repo` that stores: - **Content-addressable objects**: Files and metadata stored by SHA256 hash - **Commits**: Immutable snapshots of filesystem trees - **Refs**: Symbolic pointers to specific commits (e.g., `ubuntu/24.04/x86_64/desktop`) - **Static deltas**: Pre-calculated differences between commits for efficient updates ### Deployment Structure ``` /ostree/ ├── repo/ # OSTree repository (content-addressable storage) ├── deploy/ # Active deployments │ └── ubuntu-desktop/ # State root for Ubuntu Desktop │ ├── var/ # Shared mutable data across deployments │ └── / # Individual deployment directories └── boot/ # Bootloader configuration ``` ### Filesystem Assembly apt-ostree assembles the live filesystem using: - **Hardlinks**: Deployments use hardlinks to objects in `/ostree/repo` - **Bind mounts**: Read-only `/usr` mounted from deployment - **Symlinks**: User directories redirected to `/var` - **3-way merge**: `/etc` merged from old deployment, new deployment, and local changes ## APT-OSTree Specific Extensions ### Package Layering apt-ostree extends OSTree with APT/DEB package layering: ```rust // Core layering implementation in src/ostree.rs pub struct OstreeManager { repo: OstreeRepo, sysroot: OstreeSysroot, } impl OstreeManager { // Create new deployment with layered packages pub fn create_deployment_with_layers( &self, base_commit: &str, new_commit: &str, layered_packages: &[String], ) -> Result<(), Box> { // 1. Extract base filesystem from OSTree commit let base_tree = self.repo.read_commit(base_commit, None)?; // 2. Apply DEB package layers let layered_tree = self.apply_deb_layers(&base_tree, layered_packages)?; // 3. Create new OSTree commit let new_commit_checksum = self.repo.write_commit( &layered_tree, "Package layer update", None, None, )?; // 4. Update ref to point to new commit self.repo.set_ref(None, "ubuntu/24.04/x86_64/desktop", &new_commit_checksum)?; Ok(()) } // Apply DEB package layers to deployment pub fn apply_deb_layers( &self, base_tree: &OstreeRepoFile, packages: &[String], ) -> Result> { // Extract DEB packages and apply to filesystem tree for package in packages { let extracted_package = self.extract_deb_package(package)?; self.merge_package_into_tree(&base_tree, &extracted_package)?; } Ok(base_tree.clone()) } } ``` ### Transaction Management apt-ostree implements atomic transactions for all OSTree operations: ```rust // Transaction types for OSTree operations #[derive(Debug, Clone)] pub enum TransactionType { Deploy, Rollback, PkgChange, Rebase, Upgrade, } // Transaction execution with OSTree integration pub struct OstreeTransaction { transaction_type: TransactionType, sysroot: OstreeSysroot, } impl OstreeTransaction { // Execute transaction with OSTree commit creation pub fn execute_with_ostree_commit( &self, base_commit: &str, new_commit: &str, ) -> Result<(), Box> { match self.transaction_type { TransactionType::Deploy => { self.create_deployment(base_commit, new_commit)?; } TransactionType::Rollback => { self.rollback_to_previous_deployment()?; } TransactionType::PkgChange => { self.apply_package_changes(base_commit, new_commit)?; } _ => { return Err("Unsupported transaction type".into()); } } Ok(()) } // Rollback to previous OSTree deployment pub fn rollback_to_previous_deployment(&self) -> Result<(), Box> { let deployments = self.sysroot.get_deployments()?; if deployments.len() < 2 { return Err("No previous deployment available for rollback".into()); } // Switch to previous deployment let previous_deployment = &deployments[1]; self.sysroot.set_default_deployment(previous_deployment)?; Ok(()) } } ``` ### OSTree Commit Creation apt-ostree creates OSTree commits for all system changes: ```rust // Commit creation workflow in src/ostree.rs impl OstreeManager { pub fn create_commit( &self, base_commit: &str, new_commit: &str, subject: &str, layered_packages: &[String], ) -> Result> { // 1. Extract base filesystem from OSTree commit let base_tree = self.repo.read_commit(base_commit, None)?; // 2. Apply DEB package layers let layered_tree = self.apply_deb_layers(&base_tree, layered_packages)?; // 3. Create new OSTree commit let new_commit_checksum = self.repo.write_commit( &layered_tree, subject, None, None, )?; // 4. Update ref to point to new commit self.repo.set_ref(None, "ubuntu/24.04/x86_64/desktop", &new_commit_checksum)?; Ok(new_commit_checksum) } } ``` ## OSTree Environment Detection apt-ostree detects OSTree environments using multiple methods: ```rust // Environment detection in src/ostree_detection.rs pub struct OstreeDetection; impl OstreeDetection { pub fn is_ostree_environment() -> bool { // Method 1: Check for /ostree directory if !std::path::Path::new("/ostree").is_dir() { return false; } // Method 2: Check for /run/ostree-booted file if !std::path::Path::new("/run/ostree-booted").exists() { return false; } // Method 3: Check kernel command line for ostree parameter if let Ok(cmdline) = std::fs::read_to_string("/proc/cmdline") { if !cmdline.contains("ostree") { return false; } } // Method 4: Try to load OSTree sysroot if let Ok(sysroot) = OstreeSysroot::new_default() { if sysroot.load().is_ok() { return true; } } false } pub fn get_detection_methods() -> Vec { vec![ "Filesystem detection (/ostree directory)".to_string(), "Boot detection (/run/ostree-booted file)".to_string(), "Kernel parameter detection (ostree in /proc/cmdline)".to_string(), "Library detection (OSTree sysroot loading)".to_string(), "Service detection (daemon availability)".to_string(), ] } } ``` ## OSTree Integration Points ### Daemon Integration The apt-ostree daemon integrates with OSTree for privileged operations: ```rust // Daemon OSTree operations in src/bin/apt-ostreed.rs pub struct AptOstreedDaemon { ostree_manager: OstreeManager, } impl AptOstreedDaemon { // OSTree deployment management pub fn deploy_ostree_commit( &self, commit_checksum: &str, osname: &str, ) -> Result<(), Box> { self.ostree_manager.create_deployment(commit_checksum, osname) } // OSTree rollback operations pub fn rollback_ostree_deployment( &self, osname: &str, ) -> Result<(), Box> { self.ostree_manager.rollback_deployment(osname) } // OSTree status reporting pub fn get_ostree_status(&self) -> Result> { let deployments = self.ostree_manager.get_deployments()?; let current_deployment = self.ostree_manager.get_current_deployment()?; Ok(json!({ "deployments": deployments, "current": current_deployment, "booted": self.ostree_manager.is_booted_deployment(¤t_deployment)?, })) } } ``` ### CLI Integration apt-ostree CLI commands integrate with OSTree operations: ```rust // CLI command integration in src/main.rs pub fn deploy_command(matches: &ArgMatches) -> Result<(), Box> { let commit = matches.get_one::("COMMIT") .ok_or("No commit specified")?; // Create deployment via D-Bus daemon let client = AptOstreeClient::new()?; client.deploy(commit)?; println!("Deployment created successfully"); Ok(()) } pub fn rollback_command(_matches: &ArgMatches) -> Result<(), Box> { // Rollback via D-Bus daemon let client = AptOstreeClient::new()?; client.rollback()?; println!("Rollback completed successfully"); Ok(()) } ``` ## OSTree Performance Optimizations ### Static Delta Support apt-ostree leverages OSTree static deltas for efficient updates: ```rust // Static delta usage in src/ostree.rs impl OstreeManager { pub fn pull_with_static_deltas( &self, remote_name: &str, refspec: &str, ) -> Result<(), Box> { // Configure static delta usage self.repo.set_enable_static_deltas(true); // Pull with static delta optimization self.repo.pull(remote_name, refspec, None) } } ``` ### Content Deduplication apt-ostree benefits from OSTree's content-addressable storage: ```rust // Content deduplication example impl OstreeManager { pub fn commit_with_deduplication( &self, base_commit: &str, new_commit: &str, ) -> Result> { // OSTree automatically deduplicates identical files // Only unique content is stored in the repository let base_tree = self.repo.read_commit(base_commit, None)?; // Create commit with automatic deduplication self.repo.write_commit(&base_tree, "Update", None, None) } } ``` ## OSTree Security Features ### GPG Signature Verification apt-ostree verifies OSTree commits using GPG signatures: ```rust // GPG verification in src/ostree.rs impl OstreeManager { pub fn verify_commit_signature( &self, commit_checksum: &str, ) -> Result> { // Verify commit signature let sign = OstreeSign::new()?; self.repo.verify_commit(commit_checksum, &sign) } } ``` ### Read-Only Filesystem Enforcement apt-ostree enforces OSTree's read-only filesystem model: ```rust // Read-only enforcement in src/system.rs impl SystemManager { pub fn enforce_readonly_filesystem( &self, deployment_path: &str, ) -> Result<(), Box> { // Mount /usr as read-only let mount_cmd = format!("mount --bind -o ro {} /usr", deployment_path); self.run_command(&mount_cmd)?; Ok(()) } } ``` ## OSTree Integration Testing ### Deployment Testing ```bash # Test OSTree deployment creation apt-ostree deploy $(apt-ostree status --json | jq -r '.deployments[0].checksum') # Test OSTree rollback apt-ostree rollback # Test OSTree status apt-ostree status --json ``` ### Performance Testing ```bash # Test OSTree pull performance time ostree pull ubuntu ubuntu/24.04/x86_64/desktop # Test static delta usage ostree pull --enable-static-deltas ubuntu ubuntu/24.04/x86_64/desktop # Test commit creation performance time apt-ostree install package-name ``` ## OSTree Troubleshooting ### Common Issues 1. **OSTree repository corruption**: Use `ostree fsck` to verify repository integrity 2. **Deployment failures**: Check `/var/log/ostree.log` for detailed error messages 3. **Bootloader issues**: Verify GRUB configuration with `ostree admin boot` 4. **Space issues**: Use `ostree admin cleanup` to remove old deployments ### Debug Commands ```bash # Check OSTree repository status ostree fsck --repo=/ostree/repo # List available deployments ostree admin status # Check bootloader configuration ostree admin boot # Verify commit signatures ostree verify --repo=/ostree/repo ubuntu/24.04/x86_64/desktop ``` ## OSTree Future Enhancements ### Planned Features 1. **Composefs Integration**: Enhanced filesystem layering with composefs 2. **OCI Container Support**: Direct OSTree to OCI container conversion 3. **Bootc Compatibility**: Integration with bootc for container-native deployments 4. **Enhanced Static Deltas**: Improved delta generation and application ### Integration Roadmap - **Phase 1**: Core OSTree integration (✅ Complete) - **Phase 2**: Performance optimizations (✅ Complete) - **Phase 3**: Security enhancements (✅ Complete) - **Phase 4**: OCI container support (🔄 In Progress) - **Phase 5**: Bootc compatibility (📋 Planned) ## Ubuntu/Debian Specific Considerations ### Filesystem Layout apt-ostree adapts OSTree for Ubuntu/Debian filesystem conventions: ``` / ├── ostree/ # OSTree repository and deployments │ ├── repo/ # OSTree repository │ ├── deploy/ # Deployed systems │ └── boot/ # Boot configurations ├── var/ # Writable data (shared across deployments) │ ├── home/ # User home directories │ ├── opt/ # Optional application software │ ├── usrlocal/ # Locally installed software │ ├── etc/ # System configuration (merged on upgrade) │ └── tmp/ # Temporary files ├── etc/ # System configuration (writable) └── usr/ # Read-only system software ``` ### Package Management Integration apt-ostree integrates APT package management with OSTree: ```rust // APT-OSTree integration in src/apt.rs impl AptManager { pub fn install_packages_with_ostree( &self, packages: &[String], ) -> Result<(), Box> { // 1. Download and extract DEB packages let extracted_packages = self.download_and_extract_packages(packages)?; // 2. Create OSTree commit with package layers let ostree_manager = OstreeManager::new()?; ostree_manager.create_commit_with_layers( &self.get_current_commit()?, "Package installation", &extracted_packages, )?; // 3. Deploy new commit ostree_manager.deploy_latest_commit()?; Ok(()) } } ``` ### mmdebstrap Integration apt-ostree uses mmdebstrap for efficient base system creation: ```bash # Create base system with mmdebstrap sudo mmdebstrap --arch=amd64 --variant=minbase \ --include=systemd,systemd-sysv,ostree \ noble /tmp/ubuntu-base # Create package layer sudo mmdebstrap --arch=amd64 \ --include=ubuntu-desktop-minimal,gnome-shell \ noble /tmp/ubuntu-desktop /tmp/ubuntu-base # Create OSTree commit sudo ostree commit --repo=/ostree/repo \ --branch=ubuntu/24.04/x86_64/desktop \ --parent=ubuntu/24.04/x86_64/base \ /tmp/ubuntu-desktop ```