bootc-docs/lint/examples-and-troubleshooting.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 container lint - Examples and Troubleshooting

Practical Examples

1. Basic Container Image Linting

Minimal Working Example

FROM debian:bookworm-slim

# Install bootc
RUN apt update && apt install -y bootc && apt clean

# Create required API directories
RUN mkdir -p /dev /proc /sys /run /tmp /var

# Create proper /var/run symlink
RUN ln -sf /run /var/run

# Create /sysroot and /ostree structure
RUN mkdir -p /sysroot/ostree && ln -sf sysroot/ostree /ostree

# Create kernel structure
RUN mkdir -p /usr/lib/modules/6.1.0 && \
    echo "kernel" > /usr/lib/modules/6.1.0/vmlinuz

# Create empty /boot directory
RUN mkdir -p /boot

# Lint the container
RUN bootc container lint

Common Issues and Fixes

Issue: /var/run is a directory instead of symlink

# Problem
mkdir -p /var/run

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

Issue: Both /etc and /usr/etc exist

# Problem
mkdir -p /etc /usr/etc

# Fix (choose one)
rm -rf /usr/etc  # Keep /etc
# OR
rm -rf /etc      # Keep /usr/etc (not recommended)

Issue: Multiple kernels present

# Problem
mkdir -p /usr/lib/modules/5.4.0 /usr/lib/modules/6.1.0

# Fix
rm -rf /usr/lib/modules/5.4.0  # Keep only one

2. Advanced Container Configuration

Complete bootc-compatible Image

FROM debian:bookworm-slim

