diff --git a/actions/interface.go b/actions/interface.go index ba92f820..9f6cb8c6 100644 --- a/actions/interface.go +++ b/actions/interface.go @@ -4,6 +4,7 @@ import ( "context" "github.com/bmc-toolbox/common" + "github.com/go-logr/logr" "github.com/metal-toolbox/ironlib/model" "github.com/metal-toolbox/ironlib/utils" ) @@ -202,5 +203,5 @@ type VirtualDiskManager interface { // DiskWiper defines an interface to override disk data type DiskWiper interface { - WipeDisk(ctx context.Context, logicalName string) error + WipeDisk(ctx context.Context, log logr.Logger, logicalName string) error } diff --git a/actions/inventory.go b/actions/inventory.go index 76ab4a86..2801e41f 100644 --- a/actions/inventory.go +++ b/actions/inventory.go @@ -8,12 +8,12 @@ import ( "strings" "github.com/bmc-toolbox/common" + "github.com/go-logr/logr" "github.com/metal-toolbox/ironlib/firmware" "github.com/metal-toolbox/ironlib/model" "github.com/metal-toolbox/ironlib/utils" "github.com/pkg/errors" "github.com/r3labs/diff/v2" - "github.com/sirupsen/logrus" "golang.org/x/exp/slices" ) @@ -28,7 +28,7 @@ type InventoryCollectorAction struct { collectors Collectors // something to track our execution - log *logrus.Logger + log logr.Logger // device is the model in which the collected inventory is recorded. device *common.Device @@ -130,9 +130,10 @@ func WithDisabledCollectorUtilities(utilityNames []model.CollectorUtility) Optio } // NewActionrunner returns an Actions runner that is capable of collecting inventory. -func NewInventoryCollectorAction(ll *logrus.Logger, options ...Option) *InventoryCollectorAction { +func NewInventoryCollectorAction(log logr.Logger, options ...Option) *InventoryCollectorAction { a := &InventoryCollectorAction{ - log: ll, + log: log, + trace: log.GetV() >= 2, } // set options to override @@ -203,73 +204,73 @@ func (a *InventoryCollectorAction) Collect(ctx context.Context, device *common.D // one drive/nic/storagecontroller/psu component returns an error. // Collect initial device inventory - a.log.Debug("collect initial inventory") + a.log.V(1).Info("collect initial inventory") err := a.collectors.InventoryCollector.Collect(ctx, a.device) - a.log.WithError(err).Debug("collect initial done") + a.log.V(1).Error(err, "collect initial done") if err != nil && a.failOnError { return errors.Wrap(err, "error retrieving device inventory") } // Collect drive smart data - a.log.Debug("collect drives") + a.log.V(1).Info("collect drives") err = a.CollectDrives(ctx) - a.log.WithError(err).Debug("collect drives done") + a.log.V(1).Error(err, "collect drives done") if err != nil && a.failOnError { return errors.Wrap(err, "error retrieving drive inventory") } // Collect NIC info - a.log.Debug("collect nics") + a.log.V(1).Info("collect nics") err = a.CollectNICs(ctx) - a.log.WithError(err).Debug("collect nics done") + a.log.V(1).Error(err, "collect nics done") if err != nil && a.failOnError { return errors.Wrap(err, "error retrieving NIC inventory") } // Collect BIOS info - a.log.Debug("collect bios") + a.log.V(1).Info("collect bios") err = a.CollectBIOS(ctx) - a.log.WithError(err).Debug("collect bios done") + a.log.V(1).Error(err, "collect bios done") if err != nil && a.failOnError { return errors.Wrap(err, "error retrieving BIOS inventory") } // Collect CPLD info - a.log.Debug("collect cpld") + a.log.V(1).Info("collect cpld") err = a.CollectCPLDs(ctx) - a.log.WithError(err).Debug("collect cpld done") + a.log.V(1).Error(err, "collect cpld done") if err != nil && a.failOnError { return errors.Wrap(err, "error retrieving CPLD inventory") } // Collect BMC info - a.log.Debug("collect bmc") + a.log.V(1).Info("collect bmc") err = a.CollectBMC(ctx) - a.log.WithError(err).Debug("collect bmc done") + a.log.V(1).Error(err, "collect bmc done") if err != nil && a.failOnError { return errors.Wrap(err, "error retrieving BMC inventory") } // Collect TPM info - a.log.Debug("collect tpm") + a.log.V(1).Info("collect tpm") err = a.CollectTPMs(ctx) - a.log.WithError(err).Debug("collect tpm done") + a.log.V(1).Error(err, "collect tpm done") if err != nil && a.failOnError { return errors.Wrap(err, "error retrieving TPM inventory") } // Collect Firmware checksums - a.log.Debug("collect firmware checksum") + a.log.V(1).Info("collect firmware checksum") err = a.CollectFirmwareChecksums(ctx) - a.log.WithError(err).Debug("collect firmware checksum done") + a.log.V(1).Error(err, "collect firmware checksum done") if err != nil && a.failOnError { return errors.Wrap(err, "error retrieving Firmware checksums") } // Collect UEFI variables - a.log.Debug("collect uefi variables") + a.log.V(1).Info("collect uefi variables") err = a.CollectUEFIVariables(ctx) - a.log.WithError(err).Debug("collect uefi variables done") + a.log.V(1).Error(err, "collect uefi variables done") if err != nil && a.failOnError { return errors.Wrap(err, "error retrieving UEFI variables") } @@ -284,9 +285,9 @@ func (a *InventoryCollectorAction) Collect(ctx context.Context, device *common.D } // Collect StorageController info - a.log.Debug("collect storage controller") + a.log.V(1).Info("collect storage controller") err = a.CollectStorageControllers(ctx) - a.log.WithError(err).Debug("collect storage controller done") + a.log.V(1).Error(err, "collect storage controller done") if err != nil && a.failOnError { return errors.Wrap(err, "error retrieving StorageController inventory") } @@ -300,9 +301,9 @@ func (a *InventoryCollectorAction) Collect(ctx context.Context, device *common.D } if len(a.collectors.DriveCollectors) > 0 { - a.log.Debug("dynamic collect drive") + a.log.V(1).Info("dynamic collect drive") err = a.CollectDrives(ctx) - a.log.WithError(err).Debug("dynamic collect drive done") + a.log.V(1).Error(err, "dynamic collect drive done") if err != nil && a.failOnError { return errors.Wrap(err, "error retrieving drive inventory") @@ -311,12 +312,12 @@ func (a *InventoryCollectorAction) Collect(ctx context.Context, device *common.D } // CollectDriveCapabilities is to be invoked after Drives() - a.log.Debug("collect drive capabilities") + a.log.V(1).Info("collect drive capabilities") err = a.CollectDriveCapabilities(ctx) if err != nil && a.failOnError { return errors.Wrap(err, "error retrieving DriveCapabilities") } - a.log.WithError(err).Debug("collect drive capabilities done") + a.log.V(1).Error(err, "collect drive capabilities done") a.setDefaultAttributes() @@ -731,13 +732,13 @@ func (a *InventoryCollectorAction) CollectFirmwareChecksums(ctx context.Context) sumStr, err := a.collectors.FirmwareChecksumCollector.BIOSLogoChecksum(ctx) if err != nil { - a.log.WithError(err).Warn("error collecting BIOS Logo checksum") + a.log.V(3).Error(err, "error collecting BIOS Logo checksum") return err } if a.device.BIOS == nil { // XXX: how did we get here? - a.log.Error("nil device bios data") + a.log.Error(errors.New("nil device bios data"), "expected bios data") return nil } diff --git a/actions/inventory_test.go b/actions/inventory_test.go index fa6d1738..85db60dd 100644 --- a/actions/inventory_test.go +++ b/actions/inventory_test.go @@ -7,11 +7,11 @@ import ( "testing" "github.com/bmc-toolbox/common" + "github.com/go-logr/logr/testr" dellFixtures "github.com/metal-toolbox/ironlib/fixtures/dell" smcFixtures "github.com/metal-toolbox/ironlib/fixtures/supermicro" "github.com/metal-toolbox/ironlib/model" "github.com/metal-toolbox/ironlib/utils" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" ) @@ -47,7 +47,7 @@ func Test_Inventory_dell(t *testing.T) { WithDisabledCollectorUtilities([]model.CollectorUtility{"dmidecode"}), } - collector := NewInventoryCollectorAction(logrus.New(), options...) + collector := NewInventoryCollectorAction(testr.New(t), options...) if err := collector.Collect(context.TODO(), &device); err != nil { t.Error(err) } @@ -124,7 +124,7 @@ func Test_Inventory_smc(t *testing.T) { StorageControllerCollectors: []StorageControllerCollector{storecli}, } - collector := NewInventoryCollectorAction(logrus.New(), WithCollectors(collectors), WithTraceLevel()) + collector := NewInventoryCollectorAction(testr.New(t), WithCollectors(collectors), WithTraceLevel()) if err := collector.Collect(context.TODO(), &device); err != nil { t.Error(err) } @@ -187,7 +187,7 @@ func TestNewInventoryCollectorAction(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := NewInventoryCollectorAction(logrus.New(), tt.options...) + got := NewInventoryCollectorAction(testr.New(t), tt.options...) switch tt.name { case "trace-enabled": diff --git a/actions/storage_controller.go b/actions/storage_controller.go index cecf9f21..eb212f81 100644 --- a/actions/storage_controller.go +++ b/actions/storage_controller.go @@ -3,24 +3,27 @@ package actions import ( "context" "fmt" - "log" "strings" "github.com/bmc-toolbox/common" + "github.com/go-logr/logr" "github.com/metal-toolbox/ironlib/model" "github.com/metal-toolbox/ironlib/utils" "github.com/pkg/errors" - "github.com/sirupsen/logrus" ) var ErrVirtualDiskManagerUtilNotIdentified = errors.New("virtual disk management utility not identifed") type StorageControllerAction struct { - Logger *logrus.Logger + Logger logr.Logger + trace bool } -func NewStorageControllerAction(logger *logrus.Logger) *StorageControllerAction { - return &StorageControllerAction{logger} +func NewStorageControllerAction(logger logr.Logger) *StorageControllerAction { + return &StorageControllerAction{ + Logger: logger, + trace: logger.GetV() >= 2, + } } func (s *StorageControllerAction) CreateVirtualDisk(ctx context.Context, hba *common.StorageController, options *model.CreateVirtualDiskOptions) error { @@ -67,14 +70,8 @@ func (s *StorageControllerAction) ListVirtualDisks(ctx context.Context, hba *com // GetControllerUtility returns the utility command for the given vendor func (s *StorageControllerAction) GetControllerUtility(vendorName, modelName string) (VirtualDiskManager, error) { - var trace bool - - if s.Logger.GetLevel().String() == "trace" { - trace = true - } - if strings.EqualFold(vendorName, common.VendorMarvell) { - return utils.NewMvcliCmd(trace), nil + return utils.NewMvcliCmd(s.trace), nil } return nil, errors.Wrap(ErrVirtualDiskManagerUtilNotIdentified, "vendor: "+vendorName+" model: "+modelName) @@ -82,43 +79,28 @@ func (s *StorageControllerAction) GetControllerUtility(vendorName, modelName str // GetWipeUtility returns the wipe utility based on the disk wipping features func (s *StorageControllerAction) GetWipeUtility(logicalName string) (DiskWiper, error) { - var trace bool - - if s.Logger.GetLevel().String() == "trace" { - trace = true - } - // TODO: use disk wipping features to return the best wipe utility, currently only one available - if trace { - log.Printf("%s | Detecting wipe utility", logicalName) - } - - return utils.NewFillZeroCmd(trace), nil + s.Logger.V(6).Info("Detecting wipe utility", "device", logicalName) + return utils.NewFillZeroCmd(s.trace), nil } -func (s *StorageControllerAction) WipeDisk(ctx context.Context, logicalName string) error { +func (s *StorageControllerAction) WipeDisk(ctx context.Context, log logr.Logger, logicalName string) error { util, err := s.GetWipeUtility(logicalName) if err != nil { return err } + // Watermark disk // Before wiping the disk, we apply watermarks to later verify successful deletion - log.Printf("%s | Initiating watermarking process", logicalName) check, err := utils.ApplyWatermarks(logicalName) if err != nil { return err } + // Wipe the disk - err = util.WipeDisk(ctx, logicalName) + err = util.WipeDisk(ctx, log, logicalName) if err != nil { return err } - // Check if the watermark has been removed after wiping - log.Printf("%s | Checking if the watermark has been removed", logicalName) - err = check() - if err != nil { - return err - } - // Watermarks have been successfully removed, indicating successful deletion - log.Printf("%s | Watermarks has been removed", logicalName) - return nil + + return check() } diff --git a/device.go b/device.go index 160f5b4a..0ede9f6a 100644 --- a/device.go +++ b/device.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/bmc-toolbox/common" + "github.com/go-logr/logr" "github.com/metal-toolbox/ironlib/actions" "github.com/metal-toolbox/ironlib/errs" "github.com/metal-toolbox/ironlib/providers/asrockrack" @@ -12,12 +13,11 @@ import ( "github.com/metal-toolbox/ironlib/providers/supermicro" "github.com/metal-toolbox/ironlib/utils" "github.com/pkg/errors" - "github.com/sirupsen/logrus" ) // New returns a device Manager interface based on the hardware deviceVendor, model attributes // by default returns a Generic device instance that only returns the device inventory -func New(logger *logrus.Logger) (m actions.DeviceManager, err error) { +func New(logger logr.Logger) (m actions.DeviceManager, err error) { dmidecode, err := utils.NewDmidecode() if err != nil { return nil, errors.Wrap(errs.ErrDmiDecodeRun, err.Error()) @@ -94,18 +94,3 @@ func CheckDependencies() { fmt.Printf("util: %s, path: %s %s[ok]%s\n", name, uPath, green, reset) } } - -// Logformat adds default fields to each log entry. -type LogFormat struct { - Fields logrus.Fields - Formatter logrus.Formatter -} - -// Format satisfies the logrus.Formatter interface. -func (f *LogFormat) Format(e *logrus.Entry) ([]byte, error) { - for k, v := range f.Fields { - e.Data[k] = v - } - - return f.Formatter.Format(e) -} diff --git a/examples/biosconfig/biosconfig.go b/examples/biosconfig/biosconfig.go index 07cef091..e29ec0f8 100644 --- a/examples/biosconfig/biosconfig.go +++ b/examples/biosconfig/biosconfig.go @@ -4,7 +4,9 @@ import ( "context" "encoding/json" "fmt" + "os" + "github.com/bombsimon/logrusr/v4" "github.com/metal-toolbox/ironlib" "github.com/sirupsen/logrus" ) @@ -13,20 +15,27 @@ import ( // a sample output can be seen in the biosconfig.json file func main() { - logger := logrus.New() + l := logrus.New() + l.Formatter = &logrus.JSONFormatter{} + l.Level = logrus.TraceLevel + logger := logrusr.New(l) + device, err := ironlib.New(logger) if err != nil { - logger.Fatal(err) + logger.Error(err, "creating ironlib manager") + os.Exit(1) } features, err := device.GetBIOSConfiguration(context.TODO()) if err != nil { - logger.Fatal(err) + logger.Error(err, "getting bios config") + os.Exit(1) } j, err := json.MarshalIndent(features, " ", " ") if err != nil { - logger.Fatal(err) + logger.Error(err, "formatting json") + os.Exit(1) } fmt.Println(string(j)) diff --git a/examples/diskwipe/main.go b/examples/diskwipe/main.go index 43124f05..0c191c64 100644 --- a/examples/diskwipe/main.go +++ b/examples/diskwipe/main.go @@ -2,8 +2,10 @@ package main import ( "context" + "os" "time" + "github.com/bombsimon/logrusr/v4" "github.com/metal-toolbox/ironlib/actions" "github.com/sirupsen/logrus" ) @@ -11,15 +13,19 @@ import ( // This example invokes ironlib and wipes the disk /dev/sdZZZ with a timeout of 1 day func main() { - logger := logrus.New() - logger.Formatter = new(logrus.JSONFormatter) - logger.SetLevel(logrus.TraceLevel) + l := logrus.New() + l.Formatter = &logrus.JSONFormatter{} + l.Level = logrus.TraceLevel + logger := logrusr.New(l) + sca := actions.NewStorageControllerAction(logger) ctx, cancel := context.WithTimeout(context.Background(), 86400*time.Second) defer cancel() - err := sca.WipeDisk(ctx, "/dev/sdZZZ") + + err := sca.WipeDisk(ctx, logger, "/dev/sdZZZ") if err != nil { - logger.Fatal(err) + logger.Error(err, "wiping disk") + os.Exit(0) } - logger.Println("Wiped successfully!") + logger.Info("Wiped successfully!") } diff --git a/examples/firmware-install/firmware-install.go b/examples/firmware-install/firmware-install.go index ce2e566e..ed14df58 100644 --- a/examples/firmware-install/firmware-install.go +++ b/examples/firmware-install/firmware-install.go @@ -3,8 +3,10 @@ package main import ( "context" "fmt" + "os" "github.com/bmc-toolbox/common" + "github.com/bombsimon/logrusr/v4" "github.com/metal-toolbox/ironlib" "github.com/metal-toolbox/ironlib/model" "github.com/sirupsen/logrus" @@ -13,11 +15,15 @@ import ( // This example invokes ironlib to install the supermicro BMC firmware func main() { - logger := logrus.New() + l := logrus.New() + l.Formatter = &logrus.JSONFormatter{} + l.Level = logrus.TraceLevel + logger := logrusr.New(l) device, err := ironlib.New(logger) if err != nil { - logger.Fatal(err) + logger.Error(err, "creating ironlib manager") + os.Exit(1) } options := &model.UpdateOptions{ @@ -29,13 +35,15 @@ func main() { hardware, err := device.GetInventory(context.TODO()) if err != nil { - logger.Fatal(err) + logger.Error(err, "getting inventory") + os.Exit(1) } fmt.Println(hardware.BMC.Firmware.Installed) err = device.InstallUpdates(context.TODO(), options) if err != nil { - logger.Fatal(err) + logger.Error(err, "insatlling updates") + os.Exit(1) } } diff --git a/examples/inventory/inventory.go b/examples/inventory/inventory.go index 9630b48b..d9cda9ba 100644 --- a/examples/inventory/inventory.go +++ b/examples/inventory/inventory.go @@ -4,7 +4,9 @@ import ( "context" "encoding/json" "fmt" + "os" + "github.com/bombsimon/logrusr/v4" "github.com/metal-toolbox/ironlib" "github.com/sirupsen/logrus" ) @@ -13,22 +15,27 @@ import ( // a sample output can be seen in the inventory.json file func main() { - logger := logrus.New() - logger.Formatter = new(logrus.JSONFormatter) - logger.SetLevel(logrus.TraceLevel) + l := logrus.New() + l.Formatter = &logrus.JSONFormatter{} + l.Level = logrus.TraceLevel + logger := logrusr.New(l) + device, err := ironlib.New(logger) if err != nil { - logger.Fatal(err) + logger.Error(err, "creating ironlib manager") + os.Exit(1) } inv, err := device.GetInventory(context.TODO()) if err != nil { - logger.Fatal(err) + logger.Error(err, "getting inventory") + os.Exit(1) } j, err := json.MarshalIndent(inv, " ", " ") if err != nil { - logger.Fatal(err) + logger.Error(err, "formatting json") + os.Exit(1) } fmt.Println(string(j)) diff --git a/go.mod b/go.mod index 2ac21609..f9e2d5d1 100644 --- a/go.mod +++ b/go.mod @@ -5,16 +5,16 @@ go 1.22 require ( github.com/beevik/etree v1.1.0 github.com/bmc-toolbox/common v0.0.0-20230220061748-93ff001f4a1d + github.com/bombsimon/logrusr/v4 v4.1.0 github.com/dselans/dmidecode v0.0.0-20180814053009-65c3f9d81910 + github.com/go-logr/logr v1.4.1 github.com/pkg/errors v0.9.1 github.com/r3labs/diff/v2 v2.15.1 - github.com/r3labs/diff/v3 v3.0.1 github.com/sirupsen/logrus v1.9.0 github.com/stretchr/testify v1.8.2 github.com/tidwall/gjson v1.14.4 golang.org/x/exp v0.0.0-20230321023759-10a507213a29 golang.org/x/net v0.9.0 - gotest.tools v2.2.0+incompatible ) require ( diff --git a/go.sum b/go.sum index 574d8c36..64664f89 100644 --- a/go.sum +++ b/go.sum @@ -2,12 +2,16 @@ github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/bmc-toolbox/common v0.0.0-20230220061748-93ff001f4a1d h1:cQ30Wa8mhLzK1TSOG+g3FlneIsXtFgun61mmPwVPmD0= github.com/bmc-toolbox/common v0.0.0-20230220061748-93ff001f4a1d/go.mod h1:SY//n1PJjZfbFbmAsB6GvEKbc7UXz3d30s3kWxfJQ/c= +github.com/bombsimon/logrusr/v4 v4.1.0 h1:uZNPbwusB0eUXlO8hIUwStE6Lr5bLN6IgYgG+75kuh4= +github.com/bombsimon/logrusr/v4 v4.1.0/go.mod h1:pjfHC5e59CvjTBIU3V3sGhFWFAnsnhOR03TRc6im0l8= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dselans/dmidecode v0.0.0-20180814053009-65c3f9d81910 h1:w9T/rS5VP0SPXqYr7BpUeqf6ukp/GEWm6nXhziWzBY4= github.com/dselans/dmidecode v0.0.0-20180814053009-65c3f9d81910/go.mod h1:yGxJ4za56u74+F00gmg9RJoyXLzvrOrIat4b/Dgw9Lo= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= @@ -29,7 +33,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/r3labs/diff/v2 v2.15.1 h1:EOrVqPUzi+njlumoqJwiS/TgGgmZo83619FNDB9xQUg= github.com/r3labs/diff/v2 v2.15.1/go.mod h1:I8noH9Fc2fjSaMxqF3G2lhDdC0b+JXCfyx85tWFM9kc= -github.com/r3labs/diff/v3 v3.0.1/go.mod h1:f1S9bourRbiM66NskseyUdo0fTmEE0qKrikYJX63dgo= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= @@ -38,7 +41,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -53,8 +55,6 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= @@ -85,5 +85,3 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= diff --git a/providers/asrockrack/asrockrack.go b/providers/asrockrack/asrockrack.go index 35761106..51b7d1db 100644 --- a/providers/asrockrack/asrockrack.go +++ b/providers/asrockrack/asrockrack.go @@ -4,29 +4,21 @@ import ( "context" "github.com/bmc-toolbox/common" + "github.com/go-logr/logr" "github.com/metal-toolbox/ironlib/actions" "github.com/metal-toolbox/ironlib/model" "github.com/metal-toolbox/ironlib/utils" - "github.com/sirupsen/logrus" ) // A asrockrack device has methods to collect hardware inventory, regardless of the vendor type asrockrack struct { trace bool hw *model.Hardware - logger *logrus.Logger + logger logr.Logger } // New returns a ASRockRack device manager -func New(dmidecode *utils.Dmidecode, l *logrus.Logger) (actions.DeviceManager, error) { - var trace bool - - if l.Level == logrus.TraceLevel { - trace = true - } - - var err error - +func New(dmidecode *utils.Dmidecode, l logr.Logger) (actions.DeviceManager, error) { // set device device := common.NewDevice() @@ -43,7 +35,6 @@ func New(dmidecode *utils.Dmidecode, l *logrus.Logger) (actions.DeviceManager, e dm := &asrockrack{ hw: model.NewHardware(&device), logger: l, - trace: trace, } return dm, nil diff --git a/providers/dell/dell.go b/providers/dell/dell.go index 2ab62888..b8c1985d 100644 --- a/providers/dell/dell.go +++ b/providers/dell/dell.go @@ -5,12 +5,12 @@ import ( "os" "github.com/bmc-toolbox/common" + "github.com/go-logr/logr" "github.com/metal-toolbox/ironlib/actions" "github.com/metal-toolbox/ironlib/errs" "github.com/metal-toolbox/ironlib/model" "github.com/metal-toolbox/ironlib/utils" "github.com/pkg/errors" - "github.com/sirupsen/logrus" ) // The dell device provider struct @@ -19,7 +19,10 @@ type dell struct { hw *model.Hardware dnf *utils.Dnf dsu *utils.Dsu - logger *logrus.Logger + logger logr.Logger + trace bool + updateBaseURL string + // The DSU package version // for example 1.9.1.0-21.03.00 from https://linux.dell.com/repo/hardware/DSU_21.05.01/os_independent/x86_64/dell-system-update-1.9.1.0-21.03.00.x86_64.rpm dsuPackageVersion string @@ -27,18 +30,10 @@ type dell struct { // The DSU release version // for example: 21.05.01, from https://linux.dell.com/repo/hardware/DSU_21.05.01 dsuReleaseVersion string - - updateBaseURL string } // New returns a new Dell device manager -func New(dmidecode *utils.Dmidecode, l *logrus.Logger) (actions.DeviceManager, error) { - var trace bool - - if l.GetLevel().String() == "trace" { - trace = true - } - +func New(dmidecode *utils.Dmidecode, l logr.Logger) (actions.DeviceManager, error) { deviceVendor, err := dmidecode.Manufacturer() if err != nil { return nil, errors.Wrap(errs.NewDmidecodeValueError("manufacturer", "", 0), err.Error()) @@ -78,6 +73,7 @@ func New(dmidecode *utils.Dmidecode, l *logrus.Logger) (actions.DeviceManager, e updateBaseURL := os.Getenv(model.EnvUpdateBaseURL) // set device manager + trace := l.GetV() >= 2 dm := &dell{ hw: model.NewHardware(&device), dnf: utils.NewDnf(trace), @@ -86,6 +82,7 @@ func New(dmidecode *utils.Dmidecode, l *logrus.Logger) (actions.DeviceManager, e dsuPackageVersion: dsuPackageVersion, updateBaseURL: updateBaseURL, logger: l, + trace: trace, } return dm, nil @@ -157,7 +154,7 @@ func (d *dell) ListAvailableUpdates(ctx context.Context, options *model.UpdateOp return nil, nil } - d.logger.WithField("count", count).Info("component updates identified..") + d.logger.WithValues("count", count).Info("component updates identified..") d.hw.OemComponents.Dell = append(d.hw.OemComponents.Dell, oemUpdates...) @@ -190,10 +187,10 @@ func (d *dell) installAvailableUpdates(ctx context.Context, downloadOnly bool) e if err != nil { switch exitCode { case utils.DSUExitCodeNoUpdatesAvailable: - d.logger.Debug("update(s) not applicable for this device") + d.logger.V(1).Info("update(s) not applicable for this device") return errs.ErrNoUpdatesApplicable case utils.DSUExitCodeRebootRequired: - d.logger.Debug("update(s) applied, device requires a reboot") + d.logger.V(1).Info("update(s) applied, device requires a reboot") d.hw.PendingReboot = true default: return err @@ -219,12 +216,10 @@ func (d *dell) setUpdateOptions(options *model.UpdateOptions) { d.updateBaseURL = options.BaseURL } - d.logger.WithFields( - logrus.Fields{ - "dsu version": d.dsuPackageVersion, - "dsu repo": d.dsuReleaseVersion, - "base url": d.updateBaseURL, - }, + d.logger.WithValues( + "dsu version", d.dsuPackageVersion, + "dsu repo", d.dsuReleaseVersion, + "base url", d.updateBaseURL, ).Info("update parameters") } diff --git a/providers/dell/dell_test.go b/providers/dell/dell_test.go index 2974a989..a94de045 100644 --- a/providers/dell/dell_test.go +++ b/providers/dell/dell_test.go @@ -7,17 +7,17 @@ import ( "testing" "github.com/bmc-toolbox/common" + "github.com/go-logr/logr/testr" "github.com/metal-toolbox/ironlib/actions" dellFixtures "github.com/metal-toolbox/ironlib/fixtures/dell" "github.com/metal-toolbox/ironlib/model" "github.com/metal-toolbox/ironlib/utils" - "github.com/sirupsen/logrus" - "gotest.tools/assert" + "github.com/stretchr/testify/assert" ) var r6515fixtures = "../../fixtures/dell/r6515" -func newFakeDellDevice() *dell { +func newFakeDellDevice(t *testing.T) *dell { device := common.NewDevice() device.Oem = true @@ -31,7 +31,7 @@ func newFakeDellDevice() *dell { return &dell{ hw: hardware, dnf: utils.NewFakeDnf(), - logger: logrus.New(), + logger: testr.New(t), } } @@ -42,7 +42,7 @@ func TestGetInventory(t *testing.T) { expected.Oem = true expectedOemComponents := dellFixtures.R6515_oem_components - dell := newFakeDellDevice() + dell := newFakeDellDevice(t) // dsu b, err := os.ReadFile(r6515fixtures + "/dsu_inventory") @@ -92,13 +92,13 @@ func TestGetInventory(t *testing.T) { t.Error(err) } - assert.DeepEqual(t, dellFixtures.R6515_inventory_lshw_smartctl, device) - assert.DeepEqual(t, expectedOemComponents, dell.hw.OemComponents) + assert.Equal(t, dellFixtures.R6515_inventory_lshw_smartctl, device) + assert.Equal(t, expectedOemComponents, dell.hw.OemComponents) } // Get inventory, not listing updates available func TestListUpdates(t *testing.T) { - dell := newFakeDellDevice() + dell := newFakeDellDevice(t) // dsu b, err := os.ReadFile(r6515fixtures + "/dsu_preview") @@ -121,5 +121,5 @@ func TestListUpdates(t *testing.T) { t.Error(err) } - assert.DeepEqual(t, dellFixtures.R6515_updatePreview, device) + assert.Equal(t, dellFixtures.R6515_updatePreview, device) } diff --git a/providers/dell/helpers.go b/providers/dell/helpers.go index 249597e2..fc48ea6b 100644 --- a/providers/dell/helpers.go +++ b/providers/dell/helpers.go @@ -8,7 +8,6 @@ import ( "github.com/metal-toolbox/ironlib/model" "github.com/metal-toolbox/ironlib/utils" "github.com/pkg/errors" - "github.com/sirupsen/logrus" ) const ( @@ -74,22 +73,19 @@ func (d *dell) installUpdate(ctx context.Context, updateFile string, downgrade b e := utils.NewExecutor(updateFile) e.SetArgs(args) - if d.logger.Level == logrus.TraceLevel { + if d.trace { e.SetVerbose() } - d.logger.WithFields( - logrus.Fields{"file": updateFile}, - ).Info("Installing dell Update Bin file") + logger := d.logger.WithValues("file", updateFile) + logger.Info("Installing dell Update Bin file") result, err := e.ExecWithContext(ctx) if err != nil { return result.ExitCode, err } - d.logger.WithFields( - logrus.Fields{"file": updateFile}, - ).Info("Installed") + logger.Info("Installed") d.hw.PendingReboot = true @@ -224,17 +220,17 @@ func (d *dell) checkExitCode(exitCode int) error { case utils.DSUExitCodeUpdatesApplied: d.hw.UpdatesInstalled = true d.hw.PendingReboot = true - d.logger.Trace("update applied successfully") + d.logger.V(2).Info("update applied successfully") return nil case utils.DSUExitCodeRebootRequired, BinUpdateExitCodeRebootRequired: // updates applied, reboot required - d.logger.Trace("update applied, reboot required") + d.logger.V(2).Info("update applied, reboot required") d.hw.UpdatesInstalled = true d.hw.PendingReboot = true return nil case utils.DSUExitCodeNoUpdatesAvailable: // no applicable updates - d.logger.Trace("no pending/applicable update(s) for device") + d.logger.V(2).Info("no pending/applicable update(s) for device") return nil default: diff --git a/providers/generic/generic.go b/providers/generic/generic.go index f9b73f87..b46f028a 100644 --- a/providers/generic/generic.go +++ b/providers/generic/generic.go @@ -4,29 +4,23 @@ import ( "context" "github.com/bmc-toolbox/common" + "github.com/go-logr/logr" "github.com/metal-toolbox/ironlib/actions" "github.com/metal-toolbox/ironlib/errs" "github.com/metal-toolbox/ironlib/model" "github.com/metal-toolbox/ironlib/utils" "github.com/pkg/errors" - "github.com/sirupsen/logrus" ) // A Generic device has methods to collect hardware inventory, regardless of the vendor type Generic struct { - trace bool hw *model.Hardware - logger *logrus.Logger + logger logr.Logger + trace bool } // New returns a generic device manager -func New(dmidecode *utils.Dmidecode, l *logrus.Logger) (actions.DeviceManager, error) { - var trace bool - - if l.GetLevel().String() == "trace" { - trace = true - } - +func New(dmidecode *utils.Dmidecode, l logr.Logger) (actions.DeviceManager, error) { deviceVendor, err := dmidecode.Manufacturer() if err != nil { return nil, errors.Wrap(errs.NewDmidecodeValueError("manufacturer", "", 0), err.Error()) @@ -52,7 +46,7 @@ func New(dmidecode *utils.Dmidecode, l *logrus.Logger) (actions.DeviceManager, e return &Generic{ hw: model.NewHardware(&device), logger: l, - trace: trace, + trace: l.GetV() >= 2, }, nil } diff --git a/providers/supermicro/bios.go b/providers/supermicro/bios.go index cd4b9dee..076d6649 100644 --- a/providers/supermicro/bios.go +++ b/providers/supermicro/bios.go @@ -4,7 +4,6 @@ import ( "context" "github.com/metal-toolbox/ironlib/utils" - "github.com/sirupsen/logrus" ) // SetBIOSConfiguration sets bios configuration settings @@ -14,12 +13,6 @@ func (s *supermicro) SetBIOSConfiguration(context.Context, map[string]string) er // GetBIOSConfiguration returns bios configuration settings func (s *supermicro) GetBIOSConfiguration(ctx context.Context) (map[string]string, error) { - var trace bool - if s.logger.Level >= logrus.TraceLevel { - trace = true - } - - sum := utils.NewSupermicroSUM(trace) - + sum := utils.NewSupermicroSUM(s.trace) return sum.GetBIOSConfiguration(ctx, "") } diff --git a/providers/supermicro/supermicro.go b/providers/supermicro/supermicro.go index dcbafe75..44bbec85 100644 --- a/providers/supermicro/supermicro.go +++ b/providers/supermicro/supermicro.go @@ -4,23 +4,23 @@ import ( "context" "github.com/bmc-toolbox/common" + "github.com/go-logr/logr" "github.com/metal-toolbox/ironlib/actions" "github.com/metal-toolbox/ironlib/errs" "github.com/metal-toolbox/ironlib/firmware" "github.com/metal-toolbox/ironlib/model" "github.com/metal-toolbox/ironlib/utils" "github.com/pkg/errors" - "github.com/sirupsen/logrus" ) type supermicro struct { trace bool hw *model.Hardware - logger *logrus.Logger + logger logr.Logger dmidecode *utils.Dmidecode } -func New(dmidecode *utils.Dmidecode, l *logrus.Logger) (actions.DeviceManager, error) { +func New(dmidecode *utils.Dmidecode, l logr.Logger) (actions.DeviceManager, error) { deviceVendor, err := dmidecode.Manufacturer() if err != nil { return nil, errors.Wrap(errs.NewDmidecodeValueError("manufacturer", "", 0), err.Error()) @@ -47,7 +47,7 @@ func New(dmidecode *utils.Dmidecode, l *logrus.Logger) (actions.DeviceManager, e hw: model.NewHardware(&device), logger: l, dmidecode: dmidecode, - trace: l.GetLevel().String() == "trace", + trace: l.GetV() >= 2, }, nil } @@ -72,31 +72,26 @@ func (s *supermicro) GetInventory(ctx context.Context, options ...actions.Option // Collect device inventory s.logger.Info("Collecting hardware inventory") - var trace bool - if s.logger.GetLevel().String() == "trace" { - trace = true - } - // define collectors for supermicro hardware collectors := &actions.Collectors{ - BMCCollector: utils.NewIpmicfgCmd(trace), - BIOSCollector: utils.NewIpmicfgCmd(trace), - CPLDCollector: utils.NewIpmicfgCmd(trace), + BMCCollector: utils.NewIpmicfgCmd(s.trace), + BIOSCollector: utils.NewIpmicfgCmd(s.trace), + CPLDCollector: utils.NewIpmicfgCmd(s.trace), DriveCollectors: []actions.DriveCollector{ - utils.NewSmartctlCmd(trace), - utils.NewLsblkCmd(trace), + utils.NewSmartctlCmd(s.trace), + utils.NewLsblkCmd(s.trace), }, DriveCapabilitiesCollectors: []actions.DriveCapabilityCollector{ - utils.NewHdparmCmd(trace), - utils.NewNvmeCmd(trace), + utils.NewHdparmCmd(s.trace), + utils.NewNvmeCmd(s.trace), }, StorageControllerCollectors: []actions.StorageControllerCollector{ - utils.NewStoreCLICmd(trace), + utils.NewStoreCLICmd(s.trace), }, - NICCollector: utils.NewMlxupCmd(trace), + NICCollector: utils.NewMlxupCmd(s.trace), FirmwareChecksumCollector: firmware.NewChecksumCollector( firmware.MakeOutputPath(), - firmware.TraceExecution(trace), + firmware.TraceExecution(s.trace), ), UEFIVarsCollector: &utils.UEFIVariableCollector{}, } diff --git a/utils/fill_zero.go b/utils/fill_zero.go index 37a74448..ffe7bb4d 100644 --- a/utils/fill_zero.go +++ b/utils/fill_zero.go @@ -2,10 +2,12 @@ package utils import ( "context" + "fmt" "io" - "log" "os" "time" + + "github.com/go-logr/logr" ) type FillZero struct { @@ -21,24 +23,29 @@ func NewFillZeroCmd(trace bool) *FillZero { return &z } -func (z *FillZero) WipeDisk(ctx context.Context, logicalName string) error { - log.Println("Starting zero-fill of", logicalName) +func (z *FillZero) WipeDisk(ctx context.Context, l logr.Logger, logicalName string) error { + log := l.WithValues("device", logicalName) + log.Info("starting zero-fill") + // Write open file, err := os.OpenFile(logicalName, os.O_WRONLY, 0) if err != nil { return err } defer file.Close() + // Get disk or partition size partitionSize, err := file.Seek(0, io.SeekEnd) if err != nil { return err } - log.Printf("%s | Size: %dB\n", logicalName, partitionSize) + + log.WithValues("size", fmt.Sprintf("%dB", partitionSize)).Info("disk info detected") _, err = file.Seek(0, io.SeekStart) if err != nil { return err } + var bytesSinceLastPrint int64 var totalBytesWritten int64 buffer := make([]byte, 4096) @@ -47,7 +54,7 @@ func (z *FillZero) WipeDisk(ctx context.Context, logicalName string) error { // Check if the context has been canceled select { case <-ctx.Done(): - log.Println("Context canceled. Stopping WipeDisk") + log.Info("stopping") return ctx.Err() default: l := min(int64(len(buffer)), bytesRemaining) @@ -55,12 +62,13 @@ func (z *FillZero) WipeDisk(ctx context.Context, logicalName string) error { if writeError != nil { return writeError } + totalBytesWritten += int64(bytesWritten) bytesSinceLastPrint += int64(bytesWritten) bytesRemaining -= int64(bytesWritten) // Print progress report every 10 seconds and when done if bytesRemaining == 0 || time.Since(start) >= 10*time.Second { - printProgress(totalBytesWritten, partitionSize, &start, &bytesSinceLastPrint, logicalName) + printProgress(log, totalBytesWritten, partitionSize, start, bytesSinceLastPrint) start = time.Now() bytesSinceLastPrint = 0 } @@ -73,15 +81,19 @@ func (z *FillZero) WipeDisk(ctx context.Context, logicalName string) error { return nil } -func printProgress(totalBytesWritten, partitionSize int64, start *time.Time, bytesSinceLastPrint *int64, path string) { +func printProgress(log logr.Logger, totalBytesWritten, partitionSize int64, start time.Time, bytesSinceLastPrint int64) { // Calculate progress and ETA progress := float64(totalBytesWritten) / float64(partitionSize) * 100 - elapsed := time.Since(*start).Seconds() - speed := float64(*bytesSinceLastPrint) / elapsed // Speed in bytes per second + elapsed := time.Since(start).Seconds() + speed := float64(bytesSinceLastPrint) / elapsed // Speed in bytes per second remainingSeconds := (float64(partitionSize) - float64(totalBytesWritten)) / speed // Remaining time in seconds remainingHours := float64(remainingSeconds / 3600) mbPerSecond := speed / (1024 * 1024) - log.Printf("%s | Progress: %.2f%% | Speed: %.2f MB/s | Estimated time left: %.2f hour(s)\n", path, progress, mbPerSecond, remainingHours) + log.WithValues( + "progress", fmt.Sprintf("%.2f%%", progress), + "speed", fmt.Sprintf("%.2f MB/s", mbPerSecond), + "remaining", fmt.Sprintf("%.2f hour(s)", remainingHours), + ).Info("") } // We are in go 1.19 min not available yet diff --git a/utils/fill_zero_test.go b/utils/fill_zero_test.go index 79ecf301..3f157629 100644 --- a/utils/fill_zero_test.go +++ b/utils/fill_zero_test.go @@ -5,6 +5,8 @@ import ( "os" "strconv" "testing" + + "github.com/go-logr/logr/testr" ) func Test_NewFillZeroCmd(t *testing.T) { @@ -24,25 +26,31 @@ func Test_WipeDisk(t *testing.T) { t.Fatal(err) } defer os.Remove(tmpfile.Name()) // clean up + // Write some content to the temporary file expectedSize := int64(4096) if _, err = tmpfile.Write(make([]byte, expectedSize)); err != nil { t.Fatal(err) } + // Simulate a context ctx := context.Background() + // Create a FillZero instance zw := &FillZero{} + // Test Fill function - err = zw.WipeDisk(ctx, tmpfile.Name()) + err = zw.WipeDisk(ctx, testr.New(t), tmpfile.Name()) if err != nil { t.Errorf("Fill returned an error: %v", err) } + // Check if the file size remains the same after overwrite fileInfo, err := os.Stat(tmpfile.Name()) if err != nil { t.Fatal(err) } + if size := fileInfo.Size(); size != expectedSize { t.Errorf("Expected file size to remain %d after overwrite, got %d", expectedSize, size) }