-
Notifications
You must be signed in to change notification settings - Fork 52
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
fix(pkg/driverbuilder): multiple small fixes to local builder. #342
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,7 +20,7 @@ | |
# looking for it in a bunch of ways. Convenient when running Falco inside | ||
# a container or in other weird environments. | ||
# | ||
set -xeo pipefail | ||
set -xeuo pipefail | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as other tempaltes. |
||
|
||
{{ if or .BuildProbe (and .BuildModule (not .UseDKMS)) }} | ||
cd {{ .DriverBuildDir }} | ||
|
@@ -31,7 +31,6 @@ mkdir -p build && cd build | |
{{ end }} | ||
{{ end }} | ||
|
||
|
||
{{ if .BuildModule }} | ||
{{ if .UseDKMS }} | ||
echo "* Building kmod with DKMS" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,20 +25,23 @@ const ( | |
type LocalBuildProcessor struct { | ||
useDKMS bool | ||
downloadHeaders bool | ||
srcDir string | ||
envMap map[string]string | ||
timeout int | ||
// Whether to only print cmd output on error | ||
printOnError bool | ||
srcDir string | ||
envMap map[string]string | ||
timeout int | ||
*output.Printer | ||
} | ||
|
||
func NewLocalBuildProcessor(useDKMS, downloadHeaders bool, | ||
func NewLocalBuildProcessor(useDKMS, downloadHeaders, printOnError bool, | ||
srcDir string, | ||
envMap map[string]string, | ||
timeout int, | ||
) *LocalBuildProcessor { | ||
return &LocalBuildProcessor{ | ||
useDKMS: useDKMS, | ||
srcDir: srcDir, | ||
printOnError: printOnError, | ||
envMap: envMap, | ||
downloadHeaders: downloadHeaders, | ||
timeout: timeout, | ||
|
@@ -117,7 +120,7 @@ func (lbp *LocalBuildProcessor) Start(b *builder.Build) error { | |
|
||
// Load gcc versions from system | ||
var gccs []string | ||
if len(b.ModuleFilePath) > 0 { | ||
if len(c.ModuleFilePath) > 0 { | ||
out, err := exec.Command("which", "gcc").Output() | ||
if err != nil { | ||
return err | ||
|
@@ -166,6 +169,12 @@ func (lbp *LocalBuildProcessor) Start(b *builder.Build) error { | |
|
||
for _, gcc := range gccs { | ||
vv.GccPath = gcc | ||
if c.ModuleFilePath != "" { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added some debug info. |
||
lbp.Logger.Info("Trying to dkms install module.", lbp.Logger.Args("gcc", gcc)) | ||
} | ||
if c.ProbeFilePath != "" { | ||
lbp.Logger.Info("Trying to build eBPF probe.") | ||
} | ||
|
||
// Generate the build script from the builder | ||
driverkitScript, err := builder.Script(v, c, kr) | ||
|
@@ -181,59 +190,58 @@ func (lbp *LocalBuildProcessor) Start(b *builder.Build) error { | |
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", key, val)) | ||
} | ||
|
||
stdout, err := cmd.StdoutPipe() | ||
if err != nil { | ||
lbp.Logger.Warn("Failed to pipe stdout", lbp.Logger.Args("err", err)) | ||
_, err = cmd.CombinedOutput() | ||
} else { | ||
cmd.Stderr = cmd.Stdout // redirect stderr to stdout so that we catch it | ||
defer stdout.Close() | ||
err = cmd.Start() | ||
if err != nil { | ||
lbp.Logger.Warn("Failed to execute command", lbp.Logger.Args("err", err)) | ||
} else { | ||
// print the output of the subprocess line by line | ||
scanner := bufio.NewScanner(stdout) | ||
for scanner.Scan() { | ||
m := scanner.Text() | ||
fmt.Println(m) | ||
} | ||
err = cmd.Wait() | ||
} | ||
out, err := cmd.CombinedOutput() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to pipe and scan stdout/stderr: we are always behind a stylish spinner now, therefore we will never print these lines in real time. |
||
if !lbp.printOnError || err != nil { | ||
// Only print on error | ||
lbp.DefaultText.Print(string(out)) | ||
} | ||
|
||
// If we built the probe, disable its build for subsequent attempts (with other available gccs) | ||
if c.ProbeFilePath != "" { | ||
if _, err = os.Stat(srcProbePath); !os.IsNotExist(err) { | ||
if err = copyDataToLocalPath(srcProbePath, b.ProbeFilePath); err != nil { | ||
if err = copyDataToLocalPath(srcProbePath, c.ProbeFilePath); err != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
return err | ||
} | ||
lbp.Logger.Info("eBPF probe available", lbp.Logger.Args("path", b.ProbeFilePath)) | ||
lbp.Logger.Info("eBPF probe available", lbp.Logger.Args("path", c.ProbeFilePath)) | ||
c.ProbeFilePath = "" | ||
} | ||
} | ||
|
||
// If we received an error, perhaps we just need to try another build for the kmod. | ||
// Check if we were able to build anything. | ||
koFiles, err := filepath.Glob(srcModulePath) | ||
if err == nil && len(koFiles) > 0 { | ||
// Since only kmod might need to get rebuilt | ||
// with another gcc, break here if we actually built the kmod. | ||
break | ||
if c.ModuleFilePath != "" { | ||
koFiles, err := filepath.Glob(srcModulePath) | ||
if err == nil && len(koFiles) > 0 { | ||
// Since only kmod might need to get rebuilt | ||
// with another gcc, break here if we actually built the kmod, | ||
// since we already checked ebpf build status. | ||
if err = copyDataToLocalPath(koFiles[0], c.ModuleFilePath); err != nil { | ||
return err | ||
} | ||
lbp.Logger.Info("kernel module available", lbp.Logger.Args("path", b.ModuleFilePath)) | ||
c.ModuleFilePath = "" | ||
break | ||
} else { | ||
// print dkms build log | ||
dkmsLogFile := fmt.Sprintf("/var/lib/dkms/%s/%s/build/make.log", c.DriverName, c.DriverVersion) | ||
logs, err := os.ReadFile(filepath.Clean(dkmsLogFile)) | ||
if err != nil { | ||
lbp.Logger.Warn("Running dkms build failed, couldn't find dkms log", lbp.Logger.Args("file", dkmsLogFile)) | ||
} else { | ||
lbp.Logger.Warn("Running dkms build failed. Dumping dkms log.", lbp.Logger.Args("file", dkmsLogFile)) | ||
logBuf := bytes.NewBuffer(logs) | ||
scanner := bufio.NewScanner(logBuf) | ||
for scanner.Scan() { | ||
m := scanner.Text() | ||
lbp.DefaultText.Println(m) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
if len(b.ModuleFilePath) > 0 { | ||
// If we received an error, perhaps we must just rebuilt the kmod. | ||
// Check if we were able to build anything. | ||
koFiles, err := filepath.Glob(srcModulePath) | ||
if err != nil || len(koFiles) == 0 { | ||
return fmt.Errorf("failed to find kernel module .ko file: %s", srcModulePath) | ||
} | ||
if err = copyDataToLocalPath(koFiles[0], b.ModuleFilePath); err != nil { | ||
return err | ||
} | ||
lbp.Logger.Info("kernel module available", lbp.Logger.Args("path", b.ModuleFilePath)) | ||
if c.ModuleFilePath != "" || c.ProbeFilePath != "" { | ||
return fmt.Errorf("Failed to build all requested drivers.") | ||
} | ||
return nil | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Always print command output from within driverkit.
Falcoctl will, instead, only print on error to avoid being too noisy.