From 1a201c39b9df38c21c71b6777d6b12c3319ed863 Mon Sep 17 00:00:00 2001 From: Logan Bond Date: Fri, 28 Oct 2022 13:32:47 -0500 Subject: [PATCH] Add initial opensuse support Signed-off-by: Logan Bond --- pkg/driverbuilder/builder/opensuse.go | 214 ++++++++++++++++++ .../builder/templates/opensuse.sh | 42 ++++ 2 files changed, 256 insertions(+) create mode 100644 pkg/driverbuilder/builder/opensuse.go create mode 100644 pkg/driverbuilder/builder/templates/opensuse.sh diff --git a/pkg/driverbuilder/builder/opensuse.go b/pkg/driverbuilder/builder/opensuse.go new file mode 100644 index 00000000..637ff344 --- /dev/null +++ b/pkg/driverbuilder/builder/opensuse.go @@ -0,0 +1,214 @@ +package builder + +import ( + _ "embed" + "fmt" + "strings" + + "github.com/falcosecurity/driverkit/pkg/kernelrelease" +) + +//go:embed templates/opensuse.sh +var opensuseTemplate string + +// TargetTypeOpenSUSE identifies the OpenSUSE target. +const TargetTypeOpenSUSE Type = "opensuse" + +// base URLs +var baseURLs []string = []string{ + // general releases, leap releases + "https://mirrors.edge.kernel.org/opensuse/distribution", + "http://download.opensuse.org/distribution", + "https://download.opensuse.org/repositories/Kernel:", + // some releases are stored at the top level specifically + "http://download.opensuse.org", +} + +var releases []string = []string{ + // openSUSE leap + "43.2", + "15.0", + "15.1", + "15.2", + "15.3", + // other releases + "HEAD", + "stable", + "tumbleweed", +} + +func init() { + BuilderByTarget[TargetTypeOpenSUSE] = &opensuse{} +} + +// opensuse is a driverkit target. +type opensuse struct { +} + +type opensuseTemplateData struct { + commonTemplateData + KernelDownloadURLs []string +} + +func (o *opensuse) Name() string { + return TargetTypeOpenSUSE.String() +} + +func (o *opensuse) TemplateScript() string { + return opensuseTemplate +} + +func (o *opensuse) URLs(_ Config, kr kernelrelease.KernelRelease) ([]string, error) { + + // SUSE requires 2 urls: a kernel-default-devel*{arch}.rpm and a kernel-devel*noarch.rpm + kernelDefaultDevelPattern := fmt.Sprintf("kernel-default-devel-%s%s.rpm", kr.Fullversion, kr.FullExtraversion) + kernelDevelNoArchPattern := strings.ReplaceAll( // need to replace architecture string with "noarch" + fmt.Sprintf("kernel-devel-%s%s.rpm", kr.Fullversion, kr.FullExtraversion), + kr.Architecture.ToNonDeb(), + "noarch", + ) + + // get all possible URLs + possibleURLs := buildURLs(kr, kernelDefaultDevelPattern, kernelDevelNoArchPattern) + + // try to resolve the URLs + urls, err := getResolvingURLs(possibleURLs) + if err != nil { + return nil, err + } + + // ensure there is at least one URL of each required package type + if validateURLs(urls, kernelDefaultDevelPattern, kernelDevelNoArchPattern) { + return urls, nil + } else { + return nil, fmt.Errorf( + "URLs found, but not one of each required type: [ kernel-default-devel, kernel-devel*noarch ]: %v", + urls, + ) + } +} + +// build all possible url combinations from base URLs and releases +func buildURLs(kr kernelrelease.KernelRelease, kernelDefaultDevelPattern string, kernelDevelNoArchPattern string) []string { + + possibleURLs := []string{} + for _, release := range releases { + for _, baseURL := range baseURLs { + + possibleURLs = append( + possibleURLs, + // leap urls + fmt.Sprintf( + "%s/leap/%s/repo/oss/%s/%s", + baseURL, + release, + kr.Architecture.ToNonDeb(), + kernelDefaultDevelPattern, + ), + fmt.Sprintf( // noarch + "%s/leap/%s/repo/oss/noarch/%s", + baseURL, + release, + kernelDevelNoArchPattern, + ), + // other urls + fmt.Sprintf( + "%s/%s/repo/oss/%s/%s", + baseURL, + release, + kr.Architecture.ToNonDeb(), + kernelDevelNoArchPattern, + ), + fmt.Sprintf( // noarch + "%s/%s/repo/oss/noarch/%s", + baseURL, + release, + kernelDevelNoArchPattern, + ), + // weird opensuse site urls + fmt.Sprintf( + "%s/openSUSE-%s/Submit/standard/%s/%s", + baseURL, + release, + kr.Architecture.ToNonDeb(), + kernelDefaultDevelPattern, + ), + fmt.Sprintf( + "%s/openSUSE-%s/standard/%s/%s", + baseURL, + release, + kr.Architecture.ToNonDeb(), + kernelDefaultDevelPattern, + ), + fmt.Sprintf( + "%s/openSUSE-%s:/Submit/standard/%s/%s", + baseURL, + release, + kr.Architecture.ToNonDeb(), + kernelDefaultDevelPattern, + ), + fmt.Sprintf( + "%s/openSUSE-%s:/standard/%s/%s", + baseURL, + release, + kr.Architecture.ToNonDeb(), + kernelDefaultDevelPattern, + ), + // weird opensuse site urls - kernel-devel*noarch edition + fmt.Sprintf( + "%s/openSUSE-%s/Submit/standard/noarch/%s", + baseURL, + release, + kernelDevelNoArchPattern, + ), + fmt.Sprintf( + "%s/openSUSE-%s/standard/noarch/%s", + baseURL, + release, + kernelDevelNoArchPattern, + ), + fmt.Sprintf( + "%s/openSUSE-%s:/Submit/standard/noarch/%s", + baseURL, + release, + kernelDevelNoArchPattern, + ), + fmt.Sprintf( + "%s/openSUSE-%s:/standard/noarch/%s", + baseURL, + release, + kernelDevelNoArchPattern, + ), + ) + } + } + + return possibleURLs +} + +// check to ensure there is at least one URL of each package type +func validateURLs(urls []string, kernelDefaultDevelPattern string, kernelDevelNoArchPattern string) bool { + + // setup some flags + kernelDefaultDevelFlag := false + kernelDevelNoArchFlag := false + + for _, url := range urls { + if strings.Contains(url, kernelDefaultDevelPattern) { + kernelDefaultDevelFlag = true + } + if strings.Contains(url, kernelDevelNoArchPattern) { + kernelDevelNoArchFlag = true + } + } + + return kernelDefaultDevelFlag && kernelDevelNoArchFlag + +} + +func (o *opensuse) TemplateData(cfg Config, kr kernelrelease.KernelRelease, urls []string) interface{} { + return opensuseTemplateData{ + commonTemplateData: cfg.toTemplateData(o, kr), + KernelDownloadURLs: urls, + } +} diff --git a/pkg/driverbuilder/builder/templates/opensuse.sh b/pkg/driverbuilder/builder/templates/opensuse.sh new file mode 100644 index 00000000..fad85ad4 --- /dev/null +++ b/pkg/driverbuilder/builder/templates/opensuse.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 +{{range $url := .KernelDownloadURLs}} +curl --silent -o kernel-devel.rpm -SL {{ $url }} +# cpio will warn *extremely verbose* when trying to duplicate over the same directory - redirect stderr to null +rpm2cpio kernel-devel.rpm | cpio --quiet --extract --make-directories 2> /dev/null +{{end}} +cd /tmp/kernel-download/usr/src +ls -alh /tmp/kernel-download/usr/src +sourcedir="$(find . -type d -name "linux-*-obj" | head -n 1 | xargs readlink -f)/*/default" + +{{ if .BuildModule }} +# Build the module +cd {{ .DriverBuildDir }} +make CC=/usr/bin/gcc-{{ .GCCVersion }} KERNELDIR=$sourcedir +mv {{ .ModuleDriverName }}.ko {{ .ModuleFullPath }} +strip -g {{ .ModuleFullPath }} +# Print results +modinfo {{ .ModuleFullPath }} +{{ end }} + +{{ if .BuildProbe }} +# Build the eBPF probe +cd {{ .DriverBuildDir }}/bpf +make KERNELDIR=/tmp/kernel +ls -l probe.o +{{ end }} \ No newline at end of file