Skip to content
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(pkg,cmd): refactored builder script logic. #324

Merged
merged 5 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default to an empty map instead of nil. Not a big deal anyway.

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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each builder does now expose a kernel download/extract template too.


//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
17 changes: 13 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,19 +40,26 @@ 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
}

func (c *archlinux) URLs(kr kernelrelease.KernelRelease) ([]string, error) {
// uname -r returns "6.8.1-arch1-1" but headers URL is "6.8.1.arch1-1"
// Also, for 0-patch releases, like: "6.8.0-arch1-1", headers url is "6.8.arch1-1"
kr.FullExtraversion = strings.Replace(kr.FullExtraversion, "-arch", ".arch", 1)
if kr.Patch == 0 {
kr.Fullversion = strings.TrimSuffix(kr.Fullversion, ".0")
}

urls := []string{}
possibleCompressionSuffixes := []string{
Expand Down Expand Up @@ -140,9 +150,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
108 changes: 85 additions & 23 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 {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TemplateData method is now optional since config.ToTemplateData is enough most of the time (for now, the only exception is local builder; and i think it will remain it).

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, kernelurls []string, kr kernelrelease.KernelRelease) (string, error) {
t := template.New("download-kernel")
parsed, err := t.Parse(b.TemplateKernelUrlsScript())
if err != nil {
return "", err
}
Expand All @@ -107,7 +145,7 @@ func Script(b Builder, c Config, kr kernelrelease.KernelRelease) (string, error)
minimumURLs = bb.MinimumURLs()
}

if c.KernelUrls == nil {
if kernelurls == nil {
urls, err = b.URLs(kr)
if err != nil {
return "", err
Expand All @@ -119,7 +157,7 @@ func Script(b Builder, c Config, kr kernelrelease.KernelRelease) (string, error)
urls, err = GetResolvingURLs(urls)
}
} else {
urls, err = GetResolvingURLs(c.KernelUrls)
urls, err = GetResolvingURLs(kernelurls)
}
if err != nil {
return "", err
Expand All @@ -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),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ModuleDownloadURL is only needed at libs download time, therefore it is now part of libsDownloadTemplateData.

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
Loading
Loading