bootc-docs/edit/bootc-edit-technical-guide.md
robojerk 526f1c1afd Initial commit: Comprehensive Debian bootc documentation
- 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
2025-09-15 14:02:28 -07:00

12 KiB

bootc edit - Technical Guide

Overview

bootc edit is a declarative configuration management command that allows users to modify the host specification of a bootc-managed system. It operates similarly to kubectl apply, providing both interactive and programmatic interfaces for system configuration changes.

Purpose

The edit command serves several critical functions:

  1. Declarative Configuration: Apply changes to system configuration declaratively
  2. Interactive Editing: Use system editor for interactive configuration changes
  3. Programmatic Interface: Apply configuration from files for automation
  4. State Management: Maintain system state consistency across changes
  5. Validation: Ensure configuration changes are valid and safe

Command Syntax

bootc edit [OPTIONS...]

Basic Usage

# Interactive editing (opens in $EDITOR)
bootc edit

# Edit from file
bootc edit --filename /path/to/config.yaml

# Quiet mode (no progress output)
bootc edit --quiet

Command Options

Option Description Default Required
-f, --filename Use filename to edit system specification None No
--quiet Don't display progress false No

Architecture Overview

1. Configuration Structure

The bootc edit system operates on a Host structure that contains:

pub struct Host {
    pub resource: k8sapitypes::Resource,  // Kubernetes-style metadata
    pub spec: HostSpec,                   // Host specification
    pub status: HostStatus,               // Current system status
}

2. Host Specification

The HostSpec contains the editable configuration:

pub struct HostSpec {
    pub image: Option<ImageReference>,    // Container image reference
    pub boot_order: BootOrder,           // Boot ordering configuration
}

3. Supported Changes

Only changes to the spec section are honored:

  • Image Reference: Change the container image source
  • Boot Order: Modify boot ordering (rollback configuration)

Technical Implementation

1. Edit Command Structure

pub(crate) struct EditOpts {
    pub(crate) filename: Option<String>,  // Optional file input
    pub(crate) quiet: bool,              // Progress suppression
}

2. Edit Process Flow

async fn edit(opts: EditOpts) -> Result<()> {
    // 1. Get system storage and OSTree
    let sysroot = &get_storage().await?;
    let ostree = sysroot.get_ostree()?;
    let repo = &ostree.repo();
    
    // 2. Get current system status
    let (booted_deployment, _deployments, host) = 
        crate::status::get_status_require_booted(ostree)?;
    
    // 3. Load new configuration
    let new_host: Host = if let Some(filename) = opts.filename {
        // Load from file
        let mut r = std::io::BufReader::new(std::fs::File::open(filename)?);
        serde_yaml::from_reader(&mut r)?
    } else {
        // Interactive editing
        let tmpf = tempfile::NamedTempFile::new()?;
        serde_yaml::to_writer(std::io::BufWriter::new(tmpf.as_file()), &host)?;
        crate::utils::spawn_editor(&tmpf)?;
        tmpf.as_file().seek(std::io::SeekFrom::Start(0))?;
        serde_yaml::from_reader(&mut tmpf.as_file())?
    };
    
    // 4. Validate changes
    if new_host.spec == host.spec {
        println!("Edit cancelled, no changes made.");
        return Ok(());
    }
    
    // 5. Verify transition
    host.spec.verify_transition(&new_host.spec)?;
    let new_spec = RequiredHostSpec::from_spec(&new_host.spec)?;
    
    // 6. Apply changes
    if host.spec.boot_order != new_host.spec.boot_order {
        return crate::deploy::rollback(sysroot).await;
    }
    
    // 7. Pull and stage new image
    let fetched = crate::deploy::pull(repo, new_spec.image, None, opts.quiet, prog.clone()).await?;
    let stateroot = booted_deployment.osname();
    crate::deploy::stage(sysroot, &stateroot, &fetched, &new_spec, prog.clone()).await?;
    
    // 8. Update system
    sysroot.update_mtime()?;
    
    Ok(())
}

3. Editor Integration

The system supports multiple editors through the spawn_editor function:

pub(crate) fn spawn_editor(tmpf: &tempfile::NamedTempFile) -> Result<()> {
    let editor_variables = ["EDITOR"];
    let backup_editors = ["nano", "vim", "vi"];
    
    let editor = editor_variables.into_iter().find_map(std::env::var_os);
    let editor = if let Some(e) = editor.as_ref() {
        e.to_str()
    } else {
        backup_editors
            .into_iter()
            .find(|v| std::path::Path::new("/usr/bin").join(v).exists())
    };
    
    let editor = editor.ok_or_else(|| anyhow::anyhow!("$EDITOR is unset, and no backup editor found"))?;
    let mut editor_args = editor.split_ascii_whitespace();
    let argv0 = editor_args.next().ok_or_else(|| anyhow::anyhow!("Invalid editor: {editor}"))?;
    
    Command::new(argv0)
        .args(editor_args)
        .arg(tmpf.path())
        .lifecycle_bind()
        .run_inherited()
        .with_context(|| format!("Invoking editor {editor} failed"))
}

Configuration Format

1. YAML Structure

The configuration is stored in YAML format with the following structure:

apiVersion: v1
kind: Host
metadata:
  name: localhost
  namespace: default
spec:
  image: quay.io/myorg/debian-bootc:latest
  bootOrder: "normal"  # or "rollback"
status:
  staged: null
  booted:
    image: quay.io/myorg/debian-bootc:v1.0.0
    digest: sha256:abc123...
    version: "1.0.0"
  rollback:
    image: quay.io/myorg/debian-bootc:v0.9.0
    digest: sha256:def456...
    version: "0.9.0"
  rollbackQueued: false
  otherDeployments: []

