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
|
# Multi-stage build for Debian minimal bootc base images
|
||||||
# nested containerization, so you must build with e.g.
|
# Stage 1: Repository setup with apt-cache-ng proxy
|
||||||
# podman build --security-opt=label=disable --cap-add=all --device /dev/fuse <...>
|
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
|
# Stage 2: Builder image with tools
|
||||||
# to run the "rechunker" on the output of this build, see
|
FROM debian:sid AS builder
|
||||||
# https://coreos.github.io/rpm-ostree/experimental-build-chunked-oci/
|
# 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
|
# Install build dependencies (excluding apt-ostree since we'll copy it)
|
||||||
# example, podman build --from=quay.io/fedora/fedora:41 will get you a system
|
RUN apt-get update && apt-get install -y \
|
||||||
# that uses Fedora 41 packages. Or inject arbitrary yum repos (COPR, etc) here.
|
selinux-policy-default \
|
||||||
#
|
python3 \
|
||||||
# Note we also support --build-arg REPOS_IMAGE=quay.io/fedora/fedora:41 here
|
polkitd \
|
||||||
# since konflux doesn't yet support --from.
|
pkexec \
|
||||||
ARG REPOS_IMAGE=quay.io/fedora/fedora:rawhide
|
libpolkit-gobject-1-0 \
|
||||||
ARG BUILDER_IMAGE=quay.io/fedora/fedora:rawhide
|
ostree \
|
||||||
FROM $REPOS_IMAGE as repos
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# BOOTSTRAPPING: This can be any image that has rpm-ostree, selinux-policy-targeted
|
# Copy our local apt-ostree binary
|
||||||
# and python3 (for bootc-base-imagectl).
|
COPY apt-ostree /usr/local/bin/
|
||||||
FROM $BUILDER_IMAGE as builder
|
RUN chmod +x /usr/local/bin/apt-ostree
|
||||||
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
|
|
||||||
|
|
||||||
# This pulls in the rootfs generated in the previous step
|
# Copy our tool and manifests
|
||||||
FROM scratch
|
COPY debian-bootc-base-imagectl /usr/local/bin/
|
||||||
COPY --from=builder /target-rootfs/ /
|
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
|
# Copy the manifest directories and files
|
||||||
# This is an ad-hoc way for us to reference bootc-image-builder in
|
COPY minimal/ /minimal/
|
||||||
# a way that in theory client tooling can inspect and find. Today
|
COPY standard/ /standard/
|
||||||
# it isn't widely used.
|
COPY minimal-plus/ /minimal-plus/
|
||||||
LABEL bootc.diskimage-builder quay.io/centos-bootc/bootc-image-builder
|
COPY iot/ /iot/
|
||||||
# https://pagure.io/fedora-kiwi-descriptions/pull-request/52
|
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
|
ENV container=oci
|
||||||
# Make systemd the default
|
|
||||||
STOPSIGNAL SIGRTMIN+3
|
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
|
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`.
|
||||||
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.
|
|
||||||
|
|
||||||
## Building images
|
## Architecture
|
||||||
|
|
||||||
The current default user experience is to build *layered* images on top of the official
|
The repository follows the same architecture as Fedora's bootc-base-images:
|
||||||
binary base images produced and tested by this project. See the documentation[5] for more info.
|
|
||||||
|
|
||||||
You can build custom base images by forking this repository; however,
|
- **Minimal templates**: These are minimal base images, not complete populated systems
|
||||||
<https://gitlab.com/fedora/bootc/tracker/-/issues/32> tracks a more supportable
|
- **Component-based**: Each image type (minimal, standard, iot) is composed of reusable components
|
||||||
mechanism that is not simply forking. For more information see[6].
|
- **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
|
### Minimal (`debian-minimal`)
|
||||||
note the build process uses a special podman-ecosystem specific mechanism
|
- Essential boot infrastructure
|
||||||
to create fully custom images while inside a `Containerfile`.
|
- Basic system tools
|
||||||
You need to enable some privileges as nested containerization is required.
|
- 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
|
```bash
|
||||||
podman build --security-opt=label=disable --cap-add=all \
|
# Build with default apt-cache-ng proxy
|
||||||
--device /dev/fuse -t localhost/fedora-bootc .
|
./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.
|
### Manual Build
|
||||||
|
|
||||||
## 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.:
|
|
||||||
|
|
||||||
```bash
|
```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.
|
The build system supports apt-cache-ng proxy configuration for faster builds and offline development:
|
||||||
See this page[6] of the documentation for more information.
|
|
||||||
|
|
||||||
## 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
|
### Without Proxy
|
||||||
to the registry. Internally the content set is split up somewhat
|
```bash
|
||||||
into "tiers", but this is an internal implementation detail and may change
|
./build.sh ""
|
||||||
at any time.
|
```
|
||||||
|
|
||||||
It is planned to rework and improve this in the future, especially
|
### Custom Proxy
|
||||||
to support smaller custom images. For more on this, see
|
```bash
|
||||||
[this tracker issue](https://gitlab.com/fedora/bootc/tracker/-/issues/32).
|
./build.sh "http://your-cache-server:3142"
|
||||||
|
```
|
||||||
|
|
||||||
- **standard**: This image is the default, what is published as
|
When no proxy is specified, the build system automatically falls back to direct Debian repository URLs.
|
||||||
<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).
|
|
||||||
|
|
||||||
**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
|
- **13 (Trixie)**: Stable release (default)
|
||||||
one stakeholder of each Fedora variant WGs.
|
- **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 |
|
## Integration with bootc-image-builder
|
||||||
| ------- | -------- | ------- | ------------ |
|
|
||||||
| 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 |
|
|
||||||
|
|
||||||
## 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 |
|
1. Fork the repository
|
||||||
| ----------------------- | -------------------- | ------------ |
|
2. Create a feature branch
|
||||||
| [![Renovate][1]][2] | Dependencies | Renovate |
|
3. Make your changes
|
||||||
| [![Pre-commit][3]][4] | Static quality gates | pre-commit |
|
4. Test with the build script
|
||||||
|
5. Submit a pull request
|
||||||
|
|
||||||
[1]: https://img.shields.io/badge/renovate-enabled-brightgreen?logo=renovate
|
## License
|
||||||
[2]: https://renovatebot.com
|
|
||||||
[3]: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit
|
This project follows the same license as the Debian project.
|
||||||
[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/
|
|
||||||
|
|
|
||||||
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
|
set -xeuo pipefail
|
||||||
# This script copies the manifests from the current directory
|
# This script copies the manifests from the current directory
|
||||||
# into their installed location.
|
# 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/"
|
mkdir -p "$manifestdir/"
|
||||||
for image in minimal standard minimal-plus iot; do
|
for image in minimal standard minimal-plus iot; do
|
||||||
# Embed the generic defaults
|
# Embed the generic defaults
|
||||||
cp -a $image $manifestdir/
|
cp -a $image $manifestdir/
|
||||||
# And the top-level Fedora-specific manifests
|
# And the top-level Debian-specific manifests
|
||||||
if [ -f $image.hidden.yaml ]; then
|
if [ -f $image.hidden.yaml ]; then
|
||||||
cp -a $image.hidden.yaml $manifestdir/
|
cp -a $image.hidden.yaml $manifestdir/
|
||||||
else
|
else
|
||||||
cp -a $image.yaml $manifestdir/
|
cp -a $image.yaml $manifestdir/
|
||||||
fi
|
fi
|
||||||
# And the legacy `fedora-` prefixed names
|
# And the Debian version-specific names
|
||||||
cp -a fedora-$image.yaml $manifestdir/
|
cp -a debian-$image.yaml $manifestdir/
|
||||||
done
|
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
|
# Set the default
|
||||||
ln -s fedora-standard.yaml $manifestdir/default.yaml
|
ln -s debian-13.yaml $manifestdir/default.yaml
|
||||||
# And install dependency manifests
|
# And install dependency manifests
|
||||||
cp -a fedora-includes $manifestdir
|
cp -a debian-includes $manifestdir
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
include:
|
include:
|
||||||
- fedora-includes/generic.yaml
|
- debian-includes/generic.yaml
|
||||||
- minimal/manifest.yaml
|
- minimal/manifest.yaml
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,30 @@
|
||||||
# Fix general bugs
|
# Basic fixes for Debian minimal base images
|
||||||
|
|
||||||
postprocess:
|
postprocess:
|
||||||
# See also https://github.com/openshift/os/blob/f6cde963ee140c02364674db378b2bc4ac42675b/common.yaml#L156
|
# Fix common issues and set up essential configuration
|
||||||
# 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.
|
|
||||||
- |
|
- |
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -xeuo pipefail
|
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
|
# Fix locale issues
|
||||||
ln -sf ../tmp.mount /usr/lib/systemd/system/local-fs.target.wants
|
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
|
||||||
fi
|
echo "LANG=en_US.UTF-8" > /etc/default/locale
|
||||||
|
|
||||||
# See https://github.com/containers/bootc/issues/358
|
# Set up timezone
|
||||||
# basically systemd-tmpfiles doesn't follow symlinks; ordinarily our
|
echo "UTC" > /etc/timezone
|
||||||
# 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
|
# Fix permissions on essential files
|
||||||
# tmpfiles gives up on that before getting to `/var/roothome`.
|
chmod 644 /etc/default/locale
|
||||||
#
|
chmod 644 /etc/timezone
|
||||||
# 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
|
# Ensure proper hostname configuration
|
||||||
sed -i -e 's, /root, /var/roothome,' /usr/lib/tmpfiles.d/provision.conf > /dev/null
|
echo "debian-atomic" > /etc/hostname
|
||||||
# Because /var/roothome is also defined in rpm-ostree-0-integration.conf
|
|
||||||
# we need to delete /var/roothome
|
# Set up basic networking
|
||||||
#
|
cat > /etc/network/interfaces << 'EOF'
|
||||||
# Redirect stdout to /dev/null because of some weird stdout issue
|
auto lo
|
||||||
# with newer rpm-ostree: https://github.com/coreos/rpm-ostree/pull/5388#issuecomment-2971623787
|
iface lo inet loopback
|
||||||
sed -i -e '/^d- \/var\/roothome /d' /usr/lib/tmpfiles.d/provision.conf > /dev/null
|
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:
|
packages:
|
||||||
- systemd
|
# Bootc core components
|
||||||
- bootc
|
- bootc
|
||||||
# Required by bootc install, sgdisk has been replaced by Rust crate
|
- bootc-ostree
|
||||||
# in bootc https://github.com/containers/bootc/pull/775
|
|
||||||
- xfsprogs e2fsprogs dosfstools
|
|
||||||
|
|
||||||
exclude-packages:
|
# Bootc configuration
|
||||||
# Exclude kernel-debug-core to make sure that it doesn't somehow get
|
bootc:
|
||||||
# chosen as the package to satisfy the `kernel-core` dependency from
|
# Enable bootc functionality
|
||||||
# the kernel package.
|
- enable=true
|
||||||
- kernel-debug-core
|
# 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
|
# Bootupd configuration for Debian minimal base images
|
||||||
# xref https://github.com/coreos/fedora-coreos-tracker/issues/510
|
|
||||||
packages:
|
packages:
|
||||||
|
# Bootupd for bootloader management
|
||||||
- bootupd
|
- bootupd
|
||||||
|
|
||||||
# bootloader
|
# Bootupd configuration
|
||||||
packages-aarch64:
|
bootupd:
|
||||||
- grub2-efi-aa64 efibootmgr shim
|
# Enable bootupd functionality
|
||||||
packages-ppc64le:
|
- enable=true
|
||||||
- grub2 ostree-grub2
|
# OSTree integration
|
||||||
packages-riscv64:
|
- ostree-support=true
|
||||||
- grub2-efi-riscv64 efibootmgr
|
# Bootloader configuration
|
||||||
# Don't specify just `shim` for now because riscv isn't built in
|
- bootloader: grub
|
||||||
# main koji instance yet and thus isn't signed. Here we specify
|
# EFI support
|
||||||
# the path to the provided file so when we do switch to the signed
|
- efi-support: true
|
||||||
# `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
|
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,17 @@
|
||||||
# Configuration for the initramfs
|
# Initramfs configuration for Debian minimal base images
|
||||||
postprocess:
|
packages:
|
||||||
- |
|
# Initramfs tools
|
||||||
#!/usr/bin/env bash
|
- initramfs-tools
|
||||||
set -xeuo pipefail
|
- initramfs-tools-core
|
||||||
mkdir -p /usr/lib/dracut/dracut.conf.d
|
|
||||||
cat > /usr/lib/dracut/dracut.conf.d/20-bootc-base.conf << 'EOF'
|
# Initramfs configuration
|
||||||
# We want a generic image; hostonly makes no sense as part of a server side build
|
initramfs:
|
||||||
hostonly=no
|
# Enable initramfs generation
|
||||||
# Dracut will always fail to set security.selinux xattrs at build time
|
- enable=true
|
||||||
# https://github.com/dracut-ng/dracut-ng/issues/1561
|
# Include essential modules
|
||||||
export DRACUT_NO_XATTR=1
|
- modules:
|
||||||
add_dracutmodules+=" kernel-modules dracut-systemd systemd-initrd base ostree "
|
- ext4
|
||||||
EOF
|
- xfs
|
||||||
cat > /usr/lib/dracut/dracut.conf.d/22-bootc-generic.conf << 'EOF'
|
- btrfs
|
||||||
# Extra modules that we want by default that are known to exist in the kernel
|
- overlay
|
||||||
add_dracutmodules+=" virtiofs "
|
- ostree
|
||||||
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
|
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,19 @@
|
||||||
# Configuration to enable kernel-install integration
|
# Kernel install configuration for Debian minimal base images
|
||||||
postprocess:
|
packages:
|
||||||
- |
|
# Kernel installation tools
|
||||||
#!/usr/bin/env bash
|
- linux-base
|
||||||
set -xeuo pipefail
|
- linux-image-amd64
|
||||||
source /usr/lib/os-release
|
|
||||||
echo -e "# kernel-install will not try to run dracut and allow rpm-ostree to\n\
|
# Kernel install configuration
|
||||||
# take over. Rpm-ostree will use this to know that it is responsible\n\
|
kernel-install:
|
||||||
# to run dracut and ensure that there is only one kernel in the image\n\
|
# Enable kernel installation
|
||||||
layout=ostree" | tee /usr/lib/kernel/install.conf > /dev/null
|
- enable=true
|
||||||
# By default dnf keeps multiple versions of the kernel, with this
|
# Use systemd-boot for UEFI systems
|
||||||
# configuration we tell dnf to treat the kernel as everything else.
|
- bootloader: systemd-boot
|
||||||
# https://dnf.readthedocs.io/en/latest/conf_ref.html#main-options
|
# Kernel install directory
|
||||||
# Let's add the config to a distribution configuration file if dnf5
|
- install-dir: /boot/ostree
|
||||||
# is used, we append to /etc/dnf/dnf.conf if not.
|
# Initramfs configuration
|
||||||
# Also set protect_running_kernel=False, dnf/yum pre-dates Containers and
|
- initramfs: true
|
||||||
# uses uname to protect the running kernel even on Container builds.
|
# Kernel command line
|
||||||
if [ -d "/usr/share/dnf5/libdnf.conf.d/" ]; then
|
- cmdline: "ro root=LABEL=ROOT ostree=/ostree/boot.1/debian/14/x86_64/minimal/0"
|
||||||
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
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,18 @@
|
||||||
# Enable the Linux kernel; see also kernel-rt.
|
# Debian kernel configuration for minimal base images
|
||||||
packages:
|
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 configuration
|
||||||
- kernel-debug
|
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:
|
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"
|
edition: "2024"
|
||||||
|
|
||||||
|
|
@ -9,7 +9,7 @@ variables:
|
||||||
# Be minimal
|
# Be minimal
|
||||||
recommends: false
|
recommends: false
|
||||||
|
|
||||||
# Default to `bash` in our container, the same as other containers we ship.
|
# Default to systemd init in our container
|
||||||
container-cmd:
|
container-cmd:
|
||||||
- /sbin/init
|
- /sbin/init
|
||||||
|
|
||||||
|
|
@ -31,18 +31,28 @@ include:
|
||||||
- basic-fixes.yaml
|
- basic-fixes.yaml
|
||||||
- kernel-install.yaml
|
- kernel-install.yaml
|
||||||
- systemd-presets.yaml
|
- systemd-presets.yaml
|
||||||
|
- partitioning.yaml
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
# this is implied by dependencies but let's make it explicit
|
# Essential system utilities
|
||||||
- coreutils
|
- coreutils
|
||||||
# We need dnf for building derived container images. In Fedora, this pulls
|
# Package management - we need apt for building derived container images
|
||||||
# in dnf5. In CentOS/RHEL, this pulls in dnf(4). We can simplify this back to
|
- apt
|
||||||
# just `dnf` once the `dnf` package is retired from Fedora.
|
- apt-utils
|
||||||
- /usr/bin/dnf
|
# System initialization
|
||||||
# Even in minimal, we have this. If you don't want SELinux today, you'll need
|
- systemd
|
||||||
# to build a custom image.
|
- systemd-sysv
|
||||||
- selinux-policy-targeted
|
# Kernel and boot infrastructure
|
||||||
# And we want container-selinux because trying to layer it on later currently causes issues.
|
- 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
|
- container-selinux
|
||||||
# Needed for tpm2 bound luks
|
# TPM support for LUKS encryption
|
||||||
- tpm2-tools
|
- tpm2-tools
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
|
# OSTree configuration for Debian minimal base images
|
||||||
packages:
|
packages:
|
||||||
- ostree nss-altfiles
|
# OSTree core packages
|
||||||
|
- ostree
|
||||||
|
- ostree-utils
|
||||||
|
- libostree-1-1
|
||||||
|
|
||||||
postprocess:
|
# OSTree configuration
|
||||||
# Set up default root config
|
ostree:
|
||||||
- |
|
# Enable OSTree functionality
|
||||||
#!/usr/bin/env bash
|
- enable=true
|
||||||
set -xeuo pipefail
|
# Repository configuration
|
||||||
mkdir -p /usr/lib/ostree
|
- repo-path=/ostree/repo
|
||||||
cat > /usr/lib/ostree/prepare-root.conf << EOF
|
# Boot configuration
|
||||||
[composefs]
|
- boot-path=/boot/ostree
|
||||||
enabled = yes
|
|
||||||
[sysroot]
|
|
||||||
readonly = true
|
|
||||||
EOF
|
|
||||||
|
|
|
||||||
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`.
|
# Post-processing configuration for Debian minimal base images
|
||||||
|
postprocess:
|
||||||
# We want content lifecycled with the image
|
# Set up essential system configuration
|
||||||
opt-usrlocal: "root"
|
- |
|
||||||
|
#!/usr/bin/env bash
|
||||||
# https://github.com/CentOS/centos-bootc/issues/167
|
set -xeuo pipefail
|
||||||
machineid-compat: true
|
|
||||||
|
# Create essential directories
|
||||||
rpmdb: target
|
mkdir -p /etc/apt/apt.conf.d
|
||||||
# We never want rpmdb.sqlite-shm as it's unreproducible
|
mkdir -p /etc/systemd/system
|
||||||
rpmdb-normalize: true
|
mkdir -p /etc/ostree
|
||||||
|
|
||||||
ignore-removed-users:
|
# Configure APT for minimal system
|
||||||
- root
|
cat > /etc/apt/apt.conf.d/99-minimal << 'EOF'
|
||||||
ignore-removed-groups:
|
APT::Install-Recommends "false";
|
||||||
- root
|
APT::Install-Suggests "false";
|
||||||
# By default users and groups are injected to nss-altfiles
|
APT::Get::Assume-Yes "true";
|
||||||
# which is immutable. This list moves a selected set
|
EOF
|
||||||
# to /etc/group instead, which is mutable per system
|
|
||||||
# and allows local users to become part of these groups.
|
# Set up OSTree configuration
|
||||||
etc-group-members:
|
cat > /etc/ostree/ostree.conf << 'EOF'
|
||||||
- wheel
|
[core]
|
||||||
- systemd-journal
|
repo_mode=bare
|
||||||
- tss # https://issues.redhat.com/browse/BIFROST-618
|
EOF
|
||||||
- adm
|
|
||||||
|
# Ensure proper permissions
|
||||||
conditional-include:
|
chmod 755 /etc/apt/apt.conf.d
|
||||||
- if: passwd_mode == "full"
|
chmod 644 /etc/apt/apt.conf.d/99-minimal
|
||||||
include: check-passwd.yaml
|
chmod 644 /etc/ostree/ostree.conf
|
||||||
- if: passwd_mode == "nobody"
|
|
||||||
include: check-passwd-nobody.yaml
|
|
||||||
- if: passwd_mode == "none"
|
|
||||||
include:
|
|
||||||
check-passwd:
|
|
||||||
type: "none"
|
|
||||||
check-groups:
|
|
||||||
type: "none"
|
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,20 @@
|
||||||
# Postprocessing relating to systemd presets on the system.
|
# Systemd presets for Debian minimal base images
|
||||||
postprocess:
|
systemd-presets:
|
||||||
- |
|
# Enable essential systemd services
|
||||||
#!/bin/bash
|
enable:
|
||||||
set -xeuo pipefail
|
- systemd-networkd
|
||||||
# Override some of the default presets.
|
- systemd-resolved
|
||||||
cat <<EOF > usr/lib/systemd/system-preset/85-bootc.preset
|
- systemd-timesyncd
|
||||||
# Disable dnf-makecache.timer on bootc/image mode systems
|
- systemd-udevd
|
||||||
# https://github.com/coreos/fedora-coreos-tracker/issues/1896#issuecomment-2848251507
|
- systemd-logind
|
||||||
disable dnf-makecache.timer
|
|
||||||
EOF
|
# Disable unnecessary services
|
||||||
# Enable bootloader-update.service on F43+.
|
disable:
|
||||||
# https://github.com/coreos/fedora-coreos-tracker/issues/1468#issuecomment-2996654547
|
- systemd-firstboot
|
||||||
# https://fedoraproject.org/wiki/Changes/AutomaticBootloaderUpdatesBootc
|
- systemd-hwdb-update
|
||||||
- |
|
- systemd-machine-id-commit
|
||||||
#!/bin/bash
|
- systemd-pstore
|
||||||
set -xeuo pipefail
|
- systemd-random-seed
|
||||||
source /usr/lib/os-release
|
- systemd-sysctl
|
||||||
if [ $ID == "fedora" ] && [ ${VERSION_ID} -ge 43 ]; then
|
- systemd-user-sessions
|
||||||
echo "enable bootloader-update.service" >> /usr/lib/systemd/system-preset/85-bootc.preset
|
- systemd-vconsole-setup
|
||||||
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
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,25 @@
|
||||||
postprocess:
|
# Tmpfiles configuration for Debian minimal base images
|
||||||
|
tmpfiles:
|
||||||
|
# Essential system directories
|
||||||
- |
|
- |
|
||||||
#!/bin/bash
|
# Create essential directories with proper permissions
|
||||||
set -xeuo pipefail
|
d /var/log 0755 root root -
|
||||||
cat >/usr/lib/tmpfiles.d/bootc-base-rpmstate.conf <<'EOF'
|
d /var/cache 0755 root root -
|
||||||
# Workaround for https://bugzilla.redhat.com/show_bug.cgi?id=771713
|
d /var/tmp 1777 root root -
|
||||||
d /var/lib/rpm-state 0755 - - -
|
d /tmp 1777 root root -
|
||||||
EOF
|
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