ronantakizawa/codereview-bench huggingface dataset:
Repository: microsoft/retina
File: test/e2e/framework/scaletest/get-publish-metrics.go (Go)

Code before:

		g.telemetryClient = telemetryClient
	}

	config, err := clientcmd.BuildConfigFromFlags("", g.KubeConfigFilePath)
	if err != nil {
		return fmt.Errorf("error building kubeconfig: %w", err)
	}

	k8sClient, err := kubernetes.NewForConfig(config)
	if err != nil {
		return fmt.Errorf("error creating Kubernetes client: %w", err)
	}
	g.k8sClient = k8sClient

	metricsClient, err := metrics.NewForConfig(config)
	if err != nil {
		return fmt.Errorf("error creating metrics client: %w", err)
	}
	g.metricsClient = metricsClient

	g.stop = make(chan struct{})
	g.wg.Add(1)

	go func() {

		t := time.NewTicker(defaultInterval)

		// First execution
		err := g.getAndPublishMetrics()
		if err != nil {
			log.Fatalf("error getting and publishing number of restarts: %v", err)
			return
		}

		for {
			select {

			case <-t.C:
				err := g.getAndPublishMetrics()
				if err != nil {
					log.Fatalf("error getting and publishing number of restarts: %v", err)
					return
				}

			case <-g.stop:
				g.wg.Done()
				return

			}
		}

Review comment (suggestion):
This leaks a goroutine.

```go
defer t.Stop()
```

Not a huge deal in tests, but it's a habit you should drill.

Code after:
		g.telemetryClient = telemetryClient
	}

	config, err := clientcmd.BuildConfigFromFlags("", g.KubeConfigFilePath)
	if err != nil {
		return fmt.Errorf("error building kubeconfig: %w", err)
	}

	k8sClient, err := kubernetes.NewForConfig(config)
	if err != nil {
		return fmt.Errorf("error creating Kubernetes client: %w", err)
	}
	g.k8sClient = k8sClient

	metricsClient, err := metrics.NewForConfig(config)
	if err != nil {
		return fmt.Errorf("error creating metrics client: %w", err)
	}
	g.metricsClient = metricsClient

	g.stop = make(chan struct{})
	g.errs = new(errgroup.Group)

	g.errs.Go(func() error {

		t := time.NewTicker(defaultInterval)
		defer t.Stop()

		// First execution
		err := g.getAndPublishMetrics()
		if err != nil {
			return fmt.Errorf("failed to get and publish test metrics: %w", err)
		}

		for {
			select {

			case <-t.C:
				err := g.getAndPublishMetrics()
				if err != nil {
					return fmt.Errorf("failed to get and publish test metrics: %w", err)
				}

			case <-g.stop:
				return nil

			}
		}

	})
Repository: microsoft/retina
File: test/e2e/framework/scaletest/add-shared-labels.go (Go)

Code before:
package scaletest

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"time"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
)

const (
	timeoutToLabelAllPodsMinutes = 120
)

type patchStringValue struct {
	Op    string `json:"op"`
	Path  string `json:"path"`
	Value string `json:"value"`
}

type AddSharedLabelsToAllPods struct {
	KubeConfigFilePath    string
	NumSharedLabelsPerPod int
	Namespace             string
}

// Useful when wanting to do parameter checking, for example
// if a parameter length is known to be required less than 80 characters,
// do this here so we don't find out later on when we run the step
// when possible, try to avoid making external calls, this should be fast and simple
func (a *AddSharedLabelsToAllPods) Prevalidate() error {
	return nil
}

// Primary step where test logic is executed
// Returning an error will cause the test to fail
func (a *AddSharedLabelsToAllPods) Run() error {

Review comment (suggestion):
Again, please use `time.Duration`:

```suggestion
	podLabelTimeout = 120 * time.Minute
```

Code after:
package scaletest

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"time"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
)

type patchStringValue struct {
	Op    string `json:"op"`
	Path  string `json:"path"`
	Value string `json:"value"`
}

type AddSharedLabelsToAllPods struct {
	KubeConfigFilePath    string
	NumSharedLabelsPerPod int
	Namespace             string
}

