Hook is the Tinkerbell Installation Environment for bare-metal. It runs in-memory, installs operating system, and handles deprovisioning.
One of the Tinkerbell components is the Operating System Installation Environment (OSIE). The Tinkerbell project originally used OSIE as its default OSIE. That implementation was open-sourced by Equinix Metal as is and was difficult to modify/extend. (Not to mention confusing, OSIE is our OSIE, hook is a new OSIE and you can have your very own OSIE too) We started this project for the following reasons:
The hook project aims to provide an "in-place" swappable set of files (kernel
/initramfs
) that can be used to function as the Tinkerbell OSIE.
The key aims of this new project:
The hook project predominantly uses linuxkit as the toolkit that will produce repeatable and straightforward build of the entire in-memory operating system. The linuxkit project combines a Linux kernel with a number of additional container images to produce a Linux Operating System with just the right amount of functionality (no less / no more). We have built upon the minimal set of components:
To this minimal build, we've added our own set of containers that will provide the functionality needed for a tink-worker
to run successfully:
The hook-docker
container builds upon the upstream dind
(docker-in-docker) container.
It adds the additional functionality to retrieve the certificates needed for the docker engine to communicate with the Tinkerbell repository before it starts the docker engine.
The docker engine will be exposed through the /var/run/docker.sock
that will use a bind mount so that the container bootkit
can access it.
The hook-bootkit
container will parse the /proc/cmdline
and the metadata service in order to retrieve the specific configuration for tink-worker to be started for the current/correct machine.
It will then speak with the hook-docker
engine API through the shared /var/run/docker.sock
, where it will ask the engine to run the tink-worker:latest
container.
tink-worker:latest
will in turn begin to execute the workflow/actions associated with that machine.
This refers to the 0.9.0 version, compared to 0.8.1.
defconfig
versions, via Kbuild's make savedefconfig
hook-default-amd64
and hook-default-arm64
kernels are equivalent to the two original.armbian-
prefixed kernels are actually Armbian kernels for more exotic arm64 SBCs, or Armbian's generic UEFI kernels for both arches. Those are very fast to "build" since Armbian publishes their .deb packages in OCI images, and here we
just download and massage them into the format required by Linuxkit.hook.yaml
is replaced with hook.template.yaml
which is templated via a limited-var invocation of envsubst
; only the kernel image and the arch is actually different per-flavor.skopeo
. Can opt-out/use a fixed version.dtbs.tar.gz
artifact together with the initrd and vmlinuz. DTBs are not used by Hook or Tinkerbell right now, but will be necessary for some SBCs.id
The Hook build system is designed to handle multiple flavors.
A flavor mostly equates with a specific Linux Kernel, a LinuxKit version, and a LinuxKit YAML configuration template.
The "default" flavor ids are hook-default-amd64
and hook-default-arm64
, which use a kernel that is built and configured from source by the Hook build system.
Other flavors use Foreign kernels from other distributions to cater for special needs.
There is an inventory of all available flavors in the bash/inventory.sh file.
build.sh
)The build.sh
script is the main entry point for building a Hook flavor.
The general syntax of the cli is:
./build.sh <command> [<id>] [<key1>=<value1>] [<key2>=<value2>...]
Where:
<command>
, if not specified, defaults to build
<id>
, if not specified, defaults to hook-default-amd64
(or the arm64 variant, if running on an arm64 host); the full list is defined in the bash/inventory.sh[<key>=<value>]
is useful to set environment variables (similar to make
) and can come in any position in the command line.So, just running ./build.sh
will build the default flavor for the host architecture.
Other commands are:
kernel <id>
: builds the kernel for the specified flavor
default
ids, this will build the kernel from sourceconfig <id>
: runs kernel configuration for the specified flavor.
savedefconfig
will be run and the resulting file copied back to the host, ready for commit.build <id>
: builds the Hook flavor. The kernel must be either available for pulling, or have been built locally beforehand.qemu <id>
: builds the Hook flavor and runs it in QEMU.
MAC=<mac>
and TINK_SERVER=<ip>
env vars, see belowOther, less common commands are:
kernel-config-shell <id>
: prepares an interactive Docker shell for advanced kernel .config operations.shellcheck
: runs shellcheck on all bash scripts in the project and exits with an error if any issues are found.linuxkit-containers
: builds the LinuxKit containers for the specified architecture.Using the <key>=<value>
syntax, you can set environment variables that will be used by the build system.
Of course, you may also set them in the environment before running the script (that is heavily used by the GitHub Actions build workflow).
The most important environment variables are:
DEBUG=yes
: set this to get lots of debugging messages which can make understanding the build and finding problems easier.HOOK_VERSION
: The Hook version, ends up in /etc/os-release
and on the screen at boot.HOOK_KERNEL_OCI_BASE
: OCI base coordinates for the kernel images.HOOK_LK_CONTAINERS_OCI_BASE
: OCI base coordinates for the LinuxKit containers.CACHE_DIR
: directory where the build system will cache downloaded files. Relative to the project root.USE_LATEST_BUILT_KERNEL
: set this to yes
to use the latest built kernel from quay.io/tinkerbell/hook-kernel
.qemu
command:
TINK_SERVER=<ip>
: the IP address of the Tinkerbell GRPC server. No default.MAC=<mac>
: the MAC address of the machine that will be provisioned. No default.TINK_WORKER_IMAGE
, defaults to "quay.io/tinkerbell/tink-worker:latest"
TINK_TLS
defaults to false
TINK_GRPC_PORT
defaults to 42113
"matrix"
.
The gha-matrix
CLI command prepares a set of JSON outputs for GitHub Actions matrix workflow, based on the inventory and certain environment variables:
CI_RUNNER_<criteria>
are used to determine the GH Action runners (self-hosted or GH-hosted) that are used for each step. See bash/json-matrix.sh for details.CI_TAGS
, a space separated list of tags that will be used to filter the inventory.DOCKER_ARCH
is used by the linuxkit-containers
command to build the containers for the specified architecture.DO_PUSH
: yes
or no
, will push the built containers to the OCI registry; defaults to no
.make debug
functionality (sshd enabled) was lost in the Makefile -> bash transition;