# bootc upgrade - Technical Reference ## Architecture Overview The bootc upgrade system is built on OSTree's A/B deployment model, providing transactional updates with rollback capabilities. The system integrates with container registries to pull updates and stages them for application at the next boot. ## Core Components ### 1. Upgrade Command Structure ```rust // From cli.rs:64-89 pub(crate) struct UpgradeOpts { pub(crate) quiet: bool, // Suppress progress output pub(crate) check: bool, // Check-only mode pub(crate) apply: bool, // Apply and reboot pub(crate) soft_reboot: Option, // Soft reboot behavior pub(crate) progress: ProgressOptions, // Progress reporting } ``` **Purpose**: Command-line interface configuration **Features**: Mutually exclusive options, progress control, soft reboot support ### 2. Upgrade Implementation ```rust // From cli.rs:860-969 async fn upgrade(opts: UpgradeOpts) -> Result<()> { let sysroot = &get_storage().await?; let ostree = sysroot.get_ostree()?; let repo = &ostree.repo(); let (booted_deployment, _deployments, host) = crate::status::get_status_require_booted(ostree)?; let imgref = host.spec.image.as_ref(); let prog: ProgressWriter = opts.progress.try_into()?; // ... upgrade logic } ``` **Process Flow**: 1. **System Validation**: Check system status and compatibility 2. **Image Resolution**: Determine source image reference 3. **Update Check**: Verify if updates are available 4. **Download/Stage**: Pull and stage updates 5. **Application**: Apply updates if requested ## Upgrade Modes ### 1. Check Mode (`--check`) ```rust // From cli.rs:894-915 if opts.check { let imgref = imgref.clone().into(); let mut imp = crate::deploy::new_importer(repo, &imgref).await?; match imp.prepare().await? { PrepareResult::AlreadyPresent(_) => { println!("No changes in: {imgref:#}"); } PrepareResult::Ready(r) => { crate::deploy::check_bootc_label(&r.config); println!("Update available for: {imgref:#}"); if let Some(version) = r.version() { println!(" Version: {version}"); } println!(" Digest: {}", r.manifest_digest); changed = true; // ... diff printing } } } ``` **Purpose**: Check for updates without downloading **Benefits**: Fast execution, minimal bandwidth usage **Output**: Update availability, version info, digest comparison ### 2. Download Mode (default) ```rust // From cli.rs:916-949 let fetched = crate::deploy::pull(repo, imgref, None, opts.quiet, prog.clone()).await?; let staged_digest = staged_image.map(|s| s.digest().expect("valid digest in status")); let fetched_digest = &fetched.manifest_digest; let staged_unchanged = staged_digest .as_ref() .map(|d| d == fetched_digest) .unwrap_or_default(); let booted_unchanged = booted_image .as_ref() .map(|img| &img.manifest_digest == fetched_digest) .unwrap_or_default(); if staged_unchanged { println!("Staged update present, not changed."); handle_staged_soft_reboot(ostree, opts.soft_reboot, &host)?; if opts.apply { crate::reboot::reboot()?; } } else if booted_unchanged { println!("No update available.") } else { let osname = booted_deployment.osname(); crate::deploy::stage(sysroot, &osname, &fetched, &spec, prog.clone()).await?; changed = true; // ... diff printing } ``` **Purpose**: Download and stage updates **Process**: Registry pull → OSTree import → Staging → Status update **Features**: Duplicate detection, progress reporting, diff display ### 3. Apply Mode (`--apply`) ```rust // From cli.rs:951-968 if changed { sysroot.update_mtime()?; if opts.soft_reboot.is_some() { let updated_host = crate::status::get_status(ostree, Some(&booted_deployment))?.1; handle_staged_soft_reboot(ostree, opts.soft_reboot, &updated_host)?; } if opts.apply { crate::reboot::reboot()?; } } else { tracing::debug!("No changes"); } ``` **Purpose**: Apply staged updates and reboot **Process**: Update system status → Handle soft reboot → Reboot system **Features**: Soft reboot support, automatic reboot, status updates ## Soft Reboot System ### 1. Soft Reboot Modes ```rust // From cli.rs:81-85 #[clap(long = "soft-reboot", conflicts_with = "check")] pub(crate) soft_reboot: Option, ``` **Modes**: - `required`: Fail if soft reboot unavailable - `auto`: Use soft reboot if available, fallback to regular reboot ### 2. Soft Reboot Handling ```rust // From cli.rs:954-959 if opts.soft_reboot.is_some() { let updated_host = crate::status::get_status(ostree, Some(&booted_deployment))?.1; handle_staged_soft_reboot(ostree, opts.soft_reboot, &updated_host)?; } ``` **Purpose**: Configure soft reboot behavior **Process**: Check availability → Configure if supported → Fallback if needed ## Registry Integration ### 1. Image Reference Resolution ```rust // From cli.rs:865-889 let imgref = host.spec.image.as_ref(); let booted_image = host .status .booted .as_ref() .map(|b| b.query_image(repo)) .transpose()? .flatten(); let imgref = imgref.ok_or_else(|| anyhow::anyhow!("No image source specified"))?; ``` **Purpose**: Determine source image for updates **Process**: Get from host spec → Validate availability → Use for upgrade ### 2. Container Registry Pull ```rust // From cli.rs:917 let fetched = crate::deploy::pull(repo, imgref, None, opts.quiet, prog.clone()).await?; ``` **Purpose**: Download container image from registry **Process**: Registry authentication → Layer download → OSTree conversion **Features**: Progress reporting, error handling, signature verification ## OSTree Integration ### 1. Deployment Management ```rust // From cli.rs:864 let (booted_deployment, _deployments, host) = crate::status::get_status_require_booted(ostree)?; ``` **Purpose**: Get current system state **Process**: Query OSTree → Get booted deployment → Get host configuration ### 2. Staging Process ```rust // From cli.rs:940 crate::deploy::stage(sysroot, &osname, &fetched, &spec, prog.clone()).await?; ``` **Purpose**: Stage updates for next boot **Process**: Create new deployment → Configure bootloader → Update status **Features**: Atomic staging, rollback capability, state preservation ## Status Management ### 1. System Status Query ```rust // From cli.rs:864 let (booted_deployment, _deployments, host) = crate::status::get_status_require_booted(ostree)?; ``` **Purpose**: Get current system state **Returns**: Booted deployment, all deployments, host configuration ### 2. Status Updates ```rust // From cli.rs:952 sysroot.update_mtime()?; ``` **Purpose**: Update system modification time **Process**: Update filesystem timestamp → Trigger status refresh ## Error Handling ### 1. Compatibility Checks ```rust // From cli.rs:869-879 if imgref.is_none() { let booted_incompatible = host.status.booted.as_ref().is_some_and(|b| b.incompatible); let staged_incompatible = host.status.staged.as_ref().is_some_and(|b| b.incompatible); if booted_incompatible || staged_incompatible { return Err(anyhow::anyhow!( "Deployment contains local rpm-ostree modifications; cannot upgrade via bootc. You can run `rpm-ostree reset` to undo the modifications." )); } } ``` **Purpose**: Check system compatibility **Checks**: Local modifications, incompatible deployments **Error**: Prevents upgrade on incompatible systems ### 2. Update Validation ```rust // From cli.rs:902 crate::deploy::check_bootc_label(&r.config); ``` **Purpose**: Validate container image compatibility **Checks**: bootc labels, image configuration **Error**: Prevents upgrade of incompatible images ## Progress Reporting ### 1. Progress Writer ```rust // From cli.rs:866 let prog: ProgressWriter = opts.progress.try_into()?; ``` **Purpose**: Handle progress output **Features**: Quiet mode support, progress bars, status updates ### 2. Progress Options ```rust // From cli.rs:87-88 #[clap(flatten)] pub(crate) progress: ProgressOptions, ``` **Purpose**: Configure progress display **Options**: Quiet mode, progress bars, status updates ## Diff and Comparison ### 1. Manifest Comparison ```rust // From cli.rs:910-913 if let Some(previous_image) = booted_image.as_ref() { let diff = ostree_container::ManifestDiff::new(&previous_image.manifest, &r.manifest); diff.print(); } ``` **Purpose**: Show differences between images **Process**: Compare manifests → Generate diff → Display changes **Features**: Layer changes, configuration differences, size changes ### 2. Update Information ```rust // From cli.rs:903-908 println!("Update available for: {imgref:#}"); if let Some(version) = r.version() { println!(" Version: {version}"); } println!(" Digest: {}", r.manifest_digest); ``` **Purpose**: Display update information **Information**: Image reference, version, digest, changes ## System Integration ### 1. Storage Management ```rust // From cli.rs:861 let sysroot = &get_storage().await?; ``` **Purpose**: Get system storage interface **Features**: OSTree integration, filesystem management ### 2. Reboot Integration ```rust // From cli.rs:962 crate::reboot::reboot()?; ``` **Purpose**: Reboot system after update **Process**: Trigger system reboot → Apply staged updates **Features**: Soft reboot support, reboot coordination ## Performance Optimizations ### 1. Duplicate Detection ```rust // From cli.rs:922-929 let staged_unchanged = staged_digest .as_ref() .map(|d| d == fetched_digest) .unwrap_or_default(); let booted_unchanged = booted_image .as_ref() .map(|img| &img.manifest_digest == fetched_digest) .unwrap_or_default(); ``` **Purpose**: Avoid unnecessary downloads **Process**: Compare digests → Skip if unchanged **Benefits**: Reduced bandwidth, faster execution ### 2. Incremental Updates ```rust // From cli.rs:917 let fetched = crate::deploy::pull(repo, imgref, None, opts.quiet, prog.clone()).await?; ``` **Purpose**: Download only changed layers **Process**: Registry comparison → Layer download → OSTree import **Benefits**: Reduced bandwidth, faster updates ## Security Features ### 1. Signature Verification ```rust // From cli.rs:917 let fetched = crate::deploy::pull(repo, imgref, None, opts.quiet, prog.clone()).await?; ``` **Purpose**: Verify image signatures **Process**: Registry authentication → Signature verification → Image validation **Features**: Cryptographic verification, trust validation ### 2. Image Validation ```rust // From cli.rs:902 crate::deploy::check_bootc_label(&r.config); ``` **Purpose**: Validate image compatibility **Process**: Check bootc labels → Verify configuration → Validate compatibility **Features**: Label verification, configuration validation ## Future Enhancements ### 1. Planned Features - **Userspace Restart**: For kernel-unchanged updates - **Delta Updates**: More efficient layer downloads - **Rollback Automation**: Automatic rollback on failure - **Update Scheduling**: Time-based update application ### 2. Integration Improvements - **API Support**: REST API for update management - **Webhook Integration**: Event notifications - **Metrics Collection**: Update performance metrics - **Dashboard Integration**: Web-based management This technical reference provides comprehensive understanding of the bootc upgrade system's architecture, implementation, and integration patterns.