# Install bootc and dependencies
RUN apt update && \
    apt install -y bootc ostree systemd && \
    apt clean && \
    rm -rf /var/lib/apt/lists/*

# Create required API directories
RUN mkdir -p /dev /proc /sys /run /tmp /var

# Fix /var/run symlink
RUN ln -sf /run /var/run

# Create bootc-specific structure
RUN mkdir -p /sysroot/ostree && \
    ln -sf sysroot/ostree /ostree

# Create kernel structure
RUN mkdir -p /usr/lib/modules/6.1.0 && \
    echo "kernel" > /usr/lib/modules/6.1.0/vmlinuz && \
    echo "initramfs" > /usr/lib/modules/6.1.0/initramfs.img

# Create empty /boot directory
RUN mkdir -p /boot

# Configure composefs
RUN mkdir -p /usr/lib/ostree && \
    echo '[composefs]\nenabled = true' > /usr/lib/ostree/prepare-root.conf

# Configure kernel arguments
RUN mkdir -p /usr/lib/bootc/kargs.d && \
    echo '[kargs]\nappend = ["console=ttyS0", "quiet"]' > /usr/lib/bootc/kargs.d/99-console.toml

# Create systemd sysusers.d entries
RUN mkdir -p /usr/lib/sysusers.d && \
    echo 'u app 1000 "Application User"' > /usr/lib/sysusers.d/app.conf

# Create tmpfiles.d entries
RUN mkdir -p /usr/lib/tmpfiles.d && \
    echo 'd /var/log/app 0755 app app -' > /usr/lib/tmpfiles.d/app.conf

# Lint the container
RUN bootc container lint --fatal-warnings

3. CI/CD Integration Examples

GitHub Actions

name: Build and Lint bootc Image

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build-and-lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Build container image
        run: |
          podman build --tag my-bootc-image .
      
      - name: Lint container image
        run: |
          podman run --rm my-bootc-image bootc container lint --fatal-warnings
      
      - name: Test installation
        run: |
          podman run --rm --privileged my-bootc-image bootc install to-disk /dev/loop0

GitLab CI

stages:
  - build
  - lint
  - test

build:
  stage: build
  script:
    - podman build --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
    - podman push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

lint:
  stage: lint
  script:
    - podman run --rm $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA bootc container lint --fatal-warnings

test:
  stage: test
  script:
    - podman run --rm --privileged $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA bootc install to-disk /dev/loop0

Jenkins Pipeline

pipeline {
    agent any
    
    stages {
        stage('Build') {
            steps {
                sh 'podman build --tag my-bootc-image .'
            }
        }
        
        stage('Lint') {
            steps {
                sh 'podman run --rm my-bootc-image bootc container lint --fatal-warnings'
            }
        }
        
        stage('Test') {
            steps {
                sh 'podman run --rm --privileged my-bootc-image bootc install to-disk /dev/loop0'
            }
        }
    }
}

4. Development Workflow Examples

Pre-commit Hook

#!/bin/bash
# .git/hooks/pre-commit

echo "Running bootc container lint..."

# Build the image
podman build --tag temp-bootc-image . || exit 1

# Run lint
podman run --rm temp-bootc-image bootc container lint --fatal-warnings || {
    echo "Lint failed. Please fix issues before committing."
    podman rmi temp-bootc-image
    exit 1
}

# Clean up
podman rmi temp-bootc-image
echo "Lint passed!"

Makefile Integration

.PHONY: build lint test clean

IMAGE_NAME = my-bootc-image
IMAGE_TAG = latest

build:
	podman build --tag $(IMAGE_NAME):$(IMAGE_TAG) .

lint: build
	podman run --rm $(IMAGE_NAME):$(IMAGE_TAG) bootc container lint --fatal-warnings

test: lint
	podman run --rm --privileged $(IMAGE_NAME):$(IMAGE_TAG) bootc install to-disk /dev/loop0

clean:
	podman rmi $(IMAGE_NAME):$(IMAGE_TAG) || true

all: test

Docker Compose

version: '3.8'

services:
  build:
    build: .
    image: my-bootc-image:latest
    
  lint:
    image: my-bootc-image:latest
    command: bootc container lint --fatal-warnings
    depends_on:
      - build
      
  test:
    image: my-bootc-image:latest
    command: bootc install to-disk /dev/loop0
    privileged: true
    depends_on:
      - lint

Troubleshooting Guide

1. Common Error Messages

Problem: /var/run exists as a directory instead of symlink Solution:

# Remove directory and create symlink
rm -rf /var/run
ln -sf /run /var/run

Dockerfile Fix:

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

"Failed lint: etc-usretc: Found /usr/etc - this is a bootc implementation detail"

Problem: Both /etc and /usr/etc exist Solution:

# Choose one approach
rm -rf /usr/etc  # Keep /etc (recommended)
# OR
rm -rf /etc      # Keep /usr/etc (not recommended)

Dockerfile Fix:

RUN rm -rf /usr/etc  # Keep /etc only

"Failed lint: kernel: Multiple kernels found"

Problem: Multiple kernel versions present Solution:

# Keep only one kernel version
rm -rf /usr/lib/modules/5.4.0
# Keep /usr/lib/modules/6.1.0

Dockerfile Fix:

RUN rm -rf /usr/lib/modules/5.4.0  # Keep only 6.1.0

"Failed lint: utf8: Found non-utf8 filename"

Problem: Files with non-UTF-8 names Solution:

# Find and rename problematic files
find / -name "*" -print0 | xargs -0 -I {} sh -c 'echo "Checking: {}"'
# Rename files with non-UTF-8 names

Prevention:

# Use UTF-8 locale
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8

"Failed lint: api-base-directories: Missing API filesystem base directory"

Problem: Required directories missing Solution:

# Create all required directories
mkdir -p /dev /proc /sys /run /tmp /var

Dockerfile Fix:

RUN mkdir -p /dev /proc /sys /run /tmp /var

2. Warning Messages

"Lint warning: buildah-injected: /etc/hostname is an empty file"

Problem: Empty files injected by build system Solution:

# Remove empty files or add content
rm /etc/hostname
# OR
echo "myhostname" > /etc/hostname

Dockerfile Fix:

RUN rm -f /etc/hostname /etc/resolv.conf

"Lint warning: var-log: Found non-empty logfiles"

Problem: Log files in container image Solution:

# Remove log files
rm -rf /var/log/*
# OR create symlinks to /dev/null
ln -sf /dev/null /var/log/app.log

Dockerfile Fix:

RUN rm -rf /var/log/* && \
    mkdir -p /var/log && \
    ln -sf /dev/null /var/log/app.log

"Lint warning: nonempty-boot: Found non-empty /boot"

Problem: Content in /boot directory Solution:

# Remove content from /boot
rm -rf /boot/*
# Keep /boot empty

Dockerfile Fix:

RUN rm -rf /boot/* && mkdir -p /boot

3. Debugging Techniques

Enable Debug Output

# Enable detailed logging
RUST_LOG=debug bootc container lint

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

# List all available lints
bootc container lint --list

Test Specific Lints

# Test only fatal lints
bootc container lint --skip var-log --skip buildah-injected --skip baseimage-composefs --skip var-tmpfiles --skip sysusers --skip nonempty-boot

# Test only warning lints
bootc container lint --skip var-run --skip etc-usretc --skip bootc-kargs --skip kernel --skip utf8 --skip api-base-directories --skip baseimage-root

Inspect Container Structure

# Explore container filesystem
podman run --rm -it my-image bash

# Check specific directories
ls -la /var/run
ls -la /etc /usr/etc
ls -la /usr/lib/modules/
ls -la /boot

4. Performance Optimization

Skip Expensive Lints During Development

# Skip recursive UTF-8 check during development
bootc container lint --skip utf8

# Skip all warning lints
bootc container lint --skip var-log --skip buildah-injected --skip baseimage-composefs --skip var-tmpfiles --skip sysusers --skip nonempty-boot

Use Faster Base Images

# Use minimal base image
FROM debian:bookworm-slim

# Avoid unnecessary packages
RUN apt update && \
    apt install -y --no-install-recommends bootc && \
    apt clean && \
    rm -rf /var/lib/apt/lists/*

5. Integration Issues

Container Runtime Compatibility

Problem: Lint fails in different container runtime Solution:

# Use podman (recommended)
podman run --rm my-image bootc container lint

# Use docker with proper flags
docker run --rm my-image bootc container lint

Build Context Issues

Problem: Lint fails due to build context Solution:

# Ensure proper working directory
WORKDIR /

# Copy files explicitly
COPY . /workspace
WORKDIR /workspace

Permission Issues

Problem: Permission denied errors Solution:

# Run with proper permissions
podman run --rm --user root my-image bootc container lint

# Or fix permissions in container
RUN chmod -R 755 /usr/lib/bootc

6. Advanced Troubleshooting

Custom Lint Configuration

# Create custom lint script
#!/bin/bash
set -e

echo "Running custom lint checks..."

# Run specific lints
bootc container lint --skip utf8 --skip var-log

# Additional custom checks
if [ -f /etc/hostname ]; then
    echo "Warning: /etc/hostname should not exist in container"
fi

echo "Custom lint checks passed!"

Lint Result Analysis

# Capture lint output for analysis
bootc container lint --no-truncate > lint-results.txt 2>&1

# Analyze results
grep "Failed lint" lint-results.txt
grep "Lint warning" lint-results.txt

Automated Fixes

#!/bin/bash
# Auto-fix common issues

echo "Fixing common bootc lint issues..."

# Fix /var/run
if [ -d /var/run ] && [ ! -L /var/run ]; then
    echo "Fixing /var/run symlink..."
    rm -rf /var/run
    ln -sf /run /var/run
fi

# Fix /usr/etc
if [ -d /usr/etc ] && [ -d /etc ]; then
    echo "Removing /usr/etc (keeping /etc)..."
    rm -rf /usr/etc
fi

# Fix /boot
if [ -d /boot ] && [ "$(ls -A /boot)" ]; then
    echo "Clearing /boot directory..."
    rm -rf /boot/*
fi

# Fix log files
if [ -d /var/log ] && [ "$(ls -A /var/log)" ]; then
    echo "Clearing log files..."
    rm -rf /var/log/*
fi

echo "Auto-fix completed!"

This comprehensive examples and troubleshooting guide provides practical solutions for common bootc lint issues and integration patterns.