Skip to content
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

✨ multiple block devices support #4892

Merged
merged 4 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions providers/os/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,12 @@ var Config = plugin.Provider{
Long: "device-name",
Type: plugin.FlagType_String,
Desc: "The target device to scan, e.g. /dev/sda. Supported only for Linux scanning. Do not use together with --lun or --serial-number",
Option: plugin.FlagOption_Hidden | plugin.FlagOption_Deprecated,
},
{
Long: "device-names",
Type: plugin.FlagType_List,
Desc: "The target devices to scan, e.g. /dev/sda. Supported only for Linux scanning. Do not use together with --lun or --serial-number",
Option: plugin.FlagOption_Hidden,
},
{
Expand Down
39 changes: 28 additions & 11 deletions providers/os/connection/device/linux/device_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package linux

import (
"strconv"
"strings"

"github.com/cockroachdb/errors"
"github.com/rs/zerolog/log"
Expand All @@ -14,6 +15,7 @@ import (
const (
LunOption = "lun"
DeviceName = "device-name"
DeviceNames = "device-names"
MountAllPartitions = "mount-all-partitions"
)

Expand Down Expand Up @@ -53,11 +55,23 @@ func (d *LinuxDeviceManager) IdentifyMountTargets(opts map[string]string) ([]*sn
return []*snapshot.PartitionInfo{pi}, nil
}

partitions, err := d.identifyViaDeviceName(opts[DeviceName], opts[MountAllPartitions] == "true")
if err != nil {
return nil, err
deviceNames := strings.Split(opts[DeviceNames], ",")
if opts[DeviceName] != "" {
deviceNames = append(deviceNames, opts[DeviceName])
}
return partitions, nil

var partitions []*snapshot.PartitionInfo
var errs []error
for _, deviceName := range deviceNames {
partitionsForDevice, err := d.identifyViaDeviceName(deviceName, opts[MountAllPartitions] == "true")
if err != nil {
errs = append(errs, err)
continue
}
partitions = append(partitions, partitionsForDevice...)
}

return partitions, errors.Join(errs...)
}

func (d *LinuxDeviceManager) Mount(pi *snapshot.PartitionInfo) (string, error) {
Expand Down Expand Up @@ -86,18 +100,21 @@ func (d *LinuxDeviceManager) UnmountAndClose() {
// we cannot have both LUN and device name provided, those are mutually exclusive
func validateOpts(opts map[string]string) error {
lun := opts[LunOption]
deviceName := opts[DeviceName]

// this is needed only for the validation purposes
deviceNames := opts[DeviceNames] + opts[DeviceName]

mountAll := opts[MountAllPartitions] == "true"
if lun != "" && deviceName != "" {
return errors.New("both lun and device name provided")
if lun != "" && deviceNames != "" {
return errors.New("both lun and device names provided")
}

if lun == "" && deviceName == "" {
return errors.New("either lun or device name must be provided")
if lun == "" && deviceNames == "" {
return errors.New("either lun or device names must be provided")
}

if deviceName == "" && mountAll {
return errors.New("mount-all-partitions requires a device name")
if deviceNames == "" && mountAll {
return errors.New("mount-all-partitions requires device names")
}

return nil
Expand Down
3 changes: 3 additions & 0 deletions providers/os/connection/snapshot/blockdevices.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ func (device BlockDevice) GetMountablePartitions(includeAll bool) ([]*PartitionI
blockDevices := &BlockDevices{
BlockDevices: device.Children,
}
if len(blockDevices.BlockDevices) == 0 && device.FsType != "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice one

blockDevices.BlockDevices = append(blockDevices.BlockDevices, device)
}

// sort the candidates by size, so we can pick the largest one
sortBlockDevicesBySize(blockDevices.BlockDevices)
Expand Down
15 changes: 15 additions & 0 deletions providers/os/connection/snapshot/blockdevices_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,21 @@ func TestGetMountablePartitions(t *testing.T) {
}
require.ElementsMatch(t, expected, parts)
})

t.Run("get all non-mounted partitions (unpartitioned)", func(t *testing.T) {
block := BlockDevice{
Name: "sda",
FsType: "xfs",
Label: "ROOT",
Uuid: "1234",
}
parts, err := block.GetMountablePartitions(true)
require.NoError(t, err)
expected := []*PartitionInfo{
{Name: "/dev/sda", FsType: "xfs", Uuid: "1234", Label: "ROOT"},
}
require.ElementsMatch(t, expected, parts)
})
}

func TestLongestMatchingSuffix(t *testing.T) {
Expand Down
12 changes: 11 additions & 1 deletion providers/os/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,19 @@ func (s *Service) ParseCLI(req *plugin.ParseCLIReq) (*plugin.ParseCLIRes, error)
if lun, ok := flags["lun"]; ok {
conf.Options["lun"] = lun.RawData().Value.(string)
}

deviceNames := []string{}
if deviceName, ok := flags["device-name"]; ok {
conf.Options["device-name"] = deviceName.RawData().Value.(string)
deviceNames = append(deviceNames, deviceName.RawData().Value.(string))
}
if deviceName, ok := flags["device-names"]; ok {
deviceNamesList := deviceName.RawData().Value.([]any)
for _, deviceName := range deviceNamesList {
deviceNames = append(deviceNames, deviceName.(string))
}
}
conf.Options["device-names"] = strings.Join(deviceNames, ",")

if serialNumber, ok := flags["serial-number"]; ok {
conf.Options["serial-number"] = serialNumber.RawData().Value.(string)
}
Expand Down
Loading