- Complete documentation for all bootc commands and subcommands - Debian-specific adaptations and workarounds - Manual installation methods to bypass bootc reliability issues - Technical guides with Rust source code analysis - Flowcharts and external command references - Hidden command documentation (bootc internals, state, etc.) - Composefs integration analysis - Base image creation guides (with and without bootc binary) - Management scripts and automation - Comprehensive troubleshooting and examples
422 lines
11 KiB
Markdown
422 lines
11 KiB
Markdown
# 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<SoftRebootMode>, // 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<SoftRebootMode>,
|
|
```
|
|
|
|
**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.
|