2. Image Reference Format

spec:
  image:
    transport: "registry"
    name: "quay.io/myorg/debian-bootc"
    tag: "latest"
    # or
    digest: "sha256:abc123..."

3. Boot Order Options

spec:
  bootOrder: "normal"    # Normal boot order
  # or
  bootOrder: "rollback"  # Rollback to previous deployment

Usage Patterns

1. Interactive Editing

# Set editor environment variable
export EDITOR=vim

# Edit configuration interactively
bootc edit

Process:

  1. Current configuration is written to temporary file
  2. System editor is launched with temporary file
  3. User makes changes and saves
  4. Changes are validated and applied

2. File-Based Editing

# Create configuration file
cat > config.yaml << EOF
apiVersion: v1
kind: Host
metadata:
  name: localhost
spec:
  image: quay.io/myorg/debian-bootc:v2.0.0
  bootOrder: "normal"
EOF

# Apply configuration
bootc edit --filename config.yaml

Process:

  1. Configuration is loaded from file
  2. Changes are validated
  3. Configuration is applied to system

3. Image Switching

# Switch to different image
bootc edit --filename - << EOF
apiVersion: v1
kind: Host
metadata:
  name: localhost
spec:
  image: quay.io/myorg/debian-bootc:v2.0.0
EOF

4. Rollback Configuration

# Configure rollback
bootc edit --filename - << EOF
apiVersion: v1
kind: Host
metadata:
  name: localhost
spec:
  image: quay.io/myorg/debian-bootc:latest
  bootOrder: "rollback"
EOF

State Transitions

1. Image Changes

When the image reference changes:

  1. Validation: Verify new image exists and is accessible
  2. Download: Pull new container image from registry
  3. Staging: Stage new image for next boot
  4. Status Update: Update system status

2. Boot Order Changes

When boot order changes:

  1. Validation: Verify rollback deployment exists
  2. Rollback: Execute rollback operation
  3. Status Update: Update boot order configuration

3. No Changes

When no changes are detected:

  1. Message: Display "Edit cancelled, no changes made"
  2. Exit: Return without making changes

Error Handling

1. Editor Errors

// Editor not found
$EDITOR is unset, and no backup editor found

// Editor execution failed
Invoking editor vim failed

2. Configuration Errors

// Invalid YAML
Error parsing YAML: invalid syntax

// Invalid configuration
Error: invalid host specification

3. System Errors

// System not bootc compatible
Error: system is not bootc compatible

// Image not found
Error: image not found in registry

Integration Points

1. OSTree Integration

  • Deployment Management: Uses OSTree for deployment operations
  • Status Queries: Queries OSTree for current system state
  • Staging: Uses OSTree staging for new deployments

2. Container Registry Integration

  • Image Pulling: Uses container registry for image downloads
  • Authentication: Supports registry authentication
  • Signature Verification: Validates image signatures

3. Systemd Integration

  • Service Management: Coordinates with systemd services
  • Status Updates: Updates system status through systemd

Security Considerations

1. Configuration Validation

  • Schema Validation: Validates configuration against schema
  • Transition Validation: Ensures safe state transitions
  • Image Verification: Verifies image signatures and authenticity

2. Editor Security

  • Editor Selection: Uses secure editor selection process
  • Temporary Files: Uses secure temporary file handling
  • Process Isolation: Isolates editor process execution

3. System Security

  • Privilege Escalation: Requires appropriate privileges
  • State Consistency: Maintains system state consistency
  • Rollback Safety: Ensures safe rollback operations

Performance Considerations

1. Configuration Loading

  • File I/O: Efficient file reading and writing
  • Memory Usage: Minimal memory footprint for configuration
  • Parsing: Fast YAML parsing and validation

2. Editor Launch

  • Process Spawning: Efficient editor process creation
  • Temporary Files: Fast temporary file operations
  • Editor Detection: Quick editor availability checking

3. System Updates

  • Incremental Updates: Only updates changed components
  • Status Caching: Caches system status for performance
  • Validation Caching: Caches validation results

Troubleshooting

1. Editor Issues

# Check editor availability
which vim nano vi

# Set editor explicitly
export EDITOR=/usr/bin/vim
bootc edit

2. Configuration Issues

# Validate YAML syntax
yaml-lint config.yaml

# Check configuration schema
bootc edit --filename config.yaml --dry-run

3. System Issues

# Check system status
bootc status

# Check system compatibility
bootc status --json | jq '.status.booted'

Best Practices

1. Configuration Management

  • Version Control: Store configurations in version control
  • Validation: Validate configurations before applying
  • Backup: Backup current configuration before changes
  • Testing: Test configurations in staging environment

2. Editor Usage

  • Editor Selection: Use reliable editors (vim, nano)
  • Environment Variables: Set EDITOR environment variable
  • Backup Editors: Ensure backup editors are available
  • Editor Configuration: Configure editor for YAML editing

3. System Integration

  • Automation: Use file-based editing for automation
  • Monitoring: Monitor system status after changes
  • Rollback: Test rollback procedures regularly
  • Documentation: Document configuration changes

Future Enhancements

1. Planned Features

  • Dry Run Mode: Preview changes without applying
  • Configuration Templates: Predefined configuration templates
  • Validation Rules: Custom validation rules
  • Change Tracking: Track configuration changes over time

2. Integration Improvements

  • API Support: REST API for configuration management
  • Web Interface: Web-based configuration editor
  • Configuration Sync: Synchronize configurations across systems
  • Audit Logging: Comprehensive audit logging

This technical guide provides comprehensive understanding of the bootc edit system's architecture, implementation, and usage patterns.