Skip to content

Commit

Permalink
new(pkg,cmd): refactored builder script logic.
Browse files Browse the repository at this point in the history
Builder script has been split in 3 different scripts:
* download libs
* download headers
* build

This way, we can reuse `download libs` script among all of them.
Moreover, it is useful to have a download headers script that is invokeable by itself,
because it has the logic to download and extract headers for a given distro.

Finally, fixed a couple of things with local builder:
* redirect stderr to stdout so that we catch errors too while building
* pre initialize envMap to an empty map, instead of nil
* manage KERNELDIR env var, if set, while building with dkms

The last point allows for consumer to pass `KERNELDIR` inside `envMap` local builder processor
argument to customize the build.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
  • Loading branch information
FedeDP committed Mar 13, 2024
1 parent 318bf04 commit 4153ffa
Show file tree
Hide file tree
Showing 59 changed files with 967 additions and 472 deletions.
2 changes: 1 addition & 1 deletion cmd/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func NewLocalCmd(rootCommand *RootCmd, rootOpts *RootOptions, rootFlags *pflag.F
})
flagSet.BoolVar(&opts.useDKMS, "dkms", false, "Enforce usage of DKMS to build the kernel module.")
flagSet.StringVar(&opts.srcDir, "src-dir", "", "Enforce usage of local source dir to build drivers.")
flagSet.StringToStringVar(&opts.envMap, "env", nil, "Env variables to be enforced during the driver build.")
flagSet.StringToStringVar(&opts.envMap, "env", make(map[string]string), "Env variables to be enforced during the driver build.")
localCmd.PersistentFlags().AddFlagSet(flagSet)
return localCmd
}
Expand Down
13 changes: 9 additions & 4 deletions pkg/driverbuilder/builder/aliyunlinux.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import (
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
)

//go:embed templates/alinux_kernel.sh
var alinuxKernelTemplate string

//go:embed templates/alinux.sh
var alinuxTemplate string

Expand All @@ -32,7 +35,6 @@ func init() {
}

type alinuxTemplateData struct {
commonTemplateData
KernelDownloadURL string
}

Expand All @@ -43,6 +45,10 @@ func (c *alinux) Name() string {
return TargetTypeAlinux.String()
}

func (c *alinux) TemplateKernelUrlsScript() string {
return alinuxKernelTemplate
}

func (c *alinux) TemplateScript() string {
return alinuxTemplate
}
Expand All @@ -51,10 +57,9 @@ func (c *alinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
return fetchAlinuxKernelURLS(kr), nil
}

func (c *alinux) TemplateData(cfg Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
func (c *alinux) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} {
return alinuxTemplateData{
commonTemplateData: cfg.toTemplateData(c, kr),
KernelDownloadURL: urls[0],
KernelDownloadURL: urls[0],
}
}

Expand Down
13 changes: 9 additions & 4 deletions pkg/driverbuilder/builder/almalinux.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import (
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
)

//go:embed templates/almalinux_kernel.sh
var almaKernelTemplate string

//go:embed templates/almalinux.sh
var almaTemplate string

Expand All @@ -32,7 +35,6 @@ func init() {
}

type almaTemplateData struct {
commonTemplateData
KernelDownloadURL string
}

Expand All @@ -44,6 +46,10 @@ func (c *alma) Name() string {
return TargetTypeAlma.String()
}

func (c *alma) TemplateKernelUrlsScript() string {
return almaKernelTemplate
}

func (c *alma) TemplateScript() string {
return almaTemplate
}
Expand All @@ -52,10 +58,9 @@ func (c *alma) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
return fetchAlmaKernelURLS(kr), nil
}

func (c *alma) TemplateData(cfg Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
func (c *alma) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} {
return almaTemplateData{
commonTemplateData: cfg.toTemplateData(c, kr),
KernelDownloadURL: urls[0],
KernelDownloadURL: urls[0],
}
}

Expand Down
9 changes: 6 additions & 3 deletions pkg/driverbuilder/builder/amazonlinux.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ import (
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
)

//go:embed templates/amazonlinux_kernel.sh
var amazonlinuxKernelTemplate string

//go:embed templates/amazonlinux.sh
var amazonlinuxTemplate string

Expand Down Expand Up @@ -80,14 +83,15 @@ func init() {
}

type amazonlinuxTemplateData struct {
commonTemplateData
KernelDownloadURLs []string
}

func (a *amazonlinux) Name() string {
return TargetTypeAmazonLinux.String()
}

