![How to Build an Ubuntu Kernel with GitHub Actions](https://assets.gcore.pro/blog_containerizing_prod/uploads/2023/06/building-ubuntu-kernel-github-actions-fi.png)
Keeping a finger on the pulse of kernel development is crucial for any DevOps professional. Canonical, the powerhouse behind Ubuntu, tracks kernel mainline development via its mainline-crack Git repository. In this blog post, we will explore the construction of an efficient GitHub Actions pipeline that automates the build process and distribution of Ubuntu kernel deb packages.
Canonical provides a convenient debian/rules makefile that simplifies the building of the Ubuntu kernel. This makefile is the key tool utilized in our example. To learn more about debian/rules, check out debmake-doc.
CI Pipeline Overview
The pipeline encompasses two primary jobs: build and publish. The build job is executed within a custom Docker container, named custom-linux-builder-jammy:latest
, which is based on Ubuntu 22.04 and equipped with all necessary dependencies for Ubuntu kernel compilation. The publish job, reliant on the build job, is responsible for deploying the generated packages to a repository.
Letâs start with the overview of the entire CI pipeline:
Name: CI on: [push, workflow_dispatch] jobs: build: runs-on: [ubuntu-22-04, x64, heavy, self-hosted] container: custom-linux-builder-jammy:latest steps: - uses: actions/checkout@v3 - name: Cleanup run: | debian/rules clean rm -rf ../*.deb /packages - name: Dependencies run: | apt-get update && \ mk-build-deps \ --tool 'apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' \ --install --remove debian/control - name: Build run: | debian/rules do_tools=true binary-generic binary mkdir /packages && cp -f ../*deb /packages/. - uses: actions/upload-artifact@v3 with: name: linux_package path: /packages/ publish: runs-on: [self-hosted, ubuntu-22-04] needs: [build] steps: - name: Get Secrets uses: hashicorp/vault-action@v2.4.1 id: secrets with: url: <VAULT_INSTANCE_URL> token: ${{ secrets.VAULT_TOKEN }} secrets: | <PATH_TO_PRIVATE_KEY>| key ; - uses: actions/download-artifact@v3 with: name: linux_package - name: Send to Repo uses: appleboy/scp-action@master with: host: <REPOSITORY_URL> username: <REPOSITORY_USERNAME> key: ${{ steps.secrets.outputs.key }} port: <PORT_NUMBER> source: "*.deb" target: <PATH_IN_REPOSITORY>
Deep Dive
Letâs take a deep dive and check out the GitHub Actions pipeline in detail.
Build Phase
The build phase is the core of the pipeline, and is responsible for the Ubuntu kernel compilation and packaging. The pipeline uses Docker image custom-linux-builder-jammy:latest
, which is based on Ubuntu 22.04 and contains all necessary dependencies for building the Ubuntu kernel.
Checkout
The actions/checkout@v3
step ensures that the pipeline operates on the latest version of the codebase. This means that any recent revisions will be incorporated into the build.
Cleanup
The Cleanup step removes any residuals from previous workflows. It cleans the source tree and removes any leftover .deb packages from previous builds, ensuring youâre starting fresh. Here are the relevant commands:
debian/rules clean rm -rf ../*.deb
Dependencies
The Dependencies step prepares and installs the dependencies listed in debian/control
. It ensures that the build environment has all the tools and dependencies it needs before starting to perform the kernel compilation. The code for this step is as follows:
apt-get update && \ mk-build-deps \ --tool 'apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' \ --install --remove debian/control
Build
debian/rules do_tools=true binary-generic binary mkdir /packages && cp -f ../*deb /packages/.
The Build step handles the actual compilation and packaging of the Ubuntu kernel. It executes the debian/rules
script with the specified parameters, including do_tools=true
, binary-generic
, and binary
.
The order of these targets is important. The do_tools=true
parameter enables the build of linux common tools (bpftool, cpupower, perf, etc.) binary-generic
is executed first, so binary target can utilize results from binary-generic
.
Once the build is complete, the resulting Debian packages are stored in the parent directory (../
) and then copied to the /packages
directory for future use.
Upload Artifact
After the build is successfully completed, the actions/upload-artifact@v3
step takes over and uploads the newly generated Debian packages as an artifact named âlinux_packageâ. This sets up the final stage of the process, the publish job.
Publish
The final stage in our pipeline is the publish job. This job uploads the previously generated kernel packages to the repository. The steps are relatively simple:
- Secure secrets: First, we will utilize the
hashicorp/vault-action
to fetch secrets from a HashiCorp Vault instance. This gives secure access to the resources required in the next steps of this job. - Retrieve the artifact: This step retrieves the artifact generated by the previous âbuildâ job via
actions/download-artifact@v3
. - Deploy to repository: This step uses
appleboy/scp-action
to securely transfer the Debian packages to the desired remote repository.
By using these steps in the Publish job, the Ubuntu kernel deb packages are successfully uploaded to the specified repository, ensuring easy access and efficient distribution.
Conclusion
With this simple GitHub Actions pipeline, building and publishing Ubuntu kernels becomes an automated and efficient process, with less chance of human error. We hope this guide will help you to streamline your DevOps processes so you can boost your productivity!