diff --git a/cmd/testdata/completion-targets.txt b/cmd/testdata/completion-targets.txt index beaa23db..d1eac0b0 100644 --- a/cmd/testdata/completion-targets.txt +++ b/cmd/testdata/completion-targets.txt @@ -1,6 +1,7 @@ amazonlinux amazonlinux2 amazonlinux2022 +archlinux centos debian flatcar diff --git a/pkg/driverbuilder/builder/archlinux.go b/pkg/driverbuilder/builder/archlinux.go new file mode 100644 index 00000000..6fe3c7bc --- /dev/null +++ b/pkg/driverbuilder/builder/archlinux.go @@ -0,0 +1,105 @@ +package builder + +import ( + "bytes" + _ "embed" + "fmt" + "text/template" + + "github.com/falcosecurity/driverkit/pkg/kernelrelease" +) + +//go:embed templates/archlinux.sh +var archlinuxTemplate string + +// TargetTypeArchlinux identifies the Archlinux target. +const TargetTypeArchlinux Type = "archlinux" + +func init() { + BuilderByTarget[TargetTypeArchlinux] = &archlinux{} +} + +// archlinux is a driverkit target. +type archlinux struct { +} + +// Script compiles the script to build the kernel module and/or the eBPF probe. +func (c archlinux) Script(cfg Config, kr kernelrelease.KernelRelease) (string, error) { + t := template.New(string(TargetTypeArchlinux)) + parsed, err := t.Parse(archlinuxTemplate) + if err != nil { + return "", err + } + + var urls []string + if cfg.KernelUrls == nil { + // Check (and filter) existing kernels before continuing + urls, err = getResolvingURLs(fetchArchlinuxKernelURLS(kr, cfg.KernelVersion)) + } else { + urls, err = getResolvingURLs(cfg.KernelUrls) + } + if err != nil { + return "", err + } + + td := archlinuxTemplateData{ + DriverBuildDir: DriverDirectory, + ModuleDownloadURL: moduleDownloadURL(cfg), + KernelDownloadURL: urls[0], + GCCVersion: archlinuxGccVersionFromKernelRelease(kr), + ModuleDriverName: cfg.DriverName, + ModuleFullPath: ModuleFullPath, + BuildModule: len(cfg.Build.ModuleFilePath) > 0, + BuildProbe: len(cfg.Build.ProbeFilePath) > 0, + } + + buf := bytes.NewBuffer(nil) + err = parsed.Execute(buf, td) + if err != nil { + return "", err + } + return buf.String(), nil +} + +func fetchArchlinuxKernelURLS(kr kernelrelease.KernelRelease, kv uint16) []string { + urls := []string{} + + if kr.Architecture == "amd64" { + urls = append(urls, fmt.Sprintf( + "https://archive.archlinux.org/packages/l/linux-headers/linux-headers-%s.%s-%d-%s.pkg.tar.xz", + kr.Fullversion, + kr.Extraversion, + kv, + kr.Architecture.ToNonDeb())) + } else { + urls = append(urls, fmt.Sprintf( + "http://tardis.tiny-vps.com/aarm/packages/l/linux-%s-headers/linux-%s-headers-%s-%d-%s.pkg.tar.xz", + kr.Architecture.ToNonDeb(), + kr.Architecture.ToNonDeb(), + kr.Fullversion, + kv, + kr.Architecture.ToNonDeb())) + } + return urls +} + +type archlinuxTemplateData struct { + DriverBuildDir string + ModuleDownloadURL string + KernelDownloadURL string + GCCVersion string + ModuleDriverName string + ModuleFullPath string + BuildModule bool + BuildProbe bool +} + +func archlinuxGccVersionFromKernelRelease(kr kernelrelease.KernelRelease) string { + switch kr.Version { + case 3: + return "5" + case 2: + return "4.8" + } + return "8" +} diff --git a/pkg/driverbuilder/builder/templates/archlinux.sh b/pkg/driverbuilder/builder/templates/archlinux.sh new file mode 100644 index 00000000..0a3196c8 --- /dev/null +++ b/pkg/driverbuilder/builder/templates/archlinux.sh @@ -0,0 +1,42 @@ +#!/bin/bash +set -xeuo pipefail + +rm -Rf {{ .DriverBuildDir }} +mkdir {{ .DriverBuildDir }} +rm -Rf /tmp/module-download +mkdir -p /tmp/module-download + +curl --silent -SL {{ .ModuleDownloadURL }} | tar -xzf - -C /tmp/module-download +mv /tmp/module-download/*/driver/* {{ .DriverBuildDir }} + +cp /driverkit/module-Makefile {{ .DriverBuildDir }}/Makefile +bash /driverkit/fill-driver-config.sh {{ .DriverBuildDir }} + +# Fetch the kernel +mkdir /tmp/kernel-download +cd /tmp/kernel-download +curl --silent -o kernel-devel.pkg.tar.xz -SL {{ .KernelDownloadURL }} +tar -xf kernel-devel.pkg.tar.xz +rm -Rf /tmp/kernel +mkdir -p /tmp/kernel +mv usr/lib/modules/*/build/* /tmp/kernel + +# Change current gcc +ln -sf /usr/bin/gcc-{{ .GCCVersion }} /usr/bin/gcc + +{{ if .BuildModule }} +# Build the module +cd {{ .DriverBuildDir }} +make KERNELDIR=/tmp/kernel +mv {{ .ModuleDriverName }}.ko {{ .ModuleFullPath }} +strip -g {{ .ModuleFullPath }} +# Print results +modinfo {{ .ModuleFullPath }} +{{ end }} + +{{ if .BuildProbe }} +# Build the eBPF probe +cd {{ .DriverBuildDir }}/bpf +make LLC=/usr/bin/llc-7 CLANG=/usr/bin/clang-7 CC=/usr/bin/gcc KERNELDIR=/tmp/kernel +ls -l probe.o +{{ end }} \ No newline at end of file