-
Notifications
You must be signed in to change notification settings - Fork 109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
new: support driverkit multiarch driver builds #734
Changes from all commits
8636130
ae7c20a
ac6663a
ddc7424
f11b7e4
2163011
3090270
023f335
72bb7ce
e87df75
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,33 +5,62 @@ ifeq ($(DRIVERKIT),) | |
DRIVERKIT := "/bin/driverkit" | ||
endif | ||
|
||
CONFIGS := $(wildcard config/*/*.yaml) | ||
ALL_ARCHS := x86_64 aarch64 | ||
|
||
# Recursive wildcard | ||
rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d)) | ||
|
||
# Equals function | ||
eq = $(and $(findstring $(1),$(2)),$(findstring $(2),$(1))) | ||
|
||
CONFIGS := $(call rwildcard,config/*,*.yaml) | ||
VERSIONS := $(patsubst config/%,%,$(sort $(dir $(wildcard config/*/)))) | ||
VERSIONS := $(VERSIONS:/=) | ||
TARGET_VERSION ?= * | ||
TARGET_DISTRO ?= * | ||
TARGET_KERNEL ?= * | ||
TARGET_ARCH ?= * | ||
TARGET_ARCHS := $(if $(call eq,$(TARGET_ARCH),*),$(ALL_ARCHS),$(TARGET_ARCH)) | ||
TARGET_HEADERS ?= | ||
S3_DRIVERS_BUCKET ?= "falco-distribution" | ||
S3_DRIVERS_KEY_PREFIX ?= "driver" | ||
SKIP_EXISTING ?= true | ||
|
||
validate: $(patsubst config_%,validate/%,$(subst /,_,$(wildcard config/${TARGET_VERSION}*/${TARGET_DISTRO}_${TARGET_KERNEL}-*))) | ||
validate: validate_old validate_new | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Split in 2 sub targets to correctly manage new and old driverkit config tree. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like it, even not elegant. When needed to cleanup it will be simple. |
||
# old fmt had x86_64 only in root folder. Note: this breaks filtering for TARGET_ARCH | ||
# because validate_old will always validate any old config. | ||
# Not a big deal because we were not going to filter for TARGET_ARCH in any case. | ||
# TODO: rm once old format support is dropped | ||
validate_old: $(patsubst config_%,validate/%,$(subst /,_,$(wildcard config/${TARGET_VERSION}*/${TARGET_DISTRO}_${TARGET_KERNEL}-*))) | ||
# new fmt has $arch subfolders | ||
validate_new: $(patsubst config_%,validate/%,$(subst /,_,$(wildcard config/${TARGET_VERSION}*/${TARGET_ARCH}/${TARGET_DISTRO}_${TARGET_KERNEL}-*))) | ||
|
||
all: $(patsubst config_%,%,$(subst /,_,$(CONFIGS))) | ||
|
||
specific_target: $(patsubst config_%,%,$(subst /,_,$(wildcard config/${TARGET_VERSION}*/${TARGET_DISTRO}_${TARGET_KERNEL}-*))) | ||
specific_target: specific_target_old specific_target_new | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Split in 2 sub targets to correctly manage new and old driverkit config tree. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above |
||
# old fmt had x86_64 only in root folder. Note: this breaks filtering for TARGET_ARCH | ||
# because specific_target_old will always build any old config. | ||
# Not a big deal because we were not going to filter for TARGET_ARCH in any case. | ||
# TODO: rm once old format support is dropped | ||
specific_target_old: $(patsubst config_%,%,$(subst /,_,$(wildcard config/${TARGET_VERSION}*/${TARGET_DISTRO}_${TARGET_KERNEL}-*))) | ||
# new fmt has $arch subfolders | ||
specific_target_new: $(patsubst config_%,%,$(subst /,_,$(wildcard config/${TARGET_VERSION}*/${TARGET_ARCH}/${TARGET_DISTRO}_${TARGET_KERNEL}-*))) | ||
|
||
prepare: $(addprefix prepare_,$(VERSIONS)) | ||
publish: $(addprefix publish_,$(VERSIONS)) | ||
publish_s3: $(addprefix publish_s3_,$(VERSIONS)) | ||
|
||
generate: | ||
$(foreach VERSION,$(VERSIONS),\ | ||
utils/generate -k ${TARGET_KERNEL} -d ${TARGET_DISTRO} -v ${VERSION}; \ | ||
$(foreach ARCH,$(TARGET_ARCHS),\ | ||
$(foreach VERSION,$(VERSIONS),\ | ||
utils/generate -a '$(ARCH)' -k '${TARGET_KERNEL}' -d '${TARGET_DISTRO}' -h '${TARGET_HEADERS}' -v '${VERSION}'; \ | ||
)\ | ||
) | ||
|
||
generate/auto: | ||
utils/scrape_and_generate | ||
$(foreach ARCH,$(TARGET_ARCHS),\ | ||
utils/scrape_and_generate $(ARCH); \ | ||
) | ||
|
||
cleanup: | ||
utils/cleanup -p ${BINTRAY_SECRET} $(addprefix -v ,$(VERSIONS)) | ||
|
@@ -40,36 +69,53 @@ cleanup_s3: | |
S3_DRIVERS_BUCKET=${S3_DRIVERS_BUCKET} S3_DRIVERS_KEY_PREFIX=${S3_DRIVERS_KEY_PREFIX} utils/cleanup_s3 $(addprefix -v ,$(VERSIONS)) | ||
|
||
# $(1): pseudo-target name | ||
# $(2): driver version | ||
# $(3): config file path | ||
# $(2): config file path | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dropped unused driver version param. |
||
define gen_build_targets | ||
validate/$(1): $(3) | ||
utils/checkfiles $(3) | ||
validate/$(1): $(2) | ||
utils/checkfiles $(2) | ||
|
||
$(1): validate/$(1) $(3) | ||
DRIVERKIT=${DRIVERKIT} S3_DRIVERS_BUCKET=${S3_DRIVERS_BUCKET} S3_DRIVERS_KEY_PREFIX=${S3_DRIVERS_KEY_PREFIX} SKIP_EXISTING=${SKIP_EXISTING} utils/build $(3) | ||
$(1): validate/$(1) $(2) | ||
DRIVERKIT=${DRIVERKIT} S3_DRIVERS_BUCKET=${S3_DRIVERS_BUCKET} S3_DRIVERS_KEY_PREFIX=${S3_DRIVERS_KEY_PREFIX} SKIP_EXISTING=${SKIP_EXISTING} utils/build $(2) | ||
endef | ||
|
||
$(foreach CONFIG,$(CONFIGS),\ | ||
$(eval INNER := $(patsubst config/%,%,$(CONFIG)))\ | ||
$(eval VERSION := $(patsubst %/,%,$(dir $(INNER))))\ | ||
$(eval TARGET := $(patsubst config_%,%,$(subst /,_,$(CONFIG))))\ | ||
$(eval $(call gen_build_targets,$(TARGET),$(VERSION),$(CONFIG)))\ | ||
$(eval $(call gen_build_targets,$(TARGET),$(CONFIG)))\ | ||
) | ||
|
||
# $(1): driver version | ||
define gen_publish_targets | ||
split_$(1)_kernelmodules: | ||
# root is old x86_64 | ||
# TODO: rm once old format support is dropped | ||
ifneq ("$(wildcard output/$(1)/*.ko)","") | ||
@mkdir -p output/$(1)/kernel-module | ||
@mv -f output/$(1)/*.ko output/$(1)/kernel-module | ||
endif | ||
ifneq ("$(wildcard output/$(1)/x86_64/*.ko)","") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Basically, we now search in both root folder (old directory tree) and new $arch subfolders. |
||
@mkdir -p output/$(1)/kernel-module/x86_64 | ||
@mv -f output/$(1)/x86_64/*.ko output/$(1)/kernel-module/x86_64 | ||
endif | ||
ifneq ("$(wildcard output/$(1)/aarch64/*.ko)","") | ||
@mkdir -p output/$(1)/kernel-module/aarch64 | ||
@mv -f output/$(1)/aarch64/*.ko output/$(1)/kernel-module/aarch64 | ||
endif | ||
|
||
split_$(1)_ebpfprobes: | ||
# root is old x86_64 | ||
# TODO: rm once old format support is dropped | ||
ifneq ("$(wildcard output/$(1)/*.o)","") | ||
@mkdir -p output/$(1)/ebpf-probe | ||
@mv -f output/$(1)/*.o output/$(1)/ebpf-probe | ||
endif | ||
ifneq ("$(wildcard output/$(1)/x86_64/*.o)","") | ||
@mkdir -p output/$(1)/ebpf-probe/x86_64 | ||
@mv -f output/$(1)/x86_64/*.o output/$(1)/ebpf-probe/x86_64 | ||
endif | ||
ifneq ("$(wildcard output/$(1)/aarch64/*.o)","") | ||
@mkdir -p output/$(1)/ebpf-probe/aarch64 | ||
@mv -f output/$(1)/aarch64/*.o output/$(1)/ebpf-probe/aarch64 | ||
endif | ||
|
||
prepare_$(1): split_$(1)_kernelmodules split_$(1)_ebpfprobes | ||
@echo "upserting falcosecurity/driver/kernel-module/$(1) version..." | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,15 @@ input="$1" | |
IFS=/ read -a input_parts <<< ${input} | ||
driver_version="${input_parts[1]}" | ||
|
||
# If there is an arch subdir -> use it! | ||
# TODO: rm once old format support is dropped; just use arch="${input_parts[2]}" | ||
if [[ ${#input_parts[@]} -eq 4 ]]; then | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This workaround is needed to be able to check correct module path for old and new directory tree. |
||
arch="${input_parts[2]}/" | ||
else | ||
# fallback at no arch (ie: x86_64, root folder on s3 bucket) | ||
arch="" | ||
fi | ||
|
||
output_module= | ||
output_probe= | ||
create_variables "$input" | ||
|
@@ -26,7 +35,7 @@ check_s3_existence() { | |
|
||
# Check whether the kernel module already exists on S3 | ||
if [[ -n "${output_module}" ]]; then | ||
output_module_filename="${output_module##*/}" | ||
output_module_filename="${arch}${output_module##*/}" | ||
if [[ ${SKIP_EXISTING} == "true" ]] && check_s3_existence "${output_module_filename}"; then | ||
>&2 echo "output module already esists inside S3 bucket - skipping (${S3_DRIVERS_KEY_PREFIX}/${driver_version}/${output_module_filename})" | ||
else | ||
|
@@ -36,7 +45,7 @@ fi | |
|
||
# Check whether the eBPF probe already exists on S3 | ||
if [[ -n "${output_probe}" ]]; then | ||
output_probe_filename="${output_probe##*/}" | ||
output_probe_filename="${arch}${output_probe##*/}" | ||
if [[ ${SKIP_EXISTING} == "true" ]] && check_s3_existence "${output_probe_filename}"; then | ||
>&2 echo "output probe already esists inside S3 bucket - skipping (${S3_DRIVERS_KEY_PREFIX}/${driver_version}/${output_probe_filename})" | ||
else | ||
|
@@ -46,6 +55,6 @@ fi | |
|
||
# Build | ||
if [[ ${should_build} == "true" ]]; then | ||
mkdir -p output/${driver_version} | ||
mkdir -p output/${driver_version}/${arch} | ||
${DRIVERKIT} docker -c ${input} --driverversion ${driver_version} --timeout 1000 || echo ${input} >> output/failing.log | ||
fi |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,20 @@ source "${currentdir}/parseyaml" | |
input="$1" | ||
filename="${input##*/}" | ||
|
||
# TODO: rm once old format support is dropped; just use arch="${input_parts[2]}" | ||
function get_arch_from_path() { | ||
# Check if arch subdir exists | ||
IFS=/ read -a input_parts <<< ${1} | ||
if [[ ${#input_parts[@]} -eq 4 ]]; then | ||
arch="${input_parts[2]}/" | ||
else | ||
arch="" | ||
fi | ||
echo -n "${arch}" | ||
} | ||
|
||
arch="$(get_arch_from_path ${input})" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fetch arch from config file path (if any); it is later used to check that if config file is under a $arch subfolder, its output module and probe must be under same $arch subfolder. |
||
|
||
target= | ||
kernelrelease= | ||
kernelversion= | ||
|
@@ -34,6 +48,14 @@ if [ -n "${output_probe}" ]; then | |
>&2 echo "output probe filename is wrong (${1})" | ||
exit 1 | ||
fi | ||
|
||
# TODO: rm this external check once old format support is dropped (and we always have an arch) | ||
if [[ -n "${arch}" ]]; then | ||
if [ "$arch" != "$(get_arch_from_path ${output_probe})" ]; then | ||
>&2 echo "output probe filename has wrong architecture in its config path (${1})" | ||
exit 1 | ||
fi | ||
fi | ||
fi | ||
|
||
# Check whether the kernel module filename follows the convention otherwise exit | ||
|
@@ -43,4 +65,12 @@ if [ -n "${output_module}" ]; then | |
>&2 echo "output module filename is wrong (${1})" | ||
exit 1 | ||
fi | ||
fi | ||
|
||
# TODO: rm this external check once old format support is dropped (and we always have an arch) | ||
if [[ -n "${arch}" ]]; then | ||
if [ "$arch" != "$(get_arch_from_path ${output_module})" ]; then | ||
>&2 echo "output module filename has wrong architecture in its config path (${1})" | ||
exit 1 | ||
fi | ||
fi | ||
fi |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,8 +10,14 @@ source "${currentdir}/parseyaml" | |
TARGET_VERSION=${TARGET_VERSION:-"*"} | ||
TARGET_DISTRO=${TARGET_DISTRO:-"*"} | ||
TARGET_KERNEL=${TARGET_KERNEL:-"*"} | ||
TARGET_ARCH=${TARGET_ARCH:-"*"} | ||
|
||
configs=(config/${TARGET_VERSION}*/${TARGET_DISTRO}_${TARGET_KERNEL}-*.yaml) | ||
# Only load old configs if x86_64 or * arch is requested | ||
# TODO: rm this once old format support is dropped | ||
if [ "${TARGET_ARCH}" = "*" ] || [ "${TARGET_ARCH}" = "x86_64" ]; then | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If users filter for TARGET_ARCH, only load old config if either "*" (any) or "x86_64" is requested. |
||
configs_old=(config/${TARGET_VERSION}*/${TARGET_DISTRO}_${TARGET_KERNEL}-*.yaml) | ||
fi | ||
configs_new=(config/${TARGET_VERSION}*/${TARGET_ARCH}/${TARGET_DISTRO}_${TARGET_KERNEL}-*.yaml) | ||
|
||
total_ebpf_drivers=0 | ||
total_kmod_drivers=0 | ||
|
@@ -47,26 +53,34 @@ cleanup() { | |
hdestroy kmod_drivers_by_version | ||
} | ||
|
||
for file in "${configs[@]}" | ||
do | ||
driver_version=${file%/*} | ||
driver_version=${driver_version##config/} | ||
output_module= | ||
output_probe= | ||
create_variables "$file" | ||
if [ -n "${output_probe}" ]; then | ||
((total_ebpf_drivers=total_ebpf_drivers+1)) | ||
current_num_ebpf_drivers=$(hget ebpf_drivers_by_version "${driver_version}") || current_num_ebpf_drivers=0 | ||
((current_num_ebpf_drivers=current_num_ebpf_drivers+1)) | ||
hput ebpf_drivers_by_version "${driver_version}" "${current_num_ebpf_drivers}" | ||
fi | ||
if [ -n "${output_module}" ]; then | ||
((total_kmod_drivers=total_kmod_drivers+1)) | ||
current_num_kmod_drivers=$(hget kmod_drivers_by_version "${driver_version}") || current_num_kmod_drivers=0 | ||
((current_num_kmod_drivers=current_num_kmod_drivers+1)) | ||
hput kmod_drivers_by_version "${driver_version}" "${current_num_kmod_drivers}" | ||
fi | ||
done | ||
loop() { | ||
configs=("$@") | ||
for file in "${configs[@]}" | ||
do | ||
driver_version=${file%/*} | ||
driver_version=${driver_version##config/} | ||
driver_version=$(echo "$driver_version" | tr '/' '_') | ||
output_module= | ||
output_probe= | ||
create_variables "$file" | ||
if [ -n "${output_probe}" ]; then | ||
((total_ebpf_drivers=total_ebpf_drivers+1)) | ||
current_num_ebpf_drivers=$(hget ebpf_drivers_by_version "${driver_version}") || current_num_ebpf_drivers=0 | ||
((current_num_ebpf_drivers=current_num_ebpf_drivers+1)) | ||
hput ebpf_drivers_by_version "${driver_version}" "${current_num_ebpf_drivers}" | ||
fi | ||
if [ -n "${output_module}" ]; then | ||
((total_kmod_drivers=total_kmod_drivers+1)) | ||
current_num_kmod_drivers=$(hget kmod_drivers_by_version "${driver_version}") || current_num_kmod_drivers=0 | ||
((current_num_kmod_drivers=current_num_kmod_drivers+1)) | ||
hput kmod_drivers_by_version "${driver_version}" "${current_num_kmod_drivers}" | ||
fi | ||
done | ||
} | ||
|
||
# TODO: rm this once old format support is dropped | ||
loop "${configs_old[@]}" | ||
loop "${configs_new[@]}" | ||
|
||
for driver_version in $(hkeys kmod_drivers_by_version) | ||
do | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Find all configs under config and its subfolders (eventually, for supported $arch).