Support matching disks on DEVPATH or ID_PATH

Related to:
https://bugs.launchpad.net/subiquity/+bug/1952228
https://github.com/canonical/subiquity/pull/1389
This commit is contained in:
Ryan Mounce 2023-03-01 15:20:37 +10:30
parent 5ba82a3974
commit 7dc9668862
3 changed files with 50 additions and 0 deletions

View File

@ -385,6 +385,8 @@ A match spec supports the following keys:
* `model: foo`: matches a disk where ID_VENDOR=foo in udev, supporting globbing
* `path: foo`: matches a disk based on path (e.g. `/dev/sdc`), supporting globbing (the globbing support distinguishes this from specifying path: foo directly in the disk action)
* `id_path: foo`: matches a disk where ID_PATH=foo in udev, supporting globbing
* `devpath: foo`: matches a disk where DEVPATH=foo in udev, supporting globbing
* `serial: foo`: matches a disk where ID_SERIAL=foo in udev, supporting globbing (the globbing support distinguishes this from specifying serial: foo directly in the disk action)
* `ssd: yes|no`: matches a disk that is or is not an SSD (vs a rotating drive)
* `size: largest|smallest`: take the largest or smallest disk rather than an arbitrary one if there are multiple matches (support for `smallest` added in version 20.06.1)

View File

@ -1198,6 +1198,14 @@ class FilesystemModel(object):
def match_path(disk):
return fnmatch.fnmatchcase(disk.path, match['path'])
def match_id_path(disk):
return fnmatch.fnmatchcase(
_udev_val(disk, "ID_PATH"), match['id_path'])
def match_devpath(disk):
return fnmatch.fnmatchcase(
_udev_val(disk, "DEVPATH"), match['devpath'])
def match_ssd(disk):
is_ssd = disk.info_for_display()['rotational'] == 'false'
return is_ssd == match['ssd']
@ -1216,6 +1224,10 @@ class FilesystemModel(object):
matchers.append(match_vendor)
if 'path' in match:
matchers.append(match_path)
if 'id_path' in match:
matchers.append(match_id_path)
if 'devpath' in match:
matchers.append(match_devpath)
if 'ssd' in match:
matchers.append(match_ssd)

View File

@ -495,6 +495,42 @@ class TestAutoInstallConfig(unittest.TestCase):
new_disk = model._one(type="disk", id="disk0")
self.assertEqual(new_disk.serial, d1.serial)
def test_id_path_glob(self):
model = make_model()
d1 = make_disk(model, serial='aaaa')
d2 = make_disk(model, serial='bbbb')
fake_up_blockdata_disk(d1, ID_PATH='pci-0000:00:00.0-nvme-aaa')
fake_up_blockdata_disk(d2, ID_PATH='pci-0000:00:00.0-nvme-bbb')
model.apply_autoinstall_config([
{
'type': 'disk',
'id': 'disk0',
'match': {
'id_path': '*aaa',
},
},
])
new_disk = model._one(type="disk", id="disk0")
self.assertEqual(new_disk.serial, d1.serial)
def test_devpath_glob(self):
model = make_model()
d1 = make_disk(model, serial='aaaa')
d2 = make_disk(model, serial='bbbb')
fake_up_blockdata_disk(d1, DEVPATH='/devices/pci0000:00/aaa')
fake_up_blockdata_disk(d2, DEVPATH='/devices/pci0000:00/bbb')
model.apply_autoinstall_config([
{
'type': 'disk',
'id': 'disk0',
'match': {
'devpath': '*aaa',
},
},
])
new_disk = model._one(type="disk", id="disk0")
self.assertEqual(new_disk.serial, d1.serial)
def test_no_matching_disk(self):
model = make_model()
make_disk(model, serial='bbbb')