- 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
16 KiB
bootc switch - Technical Guide
Overview
bootc switch is a command for changing the container image reference that a bootc-managed system will boot from. It operates similarly to bootc upgrade but changes the image source rather than updating the current image. This enables blue/green deployments, A/B testing, and controlled rollouts across different image versions.
Purpose
The switch command serves several critical functions:
- Image Source Management: Change the container image reference for future boots
- Blue/Green Deployments: Switch between different image versions
- A/B Testing: Test different image versions on different systems
- Controlled Rollouts: Gradually migrate systems to new image versions
- Rollback Capability: Switch back to previous image versions
Command Syntax
bootc switch [OPTIONS...] <TARGET>
Basic Usage
# Switch to different image version
bootc switch quay.io/myorg/debian-bootc:v2.0
# Switch and apply immediately
bootc switch --apply quay.io/myorg/debian-bootc:v2.0
# Switch with soft reboot
bootc switch --apply --soft-reboot=auto quay.io/myorg/debian-bootc:v2.0
# Switch with specific transport
bootc switch --transport=oci-archive quay.io/myorg/debian-bootc:v2.0
Command Options
Core Options
| Option | Description | Default | Required |
|---|---|---|---|
TARGET |
Target image to use for next boot | None |
Yes |
--apply |
Restart/reboot into new target image | false |
No |
--quiet |
Don't display progress | false |
No |
--soft-reboot |
Configure soft reboot behavior | None |
No |
Transport Options
| Option | Description | Default | Values |
|---|---|---|---|
--transport |
Container transport type | registry |
registry, oci, oci-archive, containers-storage |
Security Options
| Option | Description | Default |
|---|---|---|
--enforce-container-sigpolicy |
Enforce container signature policy | false |
Advanced Options
| Option | Description | Default |
|---|---|---|
--retain |
Retain reference to currently booted image | false |
Architecture Overview
1. Switch Command Structure
pub(crate) struct SwitchOpts {
pub(crate) quiet: bool, // Suppress progress output
pub(crate) apply: bool, // Apply and reboot
pub(crate) soft_reboot: Option<SoftRebootMode>, // Soft reboot behavior
pub(crate) transport: String, // Container transport
pub(crate) enforce_container_sigpolicy: bool, // Signature enforcement
pub(crate) retain: bool, // Retain current image ref
pub(crate) mutate_in_place: bool, // In-place mutation (hidden)
pub(crate) progress: ProgressOptions, // Progress reporting
}
2. Switch Process Flow
async fn switch(opts: SwitchOpts) -> Result<()> {
// 1. Parse and validate target image
let transport = ostree_container::Transport::try_from(opts.transport.as_str())?;
let imgref = ostree_container::ImageReference {
transport,
name: opts.target.to_string(),
};
let sigverify = sigpolicy_from_opt(opts.enforce_container_sigpolicy);
let target = ostree_container::OstreeImageReference { sigverify, imgref };
let target = ImageReference::from(target);
// 2. Handle in-place mutation (hidden option)
if opts.mutate_in_place {
let deployid = switch_origin_inplace(&root, &target).await?;
println!("Updated {deployid} to pull from {target}");
return Ok(());
}
// 3. Get system status
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)?;
// 4. Create new specification
let new_spec = {
let mut new_spec = host.spec.clone();
new_spec.image = Some(target.clone());
new_spec
};
// 5. Check for changes
if new_spec == host.spec {
println!("Image specification is unchanged.");
return Ok(());
}
// 6. Log switch operation
tracing::info!(
message_id = SWITCH_JOURNAL_ID,
bootc.old_image_reference = old_image,
bootc.new_image_reference = &target.image,
"Switching from image {} to {}",
old_image, target.image
);
// 7. Pull and stage new image
let fetched = crate::deploy::pull(repo, &target, None, opts.quiet, prog.clone()).await?;
// 8. Handle image retention
if !opts.retain {
// Prune previous ostree ref
if let Some(booted_origin) = booted_deployment.origin() {
if let Some(ostree_ref) = booted_origin.optional_string("origin", "refspec")? {
let (remote, ostree_ref) = ostree::parse_refspec(&ostree_ref)?;
repo.set_ref_immediate(remote.as_deref(), &ostree_ref, None, cancellable)?;
}
}
}
// 9. Stage new deployment
let stateroot = booted_deployment.osname();
crate::deploy::stage(sysroot, &stateroot, &fetched, &new_spec, prog.clone()).await?;
// 10. Update system status
sysroot.update_mtime()?;
// 11. Handle soft reboot
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)?;
}
// 12. Apply changes if requested
if opts.apply {
crate::reboot::reboot()?;
}
Ok(())
}
Image Reference Handling
1. Transport Types
The switch command supports multiple container transport types:
Registry Transport (default)
bootc switch quay.io/myorg/debian-bootc:v2.0
OCI Archive Transport
bootc switch --transport=oci-archive /path/to/image.tar
OCI Transport
bootc switch --transport=oci oci:quay.io/myorg/debian-bootc:v2.0
Containers Storage Transport
bootc switch --transport=containers-storage containers-storage:quay.io/myorg/debian-bootc:v2.0
2. Image Reference Parsing
let transport = ostree_container::Transport::try_from(opts.transport.as_str())?;
let imgref = ostree_container::ImageReference {
transport,
name: opts.target.to_string(),
};
let sigverify = sigpolicy_from_opt(opts.enforce_container_sigpolicy);
let target = ostree_container::OstreeImageReference { sigverify, imgref };
Process:
- Transport Parsing: Convert string to transport enum
- Image Reference: Create container image reference
- Signature Verification: Configure signature policy
- OSTree Reference: Convert to OSTree image reference
In-Place Mutation
1. In-Place Switch Implementation
pub(crate) fn switch_origin_inplace(root: &Dir, imgref: &ImageReference) -> Result<String> {
const SWITCH_INPLACE_JOURNAL_ID: &str = "3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7";
tracing::info!(
message_id = SWITCH_INPLACE_JOURNAL_ID,
bootc.image.reference = &imgref.image,
bootc.image.transport = &imgref.transport,
bootc.switch_type = "in_place",
"Performing in-place switch to image: {}",
imgref
);
// Find deployment directory
let deploy_dir = find_deployment_directory(root)?;
// Update origin file
let origin_path = deploy_dir.join("origin");
let mut origin = std::fs::read_to_string(&origin_path)?;
// Update image reference in origin
update_origin_image_reference(&mut origin, imgref)?;
// Write updated origin
std::fs::write(&origin_path, origin)?;
// Extract deployment ID
let deploy_id = extract_deployment_id(&deploy_dir)?;
Ok(deploy_id)
}
Purpose: Directly modify the booted deployment's origin file Use Cases:
- Anaconda %post scripts
- System installation scenarios
- Emergency image switching
State Management
1. Specification Updates
let new_spec = {
let mut new_spec = host.spec.clone();
new_spec.image = Some(target.clone());
new_spec
};
Process:
- Clone Current Spec: Copy existing host specification
- Update Image Reference: Set new target image
- Preserve Other Settings: Keep boot order and other settings
2. Change Detection
if new_spec == host.spec {
println!("Image specification is unchanged.");
return Ok(());
}
Purpose: Avoid unnecessary operations when no changes are made Benefits: Performance optimization, clear user feedback
3. Image Retention
if !opts.retain {
// Prune previous ostree ref
if let Some(booted_origin) = booted_deployment.origin() {
if let Some(ostree_ref) = booted_origin.optional_string("origin", "refspec")? {
let (remote, ostree_ref) = ostree::parse_refspec(&ostree_ref)?;
repo.set_ref_immediate(remote.as_deref(), &ostree_ref, None, cancellable)?;
}
}
}
Purpose: Manage OSTree references for disk space optimization Behavior:
- Default: Remove previous image reference
- With
--retain: Keep previous image reference
Logging and Monitoring
1. Switch Operation Logging
const SWITCH_JOURNAL_ID: &str = "7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1";
tracing::info!(
message_id = SWITCH_JOURNAL_ID,
bootc.old_image_reference = old_image,
bootc.new_image_reference = &target.image,
bootc.new_image_transport = &target.transport,
"Switching from image {} to {}",
old_image, target.image
);
Purpose: Track image switching operations Fields:
message_id: Unique identifier for switch operationsbootc.old_image_reference: Previous image referencebootc.new_image_reference: New image referencebootc.new_image_transport: Transport type used
2. In-Place Switch Logging
const SWITCH_INPLACE_JOURNAL_ID: &str = "3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7";
tracing::info!(
message_id = SWITCH_INPLACE_JOURNAL_ID,
bootc.image.reference = &imgref.image,
bootc.image.transport = &imgref.transport,
bootc.switch_type = "in_place",
"Performing in-place switch to image: {}",
imgref
);
Purpose: Track in-place switch operations Fields:
message_id: Unique identifier for in-place switchesbootc.image.reference: Target image referencebootc.image.transport: Transport type usedbootc.switch_type: Operation type identifier
Usage Patterns
1. Blue/Green Deployments
# Deploy to green environment
bootc switch quay.io/myorg/debian-bootc:green
# Switch back to blue if needed
bootc switch quay.io/myorg/debian-bootc:blue
2. A/B Testing
# Switch subset of systems to version B
bootc switch quay.io/myorg/debian-bootc:v2.0-beta
# Monitor and switch back if issues
bootc switch quay.io/myorg/debian-bootc:v1.0-stable
3. Controlled Rollouts
# Switch to new version
bootc switch quay.io/myorg/debian-bootc:v2.0
# Apply immediately
bootc switch --apply quay.io/myorg/debian-bootc:v2.0
# Apply with soft reboot
bootc switch --apply --soft-reboot=auto quay.io/myorg/debian-bootc:v2.0
4. Emergency Rollbacks
# Quick rollback to previous version
bootc switch quay.io/myorg/debian-bootc:v1.0 --apply
# Rollback with retention
bootc switch --retain quay.io/myorg/debian-bootc:v1.0
Integration with Other Commands
1. Relationship to bootc upgrade
Similarities:
- Both pull and stage container images
- Both support
--applyand--soft-rebootoptions - Both use the same deployment staging process
Differences:
upgrade: Updates current image to newer versionswitch: Changes image source to different image
2. Relationship to bootc rollback
Complementary:
switch: Change to different image versionrollback: Revert to previous deployment
Usage:
# Switch to new version
bootc switch quay.io/myorg/debian-bootc:v2.0
# If issues, rollback
bootc rollback
3. Relationship to bootc status
Status Display:
# Check current status
bootc status
# Switch to new image
bootc switch quay.io/myorg/debian-bootc:v2.0
# Check updated status
bootc status
Error Handling
1. Image Validation Errors
// Invalid transport
Error: Invalid transport type 'invalid'
// Image not found
Error: Image not found in registry
// Signature verification failed
Error: Signature verification failed
2. System State Errors
// System not bootc compatible
Error: System is not bootc compatible
// No changes detected
Image specification is unchanged.
// Deployment not found
Error: No deployment directory found
3. Network and Registry Errors
// Registry connectivity
Error: Failed to connect to registry
// Authentication failed
Error: Authentication failed
// Image pull failed
Error: Failed to pull image
Security Considerations
1. Signature Verification
# Enforce signature policy
bootc switch --enforce-container-sigpolicy quay.io/myorg/debian-bootc:v2.0
Purpose: Ensure image authenticity and integrity
Requirements: Valid signature policy in /etc/containers/policy.json
2. Transport Security
Registry Transport: Uses HTTPS and authentication OCI Archive: Local file system access Containers Storage: Local container storage
3. Image Validation
- Schema Validation: Validates image configuration
- Compatibility Check: Ensures image is bootc-compatible
- Signature Verification: Validates image signatures
Performance Considerations
1. Image Pulling
- Layer Caching: Reuses existing layers when possible
- Incremental Updates: Only downloads changed layers
- Parallel Downloads: Downloads layers in parallel
2. Staging Process
- Atomic Staging: All-or-nothing staging process
- Rollback Capability: Maintains previous deployment
- Status Updates: Efficient status management
3. Disk Space Management
- Reference Pruning: Removes old image references by default
- Retention Option: Keep references with
--retain - Cleanup: Automatic cleanup of unused layers
Troubleshooting
1. Common Issues
Image Not Found
# Check image exists
podman pull quay.io/myorg/debian-bootc:v2.0
# Check registry connectivity
curl -I https://quay.io/v2/
Signature Verification Failed
# Check signature policy
cat /etc/containers/policy.json
# Verify image signatures
podman inspect quay.io/myorg/debian-bootc:v2.0
System Not Compatible
# Check system status
bootc status
# Check bootc compatibility
bootc status --json | jq '.status.booted'
2. Debug Commands
# Enable debug logging
RUST_LOG=debug bootc switch quay.io/myorg/debian-bootc:v2.0
# Check system logs
journalctl -u bootc-fetch-apply-updates.service
# Verify image
podman inspect quay.io/myorg/debian-bootc:v2.0
Best Practices
1. Image Management
- Use Semantic Versioning: Clear version numbering
- Test Before Switch: Validate images in staging
- Monitor After Switch: Watch for issues post-switch
- Keep Rollback Ready: Maintain previous versions
2. Deployment Strategy
- Blue/Green: Use different image tags
- Canary Deployments: Gradual rollout
- A/B Testing: Compare different versions
- Emergency Procedures: Quick rollback capability
3. Monitoring and Logging
- Track Switch Operations: Monitor journal logs
- Set Up Alerts: Notify on switch failures
- Monitor System Health: Watch for issues
- Document Changes: Keep change records
Future Enhancements
1. Planned Features
- Userspace Restart: For kernel-unchanged switches
- Rollback Automation: Automatic rollback on failure
- Switch Scheduling: Time-based switching
- Health Checks: Pre/post switch validation
2. Integration Improvements
- API Support: REST API for switching
- Web Interface: Web-based image management
- Configuration Management: Declarative switching
- Audit Logging: Comprehensive audit trails
This technical guide provides comprehensive understanding of the bootc switch system's architecture, implementation, and usage patterns.