// Useful when wanting to do parameter checking, for example
// if a parameter length is known to be required less than 80 characters,
// do this here so we don't find out later on when we run the step
// when possible, try to avoid making external calls, this should be fast and simple
func (a *AddSharedLabelsToAllPods) Prevalidate() error {
	return nil
}

// Primary step where test logic is executed
// Returning an error will cause the test to fail
func (a *AddSharedLabelsToAllPods) Run() error {

	if a.NumSharedLabelsPerPod < 1 {
		return nil
	}
Repository: microsoft/retina
File: pkg/plugin/conntrack/_cprog/conntrack.c (C)

Code before:
//go:build ignore

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

#include "vmlinux.h"
#include "compiler.h"
#include "bpf_helpers.h"
#include "conntrack.h"
#include "dynamic.h"

struct tcpmetadata {
	__u32 seq; // TCP sequence number
	__u32 ack_num; // TCP ack number
	__u32 tsval; // TCP timestamp value
	__u32 tsecr; // TCP timestamp echo reply
};

struct conntrackmetadata {
    /*
        bytes_*_count indicates the number of bytes sent and received in the forward and reply direction.
        These values will be based on the conntrack entry.
    */
    __u64 bytes_forward_count;
    __u64 bytes_reply_count;
    /*
        packets_*_count indicates the number of packets sent and received in the forward and reply direction.
        These values will be based on the conntrack entry.
    */
    __u64 packets_forward_count;
    __u64 packets_reply_count;
};

struct packet
{
	__u64 t_nsec; // timestamp in nanoseconds
	__u32 bytes; // packet size in bytes
	__u32 src_ip;
	__u32 dst_ip;
	__u16 src_port;
	__u16 dst_port;
	struct tcpmetadata tcp_metadata; // TCP metadata
	__u8 observation_point;
	__u8 traffic_direction;

Review comment (suggestion):
i think we discussed this offline, but do you think if it would be simpler/more practical if we just maintain the bytes and packet counts for the entire connection instead of its individual direction? cc @vakalapa

Code after:
//go:build ignore

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

#include "vmlinux.h"
#include "compiler.h"
#include "bpf_helpers.h"
#include "conntrack.h"
#include "dynamic.h"

struct tcpmetadata {
	__u32 seq; // TCP sequence number
	__u32 ack_num; // TCP ack number
	__u32 tsval; // TCP timestamp value
	__u32 tsecr; // TCP timestamp echo reply
};

struct conntrackmetadata {
    /*
        bytes_*_count indicates the number of bytes sent and received in the forward and reply direction.
        These values will be based on the conntrack entry.
    */
    __u64 bytes_forward_count;
    __u64 bytes_reply_count;
    /*
        packets_*_count indicates the number of packets sent and received in the forward and reply direction.
        These values will be based on the conntrack entry.
    */
    __u32 packets_forward_count;
    __u32 packets_reply_count;
};

struct packet
{
	__u64 t_nsec; // timestamp in nanoseconds
	__u32 bytes; // packet size in bytes
	__u32 src_ip;
	__u32 dst_ip;
	__u16 src_port;
	__u16 dst_port;
	struct tcpmetadata tcp_metadata; // TCP metadata
	__u8 observation_point;
	__u8 traffic_direction;
Repository: microsoft/retina
File: controller/Dockerfile.proto (Protocol Buffers)

Code before:
# mcr.microsoft.com/oss/go/microsoft/golang:1.23.1-cbl-mariner2.0
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang@sha256:dcd95cadab21a855894c599c9e26bfb2179aa08e7d7f99c0e8546167712ba6ef

LABEL Name=retina-builder Version=0.0.1

RUN yum update -y &&\
    yum install -y unzip

WORKDIR /tmp

RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.34.2
RUN wget https://github.com/protocolbuffers/protobuf/releases/download/v24.2/protoc-24.2-linux-x86_64.zip
RUN unzip protoc-24.2-linux-x86_64.zip -d protoc
RUN mv protoc/bin/protoc /usr/bin/protoc

WORKDIR /app
ENTRYPOINT protoc -I=. --go_out=paths=source_relative:. ./pkg/utils/metadata_linux.proto


Review comment (suggestion):
on mariner, use `tdnf` not `yum`
```suggestion
RUN tdnf update &&\
    tdnf install -y unzip
```

Code after:
# mcr.microsoft.com/oss/go/microsoft/golang:1.23.1-cbl-mariner2.0
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/oss/go/microsoft/golang@sha256:dcd95cadab21a855894c599c9e26bfb2179aa08e7d7f99c0e8546167712ba6ef

LABEL Name=retina-builder Version=0.0.1

RUN tdnf install -y unzip

WORKDIR /tmp

RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.34.2
RUN wget https://github.com/protocolbuffers/protobuf/releases/download/v24.2/protoc-24.2-linux-x86_64.zip
RUN unzip protoc-24.2-linux-x86_64.zip -d protoc
RUN mv protoc/bin/protoc /usr/bin/protoc

WORKDIR /app
ENTRYPOINT protoc -I=. --go_out=paths=source_relative:. ./pkg/utils/metadata_linux.proto
Repository: microsoft/retina
File: operator/config/config.go (Go)

Code before:
	// EnableRetinaEndpoint indicates whether to enable RetinaEndpoint
	EnableRetinaEndpoint bool          `yaml:"enableRetinaEndpoint"`
	RemoteContext        bool          `yaml:"remoteContext"`
	TelemetryInterval    time.Duration `yaml:"telemetryInterval"`
}

func GetConfig(cfgFileName string) (*OperatorConfig, error) {
	viper.SetConfigType("yaml")
	viper.SetConfigFile(cfgFileName)
	err := viper.ReadInConfig()
	if err != nil {
		return nil, fmt.Errorf("error reading config file: %w", err)
	}

	viper.AutomaticEnv()

	var cfg OperatorConfig
	viper.SetDefault("EnableRetinaEndpoint", true)
	err = viper.Unmarshal(&cfg)
	if err != nil {
		return nil, fmt.Errorf("error unmarshalling config: %w", err)
	}

	// If unset, default telemetry interval to 5 minutes.
	if cfg.TelemetryInterval == 0 {
		cfg.TelemetryInterval = 5 * time.Minute
	}

	return &cfg, nil
}


Review comment (suggestion):
let's keep to 15min, and since this is a configmap change we'll need to notify a few people

https://github.com/microsoft/retina/pull/1266/files#diff-754f5ed2c6297aa0f46f6627521cda46a66d540bcdc9713857a6a84f7fc7358aL52

Code after:
)

type OperatorConfig struct {
	config.CaptureConfig `mapstructure:",squash"`

	InstallCRDs     bool   `yaml:"installCRDs"`
	EnableTelemetry bool   `yaml:"enableTelemetry"`
	LogLevel        string `yaml:"logLevel"`
	// EnableRetinaEndpoint indicates whether to enable RetinaEndpoint
	EnableRetinaEndpoint bool          `yaml:"enableRetinaEndpoint"`
	RemoteContext        bool          `yaml:"remoteContext"`
	TelemetryInterval    time.Duration `yaml:"telemetryInterval"`
}

func GetConfig(cfgFileName string) (*OperatorConfig, error) {
	viper.SetConfigType("yaml")
	viper.SetConfigFile(cfgFileName)
	err := viper.ReadInConfig()
	if err != nil {
		return nil, fmt.Errorf("error reading config file: %w", err)
	}

	viper.AutomaticEnv()

	var cfg OperatorConfig
	viper.SetDefault("EnableRetinaEndpoint", true)
	err = viper.Unmarshal(&cfg)
	if err != nil {
		return nil, fmt.Errorf("error unmarshalling config: %w", err)
	}

	// If unset, default telemetry interval to 5 minutes.
	if cfg.TelemetryInterval == 0 {
		log.Printf("telemetryInterval is not set, defaulting to %v", DefaultTelemetryInterval)
		cfg.TelemetryInterval = DefaultTelemetryInterval
	} else if cfg.TelemetryInterval < MinTelemetryInterval {
		return nil, ErrorTelemetryIntervalTooSmall
	}

	return &cfg, nil
}
Repository: microsoft/retina
File: pkg/plugin/linuxutil/ethtool_handle_linux.go (Go)

Code before:
func NewCachedEthtool(ethHandle EthtoolInterface, opts *EthtoolOpts) *CachedEthtool {
	cache, err := lru.New[string, struct{}](int(opts.limit))
	if err != nil {
		log.Logger().Error("failed to create LRU cache: ", zap.Error(err))
	}

	return &CachedEthtool{
		EthtoolInterface: ethHandle,
		unsupported:      cache,
		l:                log.Logger().Named(string("EthtoolReader")),
	}
}

var errskip = errors.New("skip interface")

func (ce *CachedEthtool) Stats(intf string) (map[string]uint64, error) {
	// Skip unsupported interfaces
	if _, ok := ce.unsupported.Get(intf); ok {
		return nil, errskip
	}

	ifaceStats, err := ce.EthtoolInterface.Stats(intf)
	if err != nil {
		if strings.Contains(err.Error(), "operation not supported") {
			ce.unsupported.Add(intf, struct{}{})
			return nil, fmt.Errorf("interface %q not supported while retrieving stats: %w", intf, err)
		}
		return nil, fmt.Errorf("failed to retrieve interface stats for %s: %w", intf, err)
	}
	return ifaceStats, nil
}


Review comment (bug):
While it is great to have less cluttered error we lose context as well. If we are reducing the presence of error to just one interface, I don't see any harm in having extra information in the event we might have to use this for additional debug.

Code after:
package linuxutil

import (
	"strings"

	"github.com/pkg/errors"

	lru "github.com/hashicorp/golang-lru/v2"

	"github.com/microsoft/retina/pkg/log"
)

type CachedEthtool struct {
	EthtoolInterface
	unsupported *lru.Cache[string, struct{}]
	l           *log.ZapLogger
}

func NewCachedEthtool(ethHandle EthtoolInterface, unsupportedInterfacesCache *lru.Cache[string, struct{}]) *CachedEthtool {
	return &CachedEthtool{
		EthtoolInterface: ethHandle,
		unsupported:      unsupportedInterfacesCache,
		l:                log.Logger().Named(string("EthtoolReader")),
	}
}

var errskip = errors.New("skip interface")

func (ce *CachedEthtool) Stats(intf string) (map[string]uint64, error) {
	// Skip unsupported interfaces
	if _, ok := ce.unsupported.Get(intf); ok {
		return nil, errskip
	}

	ifaceStats, err := ce.EthtoolInterface.Stats(intf)
	if err != nil {
		if strings.Contains(err.Error(), "operation not supported") {
			ce.unsupported.Add(intf, struct{}{})
			return nil, errors.Wrap(err, "interface not supported while retrieving stats")
		}
		return nil, errors.Wrap(err, "failed to retrieve interface stats")
	}
	return ifaceStats, nil
}
Repository: microsoft/retina
File: pkg/plugin/linuxutil/linuxutil_linux.go (Go)

Code before:
func (lu *linuxUtil) SetupChannel(chan *hubblev1.Event) error {
	lu.l.Debug("Plugin does not support SetupChannel", zap.String("plugin", name))
	return nil
}

func (lu *linuxUtil) run(ctx context.Context) error {
	lu.l.Info("Running linuxutil plugin...")

	ethtoolOpts := &EthtoolOpts{
		errOrDropKeysOnly: true,
		addZeroVal:        false,
		limit:             defaultLimit,
	}

	ethHandle, err := ethtool.NewEthtool()
	if err != nil {
		lu.l.Error("Error while creating ethHandle: %v\n", zap.Error(err))
		return fmt.Errorf("failed to create ethHandle: %w", err)
	}
	defer ethHandle.Close()

	ethReader := NewEthtoolReader(ethtoolOpts, ethHandle)
	if ethReader == nil {
		lu.l.Error("Error while creating ethReader")
		return errors.New("error while creating ethReader")
	}

	ticker := time.NewTicker(lu.cfg.MetricsInterval)
	defer ticker.Stop()

	for {
		select {
		case <-ctx.Done():
			lu.l.Info("Context is done, linuxutil will stop running")
			return nil
		case <-ticker.C:
			opts := &NetstatOpts{
				CuratedKeys:      true,
				AddZeroVal:       false,
				ListenSock:       false,
				PrevTCPSockStats: lu.prevTCPSockStats,
			}
			var wg sync.WaitGroup

			ns := &Netstat{}
			nsReader := NewNetstatReader(opts, ns)
			wg.Add(1)
			go func() {
				defer wg.Done()
				tcpSocketStats, err := nsReader.readAndUpdate()
				if err != nil {

Review comment (bug):
One of the reason for keeping the `ethHandle` inside the loop is to make sure we are not bringing down Retina agent for transient error. Do you think the `ethHandle` error is permanent - as in if it fails once, it cannot succeed on retry? 
If you return error here, `PluginManager` will treat it as a fatal error.

Code after:
	lu.l.Debug("Plugin does not support SetupChannel", zap.String("plugin", name))
	return nil
}

func (lu *linuxUtil) run(ctx context.Context) error {
	lu.l.Info("Running linuxutil plugin...")

	// create a LRU cache to skip unsupported interfaces
	unsupportedInterfacesCache, err := lru.New[string, struct{}](int(defaultLimit))
	if err != nil {
		lu.l.Error("failed to create global LRU cache", zap.Error(err))
		return err
	}

	ticker := time.NewTicker(lu.cfg.MetricsInterval)
	defer ticker.Stop()

	for {
		select {
		case <-ctx.Done():
			lu.l.Info("Context is done, linuxutil will stop running")
			return nil
		case <-ticker.C:
			opts := &NetstatOpts{
				CuratedKeys:      true,
				AddZeroVal:       false,
				ListenSock:       false,
				PrevTCPSockStats: lu.prevTCPSockStats,
			}
			var wg sync.WaitGroup

			ns := &Netstat{}
			nsReader := NewNetstatReader(opts, ns)
			wg.Add(1)
			go func() {
				defer wg.Done()
				tcpSocketStats, err := nsReader.readAndUpdate()
				if err != nil {
					lu.l.Error("Reading netstat failed", zap.Error(err))
				}
				lu.prevTCPSockStats = tcpSocketStats
			}()

			ethtoolOpts := &EthtoolOpts{
				errOrDropKeysOnly: true,
				addZeroVal:        false,
			}

			ethHandle, err := ethtool.NewEthtool()
			if err != nil {
				lu.l.Error("Error while creating ethHandle: %v\n", zap.Error(err))
Repository: microsoft/retina
File: pkg/plugin/linuxutil/linuxutil_linux.go (Go)

Code before:
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

// Package linuxutil contains the Retina linuxutil plugin. It gathers TCP/UDP statistics and network interface statistics from the netstats and ethtool node utilities (respectively).
package linuxutil

import (
	"context"
	"fmt"
	"sync"
	"time"

	hubblev1 "github.com/cilium/cilium/pkg/hubble/api/v1"
	lru "github.com/hashicorp/golang-lru/v2"
	kcfg "github.com/microsoft/retina/pkg/config"
	"github.com/microsoft/retina/pkg/log"
	"github.com/microsoft/retina/pkg/plugin/registry"
	"github.com/pkg/errors"
	"github.com/safchain/ethtool"
	"go.uber.org/zap"
)

const defaultLimit = 2000

var globalLruCache *lru.Cache[string, struct{}]

func init() {
	registry.Add(name, New)
}

// New creates a linuxutil plugin.
func New(cfg *kcfg.Config) registry.Plugin {
	return &linuxUtil{
		cfg: cfg,
		l:   log.Logger().Named(name),
	}
}

func (lu *linuxUtil) Name() string {
	return name
}

func (lu *linuxUtil) Generate(context.Context) error {
	return nil
}

func (lu *linuxUtil) Compile(context.Context) error {
	return nil
}


Review comment (performance):
Don't use global variable, inject the cache to the functions. Something like
```
unsupportedInterfacesCache, err = lru.New[string, struct{}](int(defaultLimit))
...
ethReader := NewEthtoolReader(ethtoolOpts, ethHandle, unsupportedInterfacesCache)
...
```

Decide on the cache name if it contains something other than unsupported interfaces.

Code after:
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

// Package linuxutil contains the Retina linuxutil plugin. It gathers TCP/UDP statistics and network interface statistics from the netstats and ethtool node utilities (respectively).
package linuxutil

import (
	"context"
	"fmt"
	"sync"
	"time"

	hubblev1 "github.com/cilium/cilium/pkg/hubble/api/v1"
	lru "github.com/hashicorp/golang-lru/v2"
	kcfg "github.com/microsoft/retina/pkg/config"
	"github.com/microsoft/retina/pkg/log"
	"github.com/microsoft/retina/pkg/plugin/registry"
	"github.com/pkg/errors"
	"github.com/safchain/ethtool"
	"go.uber.org/zap"
)

func init() {
	registry.Add(name, New)
}

// New creates a linuxutil plugin.
func New(cfg *kcfg.Config) registry.Plugin {
	return &linuxUtil{
		cfg: cfg,
		l:   log.Logger().Named(name),
	}
}

func (lu *linuxUtil) Name() string {
	return name
}

func (lu *linuxUtil) Generate(context.Context) error {
	return nil
}

func (lu *linuxUtil) Compile(context.Context) error {
	return nil
}

func (lu *linuxUtil) Init() error {
	lu.l.Info("Initializing linuxutil plugin...")
	return nil
}
Repository: microsoft/retina
File: pkg/plugin/linuxutil/linuxutil_linux.go (Go)

Code before:
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

// Package linuxutil contains the Retina linuxutil plugin. It gathers TCP/UDP statistics and network interface statistics from the netstats and ethtool node utilities (respectively).
package linuxutil

import (
	"context"
	"fmt"
	"sync"
	"time"

	hubblev1 "github.com/cilium/cilium/pkg/hubble/api/v1"
	lru "github.com/hashicorp/golang-lru/v2"
	kcfg "github.com/microsoft/retina/pkg/config"
	"github.com/microsoft/retina/pkg/log"
	"github.com/microsoft/retina/pkg/plugin/registry"
	"github.com/pkg/errors"
	"github.com/safchain/ethtool"
	"go.uber.org/zap"
)

const defaultLimit = 2000

var globalLruCache *lru.Cache[string, struct{}]

func init() {
	registry.Add(name, New)
}

// New creates a linuxutil plugin.
func New(cfg *kcfg.Config) registry.Plugin {
	return &linuxUtil{
		cfg: cfg,
		l:   log.Logger().Named(name),
	}
}

func (lu *linuxUtil) Name() string {
	return name
}

func (lu *linuxUtil) Generate(context.Context) error {
	return nil
}

func (lu *linuxUtil) Compile(context.Context) error {
	return nil

Review comment (suggestion):
You can relocate this to `types_linux.go` if you want.

Code after:
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

// Package linuxutil contains the Retina linuxutil plugin. It gathers TCP/UDP statistics and network interface statistics from the netstats and ethtool node utilities (respectively).
package linuxutil

import (
	"context"
	"fmt"
	"sync"
	"time"

	hubblev1 "github.com/cilium/cilium/pkg/hubble/api/v1"
	lru "github.com/hashicorp/golang-lru/v2"
	kcfg "github.com/microsoft/retina/pkg/config"
	"github.com/microsoft/retina/pkg/log"
	"github.com/microsoft/retina/pkg/plugin/registry"
	"github.com/pkg/errors"
	"github.com/safchain/ethtool"
	"go.uber.org/zap"
)

func init() {
	registry.Add(name, New)
}

// New creates a linuxutil plugin.
func New(cfg *kcfg.Config) registry.Plugin {
	return &linuxUtil{
		cfg: cfg,
		l:   log.Logger().Named(name),
	}
}

func (lu *linuxUtil) Name() string {
	return name
}

func (lu *linuxUtil) Generate(context.Context) error {
	return nil
}

func (lu *linuxUtil) Compile(context.Context) error {
	return nil
}

func (lu *linuxUtil) Init() error {
	lu.l.Info("Initializing linuxutil plugin...")