bootc-docs/lint/bootc-lint-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

9.8 KiB

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

bootc container lint [OPTIONS...]

Basic Usage

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# 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

# This will warn:
echo "content" > /boot/somefile

# This will pass:
mkdir -p /boot
# Keep /boot empty

Integration with Container Builds

Dockerfile Integration

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

# 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

# GitHub Actions example
- name: Lint bootc container
  run: |
    podman run --rm ${{ matrix.image }} bootc container lint --fatal-warnings

Advanced Usage

Custom Root Filesystem

# Lint specific rootfs
bootc container lint --rootfs /path/to/rootfs

Selective Linting

# Skip specific lints
bootc container lint --skip var-log --skip buildah-injected

# List available lints
bootc container lint --list

Warning Management

# 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:

rm -rf /var/run
ln -sf /run /var/run

2. Both /etc and /usr/etc Exist

Problem: Container has both directories Solution:

# 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:

# 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:

# 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:

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

# Enable debug output
RUST_LOG=debug bootc container lint

Verbose Output

# Show all issues without truncation
bootc container lint --no-truncate

Specific Lint Testing

# 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

#!/bin/bash
# .git/hooks/pre-commit
podman run --rm -v $(pwd):/workspace my-bootc-image bootc container lint --rootfs /workspace

Makefile Integration

lint:
	podman run --rm $(IMAGE) bootc container lint --fatal-warnings

build: lint
	podman build --tag $(IMAGE) .

Docker Compose

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.