func (a *amazonlinux) TemplateKernelUrlsScript() string { return amazonlinuxKernelTemplate }

func (a *amazonlinux) TemplateScript() string {
return amazonlinuxTemplate
}
Expand All @@ -96,9 +100,8 @@ func (a *amazonlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
return fetchAmazonLinuxPackagesURLs(a, kr)
}

func (a *amazonlinux) TemplateData(c Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
func (a *amazonlinux) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} {
return amazonlinuxTemplateData{
commonTemplateData: c.toTemplateData(a, kr),
KernelDownloadURLs: urls,
}
}
Expand Down
11 changes: 7 additions & 4 deletions pkg/driverbuilder/builder/archlinux.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import (
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
)

//go:embed templates/archlinux_kernel.sh
var archlinuxKernelTemplate string

//go:embed templates/archlinux.sh
var archlinuxTemplate string

Expand All @@ -37,14 +40,15 @@ type archlinux struct {
}

type archlinuxTemplateData struct {
commonTemplateData
KernelDownloadURL string
}

func (c *archlinux) Name() string {
return TargetTypeArchlinux.String()
}

func (c *archlinux) TemplateKernelUrlsScript() string { return archlinuxKernelTemplate }

func (c *archlinux) TemplateScript() string {
return archlinuxTemplate
}
Expand Down Expand Up @@ -140,9 +144,8 @@ func (c *archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
return urls, nil
}

func (c *archlinux) TemplateData(cfg Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
func (c *archlinux) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} {
return archlinuxTemplateData{
commonTemplateData: cfg.toTemplateData(c, kr),
KernelDownloadURL: urls[0],
KernelDownloadURL: urls[0],
}
}
3 changes: 1 addition & 2 deletions pkg/driverbuilder/builder/bottlerocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,8 @@ func (b *bottlerocket) Name() string {
return TargetTypeBottlerocket.String()
}

