Skip to content

Commit d88e0ed

Browse files
committed
Container OS linux header install via initContainer
1 parent 0510804 commit d88e0ed

File tree

5 files changed

+216
-4
lines changed

5 files changed

+216
-4
lines changed

Makefile

+5
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ image/build:
5555
-f Dockerfile.tracerunner .
5656
$(DOCKER) tag $(IMAGE_TRACERUNNER_BRANCH) $(IMAGE_TRACERUNNER_COMMIT)
5757

58+
.PHONY: image/build-init
59+
image/build-init:
60+
$(DOCKER) build \
61+
-f ./init/Dockerfile.initcontainer ./init
62+
5863
.PHONY: image/push
5964
image/push:
6065
$(DOCKER) push $(IMAGE_TRACERUNNER_BRANCH)

init/Dockerfile.initcontainer

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
FROM alpine:3.8
2+
RUN apk add --update \
3+
bash \
4+
bc \
5+
build-base \
6+
curl \
7+
libelf-dev \
8+
linux-headers \
9+
make
10+
11+
WORKDIR /
12+
13+
COPY /fetch-linux-headers.sh /
14+
15+
ENTRYPOINT [ "/fetch-linux-headers.sh" ]

init/fetch-linux-headers.sh

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#!/bin/bash
2+
3+
set -x
4+
5+
LSB_FILE="/etc/lsb-release.host"
6+
OS_RELEASE_FILE="/etc/os-release.host"
7+
TARGET_DIR="/usr/src"
8+
HOST_MODULES_DIR="/lib/modules.host"
9+
10+
generate_headers()
11+
{
12+
echo "Generating kernel headers"
13+
cd ${BUILD_DIR}
14+
zcat /proc/config.gz > .config
15+
make ARCH=x86 oldconfig > /dev/null
16+
make ARCH=x86 prepare > /dev/null
17+
}
18+
19+
fetch_cos_linux_sources()
20+
{
21+
echo "Fetching upstream kernel sources."
22+
mkdir -p ${BUILD_DIR}
23+
curl -s "https://storage.googleapis.com/cos-tools/${BUILD_ID}/kernel-src.tar.gz" | tar -xzf - -C ${BUILD_DIR}
24+
}
25+
26+
install_cos_linux_headers()
27+
{
28+
if grep -q CHROMEOS_RELEASE_VERSION ${LSB_FILE};then
29+
BUILD_ID=$(grep CHROMEOS_RELEASE_VERSION ${LSB_FILE} | cut -d = -f 2)
30+
BUILD_DIR="/linux-lakitu-${BUILD_ID}"
31+
SOURCES_DIR="${TARGET_DIR}/linux-lakitu-${BUILD_ID}"
32+
33+
if [ ! -e "${SOURCES_DIR}/.installed" ];then
34+
echo "Installing kernel headers for for COS build ${BUILD_ID}"
35+
fetch_cos_linux_sources
36+
generate_headers
37+
mv ${BUILD_DIR} ${TARGET_DIR}
38+
touch "${SOURCES_DIR}/.installed"
39+
fi
40+
fi
41+
}
42+
43+
install_headers()
44+
{
45+
distro=$(grep ^NAME ${OS_RELEASE_FILE} | cut -d = -f 2)
46+
47+
case $distro in
48+
*"Container-Optimized OS"*)
49+
install_cos_linux_headers
50+
HEADERS_TARGET=${SOURCES_DIR}
51+
;;
52+
*)
53+
echo "WARNING: ${distro} is not a supported distro, cannot install headers, ensure they are installed to /lib/modules"
54+
esac
55+
}
56+
57+
check_headers()
58+
{
59+
modules_path=$1
60+
utsname=$(uname -r)
61+
arch=$(uname -m)
62+
kdir="${modules_path}/${utsname}"
63+
64+
[ "${arch}" == "x86_64" ] && arch="x86"
65+
66+
[ ! -e ${kdir} ] && return 1
67+
[ ! -e "${kdir}/source" ] && [ ! -e "${kdir}/build" ] && return 1
68+
69+
header_dir=$([ -e "${kdir}/source" ] && echo "${kdir}/source" || echo "${kdir}/build")
70+
71+
[ ! -e "${header_dir}/include/linux/kconfig.h" ] && return 1
72+
[ ! -e "${header_dir}/include/generated/uapi" ] && return 1
73+
[ ! -e "${header_dir}/arch/${arch}/include/generated/uapi" ] && return 1
74+
75+
return 0
76+
}
77+
78+
if [ ! -e /lib/modules/.installed ];then
79+
if ! check_headers ${HOST_MODULES_DIR}; then
80+
install_headers
81+
else
82+
HEADERS_TARGET=${HOST_MODULES_DIR}/source
83+
fi
84+
85+
mkdir -p "/lib/modules/$(uname -r)"
86+
ln -sf ${HEADERS_TARGET} "/lib/modules/$(uname -r)/source"
87+
ln -sf ${HEADERS_TARGET} "/lib/modules/$(uname -r)/build"
88+
touch /lib/modules/.installed
89+
exit 0
90+
else
91+
echo "Headers already installed"
92+
exit 0
93+
fi

pkg/tracejob/job.go

