Builds the Linux kernel into OCI images.
Kernels are built from github.com/edera-dev/linux, Edera's downstream Linux tree. Every Edera change is a commit on a branch there, so this repo carries no patch series of its own: whatever the branch says is what gets built.
This repo is a series of helper scripts and Github Actions that
- Resolve each branch listed in config.yaml to the commit it currently points at, and read
the kernel version out of that commit's
Makefile. - Use that, plus the flavors and architectures in
config.yaml, to generate a build matrix. - Fetch the source archive for that exact commit, apply the Edera kconfig fragments, and build for x86_64/aarch64.
Branch in config.yaml |
Ref on edera-dev/linux |
What it is |
|---|---|---|
6.18-lts |
edera/6.18-lts |
The 6.18 LTS series with the Edera stack. Also publishes latest. |
mainline |
edera/mainline |
Current mainline (including -rc) with the Edera stack. |
Adding a branch is three lines in config.yaml; nothing else needs to know about it.
Each build publishes one immutable tag and a set of moving aliases. For example, edera/6.18-lts at
6.18.52, commit efb09285bd95:
| Tag | Moves? |
|---|---|
zone-kernel:6.18.52-gefb09285bd95 |
no - one commit, forever |
zone-kernel:6.18.52 |
yes |
zone-kernel:6.18 |
yes |
zone-kernel:6.18-lts |
yes |
zone-kernel:latest |
yes |
and edera/mainline at 7.3-rc3, commit 391f6f12ecf5, publishes 7.3.0-rc3-g391f6f12ecf5, 7.3.0-rc3 and
mainline. A prerelease deliberately does not claim the bare series tag (7.3), which belongs to the
eventual 7.3 release.
The immutable tag names the source tree, not every build input. A change to a kconfig fragment in
configs rebuilds and republishes the same tags against the same commit; the kernel inside
changes, the tag does not. config.gz and the image's metadata (which records
KERNEL_SRC_REPO/KERNEL_SRC_REF/KERNEL_SRC_COMMIT alongside a hash of the kconfig) are what
distinguish two such builds.
The Build Kernels action takes a build spec of <type>[:<constraints>]:
new(default) - build only what the registry does not already have. Since each build carries an immutable<version>-g<commit>tag, this means "build every branch that has moved". This is what the weekly cron runs.rebuild- build everything the config selects, published or not. Use this when something other than the kernel source changed: a kconfig fragment, the buildenv, the packaging. A merge touchingconfigs/**triggers this automatically.
Constraints are semicolon-separated key=value pairs over branch, flavor and arch, with
comma-separated values:
new
rebuild:branch=mainline
rebuild:branch=6.18-lts;flavor=host,zone
new:flavor=zone;arch=aarch64
See the configs directory for more info.
- Fork this repo into your Github org/account.
- Inspect the Github Action file .github/workflows/build.yaml:
- This will use the default
GITHUB_TOKENgranted to all Github Action workflows by default to push OCI images toghcr.ioin your fork's context. Refer to Github's documentation for details on access permissions and howGITHUB_TOKENworks. - You should not need to make changes to this file, but it is best practice to understand what an Action does and what permissions it expects before you run it.
- This will use the default
- Edit config.yaml in the root of your fork:
- Edit the line
imageNameFormat: "ghcr.io/edera-dev/[image]:[tag]"and change it toimageNameFormat: "ghcr.io/<your GH org>/[image]:[tag]" - Add or remove any
Kconfigoptions you want to theflavorandvariantKconfig fragments in configs, as outlined by the README in that folder. - Commit those changes to
mainin your fork.
- Edit the line
- From your forked repository's
Actionstab, run theBuild Kernelsjob with a Build Specification like:rebuild:flavor=zone,host. This will build thezoneandhostflavors of every branch inconfig.yaml.
For most of the kernels in this registry, debugging symbols and features are disabled, to keep the kernel artifacts small.
You may want or need to build your own debugging kernel with custom options locally, and publish it to a transient OCI registry (like ttl.sh) for testing purposes.
To do this, you will need docker installed and configured correctly to support cross-builds (docker buildx) in your local environment.
The simplest way to do that is to
-
Clone this repo locally:
git clone git@github.com:edera-dev/linux-kernel-oci.git -
Manually edit config.yaml on-disk:
-
to change the
imageNameFormatkey to push to an OCI registry you have access to. -
to change the
architecturesYAML key to only include the architectures you care about (x86_64, aarch64, or both -docker buildxis used so you can build aarch64 on x86_64 and vice-versa). -
to change the
flavorsYAML key to only include the flavors you care about (host, or zone, or both). -
to change the
branchesYAML key to only include the branches you care about. You can also pointsource.repoat your own fork ofedera-dev/linuxand list a branch on it. -
For example, if I wanted to only build the
zonekernel flavor, only forx86_64, only from the LTS branch, and tag the result for a customttl.sh/hackbenregistry, the final result would look something like this:imageNameFormat: "ttl.sh/hackben/[image]:[tag]" source: repo: https://github.com/edera-dev/linux branches: - name: 6.18-lts ref: edera/6.18-lts architectures: - x86_64 flavors: - name: zone
-
-
Add or remove any
Kconfigoptions you want to theflavorandvariantKconfig fragments in configs, as outlined by the README in that folder. -
Run hack/build/docker-build.sh
- It is important you follow the previous step, and edit the config.yaml locally to reduce the number of kernels the script will try to build, or you may end up building many different kernels in parallel on your local box, which will take a very, very long time.
- When this command runs, it will generate a build matrix and print out what it will build.
- Pass a build spec as the first argument to narrow it further, e.g.
./hack/build/docker-build.sh 'rebuild:branch=6.18-lts;flavor=zone'(quote it -;is a shell metacharacter).
-
When the above command finishes, you can see the local OCI images that were built by running
docker image list. The images will be tagged with the repo you specified inimageNameFormatin the config.yaml. -
From this point, you may push those images to an OCI registry with standard commands like
docker image push <image tag>, and consume them how you wish. -
If you wish to unpack and inspect the final image (for instance, to make sure certain modules or firmware exist in the correct paths, or that the final
config.gzhas the options you expect), you can do the following to fetch and extract the image artifact you just pushed to your local disk withcrane:crane export ttl.sh/hackben/zone-kernel:6.18-lts - --platform=linux/amd64 | tar --keep-directory-symlink -xf - -C . cd `kernel` zcat config.gz cat metadata unsquashfs addons.squashfs ...
hack/build/build.sh takes KERNEL_SRC_URL directly and understands a git::<url>[::<ref>] form, which
clones that ref instead of fetching an archive. That is the escape hatch for building a work-in-progress
branch without listing it in config.yaml first. It expects the kbuild toolchain to already be present, so
run it inside the build environment image (ghcr.io/edera-dev/kernel-buildenv) rather than on a bare host:
KERNEL_VERSION=6.18.52 KERNEL_FLAVOR=zone \
KERNEL_SRC_URL='git::https://github.com/edera-dev/linux::azenla/zone-perf' \
./hack/build/build.sh