projects: split kernel-config build into three phases

...and add straw man implementations of kernel_config.base and
kernel_config.x86 as examples.

First, splitting the build: to avoid duplication, we split the build into
three parts: a "source" stage, a "config" stage, and a "build" stage. The
"source" stage allows us to use a cached image, so we don't have to
re-download the kernel source every time. The "config" step applies our
patches and generates (and checks) the kernel config. I've left this as a
separate step for now so that we can build just an image with a config in
it, without having to ^C the build. However there's no real reason it needs
to be a separate step, assuming that this kernel config design is
acceptable. The third step is the actual kernel build.

Then there is kernel config management: the bulk of it occurs in
makeconfig.sh, with the idea being that we can specify base, arch, and
version specific config options as necessary.

The config files themselves are lists of options (both positive and
negative). We include the negative options, because we want to explicitly
turn off things that are on in the default config (e.g. CONFIG_USELIB), and
it seems cleaner to do things this way then to have some sort of negative
options list.

The options files are sorted with the default behavior of the "sort"
command, which ignores comment lines, meaning that negative options and
positive options are inline with each other. I don't have a strong opinion
on whether or not to group all negative options, or whether this default
behavior makes sense, so I just left it.

Finally, obviously the .base and .x86 files are incomplete. I mostly
selected a few options with interesting dependencies or special issues
(CONFIG_PANIC_ON_OOPS) with how we manage things, so as to demo how
everything would work. It's not really clear to me that there's a good way
to generate e.g. kernel_config.base, without a lot of painstaking work
(which I'm happy to do if we agree this is a good approach).

Signed-off-by: Tycho Andersen <tycho@docker.com>
This commit is contained in:
Tycho Andersen 2017-05-08 11:45:50 -06:00
parent 1e0021d969
commit 42b6b44fa9
7 changed files with 114 additions and 19 deletions

View File

@ -1,24 +1,13 @@
ARG source=nosuchimage
FROM ${source}
FROM ${source} AS kernel-build
ARG KERNEL_VERSION
ARG KERNEL_SERIES
ARG DEBUG
COPY kernel_config-${KERNEL_SERIES} /linux/arch/x86/configs/x86_64_defconfig
COPY kernel_config.debug /linux/debug_config
RUN if [ -n "${DEBUG}" ]; then \
sed -i 's/CONFIG_PANIC_ON_OOPS=y/# CONFIG_PANIC_ON_OOPS is not set/' /linux/arch/x86/configs/x86_64_defconfig; \
cat /linux/debug_config >> /linux/arch/x86/configs/x86_64_defconfig; \
fi
RUN mkdir /out
WORKDIR /linux
# Kernel
RUN make defconfig && \
make oldconfig && \
make -j "$(getconf _NPROCESSORS_ONLN)" KCFLAGS="-fno-pie" && \
RUN make -j "$(getconf _NPROCESSORS_ONLN)" KCFLAGS="-fno-pie" && \
cp arch/x86_64/boot/bzImage /out/kernel && \
cp System.map /out

View File

@ -0,0 +1,12 @@
ARG source=nosuchimage
FROM ${source}
ARG ARCH
ARG KERNEL_SERIES
ARG DEBUG
RUN mkdir /config
COPY kernel_config.* /config/
COPY makeconfig.sh /config
RUN /config/makeconfig.sh ${ARCH} ${KERNEL_SERIES}

View File

@ -16,3 +16,6 @@ RUN set -e && for patch in /patches/*.patch; do \
echo "Applying $patch"; \
patch -p1 < "$patch"; \
done
RUN mkdir /out
RUN printf "KERNEL_SOURCE=${KERNEL_SOURCE}\n" > /out/kernel-source-info

View File

@ -35,19 +35,30 @@ sign:
define kernel
.PHONY: source_$(2)$(3)
source_$(2)$(3):
docker image inspect linuxkit/$(IMAGE)-source:$(1)-$(HASH) >/dev/null || \
@# XXX: intentionally dropping $(3) here, since the source is the same for
@# both debug and non-debug builds.
docker image inspect linuxkit/$(IMAGE)-source:$(1)$-$(HASH) >/dev/null || \
docker build -f Dockerfile.source \
--build-arg KERNEL_VERSION=$(1) \
--build-arg KERNEL_SERIES=$(2) \
--no-cache -t linuxkit/$(IMAGE)-source:$(1)-$(HASH) .
--no-cache -t linuxkit/$(IMAGE)-source:$(1)$-$(HASH) .
build_$(2)$(3): Dockerfile.build Makefile $(wildcard patches-$(2)/*) kernel_config-$(2) kernel_config.debug source_$(2)$(3)
.PHONY: config_$(2)$(3)
config_$(2)$(3): source_$(2)
docker image inspect linuxkit/$(IMAGE)-config:$(1)$(3)-$(HASH) >/dev/null || \
docker build -f Dockerfile.config \
--build-arg KERNEL_SERIES=$(2) \
--build-arg ARCH=x86 \
--build-arg DEBUG=$(3) \
--build-arg source=linuxkit/$(IMAGE)-source:$(1)-$(HASH) \
--no-cache -t linuxkit/$(IMAGE)-config:$(1)$(3)-$(HASH) .
build_$(2)$(3): Dockerfile.build Makefile $(wildcard patches-$(2)/*) kernel_config-$(2) kernel_config.debug config_$(2)$(3)
docker pull linuxkit/$(IMAGE):$(1)$(3)-$(HASH) || \
docker build -f Dockerfile.build \
--build-arg KERNEL_VERSION=$(1) \
--build-arg KERNEL_SERIES=$(2) \
--build-arg DEBUG=$(3) \
--build-arg source=linuxkit/$(IMAGE)-source:$(1)$(3)-$(HASH) \
--build-arg source=linuxkit/$(IMAGE)-config:$(1)$(3)-$(HASH) \
--no-cache -t linuxkit/$(IMAGE):$(1)$(3)-$(HASH) .
push_$(2)$(3): build_$(2)$(3)

View File

@ -0,0 +1,24 @@
CONFIG_BLK_CGROUP=y
CONFIG_BPF_SYSCALL=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUPS=y
CONFIG_CGROUP_WRITEBACK=y
CONFIG_CHECKPOINT_RESTORE=y
CONFIG_EXPERT=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_IKCONFIG_PROC=y
CONFIG_IKCONFIG=y
CONFIG_LOCALVERSION="-linuxkit"
CONFIG_MEMCG_SWAP_ENABLED=y
CONFIG_MEMCG_SWAP=y
CONFIG_MEMCG=y
CONFIG_MODULES=y
CONFIG_NAMESPACES=y
CONFIG_PANIC_ON_OOPS=y
# CONFIG_USELIB is not set
CONFIG_USER_NS=y

View File

@ -0,0 +1 @@
CONFIG_64BIT=y

View File

@ -0,0 +1,55 @@
#!/bin/bash
set -e
ARCH=$1
KERNEL_SERIES=$2
DEBUG=$3
defconfig=defconfig
if [ "${ARCH}" == "x86" ]; then
defconfig=x86_64_defconfig
fi
configpath="/linux/arch/${ARCH}/configs/${defconfig}"
cp /config/kernel_config.base "$configpath"
function append_config()
{
config=$1
if [ -f "$config" ]; then
cat "$config" >> "$configpath"
fi
}
append_config "/config/kernel_config.${ARCH}"
append_config "/config/kernel_config.${KERNEL_SERIES}"
append_config "/config/kernel_config.${ARCH}.${KERNEL_SERIES}"
if [ -n "${DEBUG}" ]; then
sed -i sed -i 's/CONFIG_PANIC_ON_OOPS=y/# CONFIG_PANIC_ON_OOPS is not set/' /linux/arch/x86/configs/x86_64_defconfig
append_config "/config/kernel_config.debug"
fi
cd /linux && make defconfig && make oldconfig
# Let's make sure things are the way we want, i.e. every option we explicitly
# set is set the same way in the resulting config.
function check_config()
{
if [ ! -f "$1" ]; then return; fi
while read line; do
if [ -n "${DEBUG}" ] && [ "$line" == "CONFIG_PANIC_ON_OOPS=y" ]; then continue; fi
grep "^${line}$" /linux/.config >/dev/null || (echo "$line set incorrectly" && false)
done < $1
}
check_config "/config/kernel_config.base"
check_config "/config/kernel_config.${ARCH}"
check_config "/config/kernel_config.${KERNEL_SERIES}"
check_config "/config/kernel_config.${ARCH}.${KERNEL_SERIES}"
if [ -n "${DEBUG}" ]; then
check_config "/config/kernel_config.debug"
fi