- 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
20 KiB
bootc status - Technical Guide
Overview
bootc status is a command for displaying the current state of a bootc-managed system. It provides comprehensive information about deployments, boot order, image references, and system configuration. The command supports multiple output formats and can be used both interactively and programmatically.
Purpose
The status command serves several critical functions:
- System State Display: Show current bootc system state
- Deployment Information: Display staged, booted, and rollback deployments
- Image References: Show container image information and metadata
- Boot Order Status: Indicate current boot order configuration
- Programmatic Access: Provide structured data for automation
- Troubleshooting: Help diagnose system issues
Command Syntax
bootc status [OPTIONS...]
Basic Usage
# Show current system status
bootc status
# Show status in JSON format
bootc status --format=json
# Show detailed status with verbose output
bootc status --verbose
# Show only booted deployment status
bootc status --booted
# Show status in YAML format
bootc status --format=yaml
Command Options
| Option | Description | Default | Required |
|---|---|---|---|
--format |
Output format (humanreadable, yaml, json) | auto |
No |
--format-version |
Format version (0, 1) | 1 |
No |
--booted |
Only display booted deployment | false |
No |
--verbose, -v |
Include additional fields | false |
No |
--json |
Output in JSON format (deprecated) | false |
No |
Output Formats
| Format | Description | Use Case |
|---|---|---|
humanreadable |
Human-friendly text output | Interactive use |
yaml |
YAML-formatted output | Programmatic parsing |
json |
JSON-formatted output | Programmatic parsing |
Architecture Overview
1. Status Command Structure
pub(crate) struct StatusOpts {
pub(crate) json: bool, // JSON output (deprecated)
pub(crate) format: Option<OutputFormat>, // Output format
pub(crate) format_version: Option<u32>, // Format version
pub(crate) booted: bool, // Only booted deployment
pub(crate) verbose: bool, // Verbose output
}
2. Status Process Flow
pub(crate) async fn status(opts: StatusOpts) -> Result<()> {
// 1. Validate format version
match opts.format_version.unwrap_or_default() {
0 | 1 => {} // Both 0 and 1 mean "v1"
o => anyhow::bail!("Unsupported format version: {o}"),
};
// 2. Get system status
let mut host = if !ostree_booted()? {
Default::default()
} else {
let sysroot = super::cli::get_storage().await?;
let ostree = sysroot.get_ostree()?;
let booted_deployment = ostree.booted_deployment();
let (_deployments, host) = get_status(&ostree, booted_deployment.as_ref())?;
host
};
// 3. Filter to booted deployment if requested
if opts.booted {
host.filter_to_slot(Slot::Booted);
}
// 4. Determine output format
let out = std::io::stdout();
let mut out = out.lock();
let legacy_opt = if opts.json {
OutputFormat::Json
} else if std::io::stdout().is_terminal() {
OutputFormat::HumanReadable
} else {
OutputFormat::Yaml
};
let format = opts.format.unwrap_or(legacy_opt);
// 5. Output in requested format
match format {
OutputFormat::Json => host.to_canon_json_writer(&mut out),
OutputFormat::Yaml => serde_yaml::to_writer(&mut out, &host),
OutputFormat::HumanReadable => {
human_readable_output(&mut out, &host, opts.verbose)
}
}
}
3. Core Status Gathering
pub(crate) fn get_status(
sysroot: &SysrootLock,
booted_deployment: Option<&ostree::Deployment>,
) -> Result<(Deployments, Host)> {
// 1. Get stateroot name
let stateroot = booted_deployment.as_ref().map(|d| d.osname());
// 2. Partition deployments
let (mut related_deployments, other_deployments) = sysroot
.deployments()
.into_iter()
.partition::<VecDeque<_>, _>(|d| Some(d.osname()) == stateroot);
// 3. Find staged deployment
let staged = related_deployments
.iter()
.position(|d| d.is_staged())
.map(|i| related_deployments.remove(i).unwrap());
// 4. Filter out booted deployment
if let Some(booted) = booted_deployment.as_ref() {
related_deployments.retain(|f| !f.equal(booted));
}
// 5. Get rollback deployment
let rollback = related_deployments.pop_front();
// 6. Determine rollback queued status
let rollback_queued = match (booted_deployment.as_ref(), rollback.as_ref()) {
(Some(booted), Some(rollback)) => rollback.index() < booted.index(),
_ => false,
};
// 7. Determine boot order
let boot_order = if rollback_queued {
BootOrder::Rollback
} else {
BootOrder::Default
};
// 8. Create deployments structure
let deployments = Deployments {
staged,
rollback,
other: related_deployments,
};
// 9. Create boot entries
let staged = deployments.staged
.as_ref()
.map(|d| boot_entry_from_deployment(sysroot, d))
.transpose()
.context("Staged deployment")?;
let booted = booted_deployment
.as_ref()
.map(|d| boot_entry_from_deployment(sysroot, d))
.transpose()
.context("Booted deployment")?;
let rollback = deployments.rollback
.as_ref()
.map(|d| boot_entry_from_deployment(sysroot, d))
.transpose()
.context("Rollback deployment")?;
// 10. Create host specification
let spec = staged
.as_ref()
.or(booted.as_ref())
.and_then(|entry| entry.image.as_ref())
.map(|img| HostSpec {
image: Some(img.image.clone()),
boot_order,
})
.unwrap_or_default();
// 11. Determine host type
let ty = if booted
.as_ref()
.map(|b| b.image.is_some())
.unwrap_or_default()
{
Some(HostType::BootcHost)
} else {
None
};
// 12. Create host status
let mut host = Host::new(spec);
host.status = HostStatus {
staged,
booted,
rollback,
other_deployments: other_deployments,
rollback_queued,
ty,
};
Ok((deployments, host))
}
Data Structures
1. Host Structure
pub struct Host {
pub resource: k8sapitypes::Resource,
pub spec: HostSpec,
pub status: HostStatus,
}
2. Host Specification
pub struct HostSpec {
pub image: Option<ImageReference>,
pub boot_order: BootOrder,
}
3. Host Status
pub struct HostStatus {
pub staged: Option<BootEntry>,
pub booted: Option<BootEntry>,
pub rollback: Option<BootEntry>,
pub other_deployments: Vec<BootEntry>,
pub rollback_queued: bool,
pub ty: Option<HostType>,
}
4. Boot Entry
pub struct BootEntry {
pub deployment: DeploymentInfo,
pub image: Option<ImageStatus>,
}
5. Image Status
pub struct ImageStatus {
pub image: ImageReference,
pub version: Option<String>,
pub timestamp: Option<chrono::DateTime<chrono::Utc>>,
pub image_digest: String,
pub architecture: String,
}
Output Formats
1. Human Readable Format
Default for terminal output
System is deployed via bootc.
Image: quay.io/myorg/debian-bootc:v2.0
Version: 2.0.0
Digest: sha256:abc123def456...
Architecture: x86_64
Boot Order: Default
Rollback Queued: false
Deployments:
Staged: None
Booted: quay.io/myorg/debian-bootc:v2.0
Rollback: quay.io/myorg/debian-bootc:v1.0
2. YAML Format
Default for non-terminal output
apiVersion: v1
kind: Host
metadata:
name: localhost
spec:
image:
image: quay.io/myorg/debian-bootc:v2.0
transport: registry
bootOrder: Default
status:
staged: null
booted:
deployment:
id: abc123def456...
osname: debian-bootc
checksum: def456ghi789...
image:
image:
image: quay.io/myorg/debian-bootc:v2.0
transport: registry
version: "2.0.0"
timestamp: "2024-01-15T10:30:00Z"
imageDigest: sha256:abc123def456...
architecture: x86_64
rollback:
deployment:
id: def456ghi789...
osname: debian-bootc
checksum: ghi789jkl012...
image:
image:
image: quay.io/myorg/debian-bootc:v1.0
transport: registry
version: "1.0.0"
timestamp: "2024-01-10T15:45:00Z"
imageDigest: sha256:def456ghi789...
architecture: x86_64
otherDeployments: []
rollbackQueued: false
ty: BootcHost
3. JSON Format
For programmatic access
{
"apiVersion": "v1",
"kind": "Host",
"metadata": {
"name": "localhost"
},
"spec": {
"image": {
"image": "quay.io/myorg/debian-bootc:v2.0",
"transport": "registry"
},
"bootOrder": "Default"
},
"status": {
"staged": null,
"booted": {
"deployment": {
"id": "abc123def456...",
"osname": "debian-bootc",
"checksum": "def456ghi789..."
},
"image": {
"image": {
"image": "quay.io/myorg/debian-bootc:v2.0",
"transport": "registry"
},
"version": "2.0.0",
"timestamp": "2024-01-15T10:30:00Z",
"imageDigest": "sha256:abc123def456...",
"architecture": "x86_64"
}
},
"rollback": {
"deployment": {
"id": "def456ghi789...",
"osname": "debian-bootc",
"checksum": "ghi789jkl012..."
},
"image": {
"image": {
"image": "quay.io/myorg/debian-bootc:v1.0",
"transport": "registry"
},
"version": "1.0.0",
"timestamp": "2024-01-10T15:45:00Z",
"imageDigest": "sha256:def456ghi789...",
"architecture": "x86_64"
}
},
"otherDeployments": [],
"rollbackQueued": false,
"ty": "BootcHost"
}
}
Deployment Detection
1. OSTree Boot Detection
if !ostree_booted()? {
Default::default()
} else {
// Get system status
}
Purpose: Check if system is booted via OSTree Process: Verify OSTree boot environment
2. Deployment Partitioning
let (mut related_deployments, other_deployments) = sysroot
.deployments()
.into_iter()
.partition::<VecDeque<_>, _>(|d| Some(d.osname()) == stateroot);
Purpose: Separate related deployments from others Process: Filter deployments by stateroot name
3. Staged Deployment Detection
let staged = related_deployments
.iter()
.position(|d| d.is_staged())
.map(|i| related_deployments.remove(i).unwrap());
Purpose: Find staged deployment for next boot Process: Look for deployment marked as staged
4. Rollback Detection
let rollback = related_deployments.pop_front();
let rollback_queued = match (booted_deployment.as_ref(), rollback.as_ref()) {
(Some(booted), Some(rollback)) => rollback.index() < booted.index(),
_ => false,
};
Purpose: Determine rollback deployment and queued status Process: Check deployment order and indices
Boot Order Management
1. Boot Order States
let boot_order = if rollback_queued {
BootOrder::Rollback
} else {
BootOrder::Default
};
States:
- Default: Current deployment first, rollback second
- Rollback: Rollback deployment first, current second
2. Rollback Queued Detection
let rollback_queued = match (booted_deployment.as_ref(), rollback.as_ref()) {
(Some(booted), Some(rollback)) => rollback.index() < booted.index(),
_ => false,
};
Purpose: Determine if rollback is queued for next boot Process: Compare deployment indices
Image Information Extraction
1. Image Status Creation
fn create_imagestatus(
image: ImageReference,
manifest_digest: &Digest,
config: &ImageConfiguration,
) -> ImageStatus {
let labels = labels_of_config(config);
let timestamp = labels
.and_then(|l| {
l.get(oci_spec::image::ANNOTATION_CREATED)
.map(|s| s.as_str())
})
.and_then(|s| chrono::DateTime::parse_from_rfc3339(s).ok())
.map(|dt| dt.with_timezone(&chrono::Utc));
let architecture = config.architecture().unwrap_or("unknown").to_string();
ImageStatus {
image,
version: labels.and_then(|l| l.get("version").cloned()),
timestamp,
image_digest: manifest_digest.to_string(),
architecture,
}
}
Purpose: Extract image metadata and configuration Process: Parse OCI image configuration and labels
2. Boot Entry Creation
fn boot_entry_from_deployment(
sysroot: &SysrootLock,
deployment: &ostree::Deployment,
) -> Result<BootEntry> {
let deployment_info = DeploymentInfo {
id: deployment.csum().to_string(),
osname: deployment.osname().to_string(),
checksum: deployment.csum().to_string(),
};
let image = if let Ok(origin) = deployment.origin() {
if let Some(refspec) = origin.optional_string("origin", "refspec")? {
if let Ok(ostree_ref) = ostree::parse_refspec(&refspec) {
if let Ok(image_ref) = ostree_container::OstreeImageReference::try_from(ostree_ref) {
let image_ref = ImageReference::from(image_ref);
let repo = &sysroot.repo();
let imgstate = ostree_container::store::query_image_commit(repo, &deployment.csum())?;
let cached = imgstate.cached_update
.map(|cached| create_imagestatus(image_ref, &cached.manifest_digest, &cached.config));
cached
} else {
None
}
} else {
None
}
} else {
None
}
} else {
None
};
Ok(BootEntry {
deployment: deployment_info,
image,
})
}
Purpose: Create boot entry from OSTree deployment Process: Extract deployment info and image metadata
Format Detection
1. Automatic Format Selection
let legacy_opt = if opts.json {
OutputFormat::Json
} else if std::io::stdout().is_terminal() {
OutputFormat::HumanReadable
} else {
OutputFormat::Yaml
};
Logic:
- JSON: If
--jsonflag specified - Human Readable: If output is a terminal
- YAML: If output is not a terminal
2. Format Version Support
match opts.format_version.unwrap_or_default() {
0 | 1 => {} // Both 0 and 1 mean "v1"
o => anyhow::bail!("Unsupported format version: {o}"),
};
Purpose: Support multiple format versions Current: Version 1 (exposed as both 0 and 1)
Filtering Options
1. Booted Deployment Filter
if opts.booted {
host.filter_to_slot(Slot::Booted);
}
Purpose: Show only booted deployment information Use Case: Focus on current deployment
2. Verbose Output
human_readable_output(&mut out, &host, opts.verbose)
Purpose: Include additional fields in human readable format Use Case: Detailed troubleshooting information
Error Handling
1. OSTree Boot Detection Errors
if !ostree_booted()? {
Default::default()
}
Error: System not booted via OSTree Response: Return default empty status
2. Deployment Access Errors
let (_deployments, host) = get_status(&ostree, booted_deployment.as_ref())?;
Error: Cannot access deployments Response: Propagate error up the call stack
3. Format Version Errors
match opts.format_version.unwrap_or_default() {
0 | 1 => {}
o => anyhow::bail!("Unsupported format version: {o}"),
};
Error: Unsupported format version Response: Return error with message
Usage Patterns
1. Interactive Use
# Check system status
bootc status
# Check with verbose output
bootc status --verbose
# Check only booted deployment
bootc status --booted
2. Programmatic Use
# Get JSON output for parsing
bootc status --format=json
# Get YAML output for parsing
bootc status --format=yaml
# Check if system is bootc compatible
bootc status --format=json | jq '.status.booted != null'
3. Automation Scripts
#!/bin/bash
# Check if rollback is queued
if bootc status --format=json | jq -r '.status.rollbackQueued' | grep -q true; then
echo "Rollback is queued for next boot"
fi
# Get current image version
CURRENT_VERSION=$(bootc status --format=json | jq -r '.status.booted.image.version // "unknown"')
echo "Current version: $CURRENT_VERSION"
Integration with Other Commands
1. Relationship to bootc upgrade
Status Before Upgrade:
bootc status
bootc upgrade --apply
bootc status
Status After Upgrade:
- Shows new staged deployment
- Shows updated booted deployment
- Shows previous deployment as rollback
2. Relationship to bootc switch
Status Before Switch:
bootc status
bootc switch quay.io/myorg/debian-bootc:v2.0
bootc status
Status After Switch:
- Shows new image reference
- Shows staged deployment
- Shows updated boot order
3. Relationship to bootc rollback
Status Before Rollback:
bootc status
bootc rollback
bootc status
Status After Rollback:
- Shows rollback queued status
- Shows updated boot order
- Shows deployment reordering
Troubleshooting
1. Common Issues
System Not Bootc Compatible
# Check if system is bootc compatible
bootc status --format=json | jq '.status.booted != null'
# Check OSTree status
ostree admin status
No Deployments Found
# Check deployment status
ostree admin status
# Check system logs
journalctl -u bootc-fetch-apply-updates.service
Format Parsing Errors
# Use specific format
bootc status --format=json
# Check format version
bootc status --format-version=1
2. Debug Commands
# Enable debug logging
RUST_LOG=debug bootc status
# Check system logs
journalctl -u bootc-fetch-apply-updates.service
# Check OSTree status
ostree admin status --verbose
Best Practices
1. Programmatic Usage
- Use JSON/YAML: For programmatic parsing
- Check Format Version: Specify format version explicitly
- Handle Errors: Check for null values and errors
- Validate Output: Verify expected fields exist
2. Interactive Usage
- Use Human Readable: For interactive use
- Use Verbose: For detailed information
- Check Booted: Focus on current deployment
- Monitor Changes: Track status over time
3. Automation
- Parse JSON: Use
jqfor JSON parsing - Check Compatibility: Verify bootc compatibility
- Monitor Status: Track deployment changes
- Handle Errors: Implement proper error handling
Future Enhancements
1. Planned Features
- Additional Formats: Support for more output formats
- Filtering Options: More granular filtering
- Status History: Track status changes over time
- Health Checks: Include system health information
2. Integration Improvements
- API Support: REST API for status queries
- Web Interface: Web-based status display
- Monitoring Integration: Integration with monitoring systems
- Alerting: Status-based alerting
This technical guide provides comprehensive understanding of the bootc status system's architecture, implementation, and usage patterns.