# bootc container lint - Comprehensive Guide ## Overview `bootc container lint` is a static analysis tool that performs comprehensive checks on bootc-compatible container images during the build process. It validates that container images meet the requirements for successful bootc installation and runtime operation. ## Purpose The lint tool serves several critical purposes: 1. **Build-time Validation**: Catch issues early in the container build process 2. **Compatibility Assurance**: Ensure images work correctly with bootc installation 3. **Best Practice Enforcement**: Promote proper container image construction 4. **Runtime Prevention**: Avoid installation failures and runtime issues ## Command Syntax ```bash bootc container lint [OPTIONS...] ``` ### Basic Usage ```bash # Lint current container image bootc container lint # Lint specific rootfs bootc container lint --rootfs /path/to/rootfs # List all available lints bootc container lint --list # Skip specific lints bootc container lint --skip var-log --skip buildah-injected # Make warnings fatal bootc container lint --fatal-warnings # Show full output (no truncation) bootc container lint --no-truncate ``` ## Lint Categories ### 1. Fatal Lints These lints **must** pass for the container to be installable. Failure will prevent bootc installation. #### var-run **Purpose**: Ensures `/var/run` is a symlink to `/run` **Check**: Verifies `/var/run` is not a physical directory **Rationale**: `/var/run` should always be a symlink to `/run` for proper systemd operation ```bash # This will fail: mkdir -p /var/run # This will pass: ln -sf /run /var/run ``` #### etc-usretc **Purpose**: Prevents both `/etc` and `/usr/etc` from existing **Check**: Ensures only `/etc` exists in container images **Rationale**: Having both causes undefined behavior; `/usr/etc` is a bootc implementation detail ```bash # This will fail: mkdir -p /etc /usr/etc # This will pass: mkdir -p /etc # OR mkdir -p /usr/etc ``` #### bootc-kargs **Purpose**: Validates kernel argument configuration files **Check**: Parses `/usr/lib/bootc/kargs.d/*.toml` files for syntax errors **Rationale**: Invalid kernel arguments will cause boot failures ```bash # Valid kargs.d file: echo '[kargs] append = ["console=ttyS0", "quiet"]' > /usr/lib/bootc/kargs.d/99-console.toml ``` #### kernel **Purpose**: Ensures exactly one kernel is present **Check**: Validates only one `/usr/lib/modules/$kver` directory exists **Rationale**: Multiple kernels cause ambiguity during boot ```bash # This will fail: mkdir -p /usr/lib/modules/5.4.0 /usr/lib/modules/6.1.0 # This will pass: mkdir -p /usr/lib/modules/6.1.0 ``` #### utf8 **Purpose**: Ensures all filenames and symlink targets are UTF-8 **Check**: Recursively validates filesystem entries **Rationale**: Non-UTF-8 names cause ostree backend failures ```bash # This will fail: touch "file\xffname" # This will pass: touch "filename" ``` #### api-base-directories **Purpose**: Verifies required API directories exist **Check**: Ensures `/dev`, `/proc`, `/sys`, `/run`, `/tmp`, `/var` exist as directories **Rationale**: These are required by systemd and Linux standards ```bash # Required directories: mkdir -p /dev /proc /sys /run /tmp /var ``` #### baseimage-root **Purpose**: Validates bootc-specific root filesystem structure **Check**: Ensures `/sysroot` exists and `/ostree` symlinks to `sysroot/ostree` **Rationale**: Required for proper bootc operation ```bash # Required structure: mkdir -p /sysroot/ostree ln -sf sysroot/ostree /ostree ``` ### 2. Warning Lints These lints indicate potential issues but don't prevent installation. #### buildah-injected **Purpose**: Detects empty files injected by container build systems **Check**: Looks for empty `/etc/hostname` or `/etc/resolv.conf` files **Rationale**: These files should contain actual content, not be empty placeholders ```bash # This will warn: touch /etc/hostname # This will pass: echo "myhostname" > /etc/hostname ``` #### baseimage-composefs **Purpose**: Recommends enabling composefs for ostree **Check**: Validates composefs configuration in `/usr/lib/ostree/prepare-root.conf` **Rationale**: Composefs improves performance and security ```bash # Enable composefs: echo '[composefs] enabled = true' > /usr/lib/ostree/prepare-root.conf ``` #### var-log **Purpose**: Warns about non-empty log files in `/var/log` **Check**: Identifies regular files with content in `/var/log` **Rationale**: Log files should be generated at runtime, not shipped in images ```bash # This will warn: echo "log content" > /var/log/app.log # This will pass: mkdir -p /var/log # OR ln -sf /dev/null /var/log/app.log ``` #### var-tmpfiles **Purpose**: Checks for missing systemd tmpfiles.d entries **Check**: Validates `/var` content has corresponding tmpfiles.d configuration **Rationale**: Ensures proper initialization across upgrades ```bash # Create tmpfiles.d entry: echo 'd /var/log/app 0755 root root -' > /usr/lib/tmpfiles.d/app.conf ``` #### sysusers **Purpose**: Validates user/group definitions have systemd sysusers.d entries **Check**: Ensures `/etc/passwd` and `/etc/group` entries have corresponding sysusers.d files **Rationale**: Prevents user/group drift across upgrades ```bash # Create sysusers.d entry: echo 'u app 1000 "Application User"' > /usr/lib/sysusers.d/app.conf ``` #### nonempty-boot **Purpose**: Warns about content in `/boot` directory **Check**: Ensures `/boot` is empty in container images **Rationale**: Kernel content should be in `/usr/lib/modules`, not `/boot` ```bash # This will warn: echo "content" > /boot/somefile # This will pass: mkdir -p /boot # Keep /boot empty ``` ## Integration with Container Builds ### Dockerfile Integration ```dockerfile FROM debian:forky-slim # Install bootc RUN apt update && apt install -y bootc && apt clean # ... your container setup ... # Lint the container image RUN bootc container lint # Continue with build... ``` ### Podman Build Integration ```bash # Build with linting podman build --tag my-bootc-image . # Or run lint separately podman run --rm my-bootc-image bootc container lint ``` ### CI/CD Integration ```yaml # GitHub Actions example - name: Lint bootc container run: | podman run --rm ${{ matrix.image }} bootc container lint --fatal-warnings ``` ## Advanced Usage ### Custom Root Filesystem ```bash # Lint specific rootfs bootc container lint --rootfs /path/to/rootfs ``` ### Selective Linting ```bash # Skip specific lints bootc container lint --skip var-log --skip buildah-injected # List available lints bootc container lint --list ``` ### Warning Management ```bash # Make warnings fatal (fail build on warnings) bootc container lint --fatal-warnings # Allow warnings but show full output bootc container lint --no-truncate ``` ## Common Issues and Solutions ### 1. /var/run Directory Issue **Problem**: `/var/run` exists as a directory instead of symlink **Solution**: ```bash rm -rf /var/run ln -sf /run /var/run ``` ### 2. Both /etc and /usr/etc Exist **Problem**: Container has both directories **Solution**: ```bash # Choose one approach: # Option 1: Use /etc only rm -rf /usr/etc # Option 2: Use /usr/etc only (not recommended) rm -rf /etc ``` ### 3. Multiple Kernels **Problem**: Multiple kernel versions present **Solution**: ```bash # Keep only one kernel rm -rf /usr/lib/modules/5.4.0 # Keep /usr/lib/modules/6.1.0 ``` ### 4. Non-UTF-8 Filenames **Problem**: Files with non-UTF-8 names **Solution**: ```bash # Find and rename files find / -name "*" -print0 | xargs -0 -I {} sh -c 'echo "Found: {}"' # Rename problematic files ``` ### 5. Missing API Directories **Problem**: Required directories missing **Solution**: ```bash mkdir -p /dev /proc /sys /run /tmp /var ``` ## Best Practices ### 1. Container Image Construction - Use minimal base images - Install only necessary packages - Clean up package caches - Avoid creating log files - Use symlinks for `/var/run` ### 2. User and Group Management - Use systemd sysusers.d for user/group definitions - Avoid direct `/etc/passwd` modifications - Use `DynamicUser=yes` in systemd services when possible ### 3. Filesystem Organization - Keep `/boot` empty - Use `/usr/lib/modules` for kernel content - Place configuration in `/usr` when possible - Use tmpfiles.d for runtime directory creation ### 4. Build Process - Run lint early in build process - Use `--fatal-warnings` in CI/CD - Fix issues immediately - Test with actual bootc installation ## Troubleshooting ### Debug Mode ```bash # Enable debug output RUST_LOG=debug bootc container lint ``` ### Verbose Output ```bash # Show all issues without truncation bootc container lint --no-truncate ``` ### Specific Lint Testing ```bash # Test specific lint bootc container lint --skip $(bootc container lint --list | grep -v var-run | awk '{print $1}' | tr '\n' ' ') ``` ## Integration with Other Tools ### Pre-commit Hooks ```bash #!/bin/bash # .git/hooks/pre-commit podman run --rm -v $(pwd):/workspace my-bootc-image bootc container lint --rootfs /workspace ``` ### Makefile Integration ```makefile lint: podman run --rm $(IMAGE) bootc container lint --fatal-warnings build: lint podman build --tag $(IMAGE) . ``` ### Docker Compose ```yaml version: '3' services: lint: image: my-bootc-image command: bootc container lint --fatal-warnings volumes: - .:/workspace working_dir: /workspace ``` ## Performance Considerations - Lint runs are relatively fast - Recursive checks (like UTF-8) may take longer on large filesystems - Use `--skip` to exclude expensive checks during development - Run full lint in CI/CD pipelines ## Future Enhancements - Additional security checks - Performance optimization suggestions - Integration with more container runtimes - Enhanced reporting formats - Custom lint rule support --- This comprehensive guide provides everything needed to effectively use `bootc container lint` for validating bootc-compatible container images.