Repository: falcosecurity/driverkit
Pull request #183 (2022-07-11 15:53:09)

new(builder): added an archlinux builder.
**What type of PR is this?**

/kind feature

<!--
Please remove the leading whitespace before the `/kind <>` you uncommented.
-->

**Any specific area of the project related to this PR?**

/area pkg


**What this PR does / why we need it**:

It can be useful to quickly test newest kernel releases.

**Which issue(s) this PR fixes**:

Fixes #

**Special notes for your reviewer**:

**Does this PR introduce a user-facing change?**:

```release-note
new(builder): added an archlinux builder.
```


poiana: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/falcosecurity/driverkit/pull/183#" title="Author self-approved">FedeDP</a>*
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **leodido** after the PR has been reviewed.
You can assign the PR to them by writing `/assign @leodido` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://prow.falco.org/command-help?repo=falcosecurity%2Fdriverkit).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/falcosecurity/driverkit/blob/master/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["leodido"]} -->

Patch:
diff --git a/pkg/driverbuilder/builder/archlinux.go b/pkg/driverbuilder/builder/archlinux.go
new file mode 100644
index 0000000..6fe3c7b
--- /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 0000000..0a3196c
--- /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


Test patch:
diff --git a/cmd/testdata/completion-targets.txt b/cmd/testdata/completion-targets.txt
index beaa23d..d1eac0b 100644
--- a/cmd/testdata/completion-targets.txt
+++ b/cmd/testdata/completion-targets.txt
@@ -1,6 +1,7 @@
 amazonlinux
 amazonlinux2
 amazonlinux2022
+archlinux
 centos
 debian
 flatcar