diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 25bb4c7..93a7c8b 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -7,16 +7,15 @@ jobs: build: name: build-${{matrix.tag}} runs-on: docker - container: node:22-bullseye + container: git.frostfs.info/truecloudlab/env:oci-image-builder-bookworm strategy: matrix: tag: - dotnet-8.0 + - oci-image-builder-bookworm - openjdk-11-maven-3.8.6 - python-3.11 - python-3.13 - env: - STORAGE_DRIVER: vfs steps: - name: Clone git repo uses: actions/checkout@v3 @@ -28,16 +27,6 @@ jobs: ${{matrix.tag}}/** id: changed - - name: Install Buildah - run: |- - apt update; apt install -y buildah - - # STORAGE_DRIVER variable is ignored if this file does not exist - touch /etc/containers/storage.conf - if: >- - github.event_name == 'workflow_dispatch' - || steps.changed.outputs.any_changed == 'true' - - name: Build OCI image run: make ${{matrix.tag}} if: >- diff --git a/oci-image-builder-bookworm/Dockerfile b/oci-image-builder-bookworm/Dockerfile new file mode 100644 index 0000000..e71ba62 --- /dev/null +++ b/oci-image-builder-bookworm/Dockerfile @@ -0,0 +1,15 @@ +FROM docker.io/node:20-bookworm-slim as node +FROM docker.io/golang:1.23-bookworm +COPY --from=node /usr/local /usr/local +COPY --from=node /opt /opt + +RUN apt-get update && \ + apt-get install -y buildah && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* +COPY docker-wrapper.sh /usr/local/bin/docker + +# Configuration for buildah inside rootless podman +COPY containers.conf /etc/containers/containers.conf +COPY registries.conf /etc/containers/registries.conf +COPY storage.conf /etc/containers/storage.conf diff --git a/oci-image-builder-bookworm/README.md b/oci-image-builder-bookworm/README.md new file mode 100644 index 0000000..72ea923 --- /dev/null +++ b/oci-image-builder-bookworm/README.md @@ -0,0 +1,39 @@ +# Forgejo Actions environment for building OCI container images + +Building OCI container images inside Forgejo Actions is somewhat non-trivial. +We need to execute Buildah inside of a rootless Podman container, which +eventually leads to a podman-in-podman scenario. Thankfully, this is not as +complex as docker-in-docker. + +This image contains everything we need for executing `make image` in our +Golang repos: + +- Go toolchain (for helper scripts called by Makefile) +- Docker wrapper (for abstracting Buildah away from human Makefile users) +- Podman configuration files + +## Usage + +Referencing this container from `.forgejo/workflows/workflow.yml`: + +```yaml +jobs: + oci-image: + runs-on: docker + container: git.frostfs.info/truecloudlab/env:oci-image-builder-bookworm +``` + +See full [live +example](https://git.frostfs.info/TrueCloudLab/action-env/src/branch/master/.forgejo/workflows/build.yml) +in action in this repo. + +## Initial Forgejo setup + +We use this image to build all images in this repo. To avoid chicken-and-egg +situation in case of disaster recovery, the first version of this image must +be pushed from outside of Forgejo Actions, e.g. from sysadmin laptop: + +```console +$ make oci-image-builder-bookworm +$ make push-oci-image-builder-bookworm +``` diff --git a/oci-image-builder-bookworm/containers.conf b/oci-image-builder-bookworm/containers.conf new file mode 100644 index 0000000..84a6932 --- /dev/null +++ b/oci-image-builder-bookworm/containers.conf @@ -0,0 +1,8 @@ +# https://github.com/containers/podman/issues/20453#issuecomment-1912725982 +[containers] +cgroupns="host" +ipcns="host" +netns="host" +pidns="host" +userns="host" +utsns="host" diff --git a/oci-image-builder-bookworm/docker-wrapper.sh b/oci-image-builder-bookworm/docker-wrapper.sh new file mode 100755 index 0000000..775f888 --- /dev/null +++ b/oci-image-builder-bookworm/docker-wrapper.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# +# A wrapper that translates `docker build` commands for use with buildah +# +set -euo pipefail +while [[ $# -ne 0 ]] +do + case "$1" in + --rm|--force-rm) + # 'rm' and 'force-rm' can only be set with either 'layers' or 'no-cache' + ;; + *) + args+=("$1") + ;; + esac + shift +done +buildah "${args[@]}" diff --git a/oci-image-builder-bookworm/registries.conf b/oci-image-builder-bookworm/registries.conf new file mode 100644 index 0000000..d15dbcc --- /dev/null +++ b/oci-image-builder-bookworm/registries.conf @@ -0,0 +1,11 @@ +unqualified-search-registries = ["docker.io"] + +[[registry]] +prefix = "docker.io" +location = "docker.io" + +[[registry.mirror]] +location = "quay.io" + +[[registry.mirror]] +location = "docker.io" diff --git a/oci-image-builder-bookworm/storage.conf b/oci-image-builder-bookworm/storage.conf new file mode 100644 index 0000000..5bde8c7 --- /dev/null +++ b/oci-image-builder-bookworm/storage.conf @@ -0,0 +1,5 @@ +# STORAGE_DRIVER variable is ignored if /etc/containers/storage.conf does not exist +[storage] +driver = "vfs" +runroot = "/run/containers/storage" +graphroot = "/var/lib/containers/storage"