Skip to content

Commit

Permalink
✨ device: include mounted option (#4907)
Browse files Browse the repository at this point in the history
* feat: include mounted option

* fix: naming

* test: include mounted
  • Loading branch information
slntopp authored Nov 21, 2024
1 parent 777f3c8 commit a90bf3a
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 16 deletions.
6 changes: 6 additions & 0 deletions providers/os/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,12 @@ var Config = plugin.Provider{
Desc: "Mount all partitions of the block device",
Option: plugin.FlagOption_Hidden,
},
{
Long: "include-mounted",
Type: plugin.FlagType_Bool,
Desc: "Include mounted block devices in the scan",
Option: plugin.FlagOption_Hidden,
},
{
Long: "platform-ids",
Type: plugin.FlagType_List,
Expand Down
13 changes: 9 additions & 4 deletions providers/os/connection/device/device_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,15 @@ func (p *DeviceConnection) Partitions() map[string]*snapshot.PartitionInfo {
// tryDetectAsset tries to detect the OS on a given block device
func tryDetectAsset(connId uint32, partition *snapshot.PartitionInfo, manager DeviceManager, conf *inventory.Config, asset *inventory.Asset) (*fs.FileSystemConnection, string, error) {
log.Debug().Str("name", partition.Name).Str("type", partition.FsType).Msg("mounting partition")
scanDir, err := manager.Mount(partition)
if err != nil {
log.Error().Err(err).Msg("unable to complete mount step")
return nil, "", err

scanDir := partition.MountPoint
var err error
if scanDir == "" {
scanDir, err = manager.Mount(partition)
if err != nil {
log.Error().Err(err).Msg("unable to complete mount step")
return nil, "", err
}
}

// create and initialize fs provider
Expand Down
7 changes: 4 additions & 3 deletions providers/os/connection/device/linux/device_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const (
DeviceName = "device-name"
DeviceNames = "device-names"
MountAllPartitions = "mount-all-partitions"
IncludeMounted = "include-mounted"
)

type LinuxDeviceManager struct {
Expand Down Expand Up @@ -66,7 +67,7 @@ func (d *LinuxDeviceManager) IdentifyMountTargets(opts map[string]string) ([]*sn
var partitions []*snapshot.PartitionInfo
var errs []error
for _, deviceName := range deviceNames {
partitionsForDevice, err := d.identifyViaDeviceName(deviceName, opts[MountAllPartitions] == "true")
partitionsForDevice, err := d.identifyViaDeviceName(deviceName, opts[MountAllPartitions] == "true", opts[IncludeMounted] == "true")
if err != nil {
errs = append(errs, err)
continue
Expand Down Expand Up @@ -153,7 +154,7 @@ func (c *LinuxDeviceManager) identifyViaLun(lun int) (*snapshot.PartitionInfo, e
return device.GetMountablePartition()
}

func (c *LinuxDeviceManager) identifyViaDeviceName(deviceName string, mountAll bool) ([]*snapshot.PartitionInfo, error) {
func (c *LinuxDeviceManager) identifyViaDeviceName(deviceName string, mountAll bool, includeMounted bool) ([]*snapshot.PartitionInfo, error) {
blockDevices, err := c.volumeMounter.CmdRunner.GetBlockDevices()
if err != nil {
return nil, err
Expand All @@ -166,7 +167,7 @@ func (c *LinuxDeviceManager) identifyViaDeviceName(deviceName string, mountAll b

if mountAll {
log.Debug().Str("device", device.Name).Msg("mounting all partitions")
return device.GetMountablePartitions(true)
return device.GetPartitions(true, includeMounted)
}

pi, err := device.GetMountablePartition()
Expand Down
21 changes: 15 additions & 6 deletions providers/os/connection/snapshot/blockdevices.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ func (blockEntries BlockDevices) FindDevice(requested string) (BlockDevice, erro
}

// Searches all the partitions in the device and finds one that can be mounted. It must be unmounted, non-boot partition
func (device BlockDevice) GetMountablePartitions(includeAll bool) ([]*PartitionInfo, error) {
func (device BlockDevice) GetPartitions(includeBoot bool, includeMounted bool) ([]*PartitionInfo, error) {
log.Debug().Str("device", device.Name).Msg("get partitions for device")

blockDevices := &BlockDevices{
Expand All @@ -182,11 +182,19 @@ func (device BlockDevice) GetMountablePartitions(includeAll bool) ([]*PartitionI
log.Debug().Str("name", partition.Name).Msg("skipping partition without filesystem type")
return false
}
if includeAll {
return !partition.isMounted()

// skip boot partitions unless includeBoot is true
if !partition.isNoBootVolume() && !includeBoot {
log.Debug().Str("name", partition.Name).Msg("skipping boot partition")
return false
}

// skip mounted partitions unless includeMounted is true
if partition.isMounted() && !includeMounted {
return false
}

return partition.isNoBootVolumeAndUnmounted()
return true
}

partitions := []*PartitionInfo{}
Expand All @@ -198,7 +206,8 @@ func (device BlockDevice) GetMountablePartitions(includeAll bool) ([]*PartitionI
partitions = append(partitions, &PartitionInfo{
Name: devFsName, FsType: partition.FsType,
Label: partition.Label, Uuid: partition.Uuid,
Aliases: partition.Aliases,
Aliases: partition.Aliases,
MountPoint: partition.MountPoint,
})
} else {
log.Debug().
Expand All @@ -219,7 +228,7 @@ func (device BlockDevice) GetMountablePartitions(includeAll bool) ([]*PartitionI
// If multiple partitions meet this criteria, the largest one is returned.
func (device BlockDevice) GetMountablePartition() (*PartitionInfo, error) {
// return the largest partition. we can extend this to be a parameter in the future
partitions, err := device.GetMountablePartitions(false)
partitions, err := device.GetPartitions(false, false)
if err != nil {
return nil, err
}
Expand Down
28 changes: 25 additions & 3 deletions providers/os/connection/snapshot/blockdevices_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ func TestGetMountablePartition(t *testing.T) {
})
}

func TestGetMountablePartitions(t *testing.T) {
func TestGetPartitions(t *testing.T) {
t.Run("get all non-mounted partitions", func(t *testing.T) {
block := BlockDevice{
Name: "sda",
Expand All @@ -277,7 +277,7 @@ func TestGetMountablePartitions(t *testing.T) {
{Uuid: "12347", FsType: "", Label: "ROOT", Name: "sda4", MountPoint: ""},
},
}
parts, err := block.GetMountablePartitions(true)
parts, err := block.GetPartitions(true, false)
require.NoError(t, err)
expected := []*PartitionInfo{
{Name: "/dev/sda2", FsType: "xfs", Uuid: "12345", Label: "ROOT"},
Expand All @@ -293,13 +293,35 @@ func TestGetMountablePartitions(t *testing.T) {
Label: "ROOT",
Uuid: "1234",
}
parts, err := block.GetMountablePartitions(true)
parts, err := block.GetPartitions(true, false)
require.NoError(t, err)
expected := []*PartitionInfo{
{Name: "/dev/sda", FsType: "xfs", Uuid: "1234", Label: "ROOT"},
}
require.ElementsMatch(t, expected, parts)
})

t.Run("get all partitions (include mounted)", func(t *testing.T) {
block := BlockDevice{
Name: "sda",
Children: []BlockDevice{
// already mounted
{Uuid: "1234", FsType: "xfs", Label: "ROOT", Name: "sda1", MountPoint: "/"},
{Uuid: "12345", FsType: "xfs", Label: "ROOT", Name: "sda2", MountPoint: ""},
{Uuid: "12346", FsType: "xfs", Label: "ROOT", Name: "sda3", MountPoint: ""},
// no fs type
{Uuid: "12347", FsType: "", Label: "ROOT", Name: "sda4", MountPoint: ""},
},
}
parts, err := block.GetPartitions(true, true)
require.NoError(t, err)
expected := []*PartitionInfo{
{Name: "/dev/sda1", FsType: "xfs", Uuid: "1234", Label: "ROOT", MountPoint: "/"},
{Name: "/dev/sda2", FsType: "xfs", Uuid: "12345", Label: "ROOT"},
{Name: "/dev/sda3", FsType: "xfs", Uuid: "12346", Label: "ROOT"},
}
require.ElementsMatch(t, expected, parts)
})
}

func TestLongestMatchingSuffix(t *testing.T) {
Expand Down
2 changes: 2 additions & 0 deletions providers/os/connection/snapshot/partition.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ type PartitionInfo struct {
Label string
// (optional) UUID is the partition UUID
Uuid string
// (optional) MountPoint is the partition mount point
MountPoint string
}

func (entry BlockDevice) isNoBootVolume() bool {
Expand Down
3 changes: 3 additions & 0 deletions providers/os/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@ func (s *Service) ParseCLI(req *plugin.ParseCLIReq) (*plugin.ParseCLIRes, error)
if mountAll, ok := flags["mount-all-partitions"]; ok {
conf.Options["mount-all-partitions"] = strconv.FormatBool(mountAll.RawData().Value.(bool))
}
if includeMounted, ok := flags["include-mounted"]; ok {
conf.Options["include-mounted"] = strconv.FormatBool(includeMounted.RawData().Value.(bool))
}

if platformIDs, ok := flags["platform-ids"]; ok {
platformIDs := platformIDs.Array
Expand Down

0 comments on commit a90bf3a

Please sign in to comment.