Skip to content

Commit

Permalink
Make Nvme a WipersGetter and pass to drive.New
Browse files Browse the repository at this point in the history
Now we have a way to get the wipe utitlies for an nvme drive easily.
  • Loading branch information
mmlb committed Jun 4, 2024
1 parent 07581f5 commit 205e1b1
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 26 deletions.
86 changes: 61 additions & 25 deletions utils/nvme.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"time"

"github.com/bmc-toolbox/common"
"github.com/metal-toolbox/ironlib/actions/wipe"
"github.com/metal-toolbox/ironlib/model"
"github.com/sirupsen/logrus"
)
Expand Down Expand Up @@ -118,7 +119,7 @@ func (n *Nvme) Drives(ctx context.Context) ([]*model.Drive, error) {
Capabilities: capabilitiesFound,
Metadata: metadata,
},
}, nil)
}, n)
}

return drives, nil
Expand Down Expand Up @@ -296,7 +297,15 @@ func (n *Nvme) WipeDisk(ctx context.Context, logger *logrus.Logger, device strin
return n.wipe(ctx, logger, device, caps)
}

func (n *Nvme) wipe(ctx context.Context, logger *logrus.Logger, device string, caps []*common.Capability) error {
// Wipers implements model.WipersGetter so *Nvme can be passed to model.NewDrive
// It returns functions that are able to wipe the drive according the capabilities reported by the drive.
// The functions are ordered by preference, in this case first function is the most secure and last is least.
// Sanitize is preferred over format, crytpographic erase modes over non-cryptographic erase.
func (n *Nvme) Wipers(d *model.Drive) []wipe.Wiper {
return n.getWipers(d.LogicalName, d.Capabilities)
}

func (n *Nvme) getWipers(device string, caps []*common.Capability) []wipe.Wiper {
var ber bool
var cer bool
var cese bool
Expand All @@ -311,41 +320,68 @@ func (n *Nvme) wipe(ctx context.Context, logger *logrus.Logger, device string, c
}
}

var utilities []wipe.Wiper

if cer {
l := logger.WithField("method", "sanitize").WithField("action", CryptoErase)
l.Info("trying wipe")
err := n.Sanitize(ctx, device, CryptoErase)
if err == nil {
return nil
}
l.WithError(err).Info("failed")
fn := wipe.WipeFunc(func(ctx context.Context, logger *logrus.Logger) error {
l := logger.WithField("method", "sanitize").WithField("action", CryptoErase)
l.Info("trying wipe")
err := n.Sanitize(ctx, device, CryptoErase)
if err == nil {
return nil
}
l.WithError(err).Info("failed")
return err
})
utilities = append(utilities, fn)
}
if ber {
l := logger.WithField("method", "sanitize").WithField("action", BlockErase)
l.Info("trying wipe")
err := n.Sanitize(ctx, device, BlockErase)
if err == nil {
return nil
}
l.WithError(err).Info("failed")
fn := wipe.WipeFunc(func(ctx context.Context, logger *logrus.Logger) error {
l := logger.WithField("method", "sanitize").WithField("action", BlockErase)
l.Info("trying wipe")
err := n.Sanitize(ctx, device, BlockErase)
if err == nil {
return nil
}
l.WithError(err).Info("failed")
return err
})
utilities = append(utilities, fn)
}
if cese {
l := logger.WithField("method", "format").WithField("setting", CryptographicErase)
fn := wipe.WipeFunc(func(ctx context.Context, logger *logrus.Logger) error {
l := logger.WithField("method", "format").WithField("setting", CryptographicErase)
l.Info("trying wipe")
err := n.Format(ctx, device, CryptographicErase)
if err == nil {
return nil
}
l.WithError(err).Info("failed")
return err
})
utilities = append(utilities, fn)
}

fn := wipe.WipeFunc(func(ctx context.Context, logger *logrus.Logger) error {
l := logger.WithField("method", "format").WithField("setting", UserDataErase)
l.Info("trying wipe")
err := n.Format(ctx, device, CryptographicErase)
err := n.Format(ctx, device, UserDataErase)
if err == nil {
return nil
}
l.WithError(err).Info("failed")
}
return err
})
utilities = append(utilities, fn)
return utilities
}

l := logger.WithField("method", "format").WithField("setting", UserDataErase)
l.Info("trying wipe")
err := n.Format(ctx, device, UserDataErase)
if err == nil {
return nil
func (n *Nvme) wipe(ctx context.Context, logger *logrus.Logger, device string, caps []*common.Capability) error {
for _, cmd := range n.getWipers(device, caps) {
if cmd.Wipe(ctx, logger) == nil {
return nil
}
}
l.WithError(err).Info("failed")
return ErrIneffectiveWipe
}

Expand Down
13 changes: 12 additions & 1 deletion utils/nvme_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,18 @@ func Test_NvmeComponents(t *testing.T) {
t.Error(err)
}

assert.Equal(t, expected, drives)
assert.Equal(t, len(expected), len(drives))
for i := range expected {
assert.Equal(t, expected[i].LogicalName, drives[i].LogicalName)
assert.Equal(t, expected[i].Serial, drives[i].Serial)
assert.Equal(t, expected[i].Vendor, drives[i].Vendor)
assert.Equal(t, expected[i].Model, drives[i].Model)
assert.Equal(t, expected[i].Description, drives[i].Description)
assert.Equal(t, expected[i].ProductName, drives[i].ProductName)
assert.Equal(t, expected[i].Firmware, drives[i].Firmware)
assert.Equal(t, expected[i].Capabilities, drives[i].Capabilities)
assert.Equal(t, expected[i].Metadata, drives[i].Metadata)
}
}

func Test_NvmeDriveCapabilities(t *testing.T) {
Expand Down

0 comments on commit 205e1b1

Please sign in to comment.