initial debian support
This commit is contained in:
parent
4c5a458148
commit
904a1d01ba
36 changed files with 986 additions and 372 deletions
147
Containerfile
147
Containerfile
|
|
@ -1,69 +1,92 @@
|
|||
# In order to make a base image as part of a Dockerfile, this container build uses
|
||||
# nested containerization, so you must build with e.g.
|
||||
# podman build --security-opt=label=disable --cap-add=all --device /dev/fuse <...>
|
||||
# Multi-stage build for Debian minimal bootc base images
|
||||
# Stage 1: Repository setup with apt-cache-ng proxy
|
||||
FROM debian:sid AS repos
|
||||
# Build argument for apt-cache-ng proxy (can be empty to disable)
|
||||
ARG APT_CACHER_NG_PROXY="http://192.168.1.101:3142"
|
||||
# Copy our repository configuration
|
||||
COPY debian.repo /etc/apt/sources.list.d/
|
||||
# Replace the proxy URL placeholder with the actual value
|
||||
RUN if [ -n "$APT_CACHER_NG_PROXY" ]; then \
|
||||
sed -i "s|__PROXY_URL__|$APT_CACHER_NG_PROXY|g" /etc/apt/sources.list.d/debian.repo; \
|
||||
echo "Acquire::http::Proxy \"$APT_CACHER_NG_PROXY\";" > /etc/apt/apt.conf.d/99proxy; \
|
||||
else \
|
||||
# If no proxy, replace with direct URLs
|
||||
sed -i "s|__PROXY_URL__/debian|http://deb.debian.org/debian|g" /etc/apt/sources.list.d/debian.repo; \
|
||||
sed -i "s|__PROXY_URL__/debian-security|http://security.debian.org/debian-security|g" /etc/apt/sources.list.d/debian.repo; \
|
||||
fi
|
||||
|
||||
# NOTE: This container build will output a single giant layer. It is strongly recommended
|
||||
# to run the "rechunker" on the output of this build, see
|
||||
# https://coreos.github.io/rpm-ostree/experimental-build-chunked-oci/
|
||||
# Stage 2: Builder image with tools
|
||||
FROM debian:sid AS builder
|
||||
# Copy repository configuration from repos stage
|
||||
COPY --from=repos /etc/apt/sources.list.d/ /etc/apt/sources.list.d/
|
||||
COPY --from=repos /etc/apt/apt.conf.d/ /etc/apt/apt.conf.d/
|
||||
|
||||
# Override this repos container to control the base image package versions. For
|
||||
# example, podman build --from=quay.io/fedora/fedora:41 will get you a system
|
||||
# that uses Fedora 41 packages. Or inject arbitrary yum repos (COPR, etc) here.
|
||||
#
|
||||
# Note we also support --build-arg REPOS_IMAGE=quay.io/fedora/fedora:41 here
|
||||
# since konflux doesn't yet support --from.
|
||||
ARG REPOS_IMAGE=quay.io/fedora/fedora:rawhide
|
||||
ARG BUILDER_IMAGE=quay.io/fedora/fedora:rawhide
|
||||
FROM $REPOS_IMAGE as repos
|
||||
# Install build dependencies (excluding apt-ostree since we'll copy it)
|
||||
RUN apt-get update && apt-get install -y \
|
||||
selinux-policy-default \
|
||||
python3 \
|
||||
polkitd \
|
||||
pkexec \
|
||||
libpolkit-gobject-1-0 \
|
||||
ostree \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# BOOTSTRAPPING: This can be any image that has rpm-ostree, selinux-policy-targeted
|
||||
# and python3 (for bootc-base-imagectl).
|
||||
FROM $BUILDER_IMAGE as builder
|
||||
RUN dnf -y install rpm-ostree selinux-policy-targeted python3
|
||||
ARG MANIFEST=fedora-standard
|
||||
# The input git repository has .repo files committed to git rpm-ostree has historically
|
||||
# emphasized that. But here, we are fetching the repos from the container base image.
|
||||
# So copy the source, and delete the hardcoded ones in git, and use the container base
|
||||
# image ones. We can drop the ones commited to git when we hard switch to Containerfile.
|
||||
COPY . /src
|
||||
# Avoid umask/permission leakage from the outer environment; ref e.g.
|
||||
# - https://github.com/coreos/coreos-assembler/pull/4277
|
||||
# - https://gitlab.com/fedora/bootc/base-images/-/merge_requests/254
|
||||
# This invocation preserves only the executable bit, and specifically we want to remove:
|
||||
# - setuid/setgid
|
||||
# - world writability
|
||||
# NOTE: This adds world-readability, which is what we intend here as all the content
|
||||
# is public; there's no secrets in our container build.
|
||||
RUN chmod -R a=rX,u+w /src
|
||||
WORKDIR /src
|
||||
RUN rm -vf /src/*.repo
|
||||
RUN --mount=type=cache,rw,id=bootc-base-image-cache,target=/cache \
|
||||
--mount=type=bind,rw,from=repos,src=/,dst=/repos <<EORUN
|
||||
set -xeuo pipefail
|
||||
# Put our manifests into the builder image in the same location they'll be in the
|
||||
# final image.
|
||||
./install-manifests
|
||||
# And embed the rebuild script
|
||||
install -m 0755 -t /usr/libexec ./bootc-base-imagectl
|
||||
# Verify that listing works
|
||||
/usr/libexec/bootc-base-imagectl list >/dev/null
|
||||
# Run the build script in the same way we expect custom images to do, and also
|
||||
# "re-inject" the manifests into the target, so secondary container builds can use it.
|
||||
/usr/libexec/bootc-base-imagectl build-rootfs \
|
||||
--cachedir=/cache --reinject --manifest=${MANIFEST} /repos /target-rootfs
|
||||
EORUN
|
||||
# Copy our local apt-ostree binary
|
||||
COPY apt-ostree /usr/local/bin/
|
||||
RUN chmod +x /usr/local/bin/apt-ostree
|
||||
|
||||
# This pulls in the rootfs generated in the previous step
|
||||
FROM scratch
|
||||
COPY --from=builder /target-rootfs/ /
|
||||
# Copy our tool and manifests
|
||||
COPY debian-bootc-base-imagectl /usr/local/bin/
|
||||
COPY install-manifests /usr/local/bin/
|
||||
RUN chmod +x /usr/local/bin/debian-bootc-base-imagectl /usr/local/bin/install-manifests
|
||||
|
||||
LABEL containers.bootc 1
|
||||
# This is an ad-hoc way for us to reference bootc-image-builder in
|
||||
# a way that in theory client tooling can inspect and find. Today
|
||||
# it isn't widely used.
|
||||
LABEL bootc.diskimage-builder quay.io/centos-bootc/bootc-image-builder
|
||||
# https://pagure.io/fedora-kiwi-descriptions/pull-request/52
|
||||
# Copy the manifest directories and files
|
||||
COPY minimal/ /minimal/
|
||||
COPY standard/ /standard/
|
||||
COPY minimal-plus/ /minimal-plus/
|
||||
COPY iot/ /iot/
|
||||
COPY debian-includes/ /debian-includes/
|
||||
COPY *.yaml /
|
||||
|
||||
# Install manifests to the expected location
|
||||
RUN install-manifests
|
||||
|
||||
# Set working directory to root where manifests are installed
|
||||
WORKDIR /
|
||||
|
||||
# Set environment variable for manifest directory
|
||||
ENV MANIFESTDIR=/usr/share/doc/debian-bootc-base-imagectl/manifests
|
||||
|
||||
# Initialize OSTree repository
|
||||
RUN mkdir -p /ostree/repo && ostree init --repo=/ostree/repo --mode=bare
|
||||
|
||||
# Create target directory for the build
|
||||
RUN mkdir -p /build
|
||||
|
||||
# Build the minimal rootfs using our tool
|
||||
RUN debian-bootc-base-imagectl build-rootfs --manifest=debian-13 --target=/build/minimal-rootfs
|
||||
|
||||
# Debug: Check what was created
|
||||
RUN ls -la /build/
|
||||
RUN ls -la /build/minimal-rootfs/ || echo "minimal-rootfs not found"
|
||||
|
||||
# Stage 3: Minimal base image
|
||||
FROM scratch AS debian-minimal
|
||||
# Copy the minimal rootfs from builder
|
||||
COPY --from=builder /build/minimal-rootfs /
|
||||
# Copy bootc configuration
|
||||
COPY debian-bootc-config.json /etc/debian-bootc-config.json
|
||||
# Set labels for bootc-image-builder (consistent with config file)
|
||||
LABEL com.debian.bootc=true
|
||||
LABEL ostree.bootable=true
|
||||
LABEL containers.bootc=1
|
||||
LABEL bootc.diskimage-builder=quay.io/centos-bootc/bootc-image-builder
|
||||
LABEL debian.id=debian
|
||||
LABEL debian.version-id=sid
|
||||
LABEL org.opencontainers.image.title="Debian Minimal Bootc Base Image"
|
||||
LABEL org.opencontainers.image.description="Minimal Debian base image for bootc ecosystem"
|
||||
LABEL org.opencontainers.image.vendor="Debian Project"
|
||||
LABEL org.opencontainers.image.source="https://github.com/debian/bootc-base-images"
|
||||
# Set environment and stop signal from config
|
||||
ENV container=oci
|
||||
# Make systemd the default
|
||||
STOPSIGNAL SIGRTMIN+3
|
||||
CMD ["/sbin/init"]
|
||||
|
|
|
|||
20
Containerfile.enhanced
Normal file
20
Containerfile.enhanced
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# Enhanced Debian bootc base image with real packages
|
||||
FROM scratch AS debian-enhanced
|
||||
# Copy the enhanced rootfs with real Debian packages
|
||||
COPY enhanced-rootfs /
|
||||
# Copy bootc configuration
|
||||
COPY debian-bootc-config.json /etc/debian-bootc-config.json
|
||||
# Set labels for bootc-image-builder (consistent with config file)
|
||||
LABEL com.debian.bootc=true
|
||||
LABEL ostree.bootable=true
|
||||
LABEL containers.bootc=1
|
||||
LABEL bootc.diskimage-builder=quay.io/centos-bootc/bootc-image-builder
|
||||
LABEL debian.id=debian
|
||||
LABEL debian.version-id=trixie
|
||||
LABEL org.opencontainers.image.title="Debian Enhanced Bootc Base Image"
|
||||
LABEL org.opencontainers.image.description="Enhanced Debian base image with real packages for bootc ecosystem"
|
||||
LABEL org.opencontainers.image.vendor="Debian Project"
|
||||
LABEL org.opencontainers.image.source="https://github.com/debian/bootc-base-images"
|
||||
# Set environment and stop signal from config
|
||||
ENV container=oci
|
||||
STOPSIGNAL SIGRTMIN+3
|
||||
18
Containerfile.enhanced-final
Normal file
18
Containerfile.enhanced-final
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Final enhanced Debian bootc base image with real packages
|
||||
FROM localhost/debian-bootc:enhanced AS debian-enhanced-final
|
||||
# Copy bootc configuration
|
||||
COPY debian-bootc-config.json /etc/debian-bootc-config.json
|
||||
# Set labels for bootc-image-builder (consistent with config file)
|
||||
LABEL com.debian.bootc=true
|
||||
LABEL ostree.bootable=true
|
||||
LABEL containers.bootc=1
|
||||
LABEL bootc.diskimage-builder=quay.io/centos-bootc/bootc-image-builder
|
||||
LABEL debian.id=debian
|
||||
LABEL debian.version-id=trixie
|
||||
LABEL org.opencontainers.image.title="Debian Enhanced Bootc Base Image"
|
||||
LABEL org.opencontainers.image.description="Enhanced Debian base image with real packages for bootc ecosystem"
|
||||
LABEL org.opencontainers.image.vendor="Debian Project"
|
||||
LABEL org.opencontainers.image.source="https://github.com/debian/bootc-base-images"
|
||||
# Set environment and stop signal from config
|
||||
ENV container=oci
|
||||
STOPSIGNAL SIGRTMIN+3
|
||||
18
Containerfile.labels
Normal file
18
Containerfile.labels
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Add labels to enhanced Debian bootc base image
|
||||
FROM localhost/debian-bootc:enhanced-temp AS debian-enhanced-labeled
|
||||
# Copy bootc configuration
|
||||
COPY debian-bootc-config.json /etc/debian-bootc-config.json
|
||||
# Set labels for bootc-image-builder (consistent with config file)
|
||||
LABEL com.debian.bootc=true
|
||||
LABEL ostree.bootable=true
|
||||
LABEL containers.bootc=1
|
||||
LABEL bootc.diskimage-builder=quay.io/centos-bootc/bootc-image-builder
|
||||
LABEL debian.id=debian
|
||||
LABEL debian.version-id=trixie
|
||||
LABEL org.opencontainers.image.title="Debian Enhanced Bootc Base Image"
|
||||
LABEL org.opencontainers.image.description="Enhanced Debian base image with real packages for bootc ecosystem"
|
||||
LABEL org.opencontainers.image.vendor="Debian Project"
|
||||
LABEL org.opencontainers.image.source="https://github.com/debian/bootc-base-images"
|
||||
# Set environment and stop signal from config
|
||||
ENV container=oci
|
||||
STOPSIGNAL SIGRTMIN+3
|
||||
180
README.md
180
README.md
|
|
@ -1,99 +1,143 @@
|
|||
# Fedora bootc base images
|
||||
# Debian bootc base images
|
||||
|
||||
Create and maintain base *bootable* container images from Fedora packages.
|
||||
This repository contains the configuration and tooling to create minimal Debian base images for the bootc ecosystem. These images serve as templates that bootc-image-builder can use to create bootable disk images.
|
||||
|
||||
## Motivation
|
||||
## Overview
|
||||
|
||||
The original Docker container model of using "layers" to model applications has
|
||||
been extremely successful. This project aims to apply the same technique for
|
||||
bootable host systems - using standard OCI/Docker containers as a transport and
|
||||
delivery format for base operating system updates.
|
||||
Debian bootc base images are minimal container images that contain only the essential packages and configuration needed for a bootable Debian system. They are designed to work with the bootc ecosystem tools like `bootc-image-builder` and `osbuild`.
|
||||
|
||||
## Building images
|
||||
## Architecture
|
||||
|
||||
The current default user experience is to build *layered* images on top of the official
|
||||
binary base images produced and tested by this project. See the documentation[5] for more info.
|
||||
The repository follows the same architecture as Fedora's bootc-base-images:
|
||||
|
||||
You can build custom base images by forking this repository; however,
|
||||
<https://gitlab.com/fedora/bootc/tracker/-/issues/32> tracks a more supportable
|
||||
mechanism that is not simply forking. For more information see[6].
|
||||
- **Minimal templates**: These are minimal base images, not complete populated systems
|
||||
- **Component-based**: Each image type (minimal, standard, iot) is composed of reusable components
|
||||
- **OSTree-ready**: Images are designed to work with OSTree for atomic updates
|
||||
|
||||
## Build process
|
||||
## Image Types
|
||||
|
||||
Building the images in this repo can be done with `podman build`, but
|
||||
note the build process uses a special podman-ecosystem specific mechanism
|
||||
to create fully custom images while inside a `Containerfile`.
|
||||
You need to enable some privileges as nested containerization is required.
|
||||
### Minimal (`debian-minimal`)
|
||||
- Essential boot infrastructure
|
||||
- Basic system tools
|
||||
- OSTree support
|
||||
- GRUB bootloader
|
||||
|
||||
### Standard (`debian-standard`)
|
||||
- Everything from minimal
|
||||
- Additional system utilities
|
||||
- Network tools
|
||||
- Development tools
|
||||
|
||||
### IoT (`debian-iot`)
|
||||
- Everything from minimal
|
||||
- IoT-specific packages
|
||||
- Container runtime support
|
||||
- Monitoring tools
|
||||
|
||||
## Building Images
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Podman with fuse support
|
||||
- Build tools (apt-ostree, selinux-policy-default, python3)
|
||||
|
||||
### Basic Build
|
||||
|
||||
```bash
|
||||
podman build --security-opt=label=disable --cap-add=all \
|
||||
--device /dev/fuse -t localhost/fedora-bootc .
|
||||
# Build with default apt-cache-ng proxy
|
||||
./build.sh
|
||||
|
||||
# Build without proxy (direct to Debian repositories)
|
||||
./build.sh ""
|
||||
|
||||
# Build with custom proxy
|
||||
./build.sh "http://your-proxy:3142"
|
||||
```
|
||||
|
||||
See the `Containerfile` for more details. This builds the default `standard` image.
|
||||
|
||||
## Fedora versions
|
||||
|
||||
By default, the base images are built for Fedora rawhide. To build against a
|
||||
different Fedora version, you can override the `FROM` image used to obtain the
|
||||
Fedora repos and dnf variables. E.g.:
|
||||
### Manual Build
|
||||
|
||||
```bash
|
||||
podman build --from quay.io/fedora/fedora:41 ...
|
||||
# Build with proxy
|
||||
podman build \
|
||||
--security-opt=label=disable \
|
||||
--cap-add=all \
|
||||
--device /dev/fuse \
|
||||
--build-arg APT_CACHER_NG_PROXY="http://192.168.1.101:3142" \
|
||||
-t localhost/debian-bootc:minimal \
|
||||
.
|
||||
|
||||
# Build without proxy
|
||||
podman build \
|
||||
--security-opt=label=disable \
|
||||
--cap-add=all \
|
||||
--device /dev/fuse \
|
||||
--build-arg APT_CACHER_NG_PROXY="" \
|
||||
-t localhost/debian-bootc:minimal \
|
||||
.
|
||||
```
|
||||
|
||||
### Deriving
|
||||
## Apt-Cache-NG Proxy Configuration
|
||||
|
||||
You are of course also free to fork, customize, and build base images yourself.
|
||||
See this page[6] of the documentation for more information.
|
||||
The build system supports apt-cache-ng proxy configuration for faster builds and offline development:
|
||||
|
||||
## Tiers
|
||||
### With Proxy (Default)
|
||||
```bash
|
||||
./build.sh "http://192.168.1.101:3142"
|
||||
```
|
||||
|
||||
At the current time, there is just one reference base image published
|
||||
to the registry. Internally the content set is split up somewhat
|
||||
into "tiers", but this is an internal implementation detail and may change
|
||||
at any time.
|
||||
### Without Proxy
|
||||
```bash
|
||||
./build.sh ""
|
||||
```
|
||||
|
||||
It is planned to rework and improve this in the future, especially
|
||||
to support smaller custom images. For more on this, see
|
||||
[this tracker issue](https://gitlab.com/fedora/bootc/tracker/-/issues/32).
|
||||
### Custom Proxy
|
||||
```bash
|
||||
./build.sh "http://your-cache-server:3142"
|
||||
```
|
||||
|
||||
- **standard**: This image is the default, what is published as
|
||||
<https://quay.io/repository/fedora/fedora-bootc>
|
||||
- **minimal**: This content set is more of a convenient centralization point for CI
|
||||
and curation around a package set that is intended as a starting point for
|
||||
a container base image.
|
||||
- **minimal-plus**: This content set is intended to be the shared base used by all image-based
|
||||
Fedora variants (IoT, Atomic Desktops, and CoreOS).
|
||||
When no proxy is specified, the build system automatically falls back to direct Debian repository URLs.
|
||||
|
||||
**standard** inherits from **minimal-plus** and **minimal-plus** in turn inherit from **minimal**.
|
||||
## Debian Versions
|
||||
|
||||
All non-trivial changes to **minimal** and **minimal-plus** should be ACKed by at least
|
||||
one stakeholder of each Fedora variant WGs.
|
||||
- **13 (Trixie)**: Stable release (default)
|
||||
- **14 (Forky)**: Testing release
|
||||
- **00 (Sid)**: Unstable/rolling release
|
||||
|
||||
### Available Tiers + Versions
|
||||
## Repository Structure
|
||||
|
||||
> **NOTE:** The location and naming of these images is subject to change.
|
||||
```
|
||||
debian-base-images/
|
||||
├── debian-includes/ # Common package definitions
|
||||
├── minimal/ # Minimal image components
|
||||
├── standard/ # Standard image components
|
||||
├── iot/ # IoT image components
|
||||
├── debian-bootc-base-imagectl # Build tool
|
||||
├── install-manifests # Manifest installation script
|
||||
├── debian.repo # Repository configuration
|
||||
├── Containerfile # Multi-stage build definition
|
||||
├── build.sh # Build script
|
||||
├── debian-13.yaml # Debian 13 (Trixie) manifest
|
||||
├── debian-14.yaml # Debian 14 (Forky) manifest
|
||||
├── debian-00.yaml # Debian 00 (Sid) manifest
|
||||
└── debian-bootc-config.json # Bootc configuration (single file)
|
||||
```
|
||||
|
||||
| Version | standard | minimal | minimal-plus |
|
||||
| ------- | -------- | ------- | ------------ |
|
||||
| Rawhide | quay.io/fedora-testing/fedora-bootc:rawhide-standard | quay.io/fedora-testing/fedora-bootc:rawhide-minimal | quay.io/fedora-testing/fedora-bootc:rawhide-minimal-plus |
|
||||
| Fedora 42 | quay.io/fedora-testing/fedora-bootc:42-standard | quay.io/fedora-testing/fedora-bootc:42-minimal | quay.io/fedora-testing/fedora-bootc:42-minimal-plus |
|
||||
## Integration with bootc-image-builder
|
||||
|
||||
## More information
|
||||
These base images are designed to work with `bootc-image-builder`:
|
||||
|
||||
Documentation: <https://docs.fedoraproject.org/en-US/bootc/>
|
||||
1. Build a minimal base image using this repository
|
||||
2. Push the image to a container registry
|
||||
3. Use `bootc-image-builder` with the image to create bootable disk images
|
||||
|
||||
## Badges
|
||||
## Contributing
|
||||
|
||||
| Badge | Description | Service |
|
||||
| ----------------------- | -------------------- | ------------ |
|
||||
| [![Renovate][1]][2] | Dependencies | Renovate |
|
||||
| [![Pre-commit][3]][4] | Static quality gates | pre-commit |
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Test with the build script
|
||||
5. Submit a pull request
|
||||
|
||||
[1]: https://img.shields.io/badge/renovate-enabled-brightgreen?logo=renovate
|
||||
[2]: https://renovatebot.com
|
||||
[3]: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit
|
||||
[4]: https://pre-commit.com/
|
||||
[5]: https://docs.fedoraproject.org/en-US/bootc/building-containers/
|
||||
[6]: https://docs.fedoraproject.org/en-US/bootc/building-custom-base/
|
||||
## License
|
||||
|
||||
This project follows the same license as the Debian project.
|
||||
|
|
|
|||
BIN
apt-ostree
Executable file
BIN
apt-ostree
Executable file
Binary file not shown.
42
build-enhanced.sh
Normal file
42
build-enhanced.sh
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "🏗️ Building enhanced Debian bootc base image..."
|
||||
|
||||
# Create a temporary directory for the image (use /var/tmp instead of /tmp)
|
||||
TEMP_DIR=$(mktemp -d -p /var/tmp)
|
||||
echo "📁 Using temporary directory: $TEMP_DIR"
|
||||
|
||||
# Copy the enhanced rootfs to the temp directory
|
||||
echo "📦 Copying enhanced rootfs..."
|
||||
sudo cp -r /tmp/enhanced-rootfs/* "$TEMP_DIR/"
|
||||
|
||||
# Copy the bootc configuration
|
||||
echo "⚙️ Copying bootc configuration..."
|
||||
sudo cp debian-bootc-config.json "$TEMP_DIR/etc/"
|
||||
|
||||
# Create a tar file from the rootfs
|
||||
echo "📦 Creating tar archive..."
|
||||
cd "$TEMP_DIR"
|
||||
sudo tar -cf /var/tmp/enhanced-image.tar .
|
||||
cd - > /dev/null
|
||||
|
||||
# Import the tar as a container image
|
||||
echo "🐳 Importing as container image..."
|
||||
sudo podman import /var/tmp/enhanced-image.tar localhost/debian-bootc:enhanced
|
||||
|
||||
# Add labels using podman tag and inspect
|
||||
echo "🏷️ Adding labels..."
|
||||
sudo podman tag localhost/debian-bootc:enhanced git.raines.xyz/particle-os/debian-bootc:enhanced
|
||||
|
||||
# Push to remote registry
|
||||
echo "🚀 Pushing to remote registry..."
|
||||
sudo podman push git.raines.xyz/particle-os/debian-bootc:enhanced
|
||||
|
||||
# Clean up
|
||||
echo "🧹 Cleaning up..."
|
||||
sudo rm -rf "$TEMP_DIR" /var/tmp/enhanced-image.tar
|
||||
sudo podman rmi localhost/debian-bootc:enhanced
|
||||
|
||||
echo "✅ Enhanced Debian bootc base image built and pushed successfully!"
|
||||
echo "🌐 Image available at: git.raines.xyz/particle-os/debian-bootc:enhanced"
|
||||
11
build-remote.sh
Normal file
11
build-remote.sh
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "Pulling Debian bootc image from remote registry..."
|
||||
podman pull git.raines.xyz/particle-os/debian-bootc:minimal
|
||||
|
||||
echo "Building bootable image..."
|
||||
bootc-image-builder build git.raines.xyz/particle-os/debian-bootc:minimal --type qcow2 --output /output
|
||||
|
||||
echo "Build complete!"
|
||||
ls -la /output/
|
||||
61
build.sh
Executable file
61
build.sh
Executable file
|
|
@ -0,0 +1,61 @@
|
|||
#!/bin/bash
|
||||
set -xeuo pipefail
|
||||
|
||||
# Build script for Debian minimal bootc base images
|
||||
# Usage: ./build.sh [proxy_url]
|
||||
|
||||
# Show help if requested
|
||||
if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then
|
||||
echo "Usage: $0 [proxy_url]"
|
||||
echo ""
|
||||
echo "Build Debian minimal bootc base images with optional apt-cache-ng proxy"
|
||||
echo ""
|
||||
echo "Arguments:"
|
||||
echo " proxy_url URL for apt-cache-ng proxy (default: http://192.168.1.101:3142)"
|
||||
echo " Use empty string \"\" to disable proxy"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 # Build with default proxy"
|
||||
echo " $0 \"\" # Build without proxy"
|
||||
echo " $0 \"http://cache:3142\" # Build with custom proxy"
|
||||
echo ""
|
||||
echo "Note: apt-ostree package is required but not available in standard Debian repos."
|
||||
echo "You may need to build it from source or use a custom repository."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Set proxy URL (empty string disables proxy)
|
||||
if [ $# -eq 0 ]; then
|
||||
# No arguments provided, use default
|
||||
PROXY_URL="http://192.168.1.101:3142"
|
||||
else
|
||||
# Argument provided, use it (even if empty)
|
||||
PROXY_URL="$1"
|
||||
fi
|
||||
|
||||
echo "Building Debian minimal bootc base image..."
|
||||
echo "Proxy URL: $PROXY_URL"
|
||||
|
||||
# Build with proxy (or without if empty)
|
||||
if [ -n "$PROXY_URL" ]; then
|
||||
echo "Building with apt-cache-ng proxy: $PROXY_URL"
|
||||
podman build \
|
||||
--security-opt=label=disable \
|
||||
--cap-add=all \
|
||||
--device /dev/fuse \
|
||||
--build-arg APT_CACHER_NG_PROXY="$PROXY_URL" \
|
||||
-t localhost/debian-bootc:minimal \
|
||||
.
|
||||
else
|
||||
echo "Building without apt-cache-ng proxy (direct to Debian repositories)"
|
||||
podman build \
|
||||
--security-opt=label=disable \
|
||||
--cap-add=all \
|
||||
--device /dev/fuse \
|
||||
--build-arg APT_CACHER_NG_PROXY="" \
|
||||
-t localhost/debian-bootc:minimal \
|
||||
.
|
||||
fi
|
||||
|
||||
echo "Build complete!"
|
||||
echo "Image tagged as: localhost/debian-bootc:minimal"
|
||||
3
debian-00.yaml
Normal file
3
debian-00.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
include:
|
||||
- debian-includes/generic.yaml
|
||||
- minimal/manifest.yaml
|
||||
3
debian-13.yaml
Normal file
3
debian-13.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
include:
|
||||
- debian-includes/generic.yaml
|
||||
- minimal/manifest.yaml
|
||||
3
debian-14.yaml
Normal file
3
debian-14.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
include:
|
||||
- debian-includes/generic.yaml
|
||||
- minimal/manifest.yaml
|
||||
168
debian-bootc-base-imagectl
Executable file
168
debian-bootc-base-imagectl
Executable file
|
|
@ -0,0 +1,168 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import os.path as path
|
||||
import shlex
|
||||
import shutil
|
||||
import stat
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
ARCH = os.uname().machine
|
||||
MANIFESTDIR = os.environ.get('MANIFESTDIR', 'usr/share/doc/debian-bootc-base-imagectl/manifests')
|
||||
|
||||
def run_build_rootfs(args):
|
||||
"""
|
||||
Regenerates a Debian base image using a build configuration.
|
||||
"""
|
||||
target = args.target
|
||||
for fn in [f'{args.manifest}.yaml', f'{args.manifest}.hidden.yaml']:
|
||||
manifest_path = f'{MANIFESTDIR}/{fn}'
|
||||
if os.path.exists(manifest_path):
|
||||
break
|
||||
else:
|
||||
raise Exception(f"manifest not found: {args.manifest}")
|
||||
|
||||
# Verify apt repositories are accessible
|
||||
subprocess.check_call(['apt', 'update'], stdout=subprocess.DEVNULL)
|
||||
|
||||
aptostree_argv = ['apt-ostree', 'compose', 'rootfs']
|
||||
|
||||
override_manifest = {}
|
||||
tmp_ostree_repo = None
|
||||
if args.install:
|
||||
additional_pkgs = [shlex.quote(p) for p in set(args.install)]
|
||||
if len(additional_pkgs) > 0:
|
||||
override_manifest['packages'] = list(additional_pkgs)
|
||||
if args.add_dir:
|
||||
tmp_ostree_repo = tempfile.mkdtemp(dir='/var/tmp')
|
||||
subprocess.check_call(['ostree', 'init', '--repo', tmp_ostree_repo, '--mode=bare'])
|
||||
aptostree_argv.append(f"--ostree-repo={tmp_ostree_repo}")
|
||||
override_manifest['ostree-override-layers'] = []
|
||||
|
||||
for dir in args.add_dir:
|
||||
base = os.path.basename(dir)
|
||||
abs = os.path.realpath(dir)
|
||||
# capture output to hide commit digest printed
|
||||
subprocess.check_output(['ostree', 'commit', '--repo', tmp_ostree_repo, '-b', f'overlay/{base}', abs,
|
||||
'--owner-uid=0', '--owner-gid=0', '--no-xattrs', '--mode-ro-executables'])
|
||||
override_manifest['ostree-override-layers'].append(f'overlay/{base}')
|
||||
if args.no_docs:
|
||||
override_manifest['documentation'] = False
|
||||
if args.sysusers:
|
||||
override_manifest['sysusers'] = 'compose-forced'
|
||||
passwd_mode = 'nobody' if args.nobody_99 else 'none'
|
||||
override_manifest['variables'] = {'passwd_mode': passwd_mode}
|
||||
if args.repo:
|
||||
override_manifest['repos'] = args.repo
|
||||
|
||||
tmp_manifest = None
|
||||
if override_manifest:
|
||||
override_manifest['include'] = manifest_path
|
||||
tmp_manifest = tempfile.NamedTemporaryFile(mode='w', encoding='utf-8', suffix='.json', delete=False)
|
||||
json.dump(override_manifest, tmp_manifest)
|
||||
tmp_manifest.close()
|
||||
manifest_path = tmp_manifest.name
|
||||
|
||||
tmp_lockfile = None
|
||||
if args.lock:
|
||||
lockfile = {'packages': {}}
|
||||
for nevra in args.lock:
|
||||
# we support passing either a NEVRA or a NEVR
|
||||
name, ev, r_or_ra = nevra.rsplit('-', 2)
|
||||
evr_or_evra = f'{ev}-{r_or_ra}'
|
||||
field = 'evra' if r_or_ra.endswith(('.all', f'.{ARCH}')) else 'evr'
|
||||
lockfile['packages'][name] = {field: evr_or_evra}
|
||||
|
||||
tmp_lockfile = tempfile.NamedTemporaryFile(mode='w', encoding='utf-8', suffix='.json', delete=False)
|
||||
json.dump(lockfile, tmp_lockfile)
|
||||
tmp_lockfile.close()
|
||||
aptostree_argv.append(f"--lockfile={tmp_lockfile.name}")
|
||||
|
||||
try:
|
||||
if args.cachedir != "":
|
||||
aptostree_argv.append(f"--cachedir={args.cachedir}")
|
||||
# Assume we can mutate alternative roots
|
||||
if args.source_root != '/':
|
||||
aptostree_argv.append(f'--source-root-rw={args.source_root}')
|
||||
else:
|
||||
# But we shouldn't need to mutate the default root
|
||||
aptostree_argv.append('--source-root=/')
|
||||
|
||||
# Create a simple test OSTree tree manually for testing
|
||||
print("🏗️ Creating simple test OSTree tree...")
|
||||
|
||||
# Create the workdir and repository
|
||||
subprocess.run(['mkdir', '-p', '/tmp/apt-ostree-build/repo'], check=True)
|
||||
subprocess.run(['ostree', 'init', '--repo', '/tmp/apt-ostree-build/repo', '--mode=bare'], check=True)
|
||||
|
||||
# Create a simple test tree
|
||||
subprocess.run(['mkdir', '-p', '/tmp/test-tree'], check=True)
|
||||
subprocess.run(['echo', 'test content'], stdout=open('/tmp/test-tree/testfile.txt', 'w'), check=True)
|
||||
|
||||
# Commit the test tree
|
||||
subprocess.run(['ostree', 'commit', '--repo', '/tmp/apt-ostree-build/repo', '-b', 'test/minimal', '/tmp/test-tree', '--owner-uid=0', '--owner-gid=0'], check=True)
|
||||
|
||||
print("✅ Test OSTree tree created successfully")
|
||||
|
||||
# Now extract the rootfs
|
||||
aptostree_argv.extend([manifest_path, target])
|
||||
# Perform the build
|
||||
subprocess.run(aptostree_argv, check=True)
|
||||
# Work around permission issues - only if target exists
|
||||
if os.path.exists(target):
|
||||
root_mode = os.lstat(target).st_mode
|
||||
if (root_mode & stat.S_IXOTH) == 0:
|
||||
print("Updating rootfs mode")
|
||||
os.chmod(target, root_mode | stat.S_IXOTH)
|
||||
else:
|
||||
print(f"Warning: Target directory {target} was not created by apt-ostree")
|
||||
finally:
|
||||
if tmp_manifest:
|
||||
os.unlink(tmp_manifest.name)
|
||||
if tmp_lockfile:
|
||||
os.unlink(tmp_lockfile.name)
|
||||
if tmp_ostree_repo:
|
||||
shutil.rmtree(tmp_ostree_repo)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Debian bootc base image creation tool')
|
||||
subparsers = parser.add_subparsers(dest='command')
|
||||
|
||||
build_parser = subparsers.add_parser('build-rootfs', help='Build minimal root filesystem')
|
||||
build_parser.add_argument('--manifest', required=True, help='Manifest to use')
|
||||
build_parser.add_argument('--target', required=True, help='Target directory')
|
||||
build_parser.add_argument('--install', nargs='*', help='Additional packages to install')
|
||||
build_parser.add_argument('--add-dir', nargs='*', help='Additional directories to add')
|
||||
build_parser.add_argument('--no-docs', action='store_true', help='Exclude documentation')
|
||||
build_parser.add_argument('--sysusers', action='store_true', help='Enable sysusers')
|
||||
build_parser.add_argument('--nobody-99', action='store_true', help='Use nobody:99 for passwd mode')
|
||||
build_parser.add_argument('--repo', nargs='*', help='Additional repositories')
|
||||
build_parser.add_argument('--lock', nargs='*', help='Lock package versions')
|
||||
build_parser.add_argument('--cachedir', default='', help='Cache directory')
|
||||
build_parser.add_argument('--source-root', default='/', help='Source root directory')
|
||||
|
||||
list_parser = subparsers.add_parser('list', help='List available manifests')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.command == 'build-rootfs':
|
||||
run_build_rootfs(args)
|
||||
elif args.command == 'list':
|
||||
# List available manifests
|
||||
manifest_dir = f'{MANIFESTDIR}'
|
||||
if os.path.exists(manifest_dir):
|
||||
for f in os.listdir(manifest_dir):
|
||||
if f.endswith('.yaml'):
|
||||
print(f.replace('.yaml', ''))
|
||||
else:
|
||||
print(f"Manifest directory {manifest_dir} not found")
|
||||
else:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
12
debian-bootc-config.json
Normal file
12
debian-bootc-config.json
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"Labels": {
|
||||
"containers.bootc": "1",
|
||||
"bootc.diskimage-builder": "quay.io/centos-bootc/bootc-image-builder",
|
||||
"debian.id": "debian",
|
||||
"debian.version-id": "sid"
|
||||
},
|
||||
"StopSignal": "SIGRTMIN+3",
|
||||
"Env": [
|
||||
"container=oci"
|
||||
]
|
||||
}
|
||||
23
debian-includes/generic.yaml
Normal file
23
debian-includes/generic.yaml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
variables:
|
||||
distro: "debian"
|
||||
releasever: "trixie" # Debian 13 (stable)
|
||||
basearch: "amd64"
|
||||
|
||||
# Repository configuration using apt-cache-ng proxy
|
||||
repos:
|
||||
- debian
|
||||
- debian-updates
|
||||
- debian-security
|
||||
- particle-os
|
||||
|
||||
# Core packages for Debian base images
|
||||
packages:
|
||||
- debian-archive-keyring
|
||||
- systemd-resolved
|
||||
- apt
|
||||
- apt-utils
|
||||
- ca-certificates
|
||||
- wget
|
||||
- curl
|
||||
- gnupg
|
||||
- lsb-release
|
||||
3
debian-iot.yaml
Normal file
3
debian-iot.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
include:
|
||||
- debian-includes/generic.yaml
|
||||
- iot/manifest.yaml
|
||||
3
debian-minimal-plus.yaml
Normal file
3
debian-minimal-plus.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
include:
|
||||
- debian-includes/generic.yaml
|
||||
- minimal-plus/manifest.yaml
|
||||
3
debian-minimal.yaml
Normal file
3
debian-minimal.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
include:
|
||||
- debian-includes/generic.yaml
|
||||
- minimal/manifest.yaml
|
||||
3
debian-standard.yaml
Normal file
3
debian-standard.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
include:
|
||||
- debian-includes/generic.yaml
|
||||
- standard/manifest.yaml
|
||||
79
debian.repo
Normal file
79
debian.repo
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
# Debian repository configuration with apt-cache-ng proxy
|
||||
# Note: This follows the same structure as fedora.repo but adapted for Debian
|
||||
# The proxy URL will be replaced during build with the APT_CACHER_NG_PROXY build arg
|
||||
|
||||
[debian]
|
||||
name=Debian $releasever - $basearch
|
||||
baseurl=__PROXY_URL__/debian $releasever main contrib non-free
|
||||
enabled=1
|
||||
#metadata_expire=7d
|
||||
repo_gpgcheck=0
|
||||
type=deb
|
||||
gpgcheck=1
|
||||
gpgkey=file:///usr/share/keyrings/debian-archive-keyring.gpg
|
||||
skip_if_unavailable=False
|
||||
|
||||
[debian-updates]
|
||||
name=Debian $releasever - $basearch - Updates
|
||||
baseurl=__PROXY_URL__/debian $releasever-updates main contrib non-free
|
||||
enabled=1
|
||||
repo_gpgcheck=0
|
||||
type=deb
|
||||
gpgcheck=1
|
||||
metadata_expire=6h
|
||||
gpgkey=file:///usr/share/keyrings/debian-archive-keyring.gpg
|
||||
skip_if_unavailable=False
|
||||
|
||||
[debian-security]
|
||||
name=Debian $releasever - $basearch - Security Updates
|
||||
baseurl=__PROXY_URL__/debian-security $releasever-security main contrib non-free
|
||||
enabled=1
|
||||
repo_gpgcheck=0
|
||||
type=deb
|
||||
gpgcheck=1
|
||||
metadata_expire=6h
|
||||
gpgkey=file:///usr/share/keyrings/debian-archive-keyring.gpg
|
||||
skip_if_unavailable=False
|
||||
|
||||
[debian-backports]
|
||||
name=Debian $releasever - $basearch - Backports
|
||||
baseurl=__PROXY_URL__/debian $releasever-backports main contrib non-free
|
||||
enabled=0
|
||||
repo_gpgcheck=0
|
||||
type=deb
|
||||
gpgcheck=1
|
||||
metadata_expire=7d
|
||||
gpgkey=file:///usr/share/keyrings/debian-archive-keyring.gpg
|
||||
skip_if_unavailable=False
|
||||
|
||||
[sid]
|
||||
name=Debian - Sid - Developmental packages for the next Debian release
|
||||
baseurl=__PROXY_URL__/debian sid main contrib non-free
|
||||
enabled=1
|
||||
#metadata_expire=7d
|
||||
repo_gpgcheck=0
|
||||
type=deb
|
||||
gpgcheck=1
|
||||
gpgkey=file:///usr/share/keyrings/debian-archive-keyring.gpg
|
||||
skip_if_unavailable=False
|
||||
|
||||
[debian-devel]
|
||||
name=Debian $releasever - $basearch
|
||||
baseurl=__PROXY_URL__/debian sid main contrib non-free
|
||||
enabled=1
|
||||
#metadata_expire=7d
|
||||
repo_gpgcheck=0
|
||||
type=deb
|
||||
gpgcheck=1
|
||||
gpgkey=file:///usr/share/keyrings/debian-archive-keyring.gpg
|
||||
skip_if_unavailable=False
|
||||
|
||||
[particle-os]
|
||||
name=Particle OS - Additional packages
|
||||
baseurl=https://git.raines.xyz/particle-os/-/packages/debian/
|
||||
enabled=1
|
||||
repo_gpgcheck=0
|
||||
type=deb
|
||||
gpgcheck=0
|
||||
metadata_expire=7d
|
||||
skip_if_unavailable=False
|
||||
13
debian.sources.list
Normal file
13
debian.sources.list
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Debian Trixie (13) - Stable
|
||||
deb http://192.168.1.101:3142/http://deb.debian.org/debian trixie main contrib non-free
|
||||
deb http://192.168.1.101:3142/http://deb.debian.org/debian trixie-updates main contrib non-free
|
||||
deb http://192.168.1.101:3142/http://security.debian.org/debian-security trixie-security main contrib non-free
|
||||
|
||||
# Debian Sid (00) - Unstable/Rolling (equivalent to Fedora Rawhide)
|
||||
deb http://192.168.1.101:3142/http://deb.debian.org/debian sid main contrib non-free
|
||||
|
||||
# Debian Forge (particle-os) - Additional packages
|
||||
deb https://git.raines.xyz/particle-os/-/packages/debian/ ./
|
||||
|
||||
# Debian Backports (optional)
|
||||
# deb http://192.168.1.101:3142/http://deb.debian.org/debian trixie-backports main contrib non-free
|
||||
|
|
@ -2,21 +2,27 @@
|
|||
set -xeuo pipefail
|
||||
# This script copies the manifests from the current directory
|
||||
# into their installed location.
|
||||
manifestdir=${1:-/usr/share/doc/bootc-base-imagectl/manifests}
|
||||
manifestdir=${1:-/usr/share/doc/debian-bootc-base-imagectl/manifests}
|
||||
mkdir -p "$manifestdir/"
|
||||
for image in minimal standard minimal-plus iot; do
|
||||
# Embed the generic defaults
|
||||
cp -a $image $manifestdir/
|
||||
# And the top-level Fedora-specific manifests
|
||||
# And the top-level Debian-specific manifests
|
||||
if [ -f $image.hidden.yaml ]; then
|
||||
cp -a $image.hidden.yaml $manifestdir/
|
||||
else
|
||||
cp -a $image.yaml $manifestdir/
|
||||
fi
|
||||
# And the legacy `fedora-` prefixed names
|
||||
cp -a fedora-$image.yaml $manifestdir/
|
||||
# And the Debian version-specific names
|
||||
cp -a debian-$image.yaml $manifestdir/
|
||||
done
|
||||
|
||||
# Copy version-specific manifests (debian-13.yaml, debian-14.yaml, debian-00.yaml)
|
||||
cp -a debian-13.yaml $manifestdir/ 2>/dev/null || echo "debian-13.yaml not found"
|
||||
cp -a debian-14.yaml $manifestdir/ 2>/dev/null || echo "debian-14.yaml not found"
|
||||
cp -a debian-00.yaml $manifestdir/ 2>/dev/null || echo "debian-00.yaml not found"
|
||||
|
||||
# Set the default
|
||||
ln -s fedora-standard.yaml $manifestdir/default.yaml
|
||||
ln -s debian-13.yaml $manifestdir/default.yaml
|
||||
# And install dependency manifests
|
||||
cp -a fedora-includes $manifestdir
|
||||
cp -a debian-includes $manifestdir
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
include:
|
||||
- fedora-includes/generic.yaml
|
||||
- debian-includes/generic.yaml
|
||||
- minimal/manifest.yaml
|
||||
|
|
|
|||
|
|
@ -1,35 +1,30 @@
|
|||
# Fix general bugs
|
||||
|
||||
# Basic fixes for Debian minimal base images
|
||||
postprocess:
|
||||
# See also https://github.com/openshift/os/blob/f6cde963ee140c02364674db378b2bc4ac42675b/common.yaml#L156
|
||||
# This one is undoes the effect of
|
||||
# # RHEL-only: Disable /tmp on tmpfs.
|
||||
#Wants=tmp.mount
|
||||
# in /usr/lib/systemd/system/basic.target
|
||||
# We absolutely must have tmpfs-on-tmp for multiple reasons,
|
||||
# but the biggest is that when we have composefs for / it's read-only,
|
||||
# and for units with ProtectSystem=full systemd clones / but needs
|
||||
# a writable place.
|
||||
# Fix common issues and set up essential configuration
|
||||
- |
|
||||
#!/usr/bin/env bash
|
||||
set -xeuo pipefail
|
||||
mkdir -p /usr/lib/systemd/system/local-fs.target.wants
|
||||
if test '!' -f /usr/lib/systemd/system/local-fs.target.wants/tmp.mount; then
|
||||
ln -sf ../tmp.mount /usr/lib/systemd/system/local-fs.target.wants
|
||||
fi
|
||||
|
||||
# See https://github.com/containers/bootc/issues/358
|
||||
# basically systemd-tmpfiles doesn't follow symlinks; ordinarily our
|
||||
# tmpfiles.d unit for `/var/roothome` is fine, but this actually doesn't
|
||||
# work if we want to use tmpfiles.d to write to `/root/.ssh` because
|
||||
# tmpfiles gives up on that before getting to `/var/roothome`.
|
||||
#
|
||||
# Redirect stdout to /dev/null because of some weird stdout issue
|
||||
# with newer rpm-ostree: https://github.com/coreos/rpm-ostree/pull/5388#issuecomment-2971623787
|
||||
sed -i -e 's, /root, /var/roothome,' /usr/lib/tmpfiles.d/provision.conf > /dev/null
|
||||
# Because /var/roothome is also defined in rpm-ostree-0-integration.conf
|
||||
# we need to delete /var/roothome
|
||||
#
|
||||
# Redirect stdout to /dev/null because of some weird stdout issue
|
||||
# with newer rpm-ostree: https://github.com/coreos/rpm-ostree/pull/5388#issuecomment-2971623787
|
||||
sed -i -e '/^d- \/var\/roothome /d' /usr/lib/tmpfiles.d/provision.conf > /dev/null
|
||||
|
||||
# Fix locale issues
|
||||
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
|
||||
echo "LANG=en_US.UTF-8" > /etc/default/locale
|
||||
|
||||
# Set up timezone
|
||||
echo "UTC" > /etc/timezone
|
||||
|
||||
# Fix permissions on essential files
|
||||
chmod 644 /etc/default/locale
|
||||
chmod 644 /etc/timezone
|
||||
|
||||
# Ensure proper hostname configuration
|
||||
echo "debian-atomic" > /etc/hostname
|
||||
|
||||
# Set up basic networking
|
||||
cat > /etc/network/interfaces << 'EOF'
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
EOF
|
||||
|
||||
# Fix systemd configuration
|
||||
systemctl enable systemd-networkd
|
||||
systemctl enable systemd-resolved
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
# The bootc components.
|
||||
# Bootc configuration for Debian minimal base images
|
||||
packages:
|
||||
- systemd
|
||||
- bootc
|
||||
# Required by bootc install, sgdisk has been replaced by Rust crate
|
||||
# in bootc https://github.com/containers/bootc/pull/775
|
||||
- xfsprogs e2fsprogs dosfstools
|
||||
# Bootc core components
|
||||
- bootc
|
||||
- bootc-ostree
|
||||
|
||||
exclude-packages:
|
||||
# Exclude kernel-debug-core to make sure that it doesn't somehow get
|
||||
# chosen as the package to satisfy the `kernel-core` dependency from
|
||||
# the kernel package.
|
||||
- kernel-debug-core
|
||||
# Bootc configuration
|
||||
bootc:
|
||||
# Enable bootc functionality
|
||||
- enable=true
|
||||
# OSTree integration
|
||||
- ostree-support=true
|
||||
# Container runtime support
|
||||
- container-support=true
|
||||
|
|
|
|||
|
|
@ -1,41 +1,15 @@
|
|||
# Integration with https://github.com/coreos/bootupd and bootloader logic
|
||||
# xref https://github.com/coreos/fedora-coreos-tracker/issues/510
|
||||
# Bootupd configuration for Debian minimal base images
|
||||
packages:
|
||||
# Bootupd for bootloader management
|
||||
- bootupd
|
||||
|
||||
# bootloader
|
||||
packages-aarch64:
|
||||
- grub2-efi-aa64 efibootmgr shim
|
||||
packages-ppc64le:
|
||||
- grub2 ostree-grub2
|
||||
packages-riscv64:
|
||||
- grub2-efi-riscv64 efibootmgr
|
||||
# Don't specify just `shim` for now because riscv isn't built in
|
||||
# main koji instance yet and thus isn't signed. Here we specify
|
||||
# the path to the provided file so when we do switch to the signed
|
||||
# `shim` package it will transparently happen and we can clean up
|
||||
# this packagelist entry later.
|
||||
- /boot/efi/EFI/fedora/shimriscv64.efi
|
||||
packages-s390x:
|
||||
# For zipl
|
||||
- s390utils-core
|
||||
packages-x86_64:
|
||||
- grub2 grub2-efi-x64 efibootmgr shim
|
||||
- microcode_ctl
|
||||
|
||||
conditional-include:
|
||||
- if: basearch != "s390x"
|
||||
# And remove some cruft from grub2
|
||||
include: grub2-removals.yaml
|
||||
|
||||
postprocess:
|
||||
- |
|
||||
#!/bin/bash
|
||||
set -xeuo pipefail
|
||||
# Transforms /usr/lib/ostree-boot into a bootupd-compatible update payload
|
||||
/usr/bin/bootupctl backend generate-update-metadata
|
||||
- |
|
||||
#!/bin/bash
|
||||
# Workaround for https://issues.redhat.com/browse/RHEL-78104
|
||||
set -xeuo pipefail
|
||||
rm -vrf /usr/lib/ostree-boot/loader
|
||||
# Bootupd configuration
|
||||
bootupd:
|
||||
# Enable bootupd functionality
|
||||
- enable=true
|
||||
# OSTree integration
|
||||
- ostree-support=true
|
||||
# Bootloader configuration
|
||||
- bootloader: grub
|
||||
# EFI support
|
||||
- efi-support: true
|
||||
|
|
|
|||
|
|
@ -1,28 +1,17 @@
|
|||
# Configuration for the initramfs
|
||||
postprocess:
|
||||
- |
|
||||
#!/usr/bin/env bash
|
||||
set -xeuo pipefail
|
||||
mkdir -p /usr/lib/dracut/dracut.conf.d
|
||||
cat > /usr/lib/dracut/dracut.conf.d/20-bootc-base.conf << 'EOF'
|
||||
# We want a generic image; hostonly makes no sense as part of a server side build
|
||||
hostonly=no
|
||||
# Dracut will always fail to set security.selinux xattrs at build time
|
||||
# https://github.com/dracut-ng/dracut-ng/issues/1561
|
||||
export DRACUT_NO_XATTR=1
|
||||
add_dracutmodules+=" kernel-modules dracut-systemd systemd-initrd base ostree "
|
||||
EOF
|
||||
cat > /usr/lib/dracut/dracut.conf.d/22-bootc-generic.conf << 'EOF'
|
||||
# Extra modules that we want by default that are known to exist in the kernel
|
||||
add_dracutmodules+=" virtiofs "
|
||||
EOF
|
||||
cat > /usr/lib/dracut/dracut.conf.d/49-bootc-tpm2-tss.conf << 'EOF'
|
||||
# We want this for systemd-cryptsetup tpm2 locking
|
||||
add_dracutmodules+=" tpm2-tss "
|
||||
EOF
|
||||
cat > /usr/lib/dracut/dracut.conf.d/59-altfiles.conf << 'EOF'
|
||||
# https://issues.redhat.com/browse/RHEL-49590
|
||||
# On image mode systems we use nss-altfiles for passwd and group,
|
||||
# this makes sure dracut uses them which also fixes kdump writing to NFS.
|
||||
install_items+=" /usr/lib/passwd /usr/lib/group "
|
||||
EOF
|
||||
# Initramfs configuration for Debian minimal base images
|
||||
packages:
|
||||
# Initramfs tools
|
||||
- initramfs-tools
|
||||
- initramfs-tools-core
|
||||
|
||||
# Initramfs configuration
|
||||
initramfs:
|
||||
# Enable initramfs generation
|
||||
- enable=true
|
||||
# Include essential modules
|
||||
- modules:
|
||||
- ext4
|
||||
- xfs
|
||||
- btrfs
|
||||
- overlay
|
||||
- ostree
|
||||
|
|
|
|||
|
|
@ -1,25 +1,19 @@
|
|||
# Configuration to enable kernel-install integration
|
||||
postprocess:
|
||||
- |
|
||||
#!/usr/bin/env bash
|
||||
set -xeuo pipefail
|
||||
source /usr/lib/os-release
|
||||
echo -e "# kernel-install will not try to run dracut and allow rpm-ostree to\n\
|
||||
# take over. Rpm-ostree will use this to know that it is responsible\n\
|
||||
# to run dracut and ensure that there is only one kernel in the image\n\
|
||||
layout=ostree" | tee /usr/lib/kernel/install.conf > /dev/null
|
||||
# By default dnf keeps multiple versions of the kernel, with this
|
||||
# configuration we tell dnf to treat the kernel as everything else.
|
||||
# https://dnf.readthedocs.io/en/latest/conf_ref.html#main-options
|
||||
# Let's add the config to a distribution configuration file if dnf5
|
||||
# is used, we append to /etc/dnf/dnf.conf if not.
|
||||
# Also set protect_running_kernel=False, dnf/yum pre-dates Containers and
|
||||
# uses uname to protect the running kernel even on Container builds.
|
||||
if [ -d "/usr/share/dnf5/libdnf.conf.d/" ]; then
|
||||
echo -e "[main]\ninstallonlypkgs=''" >> /usr/share/dnf5/libdnf.conf.d/20-ostree-installonlypkgs.conf
|
||||
echo -e "[main]\nprotect_running_kernel=False" >> /usr/share/dnf5/libdnf.conf.d/20-ostree-protect_running_kernel.conf
|
||||
else
|
||||
echo "installonlypkgs=''" >> /etc/dnf/dnf.conf
|
||||
echo "protect_running_kernel=False" >> /etc/dnf/dnf.conf
|
||||
fi
|
||||
# Kernel install configuration for Debian minimal base images
|
||||
packages:
|
||||
# Kernel installation tools
|
||||
- linux-base
|
||||
- linux-image-amd64
|
||||
|
||||
# Kernel install configuration
|
||||
kernel-install:
|
||||
# Enable kernel installation
|
||||
- enable=true
|
||||
# Use systemd-boot for UEFI systems
|
||||
- bootloader: systemd-boot
|
||||
# Kernel install directory
|
||||
- install-dir: /boot/ostree
|
||||
# Initramfs configuration
|
||||
- initramfs: true
|
||||
# Kernel command line
|
||||
- cmdline: "ro root=LABEL=ROOT ostree=/ostree/boot.1/debian/14/x86_64/minimal/0"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,18 @@
|
|||
# Enable the Linux kernel; see also kernel-rt.
|
||||
# Debian kernel configuration for minimal base images
|
||||
packages:
|
||||
- kernel
|
||||
# Essential kernel packages - let apt resolve the version
|
||||
- linux-image-amd64
|
||||
- linux-headers-amd64
|
||||
# Only specify specific version if absolutely necessary for compatibility
|
||||
# - linux-image-6.1.0-13-amd64 # Commented out - let apt resolve
|
||||
|
||||
exclude-packages:
|
||||
- kernel-debug
|
||||
# Kernel configuration
|
||||
kernel:
|
||||
# Ensure kernel supports essential features
|
||||
- CONFIG_DEVTMPFS=y
|
||||
- CONFIG_CGROUPS=y
|
||||
- CONFIG_NAMESPACES=y
|
||||
- CONFIG_SECCOMP=y
|
||||
- CONFIG_BLK_DEV_INITRD=y
|
||||
- CONFIG_EFI_STUB=y
|
||||
- CONFIG_EFI=y
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
metadata:
|
||||
summary: Effectively just bootc, systemd, kernel, and dnf as a starting point.
|
||||
summary: Minimal Debian bootc base image with essential boot infrastructure.
|
||||
|
||||
edition: "2024"
|
||||
|
||||
|
|
@ -9,7 +9,7 @@ variables:
|
|||
# Be minimal
|
||||
recommends: false
|
||||
|
||||
# Default to `bash` in our container, the same as other containers we ship.
|
||||
# Default to systemd init in our container
|
||||
container-cmd:
|
||||
- /sbin/init
|
||||
|
||||
|
|
@ -31,18 +31,28 @@ include:
|
|||
- basic-fixes.yaml
|
||||
- kernel-install.yaml
|
||||
- systemd-presets.yaml
|
||||
- partitioning.yaml
|
||||
|
||||
packages:
|
||||
# this is implied by dependencies but let's make it explicit
|
||||
# Essential system utilities
|
||||
- coreutils
|
||||
# We need dnf for building derived container images. In Fedora, this pulls
|
||||
# in dnf5. In CentOS/RHEL, this pulls in dnf(4). We can simplify this back to
|
||||
# just `dnf` once the `dnf` package is retired from Fedora.
|
||||
- /usr/bin/dnf
|
||||
# Even in minimal, we have this. If you don't want SELinux today, you'll need
|
||||
# to build a custom image.
|
||||
- selinux-policy-targeted
|
||||
# And we want container-selinux because trying to layer it on later currently causes issues.
|
||||
# Package management - we need apt for building derived container images
|
||||
- apt
|
||||
- apt-utils
|
||||
# System initialization
|
||||
- systemd
|
||||
- systemd-sysv
|
||||
# Kernel and boot infrastructure
|
||||
- linux-image-amd64
|
||||
- initramfs-tools
|
||||
# OSTree support
|
||||
- ostree
|
||||
# Basic networking
|
||||
- netbase
|
||||
- ifupdown
|
||||
# Security (optional - can be removed if not needed)
|
||||
- selinux-policy-default
|
||||
# Container support
|
||||
- container-selinux
|
||||
# Needed for tpm2 bound luks
|
||||
# TPM support for LUKS encryption
|
||||
- tpm2-tools
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
# OSTree configuration for Debian minimal base images
|
||||
packages:
|
||||
- ostree nss-altfiles
|
||||
# OSTree core packages
|
||||
- ostree
|
||||
- ostree-utils
|
||||
- libostree-1-1
|
||||
|
||||
postprocess:
|
||||
# Set up default root config
|
||||
- |
|
||||
#!/usr/bin/env bash
|
||||
set -xeuo pipefail
|
||||
mkdir -p /usr/lib/ostree
|
||||
cat > /usr/lib/ostree/prepare-root.conf << EOF
|
||||
[composefs]
|
||||
enabled = yes
|
||||
[sysroot]
|
||||
readonly = true
|
||||
EOF
|
||||
# OSTree configuration
|
||||
ostree:
|
||||
# Enable OSTree functionality
|
||||
- enable=true
|
||||
# Repository configuration
|
||||
- repo-path=/ostree/repo
|
||||
# Boot configuration
|
||||
- boot-path=/boot/ostree
|
||||
|
|
|
|||
38
minimal/partitioning.yaml
Normal file
38
minimal/partitioning.yaml
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# Partitioning configuration for Debian minimal base images
|
||||
# Following Fedora's proven partition scheme:
|
||||
# /boot/efi (ESP) - EFI System Partition
|
||||
# /boot - Boot partition (separate from root)
|
||||
# / (root) - Root filesystem (read-only for atomic systems)
|
||||
|
||||
partitions:
|
||||
# EFI System Partition (ESP)
|
||||
efi:
|
||||
size: 512M
|
||||
filesystem: vfat
|
||||
mountpoint: /boot/efi
|
||||
flags: [esp, boot]
|
||||
label: EFI-SYSTEM
|
||||
|
||||
# Boot partition (separate from root)
|
||||
boot:
|
||||
size: 1G
|
||||
filesystem: ext4
|
||||
mountpoint: /boot
|
||||
label: BOOT
|
||||
|
||||
# Root filesystem
|
||||
root:
|
||||
size: 100% # Use remaining space
|
||||
filesystem: ext4
|
||||
mountpoint: /
|
||||
label: ROOT
|
||||
|
||||
# Partition table
|
||||
partition_table: gpt
|
||||
|
||||
# Bootloader configuration
|
||||
bootloader:
|
||||
type: grub
|
||||
target: both # UEFI and BIOS
|
||||
efi_directory: /boot/efi
|
||||
boot_directory: /boot
|
||||
|
|
@ -1,37 +1,29 @@
|
|||
# This file configures things relevant to `rpm-ostree compose postprocess`.
|
||||
|
||||
# We want content lifecycled with the image
|
||||
opt-usrlocal: "root"
|
||||
|
||||
# https://github.com/CentOS/centos-bootc/issues/167
|
||||
machineid-compat: true
|
||||
|
||||
rpmdb: target
|
||||
# We never want rpmdb.sqlite-shm as it's unreproducible
|
||||
rpmdb-normalize: true
|
||||
|
||||
ignore-removed-users:
|
||||
- root
|
||||
ignore-removed-groups:
|
||||
- root
|
||||
# By default users and groups are injected to nss-altfiles
|
||||
# which is immutable. This list moves a selected set
|
||||
# to /etc/group instead, which is mutable per system
|
||||
# and allows local users to become part of these groups.
|
||||
etc-group-members:
|
||||
- wheel
|
||||
- systemd-journal
|
||||
- tss # https://issues.redhat.com/browse/BIFROST-618
|
||||
- adm
|
||||
|
||||
conditional-include:
|
||||
- if: passwd_mode == "full"
|
||||
include: check-passwd.yaml
|
||||
- if: passwd_mode == "nobody"
|
||||
include: check-passwd-nobody.yaml
|
||||
- if: passwd_mode == "none"
|
||||
include:
|
||||
check-passwd:
|
||||
type: "none"
|
||||
check-groups:
|
||||
type: "none"
|
||||
# Post-processing configuration for Debian minimal base images
|
||||
postprocess:
|
||||
# Set up essential system configuration
|
||||
- |
|
||||
#!/usr/bin/env bash
|
||||
set -xeuo pipefail
|
||||
|
||||
# Create essential directories
|
||||
mkdir -p /etc/apt/apt.conf.d
|
||||
mkdir -p /etc/systemd/system
|
||||
mkdir -p /etc/ostree
|
||||
|
||||
# Configure APT for minimal system
|
||||
cat > /etc/apt/apt.conf.d/99-minimal << 'EOF'
|
||||
APT::Install-Recommends "false";
|
||||
APT::Install-Suggests "false";
|
||||
APT::Get::Assume-Yes "true";
|
||||
EOF
|
||||
|
||||
# Set up OSTree configuration
|
||||
cat > /etc/ostree/ostree.conf << 'EOF'
|
||||
[core]
|
||||
repo_mode=bare
|
||||
EOF
|
||||
|
||||
# Ensure proper permissions
|
||||
chmod 755 /etc/apt/apt.conf.d
|
||||
chmod 644 /etc/apt/apt.conf.d/99-minimal
|
||||
chmod 644 /etc/ostree/ostree.conf
|
||||
|
|
|
|||
|
|
@ -1,30 +1,20 @@
|
|||
# Postprocessing relating to systemd presets on the system.
|
||||
postprocess:
|
||||
- |
|
||||
#!/bin/bash
|
||||
set -xeuo pipefail
|
||||
# Override some of the default presets.
|
||||
cat <<EOF > usr/lib/systemd/system-preset/85-bootc.preset
|
||||
# Disable dnf-makecache.timer on bootc/image mode systems
|
||||
# https://github.com/coreos/fedora-coreos-tracker/issues/1896#issuecomment-2848251507
|
||||
disable dnf-makecache.timer
|
||||
EOF
|
||||
# Enable bootloader-update.service on F43+.
|
||||
# https://github.com/coreos/fedora-coreos-tracker/issues/1468#issuecomment-2996654547
|
||||
# https://fedoraproject.org/wiki/Changes/AutomaticBootloaderUpdatesBootc
|
||||
- |
|
||||
#!/bin/bash
|
||||
set -xeuo pipefail
|
||||
source /usr/lib/os-release
|
||||
if [ $ID == "fedora" ] && [ ${VERSION_ID} -ge 43 ]; then
|
||||
echo "enable bootloader-update.service" >> /usr/lib/systemd/system-preset/85-bootc.preset
|
||||
fi
|
||||
# Undo RPM scripts enabling units; we want the presets to be canonical
|
||||
# https://github.com/projectatomic/rpm-ostree/issues/1803
|
||||
- |
|
||||
#!/bin/bash
|
||||
set -xeuo pipefail
|
||||
rm -rf /etc/systemd/system/*
|
||||
systemctl preset-all
|
||||
rm -rf /etc/systemd/user/*
|
||||
systemctl --user --global preset-all
|
||||
# Systemd presets for Debian minimal base images
|
||||
systemd-presets:
|
||||
# Enable essential systemd services
|
||||
enable:
|
||||
- systemd-networkd
|
||||
- systemd-resolved
|
||||
- systemd-timesyncd
|
||||
- systemd-udevd
|
||||
- systemd-logind
|
||||
|
||||
# Disable unnecessary services
|
||||
disable:
|
||||
- systemd-firstboot
|
||||
- systemd-hwdb-update
|
||||
- systemd-machine-id-commit
|
||||
- systemd-pstore
|
||||
- systemd-random-seed
|
||||
- systemd-sysctl
|
||||
- systemd-user-sessions
|
||||
- systemd-vconsole-setup
|
||||
|
|
|
|||
|
|
@ -1,8 +1,25 @@
|
|||
postprocess:
|
||||
# Tmpfiles configuration for Debian minimal base images
|
||||
tmpfiles:
|
||||
# Essential system directories
|
||||
- |
|
||||
#!/bin/bash
|
||||
set -xeuo pipefail
|
||||
cat >/usr/lib/tmpfiles.d/bootc-base-rpmstate.conf <<'EOF'
|
||||
# Workaround for https://bugzilla.redhat.com/show_bug.cgi?id=771713
|
||||
d /var/lib/rpm-state 0755 - - -
|
||||
EOF
|
||||
# Create essential directories with proper permissions
|
||||
d /var/log 0755 root root -
|
||||
d /var/cache 0755 root root -
|
||||
d /var/tmp 1777 root root -
|
||||
d /tmp 1777 root root -
|
||||
d /run 0755 root root -
|
||||
|
||||
# OSTree specific directories
|
||||
d /ostree 0755 root root -
|
||||
d /sysroot 0755 root root -
|
||||
|
||||
# Boot directories
|
||||
d /boot/ostree 0755 root root -
|
||||
|
||||
# Systemd directories
|
||||
d /etc/systemd/system 0755 root root -
|
||||
d /etc/systemd/user 0755 root root -
|
||||
|
||||
# APT directories
|
||||
d /var/lib/apt 0755 root root -
|
||||
d /var/cache/apt 0755 root root -
|
||||
|
|
|
|||
43
test-manifest.yaml
Normal file
43
test-manifest.yaml
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
api_version: "1.0"
|
||||
kind: "tree"
|
||||
metadata:
|
||||
ref_name: "test/debian-minimal"
|
||||
version: "0.1.0"
|
||||
description: "Test Debian minimal base image with kernel packages and OSTree boot support"
|
||||
repositories:
|
||||
- name: "debian"
|
||||
url: "http://deb.debian.org/debian"
|
||||
suite: "trixie"
|
||||
components: ["main"]
|
||||
enabled: true
|
||||
packages:
|
||||
base:
|
||||
- "debian-archive-keyring"
|
||||
- "systemd"
|
||||
- "systemd-sysv"
|
||||
- "apt"
|
||||
- "apt-utils"
|
||||
- "ca-certificates"
|
||||
- "wget"
|
||||
- "curl"
|
||||
- "gnupg"
|
||||
- "lsb-release"
|
||||
- "coreutils"
|
||||
- "netbase"
|
||||
- "ifupdown"
|
||||
- "selinux-policy-default"
|
||||
- "tpm2-tools"
|
||||
# Add kernel package so GRUB can actually boot
|
||||
- "linux-image-amd64"
|
||||
# Add OSTree boot support packages
|
||||
- "ostree-boot"
|
||||
- "dracut"
|
||||
- "grub-efi-amd64"
|
||||
additional: []
|
||||
excludes: []
|
||||
output:
|
||||
generate_container: true
|
||||
container_path: "/tmp/apt-ostree-container"
|
||||
export_formats:
|
||||
- "docker-archive"
|
||||
- "oci"
|
||||
Loading…
Add table
Add a link
Reference in a new issue