Skip to content

Commit

Permalink
new(pkg/driver,cmd/driver): allow users to override kernelrelease and…
Browse files Browse the repository at this point in the history
… kernelversion.

Moreover, added support for a couple of curl related flags in falco-driver-loader.

Signed-off-by: Federico Di Pierro <[email protected]>
  • Loading branch information
FedeDP committed Nov 6, 2023
1 parent e554f30 commit ba10f3e
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 130 deletions.
52 changes: 41 additions & 11 deletions cmd/driver/prepare/prepare.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@
package driverprepare

import (
"crypto/tls"
"errors"
"fmt"
"net/http"
"time"

"github.com/spf13/cobra"
"golang.org/x/net/context"
Expand All @@ -29,14 +32,22 @@ import (
"github.com/falcosecurity/falcoctl/pkg/output"
)

type driverDownloadOptions struct {
DriverRepos []string
InsecureDownload bool
HttpTimeout time.Duration

Check warning on line 38 in cmd/driver/prepare/prepare.go

View workflow job for this annotation

GitHub Actions / Lint golang files

var-naming: struct field HttpTimeout should be HTTPTimeout (revive)
}

// DriverPrepareOptions contains the options for the driver prepare command.
type driverPrepareOptions struct {
*options.Common
*options.Driver
Download bool
Build bool
DriverVersion string
DriverRepos []string
Download bool
Build bool
DriverVersion string
DriverKernelRelease string
DriverKernelVersion string
driverDownloadOptions
}

// NewDriverPrepareCmd returns the driver prepare command.
Expand All @@ -63,14 +74,26 @@ func NewDriverPrepareCmd(ctx context.Context, opt *options.Common) *cobra.Comman
cmd.Flags().BoolVar(&o.Download, "download", true, "Whether to enable download of drivers")
cmd.Flags().BoolVar(&o.Build, "build", true, "Whether to enable build of drivers")
cmd.Flags().StringVar(&o.DriverVersion, "driver-version", "", "Driver version to be built")
cmd.Flags().StringVar(&o.DriverKernelRelease, "driver-kernelrelease", "", "Specify the kernel release for which to download/build the driver in the same format used by 'uname -r' (e.g. '6.1.0-10-cloud-amd64')")
cmd.Flags().StringVar(&o.DriverKernelVersion, "driver-kernelversion", "", "Specify the kernel version for which to download/build the driver in the same format used by 'uname -v' (e.g. '#1 SMP PREEMPT_DYNAMIC Debian 6.1.38-2 (2023-07-27)')")
cmd.Flags().StringSliceVar(&o.DriverRepos, "driver-repo", []string{driverdistro.DefaultFalcoRepo}, "Specify different URL(s) where to look for prebuilt drivers")
cmd.Flags().BoolVar(&o.InsecureDownload, "http-insecure", false, "Whether you want to allow insecure downloads or not")
cmd.Flags().DurationVar(&o.HttpTimeout, "http-timeout", 60*time.Second, "Timeout for each http try")

if err := cmd.MarkFlagRequired("driver-version"); err != nil {
output.ExitOnErr(o.Printer, fmt.Errorf("unable to mark flag \"driver-version\" as required"))
}
return cmd
}

func setDefaultHTTPClientOpts(downloadOptions driverDownloadOptions) {
// Skip insecure verify
if downloadOptions.InsecureDownload {
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
}
http.DefaultClient.Timeout = downloadOptions.HttpTimeout
}

// RunDriverPrepare implements the driver prepare command.
func (o *driverPrepareOptions) RunDriverPrepare(_ context.Context, _ []string) error {
driver, err := config.Driverer()
Expand All @@ -83,11 +106,18 @@ func (o *driverPrepareOptions) RunDriverPrepare(_ context.Context, _ []string) e
return err
}

if o.DriverKernelRelease != "" {
info.KernelRelease = o.DriverKernelRelease
}
if o.DriverKernelVersion != "" {
info.KernelVersion = driverkernel.FormatVersion(o.DriverKernelVersion)
}