+77-4
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ func (t *TraceJobClient) CreateJob(nj TraceJob) (*batchv1.Job, error) {
238238
},
239239
},
240240
apiv1.Volume{
241-
Name: "modules",
241+
Name: "modules-host",
242242
VolumeSource: apiv1.VolumeSource{
243243
HostPath: &apiv1.HostPathVolumeSource{
244244
Path: "/lib/modules",
@@ -253,6 +253,69 @@ func (t *TraceJobClient) CreateJob(nj TraceJob) (*batchv1.Job, error) {
253253
},
254254
},
255255
},
256+
apiv1.Volume{
257+
Name: "lsb-release",
258+
VolumeSource: apiv1.VolumeSource{
259+
HostPath: &apiv1.HostPathVolumeSource{
260+
Path: "/etc/lsb-release",
261+
},
262+
},
263+
},
264+
apiv1.Volume{
265+
Name: "os-release",
266+
VolumeSource: apiv1.VolumeSource{
267+
HostPath: &apiv1.HostPathVolumeSource{
268+
Path: "/etc/os-release",
269+
},
270+
},
271+
},
272+
apiv1.Volume{
273+
Name: "modules-dir",
274+
VolumeSource: apiv1.VolumeSource{
275+
HostPath: &apiv1.HostPathVolumeSource{
276+
Path: "/var/cache/linux-headers/modules_dir",
277+
},
278+
},
279+
},
280+
apiv1.Volume{
281+
Name: "linux-headers-generated",
282+
VolumeSource: apiv1.VolumeSource{
283+
HostPath: &apiv1.HostPathVolumeSource{
284+
Path: "/var/cache/linux-headers/generated",
285+
},
286+
},
287+
},
288+
},
289+
InitContainers: []apiv1.Container{
290+
apiv1.Container{
291+
Name: "kubectl-trace-init",
292+
Image: version.InitImageNameTag(),
293+
VolumeMounts: []apiv1.VolumeMount{
294+
apiv1.VolumeMount{
295+
Name: "lsb-release",
296+
MountPath: "/etc/lsb-release.host",
297+
ReadOnly: true,
298+
},
299+
apiv1.VolumeMount{
300+
Name: "os-release",
301+
MountPath: "/etc/os-release.host",
302+
ReadOnly: true,
303+
},
304+
apiv1.VolumeMount{
305+
Name: "modules-dir",
306+
MountPath: "/lib/modules",
307+
},
308+
apiv1.VolumeMount{
309+
Name: "modules-host",
310+
MountPath: "/lib/modules.host",
311+
ReadOnly: true,
312+
},
313+
apiv1.VolumeMount{
314+
Name: "linux-headers-generated",
315+
MountPath: "/usr/src/",
316+
},
317+
},
318+
},
256319
},
257320
Containers: []apiv1.Container{
258321
apiv1.Container{
@@ -278,13 +341,23 @@ func (t *TraceJobClient) CreateJob(nj TraceJob) (*batchv1.Job, error) {
278341
ReadOnly: true,
279342
},
280343
apiv1.VolumeMount{
281-
Name: "modules",
344+
Name: "sys",
345+
MountPath: "/sys",
346+
ReadOnly: true,
347+
},
348+
apiv1.VolumeMount{
349+
Name: "modules-dir",
282350
MountPath: "/lib/modules",
283351
ReadOnly: true,
284352
},
285353
apiv1.VolumeMount{
286-
Name: "sys",
287-
MountPath: "/sys",
354+
Name: "modules-host",
355+
MountPath: "/lib/modules.host",
356+
ReadOnly: true,
357+
},
358+
apiv1.VolumeMount{
359+
Name: "linux-headers-generated",
360+
MountPath: "/usr/src/",
288361
ReadOnly: true,
289362
},
290363
},

pkg/version/version.go

+26
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,38 @@ import (
1010
var gitCommit string
1111
var buildTime string
1212
var versionFormat = "git commit: %s\nbuild date: %s"
13+
var imageNameTagFormat = "%s:%s"
14+
var defaultImageName = "quay.io/fntlnz/kubectl-trace-bpftrace"
15+
var defaultImageTag = "latest"
16+
var defaultInitImageName = "quay.io/dalehamel/kubectl-trace-init"
17+
var defaultInitImageTag = "latest"
18+
19+
// ImageName returns the container image name defined in Makefile
20+
func ImageName() string {
21+
return imageName
22+
}
1323

1424
// GitCommit returns the git commit
1525
func GitCommit() string {
1626
return gitCommit
1727
}
1828

29+
func ImageNameTag() string {
30+
imageName := ImageName()
31+
tag := GitCommit()
32+
if len(tag) == 0 {
33+
tag = defaultImageTag
34+
}
35+
if len(imageName) == 0 {
36+
imageName = defaultImageName
37+
}
38+
return fmt.Sprintf(imageNameTagFormat, imageName, tag)
39+
}
40+
41+
func InitImageNameTag() string {
42+
return fmt.Sprintf(imageNameTagFormat, defaultInitImageName, defaultInitImageTag)
43+
}
44+
1945
// Time returns the build time
2046
func Time() *time.Time {
2147
if len(buildTime) == 0 {

0 commit comments

Comments
 (0)