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
This commit is contained in:
commit
526f1c1afd
67 changed files with 34174 additions and 0 deletions
434
lint/bootc-lint-guide.md
Normal file
434
lint/bootc-lint-guide.md
Normal file
|
|
@ -0,0 +1,434 @@
|
|||
# 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.
|
||||
578
lint/examples-and-troubleshooting.md
Normal file
578
lint/examples-and-troubleshooting.md
Normal file
|
|
@ -0,0 +1,578 @@
|
|||
# bootc container lint - Examples and Troubleshooting
|
||||
|
||||
## Practical Examples
|
||||
|
||||
### 1. Basic Container Image Linting
|
||||
|
||||
#### Minimal Working Example
|
||||
|
||||
```dockerfile
|
||||
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
|
||||
```bash
|
||||
# Problem
|
||||
mkdir -p /var/run
|
||||
|
||||
# Fix
|
||||
rm -rf /var/run
|
||||
ln -sf /run /var/run
|
||||
```
|
||||
|
||||
**Issue**: Both `/etc` and `/usr/etc` exist
|
||||
```bash
|
||||
# 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
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```dockerfile
|
||||
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
|
||||
|
||||
```yaml
|
||||
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
|
||||
|
||||
```yaml
|
||||
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
|
||||
|
||||
```groovy
|
||||
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
|
||||
|
||||
```bash
|
||||
#!/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
|
||||
|
||||
```makefile
|
||||
.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
|
||||
|
||||
```yaml
|
||||
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
|
||||
|
||||
#### "Failed lint: var-run: Not a symlink: var/run"
|
||||
|
||||
**Problem**: `/var/run` exists as a directory instead of symlink
|
||||
**Solution**:
|
||||
```bash
|
||||
# Remove directory and create symlink
|
||||
rm -rf /var/run
|
||||
ln -sf /run /var/run
|
||||
```
|
||||
|
||||
**Dockerfile Fix**:
|
||||
```dockerfile
|
||||
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**:
|
||||
```bash
|
||||
# Choose one approach
|
||||
rm -rf /usr/etc # Keep /etc (recommended)
|
||||
# OR
|
||||
rm -rf /etc # Keep /usr/etc (not recommended)
|
||||
```
|
||||
|
||||
**Dockerfile Fix**:
|
||||
```dockerfile
|
||||
RUN rm -rf /usr/etc # Keep /etc only
|
||||
```
|
||||
|
||||
#### "Failed lint: kernel: Multiple kernels found"
|
||||
|
||||
**Problem**: Multiple kernel versions present
|
||||
**Solution**:
|
||||
```bash
|
||||
# Keep only one kernel version
|
||||
rm -rf /usr/lib/modules/5.4.0
|
||||
# Keep /usr/lib/modules/6.1.0
|
||||
```
|
||||
|
||||
**Dockerfile Fix**:
|
||||
```dockerfile
|
||||
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**:
|
||||
```bash
|
||||
# Find and rename problematic files
|
||||
find / -name "*" -print0 | xargs -0 -I {} sh -c 'echo "Checking: {}"'
|
||||
# Rename files with non-UTF-8 names
|
||||
```
|
||||
|
||||
**Prevention**:
|
||||
```dockerfile
|
||||
# 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**:
|
||||
```bash
|
||||
# Create all required directories
|
||||
mkdir -p /dev /proc /sys /run /tmp /var
|
||||
```
|
||||
|
||||
**Dockerfile Fix**:
|
||||
```dockerfile
|
||||
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**:
|
||||
```bash
|
||||
# Remove empty files or add content
|
||||
rm /etc/hostname
|
||||
# OR
|
||||
echo "myhostname" > /etc/hostname
|
||||
```
|
||||
|
||||
**Dockerfile Fix**:
|
||||
```dockerfile
|
||||
RUN rm -f /etc/hostname /etc/resolv.conf
|
||||
```
|
||||
|
||||
#### "Lint warning: var-log: Found non-empty logfiles"
|
||||
|
||||
**Problem**: Log files in container image
|
||||
**Solution**:
|
||||
```bash
|
||||
# Remove log files
|
||||
rm -rf /var/log/*
|
||||
# OR create symlinks to /dev/null
|
||||
ln -sf /dev/null /var/log/app.log
|
||||
```
|
||||
|
||||
**Dockerfile Fix**:
|
||||
```dockerfile
|
||||
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**:
|
||||
```bash
|
||||
# Remove content from /boot
|
||||
rm -rf /boot/*
|
||||
# Keep /boot empty
|
||||
```
|
||||
|
||||
**Dockerfile Fix**:
|
||||
```dockerfile
|
||||
RUN rm -rf /boot/* && mkdir -p /boot
|
||||
```
|
||||
|
||||
### 3. Debugging Techniques
|
||||
|
||||
#### Enable Debug Output
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```dockerfile
|
||||
# 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**:
|
||||
```bash
|
||||
# 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**:
|
||||
```dockerfile
|
||||
# Ensure proper working directory
|
||||
WORKDIR /
|
||||
|
||||
# Copy files explicitly
|
||||
COPY . /workspace
|
||||
WORKDIR /workspace
|
||||
```
|
||||
|
||||
#### Permission Issues
|
||||
|
||||
**Problem**: Permission denied errors
|
||||
**Solution**:
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
#!/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.
|
||||
243
lint/quick-reference.md
Normal file
243
lint/quick-reference.md
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
# bootc container lint - Quick Reference
|
||||
|
||||
## Command Syntax
|
||||
|
||||
```bash
|
||||
bootc container lint [OPTIONS...]
|
||||
```
|
||||
|
||||
## Common Options
|
||||
|
||||
| Option | Description | Example |
|
||||
|--------|-------------|---------|
|
||||
| `--rootfs` | Specify root filesystem path | `--rootfs /path/to/rootfs` |
|
||||
| `--fatal-warnings` | Treat warnings as fatal errors | `--fatal-warnings` |
|
||||
| `--list` | List all available lints | `--list` |
|
||||
| `--skip` | Skip specific lints | `--skip var-log --skip buildah-injected` |
|
||||
| `--no-truncate` | Show full output (no truncation) | `--no-truncate` |
|
||||
|
||||
## Fatal Lints (Must Pass)
|
||||
|
||||
| Lint | Purpose | Fix |
|
||||
|------|---------|-----|
|
||||
| `var-run` | `/var/run` must be symlink to `/run` | `ln -sf /run /var/run` |
|
||||
| `etc-usretc` | Only `/etc` OR `/usr/etc` (not both) | `rm -rf /usr/etc` |
|
||||
| `bootc-kargs` | Valid kernel args in `/usr/lib/bootc/kargs.d/` | Fix TOML syntax |
|
||||
| `kernel` | Exactly one kernel in `/usr/lib/modules/` | `rm -rf /usr/lib/modules/5.4.0` |
|
||||
| `utf8` | All filenames must be UTF-8 | Rename non-UTF-8 files |
|
||||
| `api-base-directories` | Required dirs: `/dev`, `/proc`, `/sys`, `/run`, `/tmp`, `/var` | `mkdir -p /dev /proc /sys /run /tmp /var` |
|
||||
| `baseimage-root` | Required: `/sysroot`, `/ostree -> sysroot/ostree` | `mkdir -p /sysroot/ostree && ln -sf sysroot/ostree /ostree` |
|
||||
|
||||
## Warning Lints (Recommended)
|
||||
|
||||
| Lint | Purpose | Fix |
|
||||
|------|---------|-----|
|
||||
| `buildah-injected` | No empty `/etc/hostname` or `/etc/resolv.conf` | `rm /etc/hostname /etc/resolv.conf` |
|
||||
| `baseimage-composefs` | Enable composefs in ostree | `echo '[composefs]\nenabled = true' > /usr/lib/ostree/prepare-root.conf` |
|
||||
| `var-log` | No log files in `/var/log` | `rm -rf /var/log/*` |
|
||||
| `var-tmpfiles` | `/var` content needs tmpfiles.d entries | Create `/usr/lib/tmpfiles.d/*.conf` |
|
||||
| `sysusers` | Users/groups need sysusers.d entries | Create `/usr/lib/sysusers.d/*.conf` |
|
||||
| `nonempty-boot` | `/boot` should be empty | `rm -rf /boot/*` |
|
||||
|
||||
## Quick Fixes
|
||||
|
||||
### Fix Common Issues
|
||||
|
||||
```bash
|
||||
# Fix /var/run
|
||||
rm -rf /var/run && ln -sf /run /var/run
|
||||
|
||||
# Fix /usr/etc
|
||||
rm -rf /usr/etc
|
||||
|
||||
# Fix /boot
|
||||
rm -rf /boot/* && mkdir -p /boot
|
||||
|
||||
# Fix log files
|
||||
rm -rf /var/log/*
|
||||
|
||||
# Fix empty files
|
||||
rm -f /etc/hostname /etc/resolv.conf
|
||||
```
|
||||
|
||||
### Create Required Structure
|
||||
|
||||
```bash
|
||||
# API directories
|
||||
mkdir -p /dev /proc /sys /run /tmp /var
|
||||
|
||||
# bootc structure
|
||||
mkdir -p /sysroot/ostree
|
||||
ln -sf sysroot/ostree /ostree
|
||||
|
||||
# Kernel structure
|
||||
mkdir -p /usr/lib/modules/6.1.0
|
||||
echo "kernel" > /usr/lib/modules/6.1.0/vmlinuz
|
||||
|
||||
# Empty /boot
|
||||
mkdir -p /boot
|
||||
```
|
||||
|
||||
## Dockerfile Examples
|
||||
|
||||
### Minimal Working Container
|
||||
|
||||
```dockerfile
|
||||
FROM debian:bookworm-slim
|
||||
|
||||
# Install bootc
|
||||
RUN apt update && apt install -y bootc && apt clean
|
||||
|
||||
# Fix common issues
|
||||
RUN rm -rf /var/run && ln -sf /run /var/run
|
||||
RUN rm -rf /usr/etc
|
||||
RUN rm -rf /boot/* && mkdir -p /boot
|
||||
RUN rm -rf /var/log/*
|
||||
|
||||
# Create required structure
|
||||
RUN mkdir -p /dev /proc /sys /run /tmp /var
|
||||
RUN mkdir -p /sysroot/ostree && ln -sf sysroot/ostree /ostree
|
||||
RUN mkdir -p /usr/lib/modules/6.1.0
|
||||
RUN echo "kernel" > /usr/lib/modules/6.1.0/vmlinuz
|
||||
|
||||
# Lint
|
||||
RUN bootc container lint --fatal-warnings
|
||||
```
|
||||
|
||||
### Complete bootc Image
|
||||
|
||||
```dockerfile
|
||||
FROM debian:bookworm-slim
|
||||
|
||||
# Install dependencies
|
||||
RUN apt update && \
|
||||
apt install -y bootc ostree systemd && \
|
||||
apt clean && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Fix common issues
|
||||
RUN rm -rf /var/run && ln -sf /run /var/run
|
||||
RUN rm -rf /usr/etc
|
||||
RUN rm -rf /boot/* && mkdir -p /boot
|
||||
RUN rm -rf /var/log/*
|
||||
|
||||
# Create required structure
|
||||
RUN mkdir -p /dev /proc /sys /run /tmp /var
|
||||
RUN mkdir -p /sysroot/ostree && ln -sf sysroot/ostree /ostree
|
||||
RUN mkdir -p /usr/lib/modules/6.1.0
|
||||
RUN echo "kernel" > /usr/lib/modules/6.1.0/vmlinuz
|
||||
|
||||
# Configure composefs
|
||||
RUN mkdir -p /usr/lib/ostree && \
|
||||
echo '[composefs]\nenabled = true' > /usr/lib/ostree/prepare-root.conf
|
||||
|
||||
# Configure kernel args
|
||||
RUN mkdir -p /usr/lib/bootc/kargs.d && \
|
||||
echo '[kargs]\nappend = ["console=ttyS0", "quiet"]' > /usr/lib/bootc/kargs.d/99-console.toml
|
||||
|
||||
# Lint
|
||||
RUN bootc container lint --fatal-warnings
|
||||
```
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
```yaml
|
||||
- name: Lint bootc container
|
||||
run: podman run --rm ${{ matrix.image }} bootc container lint --fatal-warnings
|
||||
```
|
||||
|
||||
### GitLab CI
|
||||
|
||||
```yaml
|
||||
lint:
|
||||
script:
|
||||
- podman run --rm $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA bootc container lint --fatal-warnings
|
||||
```
|
||||
|
||||
### Jenkins
|
||||
|
||||
```groovy
|
||||
stage('Lint') {
|
||||
steps {
|
||||
sh 'podman run --rm my-image bootc container lint --fatal-warnings'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Common Commands
|
||||
|
||||
```bash
|
||||
# Basic lint
|
||||
bootc container lint
|
||||
|
||||
# Lint with warnings as fatal
|
||||
bootc container lint --fatal-warnings
|
||||
|
||||
# Lint specific rootfs
|
||||
bootc container lint --rootfs /path/to/rootfs
|
||||
|
||||
# Skip specific lints
|
||||
bootc container lint --skip var-log --skip buildah-injected
|
||||
|
||||
# Show all issues
|
||||
bootc container lint --no-truncate
|
||||
|
||||
# List available lints
|
||||
bootc container lint --list
|
||||
|
||||
# Debug mode
|
||||
RUST_LOG=debug bootc container lint
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Errors
|
||||
|
||||
| Error | Cause | Fix |
|
||||
|-------|-------|-----|
|
||||
| `Not a symlink: var/run` | `/var/run` is directory | `ln -sf /run /var/run` |
|
||||
| `Found /usr/etc` | Both `/etc` and `/usr/etc` exist | `rm -rf /usr/etc` |
|
||||
| `Multiple kernels found` | Multiple kernel versions | Keep only one |
|
||||
| `Found non-utf8 filename` | Non-UTF-8 filenames | Rename files |
|
||||
| `Missing API filesystem base directory` | Missing required dirs | `mkdir -p /dev /proc /sys /run /tmp /var` |
|
||||
|
||||
### Debug Commands
|
||||
|
||||
```bash
|
||||
# Check container structure
|
||||
podman run --rm -it my-image bash
|
||||
ls -la /var/run
|
||||
ls -la /etc /usr/etc
|
||||
ls -la /usr/lib/modules/
|
||||
ls -la /boot
|
||||
|
||||
# Test specific lints
|
||||
bootc container lint --skip utf8 --skip var-log
|
||||
|
||||
# Show full output
|
||||
bootc container lint --no-truncate
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Run lint early** in build process
|
||||
2. **Use `--fatal-warnings`** in CI/CD
|
||||
3. **Fix issues immediately** when found
|
||||
4. **Test with actual bootc installation**
|
||||
5. **Use minimal base images**
|
||||
6. **Clean up package caches**
|
||||
7. **Avoid creating log files**
|
||||
8. **Use symlinks for `/var/run`**
|
||||
|
||||
## File Locations
|
||||
|
||||
| Purpose | Location |
|
||||
|---------|----------|
|
||||
| Kernel args | `/usr/lib/bootc/kargs.d/*.toml` |
|
||||
| Composefs config | `/usr/lib/ostree/prepare-root.conf` |
|
||||
| Sysusers config | `/usr/lib/sysusers.d/*.conf` |
|
||||
| Tmpfiles config | `/usr/lib/tmpfiles.d/*.conf` |
|
||||
| Kernel files | `/usr/lib/modules/$kver/vmlinuz` |
|
||||
| Initramfs | `/usr/lib/modules/$kver/initramfs.img` |
|
||||
550
lint/technical-reference.md
Normal file
550
lint/technical-reference.md
Normal file
|
|
@ -0,0 +1,550 @@
|
|||
# bootc container lint - Technical Reference
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
The bootc lint system is built on a distributed slice architecture using the `linkme` crate, allowing for modular lint registration and execution. The system supports both regular and recursive lints, with configurable execution and output formatting.
|
||||
|
||||
## Core Components
|
||||
|
||||
### 1. Lint Registration System
|
||||
|
||||
```rust
|
||||
// From lints.rs:86-87
|
||||
#[distributed_slice]
|
||||
pub(crate) static LINTS: [Lint];
|
||||
```
|
||||
|
||||
**Purpose**: Central registry for all lint checks
|
||||
**Implementation**: Uses `linkme` distributed slices for automatic registration
|
||||
**Benefits**: Modular design, easy addition of new lints
|
||||
|
||||
### 2. Lint Types
|
||||
|
||||
#### Fatal Lints
|
||||
```rust
|
||||
// From lints.rs:92-98
|
||||
enum LintType {
|
||||
Fatal, // Must pass for installation
|
||||
Warning, // Recommended but not required
|
||||
}
|
||||
```
|
||||
|
||||
**Fatal Lints**: Prevent bootc installation if they fail
|
||||
**Warning Lints**: Show warnings but allow installation to proceed
|
||||
|
||||
### 3. Root Type Classification
|
||||
|
||||
```rust
|
||||
// From lints.rs:106-111
|
||||
enum RootType {
|
||||
Running, // Running system root
|
||||
Alternative, // Alternative/container root
|
||||
}
|
||||
```
|
||||
|
||||
**Running**: Lints that apply to running systems
|
||||
**Alternative**: Lints that apply to container images
|
||||
|
||||
## Lint Execution Engine
|
||||
|
||||
### 1. Execution Flow
|
||||
|
||||
```rust
|
||||
// From lints.rs:254-364
|
||||
fn lint_inner<'skip>(
|
||||
root: &Dir,
|
||||
root_type: RootType,
|
||||
config: &LintExecutionConfig,
|
||||
skip: impl IntoIterator<Item = &'skip str>,
|
||||
mut output: impl std::io::Write,
|
||||
) -> Result<LintExecutionResult>
|
||||
```
|
||||
|
||||
**Process**:
|
||||
1. Filter applicable lints based on root type
|
||||
2. Separate regular and recursive lints
|
||||
3. Execute regular lints
|
||||
4. Execute recursive lints via filesystem walk
|
||||
5. Collect and report results
|
||||
|
||||
### 2. Recursive Lint Execution
|
||||
|
||||
```rust
|
||||
// From lints.rs:295-328
|
||||
root.walk(
|
||||
&WalkConfiguration::default()
|
||||
.noxdev()
|
||||
.path_base(Path::new("/")),
|
||||
|e| -> std::io::Result<_> {
|
||||
// Execute recursive lints on each filesystem entry
|
||||
},
|
||||
)?;
|
||||
```
|
||||
|
||||
**Features**:
|
||||
- Filesystem traversal with `noxdev` (no cross-device)
|
||||
- Early termination on first error
|
||||
- Efficient processing of large filesystems
|
||||
|
||||
### 3. Output Formatting
|
||||
|
||||
```rust
|
||||
// From lints.rs:200-235
|
||||
fn format_items<T>(
|
||||
config: &LintExecutionConfig,
|
||||
header: &str,
|
||||
items: impl Iterator<Item = T>,
|
||||
o: &mut String,
|
||||
) -> Result<()>
|
||||
```
|
||||
|
||||
**Features**:
|
||||
- Configurable truncation (default: 5 items)
|
||||
- Consistent formatting across lints
|
||||
- Support for custom display implementations
|
||||
|
||||
## Individual Lint Implementations
|
||||
|
||||
### 1. var-run Lint
|
||||
|
||||
```rust
|
||||
// From lints.rs:397-410
|
||||
static LINT_VAR_RUN: Lint = Lint::new_fatal(
|
||||
"var-run",
|
||||
"Check for /var/run being a physical directory; this is always a bug.",
|
||||
check_var_run,
|
||||
);
|
||||
```
|
||||
|
||||
**Purpose**: Ensures `/var/run` is a symlink to `/run`
|
||||
**Check**: Validates symlink existence and target
|
||||
**Rationale**: Required for proper systemd operation
|
||||
|
||||
### 2. etc-usretc Lint
|
||||
|
||||
```rust
|
||||
// From lints.rs:435-458
|
||||
static LINT_ETC_USRUSETC: Lint = Lint::new_fatal(
|
||||
"etc-usretc",
|
||||
"Verify that only one of /etc or /usr/etc exist...",
|
||||
check_usretc,
|
||||
);
|
||||
```
|
||||
|
||||
**Purpose**: Prevents both `/etc` and `/usr/etc` from existing
|
||||
**Check**: Validates mutual exclusivity
|
||||
**Rationale**: `/usr/etc` is a bootc implementation detail
|
||||
|
||||
### 3. bootc-kargs Lint
|
||||
|
||||
```rust
|
||||
// From lints.rs:461-471
|
||||
static LINT_KARGS: Lint = Lint::new_fatal(
|
||||
"bootc-kargs",
|
||||
"Verify syntax of /usr/lib/bootc/kargs.d.",
|
||||
check_parse_kargs,
|
||||
);
|
||||
```
|
||||
|
||||
**Purpose**: Validates kernel argument configuration
|
||||
**Check**: Parses TOML files in `/usr/lib/bootc/kargs.d/`
|
||||
**Integration**: Uses `crate::bootc_kargs::get_kargs_in_root`
|
||||
|
||||
### 4. kernel Lint
|
||||
|
||||
```rust
|
||||
// From lints.rs:473-486
|
||||
static LINT_KERNEL: Lint = Lint::new_fatal(
|
||||
"kernel",
|
||||
"Check for multiple kernels...",
|
||||
check_kernel,
|
||||
);
|
||||
```
|
||||
|
||||
**Purpose**: Ensures exactly one kernel is present
|
||||
**Check**: Validates `/usr/lib/modules/$kver` directories
|
||||
**Integration**: Uses `ostree_ext::bootabletree::find_kernel_dir_fs`
|
||||
|
||||
### 5. utf8 Lint (Recursive)
|
||||
|
||||
```rust
|
||||
// From lints.rs:489-522
|
||||
static LINT_UTF8: Lint = Lint {
|
||||
name: "utf8",
|
||||
description: "Check for non-UTF8 filenames...",
|
||||
ty: LintType::Fatal,
|
||||
root_type: None,
|
||||
f: LintFnTy::Recursive(check_utf8),
|
||||
};
|
||||
```
|
||||
|
||||
**Purpose**: Ensures all filenames and symlink targets are UTF-8
|
||||
**Check**: Recursively validates filesystem entries
|
||||
**Features**: Handles symlinks, broken links, and special cases
|
||||
|
||||
### 6. api-base-directories Lint
|
||||
|
||||
```rust
|
||||
// From lints.rs:535-558
|
||||
static LINT_API_DIRS: Lint = Lint::new_fatal(
|
||||
"api-base-directories",
|
||||
"Verify that expected base API directories exist...",
|
||||
check_api_dirs,
|
||||
);
|
||||
```
|
||||
|
||||
**Purpose**: Validates required systemd API directories
|
||||
**Check**: Ensures `/dev`, `/proc`, `/sys`, `/run`, `/tmp`, `/var` exist
|
||||
**Rationale**: Required by systemd and Linux standards
|
||||
|
||||
### 7. baseimage-root Lint
|
||||
|
||||
```rust
|
||||
// From lints.rs:610-632
|
||||
static LINT_BASEIMAGE_ROOT: Lint = Lint::new_fatal(
|
||||
"baseimage-root",
|
||||
"Check that expected files are present in the root...",
|
||||
check_baseimage_root,
|
||||
);
|
||||
```
|
||||
|
||||
**Purpose**: Validates bootc-specific root structure
|
||||
**Check**: Ensures `/sysroot` exists and `/ostree` symlinks correctly
|
||||
**Integration**: Checks embedded documentation for consistency
|
||||
|
||||
## Warning Lints
|
||||
|
||||
### 1. buildah-injected Lint
|
||||
|
||||
```rust
|
||||
// From lints.rs:412-433
|
||||
static LINT_BUILDAH_INJECTED: Lint = Lint::new_warning(
|
||||
"buildah-injected",
|
||||
"Check for an invalid /etc/hostname or /etc/resolv.conf...",
|
||||
check_buildah_injected,
|
||||
)
|
||||
.set_root_type(RootType::Alternative);
|
||||
```
|
||||
|
||||
**Purpose**: Detects empty files injected by build systems
|
||||
**Check**: Looks for empty `/etc/hostname` or `/etc/resolv.conf`
|
||||
**Scope**: Only applies to alternative roots (container images)
|
||||
|
||||
### 2. baseimage-composefs Lint
|
||||
|
||||
```rust
|
||||
// From lints.rs:560-581
|
||||
static LINT_COMPOSEFS: Lint = Lint::new_warning(
|
||||
"baseimage-composefs",
|
||||
"Check that composefs is enabled for ostree...",
|
||||
check_composefs,
|
||||
);
|
||||
```
|
||||
|
||||
**Purpose**: Recommends composefs for ostree
|
||||
**Check**: Validates composefs configuration
|
||||
**Integration**: Uses `ostree_prepareroot` for configuration parsing
|
||||
|
||||
### 3. var-log Lint
|
||||
|
||||
```rust
|
||||
// From lints.rs:656-682
|
||||
static LINT_VARLOG: Lint = Lint::new_warning(
|
||||
"var-log",
|
||||
"Check for non-empty regular files in /var/log...",
|
||||
check_varlog,
|
||||
);
|
||||
```
|
||||
|
||||
**Purpose**: Warns about log files in container images
|
||||
**Check**: Identifies non-empty files in `/var/log`
|
||||
**Features**: Recursive directory scanning with size checking
|
||||
|
||||
### 4. var-tmpfiles Lint
|
||||
|
||||
```rust
|
||||
// From lints.rs:684-712
|
||||
static LINT_VAR_TMPFILES: Lint = Lint::new_warning(
|
||||
"var-tmpfiles",
|
||||
"Check for content in /var that does not have corresponding systemd tmpfiles.d entries...",
|
||||
check_var_tmpfiles,
|
||||
)
|
||||
.set_root_type(RootType::Running);
|
||||
```
|
||||
|
||||
**Purpose**: Validates tmpfiles.d configuration
|
||||
**Check**: Ensures `/var` content has corresponding tmpfiles.d entries
|
||||
**Scope**: Only applies to running systems
|
||||
**Integration**: Uses `bootc_tmpfiles` crate
|
||||
|
||||
### 5. sysusers Lint
|
||||
|
||||
```rust
|
||||
// From lints.rs:714-743
|
||||
static LINT_SYSUSERS: Lint = Lint::new_warning(
|
||||
"sysusers",
|
||||
"Check for users in /etc/passwd and groups in /etc/group...",
|
||||
check_sysusers,
|
||||
);
|
||||
```
|
||||
|
||||
**Purpose**: Validates user/group definitions
|
||||
**Check**: Ensures sysusers.d entries exist for passwd/group entries
|
||||
**Integration**: Uses `bootc_sysusers` crate
|
||||
|
||||
### 6. nonempty-boot Lint
|
||||
|
||||
```rust
|
||||
// From lints.rs:745-773
|
||||
static LINT_NONEMPTY_BOOT: Lint = Lint::new_warning(
|
||||
"nonempty-boot",
|
||||
"The /boot directory should be present, but empty...",
|
||||
check_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`
|
||||
|
||||
## Configuration and Options
|
||||
|
||||
### 1. LintExecutionConfig
|
||||
|
||||
```rust
|
||||
// From lints.rs:69-72
|
||||
struct LintExecutionConfig {
|
||||
no_truncate: bool,
|
||||
}
|
||||
```
|
||||
|
||||
**no_truncate**: Controls output truncation (default: false, shows 5 items)
|
||||
|
||||
### 2. WarningDisposition
|
||||
|
||||
```rust
|
||||
// From lints.rs:101-104
|
||||
enum WarningDisposition {
|
||||
AllowWarnings, // Warnings don't fail the build
|
||||
FatalWarnings, // Warnings are treated as fatal
|
||||
}
|
||||
```
|
||||
|
||||
**Purpose**: Controls how warnings are handled
|
||||
**Default**: AllowWarnings
|
||||
|
||||
### 3. RootType
|
||||
|
||||
```rust
|
||||
// From lints.rs:106-111
|
||||
enum RootType {
|
||||
Running, // Running system root
|
||||
Alternative, // Alternative/container root
|
||||
}
|
||||
```
|
||||
|
||||
**Purpose**: Determines which lints apply to which root types
|
||||
**Filtering**: Lints can be restricted to specific root types
|
||||
|
||||
## Error Handling
|
||||
|
||||
### 1. LintError Type
|
||||
|
||||
```rust
|
||||
// From lints.rs:38-67
|
||||
struct LintError(String);
|
||||
|
||||
impl std::fmt::Display for LintError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(&self.0)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Purpose**: Represents lint failures
|
||||
**Features**: Custom display implementation for formatted output
|
||||
|
||||
### 2. Result Types
|
||||
|
||||
```rust
|
||||
// From lints.rs:44
|
||||
type LintResult = Result<std::result::Result<(), LintError>>;
|
||||
```
|
||||
|
||||
**Outer Result**: Runtime errors (file system issues, etc.)
|
||||
**Inner Result**: Lint success/failure
|
||||
**Pattern**: `Ok(Ok(()))` = success, `Ok(Err(LintError))` = lint failure
|
||||
|
||||
### 3. Error Reporting
|
||||
|
||||
```rust
|
||||
// From lints.rs:340-356
|
||||
if let Err(e) = r {
|
||||
match lint.ty {
|
||||
LintType::Fatal => {
|
||||
writeln!(output, "Failed lint: {name}: {e}")?;
|
||||
fatal += 1;
|
||||
}
|
||||
LintType::Warning => {
|
||||
writeln!(output, "Lint warning: {name}: {e}")?;
|
||||
warnings += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Format**: Consistent error message formatting
|
||||
**Categorization**: Separate handling for fatal vs warning errors
|
||||
|
||||
## Performance Optimizations
|
||||
|
||||
### 1. Early Termination
|
||||
|
||||
```rust
|
||||
// From lints.rs:300-303
|
||||
if recursive_lints.is_empty() {
|
||||
return Ok(ControlFlow::Break(()));
|
||||
}
|
||||
```
|
||||
|
||||
**Feature**: Stops processing when no recursive lints remain
|
||||
**Benefit**: Avoids unnecessary filesystem traversal
|
||||
|
||||
### 2. Lint Filtering
|
||||
|
||||
```rust
|
||||
// From lints.rs:265-275
|
||||
let (mut applicable_lints, skipped_lints): (Vec<_>, Vec<_>) = LINTS.iter().partition(|lint| {
|
||||
if skip.contains(lint.name) {
|
||||
return false;
|
||||
}
|
||||
if let Some(lint_root_type) = lint.root_type {
|
||||
if lint_root_type != root_type {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
});
|
||||
```
|
||||
|
||||
**Feature**: Only runs applicable lints
|
||||
**Benefit**: Reduces execution time for irrelevant checks
|
||||
|
||||
### 3. Output Truncation
|
||||
|
||||
```rust
|
||||
// From lints.rs:221-233
|
||||
if config.no_truncate {
|
||||
// Show all items
|
||||
} else {
|
||||
// Show limited items with count
|
||||
if rest > 0 {
|
||||
writeln!(o, " ...and {rest} more")?;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Feature**: Configurable output length
|
||||
**Default**: 5 items per lint
|
||||
**Benefit**: Prevents overwhelming output for large issues
|
||||
|
||||
## Testing Framework
|
||||
|
||||
### 1. Test Fixtures
|
||||
|
||||
```rust
|
||||
// From lints.rs:788-814
|
||||
fn passing_fixture() -> Result<cap_std_ext::cap_tempfile::TempDir> {
|
||||
let root = cap_std_ext::cap_tempfile::tempdir(cap_std::ambient_authority())?;
|
||||
for d in API_DIRS {
|
||||
root.create_dir(d)?;
|
||||
}
|
||||
// ... setup valid filesystem structure
|
||||
Ok(root)
|
||||
}
|
||||
```
|
||||
|
||||
**Purpose**: Creates test filesystems for lint validation
|
||||
**Features**: Both passing and failing test cases
|
||||
|
||||
### 2. Individual Lint Tests
|
||||
|
||||
```rust
|
||||
// From lints.rs:816-828
|
||||
#[test]
|
||||
fn test_var_run() -> Result<()> {
|
||||
let root = &fixture()?;
|
||||
let config = &LintExecutionConfig::default();
|
||||
// Test passing case
|
||||
check_var_run(root, config).unwrap().unwrap();
|
||||
// Test failing case
|
||||
root.create_dir_all("var/run/foo")?;
|
||||
assert!(check_var_run(root, config).unwrap().is_err());
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
**Coverage**: Each lint has dedicated tests
|
||||
**Scenarios**: Both success and failure cases
|
||||
|
||||
### 3. Integration Tests
|
||||
|
||||
```rust
|
||||
// From lints.rs:844-889
|
||||
#[test]
|
||||
fn test_lint_inner() -> Result<()> {
|
||||
let root = &passing_fixture()?;
|
||||
let config = &LintExecutionConfig::default();
|
||||
let mut out = Vec::new();
|
||||
let root_type = RootType::Alternative;
|
||||
let r = lint_inner(root, root_type, config, [], &mut out).unwrap();
|
||||
// Verify results
|
||||
assert_eq!(r.passed, *ALTROOT_LINTS);
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
**Purpose**: Tests the complete lint execution flow
|
||||
**Validation**: Verifies correct counting and categorization
|
||||
|
||||
## Integration Points
|
||||
|
||||
### 1. OSTree Integration
|
||||
|
||||
- Uses `ostree_ext::bootabletree` for kernel detection
|
||||
- Integrates with `ostree_prepareroot` for composefs validation
|
||||
- Leverages OSTree's filesystem understanding
|
||||
|
||||
### 2. Systemd Integration
|
||||
|
||||
- Validates systemd API directories
|
||||
- Checks tmpfiles.d configuration
|
||||
- Validates sysusers.d entries
|
||||
|
||||
### 3. Container Runtime Integration
|
||||
|
||||
- Designed for container build processes
|
||||
- Supports various root filesystem types
|
||||
- Handles container-specific issues
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
### 1. Extensibility
|
||||
|
||||
- Plugin system for custom lints
|
||||
- Configuration file support
|
||||
- Custom output formats
|
||||
|
||||
### 2. Performance
|
||||
|
||||
- Parallel lint execution
|
||||
- Incremental checking
|
||||
- Caching mechanisms
|
||||
|
||||
### 3. Integration
|
||||
|
||||
- IDE integration
|
||||
- CI/CD pipeline optimization
|
||||
- Real-time feedback
|
||||
|
||||
This technical reference provides comprehensive understanding of the bootc lint system's architecture, implementation, and usage patterns.
|
||||
Loading…
Add table
Add a link
Reference in a new issue