o.Printer.Logger.Info("Running falcoctl driver prepare", o.Printer.Logger.Args(
"driver version", o.DriverVersion,
"driver type", driver.Type,
"driver name", o.Name,
"arch", info.Architecture,
"arch", driverdistro.GetArchitecture(),
"kernel release", info.KernelRelease,
"kernel version", info.KernelVersion))

Expand All @@ -96,7 +126,7 @@ func (o *driverPrepareOptions) RunDriverPrepare(_ context.Context, _ []string) e
return nil
}

d, err := driverdistro.DiscoverDistro(o.Printer, o.HostRoot)
d, err := driverdistro.DiscoverDistro(info, o.HostRoot)
if err != nil {
if errors.Is(err, driverdistro.ErrUnsupported) && o.Build {
o.Download = false
Expand All @@ -112,12 +142,12 @@ func (o *driverPrepareOptions) RunDriverPrepare(_ context.Context, _ []string) e
return err
}

setDefaultHTTPClientOpts(o.driverDownloadOptions)

var dest string
if o.Download {
// Fixup kernel information before attempting to download
downloadInfo := d.FixupKernel(info)

dest, err = d.Download(downloadInfo, o.Driver, driver.Type, o.DriverVersion, o.DriverRepos)
driverFileName := driverdistro.DriverToFilename(d, info, o.Driver, driver.Type)
dest, err = driverdistro.Download(d, o.Printer, driverFileName, o.DriverVersion, o.DriverRepos)
if err == nil {
// We don't care about errors at this stage
_ = driver.Type.Load(o.Printer, dest, false)
Expand All @@ -129,7 +159,7 @@ func (o *driverPrepareOptions) RunDriverPrepare(_ context.Context, _ []string) e
}

if o.Build {
dest, err = d.Build()
dest, err = driverdistro.Build(d, o.Printer)
if err == nil {
// We don't care about errors
_ = driver.Type.Load(o.Printer, dest, false)
Expand Down
4 changes: 2 additions & 2 deletions cmd/driver/select/select.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ func (o *driverSelectOptions) RunDriverSelect(_ context.Context, args []string)
}

o.Printer.Logger.Info("Running falcoctl driver select", o.Printer.Logger.Args(
"arch", info.Architecture,
"arch", driverdistro.GetArchitecture(),
"kernel release", info.KernelRelease,
"kernel version", info.KernelVersion))

d, err := driverdistro.DiscoverDistro(o.Printer, o.HostRoot)
d, err := driverdistro.DiscoverDistro(info, o.HostRoot)
if err != nil {
return nil, err
}
Expand Down
7 changes: 3 additions & 4 deletions pkg/driver/distro/amzn.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@ package driverdistro

import (
"fmt"
driverkernel "github.com/falcosecurity/falcoctl/pkg/driver/kernel"

Check failure on line 20 in pkg/driver/distro/amzn.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)

"gopkg.in/ini.v1"

Check failure on line 22 in pkg/driver/distro/amzn.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"
)

func init() {
Expand All @@ -31,7 +30,7 @@ type amzn struct {
*generic
}

func (a *amzn) init(printer *output.Printer, _ string, cfg *ini.File) error {
func (a *amzn) init(i driverkernel.Info, _ string, cfg *ini.File) error {
idKey := cfg.Section("").Key("VERSION_ID")
if idKey == nil {
// OS-release without `VERSION_ID` (can it happen?)
Expand All @@ -49,5 +48,5 @@ func (a *amzn) init(printer *output.Printer, _ string, cfg *ini.File) error {
default:
newID = "amazonlinux"
}
return a.generic.init(printer, newID, cfg)
return a.generic.init(i, newID, cfg)
}
7 changes: 3 additions & 4 deletions pkg/driver/distro/bottlerocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (
"gopkg.in/ini.v1"

driverkernel "github.com/falcosecurity/falcoctl/pkg/driver/kernel"
"github.com/falcosecurity/falcoctl/pkg/output"
)

func init() {
Expand All @@ -35,7 +34,7 @@ type bottlerocket struct {
versionID string
}

func (b *bottlerocket) init(printer *output.Printer, id string, cfg *ini.File) error {
func (b *bottlerocket) init(i driverkernel.Info, id string, cfg *ini.File) error {
idKey := cfg.Section("").Key("VERSION_ID")
if idKey == nil {
// OS-release without `VERSION_ID` (can it happen?)
Expand All @@ -49,10 +48,10 @@ func (b *bottlerocket) init(printer *output.Printer, id string, cfg *ini.File) e
}
b.variantID = strings.Split(idKey.String(), "-")[0]

return b.generic.init(printer, id, cfg)
return b.generic.init(i, id, cfg)
}

func (b *bottlerocket) FixupKernel(i driverkernel.Info) driverkernel.Info {
func (b *bottlerocket) fixupKernel(i driverkernel.Info) driverkernel.Info {
i.KernelVersion = fmt.Sprintf("1_%s-%s", b.versionID, b.variantID)
return i
}
2 changes: 1 addition & 1 deletion pkg/driver/distro/debian.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (d *debian) check(hostRoot string) bool {
return false
}

func (d *debian) FixupKernel(i driverkernel.Info) driverkernel.Info {
func (d *debian) fixupKernel(i driverkernel.Info) driverkernel.Info {
// Workaround: debian kernelreleases might now be actual kernel running;
// instead, they might be the Debian kernel package
// providing the compatible kernel ABI
Expand Down
95 changes: 84 additions & 11 deletions pkg/driver/distro/distro.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ package driverdistro

import (
"fmt"
"github.com/docker/docker/pkg/homedir"

Check failure on line 20 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/falcoctl/pkg/options"
"io"
"net/http"
"os"
"runtime"
"strings"

Check failure on line 27 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)
"gopkg.in/ini.v1"

driverkernel "github.com/falcosecurity/falcoctl/pkg/driver/kernel"
drivertype "github.com/falcosecurity/falcoctl/pkg/driver/type"

Check failure on line 31 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/falcoctl/pkg/options"
"github.com/falcosecurity/falcoctl/pkg/output"
)

Expand All @@ -40,11 +45,9 @@ var ErrUnsupported = fmt.Errorf("failed to determine distro")
// Distro is the common interface used by distro-specific implementations.
// Most of the distro-specific only partially override the default `generic` implementation.
type Distro interface {
init(printer *output.Printer, id string, cfg *ini.File) error // private
init(i driverkernel.Info, id string, cfg *ini.File) error // private
GetTargetID(i driverkernel.Info) string
FixupKernel(i driverkernel.Info) driverkernel.Info
Download(i driverkernel.Info, opts *options.Driver, driverType drivertype.DriverType, driverVer string, repos []string) (string, error)
Build() (string, error)
fixupKernel(i driverkernel.Info) driverkernel.Info // private
PreferredDriver(i driverkernel.Info) drivertype.DriverType
}

Expand All @@ -54,8 +57,8 @@ type checker interface {

// DiscoverDistro tries to fetch the correct Distro by looking at /etc/os-release or
// by cycling on all supported distros and checking them one by one.
func DiscoverDistro(printer *output.Printer, hostRoot string) (Distro, error) {
distro, err := getOSReleaseDistro(printer, hostRoot)
func DiscoverDistro(i driverkernel.Info, hostRoot string) (Distro, error) {
distro, err := getOSReleaseDistro(i, hostRoot)
if err == nil {
return distro, nil
}
Expand All @@ -64,20 +67,20 @@ func DiscoverDistro(printer *output.Printer, hostRoot string) (Distro, error) {
for id, d := range distros {
dd, ok := d.(checker)
if ok && dd.check(hostRoot) {
err = d.init(printer, id, nil)
err = d.init(i, id, nil)
return d, err
}
}

// Return a generic distro to try the build
distro = &generic{}
if err = distro.init(printer, "undetermined", nil); err != nil {
if err = distro.init(i, "undetermined", nil); err != nil {
return nil, err
}
return distro, ErrUnsupported
}

func getOSReleaseDistro(printer *output.Printer, hostRoot string) (Distro, error) {
func getOSReleaseDistro(i driverkernel.Info, hostRoot string) (Distro, error) {
cfg, err := ini.Load(hostRoot + "/etc/os-release")
if err != nil {
return nil, err
Expand All @@ -100,8 +103,78 @@ func getOSReleaseDistro(printer *output.Printer, hostRoot string) (Distro, error
if !exist {
distro = &generic{}
}
if err = distro.init(printer, id, cfg); err != nil {
if err = distro.init(i, id, cfg); err != nil {
return nil, err
}
return distro, nil
}

func toURL(repo, driverVer, fileName string) string {
return fmt.Sprintf("%s/%s/%s/%s", repo, driverVer, GetArchitecture(), fileName)
}

func toLocalPath(driverVer, fileName string) string {
return fmt.Sprintf("%s/.falco/%s/%s/%s", homedir.Get(), driverVer, GetArchitecture(), fileName)
}

// DriverToFilename returns the filename for a given distro's driver.
func DriverToFilename(d Distro, i driverkernel.Info, opts *options.Driver, driverType drivertype.DriverType) string {
// Fixup kernel information before attempting to download
fixedInfo := d.fixupKernel(i)
return fmt.Sprintf("%s_%s_%s_%s%s", opts.Name, d.GetTargetID(i), fixedInfo.KernelRelease, fixedInfo.KernelVersion, driverType.Extension())
}

// GetArchitecture returns current arch as non-deb name (ie: x86_64/aarch64)
func GetArchitecture() string {
switch runtime.GOARCH {
case "amd64":
return "x86_64"
case "arm64":
return "aarch64"
default:
return "uknown"
}
}

func Build(_ Distro, _ *output.Printer) (string, error) {

Check warning on line 139 in pkg/driver/distro/distro.go

View workflow job for this annotation

GitHub Actions / Lint golang files

exported: exported function Build should have comment or be unexported (revive)
// TODO compile
// flatcar specific: flatcar_relocate_tools
// cos specific...
// minikube specific...
return "", fmt.Errorf("build unimplemented")
}

func Download(_ Distro, printer *output.Printer, driverFileName, driverVer string, repos []string) (string, error) {

Check warning on line 147 in pkg/driver/distro/distro.go

View workflow job for this annotation

GitHub Actions / Lint golang files

exported: exported function Download should have comment or be unexported (revive)
// Skip if existent
destination := toLocalPath(driverVer, driverFileName)
f, err := os.Open(destination) //nolint:gosec // false positive
if err == nil {
_ = f.Close()
printer.Logger.Info("Skipping download, driver already present.", printer.Logger.Args("path", destination))
return destination, nil
}

// Try to download from any specified repository,
// stopping at first successful http GET.
for _, repo := range repos {
url := toURL(repo, driverVer, driverFileName)
printer.Logger.Info("Trying to download a driver", printer.Logger.Args("url", url))

resp, err := http.Get(url) //nolint:gosec // false positive
if err != nil || resp.StatusCode != 200 {
continue
}

out, err := os.Create(destination) //nolint:gosec // false positive
if err != nil {
return destination, err
}
_, err = io.Copy(out, resp.Body)
if err != nil {
return destination, err
}
_ = resp.Body.Close()
return destination, nil
}
return destination, fmt.Errorf("unable to find a prebuilt driver")
}
7 changes: 3 additions & 4 deletions pkg/driver/distro/flatcar.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"gopkg.in/ini.v1"

driverkernel "github.com/falcosecurity/falcoctl/pkg/driver/kernel"
"github.com/falcosecurity/falcoctl/pkg/output"
)

func init() {
Expand All @@ -33,17 +32,17 @@ type flatcar struct {
versionID string
}

func (f *flatcar) init(printer *output.Printer, id string, cfg *ini.File) error {
func (f *flatcar) init(i driverkernel.Info, id string, cfg *ini.File) error {
idKey := cfg.Section("").Key("VERSION_ID")
if idKey == nil {
// OS-release without `VERSION_ID` (can it happen?)
return fmt.Errorf("no VERSION_ID present for flatcar")
}
f.versionID = idKey.String()
return f.generic.init(printer, id, cfg)
return f.generic.init(i, id, cfg)
}

func (f *flatcar) FixupKernel(i driverkernel.Info) driverkernel.Info {
func (f *flatcar) fixupKernel(i driverkernel.Info) driverkernel.Info {
i.KernelRelease = f.versionID
return i
}
Loading

0 comments on commit ba10f3e

Please sign in to comment.