func (b *bottlerocket) TemplateData(c Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
func (b *bottlerocket) KernelTemplateData(kr kernelrelease.KernelRelease, urls []string) interface{} {
return vanillaTemplateData{
commonTemplateData: c.toTemplateData(b, kr),
KernelDownloadURL: urls[0],
KernelLocalVersion: kr.FullExtraversion,
}
Expand Down
104 changes: 83 additions & 21 deletions pkg/driverbuilder/builder/builders.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package builder

import (
"bytes"
_ "embed"
"errors"
"fmt"
"log/slog"
Expand Down Expand Up @@ -51,6 +52,9 @@ const (
sed -i s/'DRIVER_COMMIT ""'/'DRIVER_COMMIT "%s"'/g driver/src/driver_config.h`
)

//go:embed templates/libs_download.sh
var libsDownloadTemplate string

var HeadersNotFoundErr = errors.New("kernel headers not found")

// Config contains all the configurations needed to build the kernel module or the eBPF probe.
Expand All @@ -70,33 +74,67 @@ func (c Config) ToProbeFullPath() string {
}

type commonTemplateData struct {
DriverBuildDir string
ModuleDownloadURL string
ModuleDriverName string
ModuleFullPath string
BuildModule bool
BuildProbe bool
GCCVersion string
CmakeCmd string
DriverBuildDir string
ModuleDriverName string
ModuleFullPath string
BuildModule bool
BuildProbe bool
GCCVersion string
CmakeCmd string
}

// Builder represents a builder capable of generating a script for a driverkit target.
type Builder interface {
Name() string
TemplateKernelUrlsScript() string
TemplateScript() string
URLs(kr kernelrelease.KernelRelease) ([]string, error)
TemplateData(c Config, kr kernelrelease.KernelRelease, urls []string) interface{} // error return type is managed
KernelTemplateData(kr kernelrelease.KernelRelease, urls []string) interface{} // error return type is managed
}

// MinimumURLsBuilder is an optional interface
// MinimumURLsBuilder is an optional interface implemented by builders
// to specify minimum number of requested headers urls
type MinimumURLsBuilder interface {
MinimumURLs() int
}

func Script(b Builder, c Config, kr kernelrelease.KernelRelease) (string, error) {
t := template.New(b.Name())
parsed, err := t.Parse(b.TemplateScript())
// TemplateDataSpecifier is an optional interface implemented by builders
// to specify a custom template data instead of the default one.
type TemplateDataSpecifier interface {
TemplateData(c Config, kr kernelrelease.KernelRelease) interface{}
}

type libsDownloadTemplateData struct {
DriverBuildDir string
ModuleDownloadURL string
}

// LibsDownloadScript returns the script that downloads and configures libs repo at requested commit/tag
func LibsDownloadScript(c Config) (string, error) {
t := template.New("download-libs")
parsed, err := t.Parse(libsDownloadTemplate)
if err != nil {
return "", err
}

td := libsDownloadTemplateData{
DriverBuildDir: DriverDirectory,
ModuleDownloadURL: fmt.Sprintf("%s/%s.tar.gz", c.DownloadBaseURL, c.DriverVersion),
}

buf := bytes.NewBuffer(nil)
err = parsed.Execute(buf, td)
if err != nil {
return "", err
}

return buf.String(), nil
}

// KernelDownloadScript returns the script that will download and extract kernel headers
func KernelDownloadScript(b Builder, c Config, kr kernelrelease.KernelRelease) (string, error) {
t := template.New("download-kernel")
parsed, err := t.Parse(b.TemplateKernelUrlsScript())
if err != nil {
return "", err
}
Expand Down Expand Up @@ -129,7 +167,7 @@ func Script(b Builder, c Config, kr kernelrelease.KernelRelease) (string, error)
return "", fmt.Errorf("not enough headers packages found; expected %d, found %d", minimumURLs, len(urls))
}

td := b.TemplateData(c, kr, urls)
td := b.KernelTemplateData(kr, urls)
if tdErr, ok := td.(error); ok {
return "", tdErr
}
Expand All @@ -139,6 +177,31 @@ func Script(b Builder, c Config, kr kernelrelease.KernelRelease) (string, error)
if err != nil {
return "", err
}

return buf.String(), nil
}

// Script retrieves the actually drivers building script
func Script(b Builder, c Config, kr kernelrelease.KernelRelease) (string, error) {
t := template.New(b.Name())
parsed, err := t.Parse(b.TemplateScript())
if err != nil {
return "", err
}

var td interface{}
if bb, ok := b.(TemplateDataSpecifier); ok {
td = bb.TemplateData(c, kr)
} else {
td = c.toTemplateData(b, kr)
}

buf := bytes.NewBuffer(nil)
err = parsed.Execute(buf, td)
if err != nil {
return "", err
}

return buf.String(), nil
}

Expand Down Expand Up @@ -305,13 +368,12 @@ func Targets() []string {
func (c Config) toTemplateData(b Builder, kr kernelrelease.KernelRelease) commonTemplateData {
c.setGCCVersion(b, kr)
return commonTemplateData{
DriverBuildDir: DriverDirectory,
ModuleDownloadURL: fmt.Sprintf("%s/%s.tar.gz", c.DownloadBaseURL, c.DriverVersion),
ModuleDriverName: c.DriverName,
ModuleFullPath: c.ToDriverFullPath(),
BuildModule: len(c.ModuleFilePath) > 0,
BuildProbe: len(c.ProbeFilePath) > 0,
GCCVersion: c.GCCVersion,
DriverBuildDir: DriverDirectory,
ModuleDriverName: c.DriverName,
ModuleFullPath: c.ToDriverFullPath(),
BuildModule: len(c.ModuleFilePath) > 0,
BuildProbe: len(c.ProbeFilePath) > 0,
GCCVersion: c.GCCVersion,
CmakeCmd: fmt.Sprintf(cmakeCmdFmt,
c.DriverName,
c.DriverName,
Expand Down
11 changes: 7 additions & 4 deletions pkg/driverbuilder/builder/centos.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import (
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
)

//go:embed templates/centos_kernel.sh
var centosKernelTemplate string

//go:embed templates/centos.sh
var centosTemplate string

Expand All @@ -37,14 +40,15 @@ type centos struct {
}

type centosTemplateData struct {
commonTemplateData
KernelDownloadURL string
}

func (c *centos) Name() string {
return TargetTypeCentos.String()
}

func (c *centos) TemplateKernelUrlsScript() string { return centosKernelTemplate }

func (c *centos) TemplateScript() string {
return centosTemplate
}
Expand Down Expand Up @@ -176,10 +180,9 @@ func (c *centos) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
return urls, nil
}

func (c *centos) TemplateData(cfg Config, kr kernelrelease.KernelRelease, urls []string) interface{} {
func (c *centos) KernelTemplateData(_ kernelrelease.KernelRelease, urls []string) interface{} {
return centosTemplateData{
commonTemplateData: cfg.toTemplateData(c, kr),
KernelDownloadURL: urls[0],
KernelDownloadURL: urls[0],
}
}

Expand Down
Loading

0 comments on commit 4153ffa

Please sign in to comment.