Skip to content

Commit

Permalink
new(pkg): use new driverkit local build processor instead of implemen…
Browse files Browse the repository at this point in the history
…ting drivers build.

Bumped driverkit to a development version.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
  • Loading branch information
FedeDP committed Feb 14, 2024
1 parent 43f1d3c commit 4c20d62
Show file tree
Hide file tree
Showing 7 changed files with 441 additions and 408 deletions.
192 changes: 122 additions & 70 deletions go.mod

Large diffs are not rendered by default.

453 changes: 279 additions & 174 deletions go.sum

Large diffs are not rendered by default.

43 changes: 27 additions & 16 deletions pkg/driver/distro/distro.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"compress/gzip"
"errors"
"fmt"
"github.com/falcosecurity/driverkit/cmd"

Check failure on line 23 in pkg/driver/distro/distro.go

View workflow job for this annotation

GitHub Actions / Lint golang files

File is not `gci`-ed with --skip-generated -s standard -s default -s prefix(github.com/falcosecurity/falcoctl) (gci)
"github.com/falcosecurity/driverkit/pkg/driverbuilder"
"io"
"net/http"
"net/url"
Expand Down Expand Up @@ -168,29 +170,38 @@ func Build(ctx context.Context,
driverType drivertype.DriverType,
driverVer string,
) (string, error) {
printer.Logger.Info("Trying to compile the requested driver")
driverFileName := toFilename(d, &kr, driverName, driverType)
destination := toLocalPath(driverVer, driverFileName, kr.Architecture.ToNonDeb())
if exist, _ := utils.FileExists(destination); exist {
return destination, ErrAlreadyPresent
destPath := toLocalPath(driverVer, driverFileName, kr.Architecture.ToNonDeb())
if exist, _ := utils.FileExists(destPath); exist {
return destPath, ErrAlreadyPresent
}

env, err := d.customizeBuild(ctx, printer, driverType, kr)
if err != nil {
return "", err
}
path, err := driverType.Build(ctx, printer, kr, driverName, driverVer, env)
if err != nil {
return "", err
}
// Copy the path to the expected location.
// NOTE: for kmod, this is not useful since the driver will
// be loaded directly by dkms.
printer.Logger.Info("Copying built driver to its destination.", printer.Logger.Args("src", path, "dst", destination))
f, err := os.Open(filepath.Clean(path))
if err != nil {
return "", err
}
return destination, copyDataToLocalPath(destination, f)

srcPath := fmt.Sprintf("/usr/src/%s-%s", driverName, driverVer)

fixedKr := d.FixupKernel(kr)
ro := cmd.NewRootOptions()
ro.Architecture = fixedKr.Architecture.String()
ro.DriverVersion = driverVer
ro.KernelVersion = fixedKr.KernelVersion
ro.ModuleDriverName = driverName
ro.ModuleDeviceName = driverName
ro.KernelRelease = fixedKr.String()
ro.Target = "local"
ro.Output = driverType.ToOutput(destPath)
// This should never happen since both kmod and bpf implement ToOutput;
// the only case this can happen is if a Build is requested for modern-bpf driver type.
// But "install" cmd is smart enough to avoid that situation.
if ro.Output.Module == "" && ro.Output.Probe == "" {
return "", errors.New("driver build without outputs attempted")
}
err = driverbuilder.NewLocalBuildProcessor(1000, true, srcPath, env).Start(ro.ToBuild())
return destPath, err
}

// Download will try to download drivers for a distro trying specified repos.
Expand Down
51 changes: 4 additions & 47 deletions pkg/driver/type/bpf.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,11 @@ package drivertype

import (
"fmt"
"github.com/falcosecurity/driverkit/cmd"

Check failure on line 20 in pkg/driver/type/bpf.go

View workflow job for this annotation

GitHub Actions / Lint golang files

File is not `gci`-ed with --skip-generated -s standard -s default -s prefix(github.com/falcosecurity/falcoctl) (gci)
"os"
"os/exec"
"path/filepath"

"github.com/docker/docker/pkg/homedir"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"golang.org/x/net/context"
"k8s.io/utils/mount"

"github.com/falcosecurity/falcoctl/internal/utils"
"github.com/falcosecurity/falcoctl/pkg/output"
)

Expand Down Expand Up @@ -73,46 +68,8 @@ func (b *bpf) HasArtifacts() bool {
return true
}

//nolint:gocritic // the method shall not be able to modify kr
func (b *bpf) Build(ctx context.Context,
printer *output.Printer,
_ kernelrelease.KernelRelease,
driverName, driverVersion string,
env map[string]string,
) (string, error) {
// We don't fail if this fails; let's try to build a probe anyway.
_ = mountKernelDebug(printer)
srcPath := fmt.Sprintf("/usr/src/%s-%s/bpf", driverName, driverVersion)

makeCmdArgs := fmt.Sprintf(`make -C %q`, filepath.Clean(srcPath))
makeCmd := exec.CommandContext(ctx, "bash", "-c", makeCmdArgs) //nolint:gosec // false positive
// Append requested env variables to the command env
makeCmd.Env = os.Environ()
for key, val := range env {
makeCmd.Env = append(makeCmd.Env, fmt.Sprintf("%s=%s", key, val))
}
out, err := makeCmd.CombinedOutput()
if err != nil {
printer.DefaultText.Print(string(out))
}
outProbe := fmt.Sprintf("%s/probe.o", srcPath)
return outProbe, err
}

func mountKernelDebug(printer *output.Printer) error {
// Mount /sys/kernel/debug that is needed on old (pre 4.17) kernel releases,
// since these releases still did not support raw tracepoints.
// BPF_PROG_TYPE_RAW_TRACEPOINT was introduced in 4.17 indeed:
// https://github.com/torvalds/linux/commit/c4f6699dfcb8558d138fe838f741b2c10f416cf9
exists, _ := utils.FileExists("/sys/kernel/debug/tracing")
if exists {
return nil
}
printer.Logger.Info("Mounting debugfs for bpf driver.")
mounter := mount.New("/bin/mount")
err := mounter.Mount("debugfs", "/sys/kernel/debug", "debugfs", []string{"nodev"})
if err != nil {
printer.Logger.Warn("Failed to mount debugfs.", printer.Logger.Args("err", err))
func (b *bpf) ToOutput(destPath string) cmd.OutputOptions {
return cmd.OutputOptions{
Probe: destPath,
}
return err
}
94 changes: 4 additions & 90 deletions pkg/driver/type/kmod.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,11 @@ import (
"bufio"
"bytes"
"fmt"
"os"
"github.com/falcosecurity/driverkit/cmd"

Check failure on line 22 in pkg/driver/type/kmod.go

View workflow job for this annotation

GitHub Actions / Lint golang files

File is not `gci`-ed with --skip-generated -s standard -s default -s prefix(github.com/falcosecurity/falcoctl) (gci)
"os/exec"
"path/filepath"
"strings"
"time"

"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"golang.org/x/net/context"

"github.com/falcosecurity/falcoctl/pkg/output"
)

Expand Down Expand Up @@ -165,90 +161,8 @@ func (k *kmod) HasArtifacts() bool {
return true
}

func createDKMSMakeFile(gcc string) error {
file, err := os.OpenFile("/tmp/falco-dkms-make", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o777) //nolint:gosec // we need the file to be executable
if err != nil {
return err
}
defer file.Close()

_, err = fmt.Fprintln(file, "#!/usr/bin/env bash")
if err == nil {
_, err = fmt.Fprintln(file, `make CC=`+gcc+` $@`)
}
return err
}

//nolint:gocritic // the method shall not be able to modify kr
func (k *kmod) Build(ctx context.Context,
printer *output.Printer,
kr kernelrelease.KernelRelease,
driverName, driverVersion string,
_ map[string]string,
) (string, error) {
// Skip dkms on UEK hosts because it will always fail
if strings.Contains(kr.String(), "uek") {
printer.Logger.Warn("Skipping because the dkms install always fail (on UEK hosts).")
return "", fmt.Errorf("unsupported on uek hosts")
}

out, err := exec.Command("which", "gcc").Output()
if err != nil {
return "", err
}
gccDir := filepath.Dir(string(out))

gccs, err := filepath.Glob(gccDir + "/gcc*")
if err != nil {
return "", err
}

for _, gcc := range gccs {
// Filter away gcc-{ar,nm,...}
// Only gcc compiler has `-print-search-dirs` option.
gccSearchArgs := fmt.Sprintf(`%s -print-search-dirs 2>&1 | grep "install:"`, gcc)
_, err = exec.Command("bash", "-c", gccSearchArgs).Output() //nolint:gosec // false positive
if err != nil {
continue
}

printer.Logger.Info("Trying to dkms install module.", printer.Logger.Args("gcc", gcc))
err = createDKMSMakeFile(gcc)
if err != nil {
printer.Logger.Warn("Could not fill /tmp/falco-dkms-make content.")
continue
}
dkmsCmdArgs := fmt.Sprintf(`dkms install --directive="MAKE='/tmp/falco-dkms-make'" -m %q -v %q -k %q --verbose`,
driverName, driverVersion, kr.String())

// Try the build through dkms
out, err = exec.CommandContext(ctx, "bash", "-c", dkmsCmdArgs).CombinedOutput() //nolint:gosec // false positive
if err == nil {
koGlob := fmt.Sprintf("/var/lib/dkms/%s/%s/%s/%s/module/%s", driverName, driverVersion, kr.String(), kr.Architecture.ToNonDeb(), driverName)
var koFiles []string
koFiles, err = filepath.Glob(koGlob + ".*")
if err != nil || len(koFiles) == 0 {
printer.Logger.Warn("Module file not found.")
continue
}
koFile := koFiles[0]
printer.Logger.Info("Module installed in dkms.", printer.Logger.Args("file", koFile))
return koFile, nil
}
printer.DefaultText.Print(string(out))
dkmsLogFile := fmt.Sprintf("/var/lib/dkms/$%s/%s/build/make.log", driverName, driverVersion)
logs, err := os.ReadFile(filepath.Clean(dkmsLogFile))
if err != nil {
printer.Logger.Warn("Running dkms build failed, couldn't find dkms log", printer.Logger.Args("file", dkmsLogFile))
} else {
printer.Logger.Warn("Running dkms build failed. Dumping dkms log.", printer.Logger.Args("file", dkmsLogFile))
logBuf := bytes.NewBuffer(logs)
scanner := bufio.NewScanner(logBuf)
for scanner.Scan() {
m := scanner.Text()
printer.DefaultText.Println(m)
}
}
func (k *kmod) ToOutput(destPath string) cmd.OutputOptions {
return cmd.OutputOptions{
Module: destPath,
}
return "", fmt.Errorf("failed to compile the module")
}
9 changes: 3 additions & 6 deletions pkg/driver/type/modernbpf.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
package drivertype

import (
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"golang.org/x/net/context"

"github.com/falcosecurity/driverkit/cmd"

Check failure on line 19 in pkg/driver/type/modernbpf.go

View workflow job for this annotation

GitHub Actions / Lint golang files

File is not `gci`-ed with --skip-generated -s standard -s default -s prefix(github.com/falcosecurity/falcoctl) (gci)
"github.com/falcosecurity/falcoctl/pkg/output"
)

Expand Down Expand Up @@ -51,7 +49,6 @@ func (m *modernBpf) HasArtifacts() bool {
return false
}

//nolint:gocritic // the method shall not be able to modify kr
func (m *modernBpf) Build(_ context.Context, _ *output.Printer, _ kernelrelease.KernelRelease, _, _ string, _ map[string]string) (string, error) {
return "", nil
func (m *modernBpf) ToOutput(_ string) cmd.OutputOptions {
return cmd.OutputOptions{}
}
7 changes: 2 additions & 5 deletions pkg/driver/type/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ package drivertype

import (
"fmt"

"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"golang.org/x/net/context"
"github.com/falcosecurity/driverkit/cmd"

"github.com/falcosecurity/falcoctl/pkg/output"
)
Expand All @@ -37,8 +35,7 @@ type DriverType interface {
Load(printer *output.Printer, src, driverName string, fallback bool) error
Extension() string
HasArtifacts() bool
Build(ctx context.Context, printer *output.Printer, kr kernelrelease.KernelRelease,
driverName, driverVersion string, env map[string]string) (string, error)
ToOutput(destPath string) cmd.OutputOptions
}

// GetTypes return the list of supported driver types.
Expand Down

0 comments on commit 4c20d62

Please sign in to comment.