Skip to content

Commit

Permalink
Merge branch '3.2-devel' into 3.3-devel
Browse files Browse the repository at this point in the history
  • Loading branch information
vojtechtrefny committed Aug 20, 2020
2 parents 6619caa + f315d01 commit 67d7908
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 62 deletions.
51 changes: 34 additions & 17 deletions blivet/devicetree.py
Original file line number Diff line number Diff line change
Expand Up @@ -934,31 +934,48 @@ def expand_taglist(self, taglist):
result.add(item)
return result

def _disk_in_taglist(self, disk, taglist):
# Taglist is a list containing mix of disk names and tags into which disk may belong.
# Check if it does. Raise ValueError if unknown tag is encountered.
if disk.name in taglist:
return True
tags = [t[1:] for t in taglist if t.startswith("@")]
for tag in tags:
if tag not in Tags.__members__:
raise ValueError("unknown ignoredisk tag '@%s' encountered" % tag)
if Tags(tag) in disk.tags:
return True
return False

def _is_ignored_disk(self, disk):
""" Checks config for lists of exclusive and ignored disks
and returns if the given one should be ignored
"""

def disk_in_taglist(disk, taglist):
# Taglist is a list containing mix of disk names and tags into which disk may belong.
# Check if it does. Raise ValueError if unknown tag is encountered.
if disk.name in taglist:
return True
tags = [t[1:] for t in taglist if t.startswith("@")]
for tag in tags:
if tag not in Tags.__members__:
raise ValueError("unknown ignoredisk tag '@%s' encountered" % tag)
if Tags(tag) in disk.tags:
return True
return False

return ((self.ignored_disks and disk_in_taglist(disk, self.ignored_disks)) or
(self.exclusive_disks and not disk_in_taglist(disk, self.exclusive_disks)))
return ((self.ignored_disks and self._disk_in_taglist(disk, self.ignored_disks)) or
(self.exclusive_disks and not self._disk_in_taglist(disk, self.exclusive_disks)))

def _hide_ignored_disks(self):
# hide any subtrees that begin with an ignored disk
for disk in [d for d in self._devices if d.is_disk]:
if self._is_ignored_disk(disk):
is_ignored = self.ignored_disks and self._disk_in_taglist(disk, self.ignored_disks)
is_exclusive = self.exclusive_disks and self._disk_in_taglist(disk, self.exclusive_disks)

if is_ignored:
if len(disk.children) == 1:
if not all(self._is_ignored_disk(d) for d in disk.children[0].parents):
raise DeviceTreeError("Including only a subset of raid/multipath member disks is not allowed.")

# and also children like fwraid or mpath
self.hide(disk.children[0])

# this disk is ignored: ignore it and all it's potential parents
for p in disk.parents:
self.hide(p)

# and finally hide the disk itself
self.hide(disk)

if self.exclusive_disks and not is_exclusive:
ignored = True
# If the filter allows all members of a fwraid or mpath, the
# fwraid or mpath itself is implicitly allowed as well. I don't
Expand Down
157 changes: 112 additions & 45 deletions tests/devicetree_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,51 +399,6 @@ def test_hide_ignored_disks(self):
self.assertTrue(sdb in tree.devices)
self.assertTrue(sdc in tree.devices)

# now test exclusive_disks special cases for multipath
sda.format = get_format("multipath_member", exists=True)
sdb.format = get_format("multipath_member", exists=True)
sdc.format = get_format("multipath_member", exists=True)
mpatha = MultipathDevice("mpatha", parents=[sda, sdb, sdc])
tree._add_device(mpatha)

tree.ignored_disks = []
tree.exclusive_disks = ["mpatha"]

with patch.object(tree, "hide") as hide:
tree._hide_ignored_disks()
self.assertFalse(hide.called)

tree._hide_ignored_disks()
self.assertTrue(sda in tree.devices)
self.assertTrue(sdb in tree.devices)
self.assertTrue(sdc in tree.devices)
self.assertTrue(mpatha in tree.devices)

# all members in exclusive_disks implies the mpath in exclusive_disks
tree.exclusive_disks = ["sda", "sdb", "sdc"]
with patch.object(tree, "hide") as hide:
tree._hide_ignored_disks()
self.assertFalse(hide.called)

tree._hide_ignored_disks()
self.assertTrue(sda in tree.devices)
self.assertTrue(sdb in tree.devices)
self.assertTrue(sdc in tree.devices)
self.assertTrue(mpatha in tree.devices)

tree.exclusive_disks = ["sda", "sdb"]
with patch.object(tree, "hide") as hide:
tree._hide_ignored_disks()
hide.assert_any_call(mpatha)
hide.assert_any_call(sdc)

# verify that hide works as expected
tree._hide_ignored_disks()
self.assertTrue(sda in tree.devices)
self.assertTrue(sdb in tree.devices)
self.assertFalse(sdc in tree.devices)
self.assertFalse(mpatha in tree.devices)

def test_get_related_disks(self):
tree = DeviceTree()

Expand Down Expand Up @@ -476,3 +431,115 @@ def test_get_related_disks(self):
tree.unhide(sda)
self.assertEqual(tree.get_related_disks(sda), set([sda, sdb]))
self.assertEqual(tree.get_related_disks(sdb), set([sda, sdb]))


class DeviceTreeIgnoredExclusiveMultipathTestCase(unittest.TestCase):

def setUp(self):
self.tree = DeviceTree()

self.sda = DiskDevice("sda")
self.sdb = DiskDevice("sdb")
self.sdc = DiskDevice("sdc")

self.tree._add_device(self.sda)
self.tree._add_device(self.sdb)
self.tree._add_device(self.sdc)

self.assertTrue(self.sda in self.tree.devices)
self.assertTrue(self.sdb in self.tree.devices)
self.assertTrue(self.sdc in self.tree.devices)

# now test exclusive_disks special cases for multipath
self.sda.format = get_format("multipath_member", exists=True)
self.sdb.format = get_format("multipath_member", exists=True)
self.sdc.format = get_format("multipath_member", exists=True)
self.mpatha = MultipathDevice("mpatha", parents=[self.sda, self.sdb, self.sdc])
self.tree._add_device(self.mpatha)

def test_exclusive_disks_multipath_1(self):
# multipath is exclusive -> all disks should be exclusive
self.tree.ignored_disks = []
self.tree.exclusive_disks = ["mpatha"]

with patch.object(self.tree, "hide") as hide:
self.tree._hide_ignored_disks()
self.assertFalse(hide.called)

self.tree._hide_ignored_disks()
self.assertTrue(self.sda in self.tree.devices)
self.assertTrue(self.sdb in self.tree.devices)
self.assertTrue(self.sdc in self.tree.devices)
self.assertTrue(self.mpatha in self.tree.devices)

def test_exclusive_disks_multipath_2(self):
# all disks exclusive -> mpath should also be exclusive
self.tree.exclusive_disks = ["sda", "sdb", "sdc"]
with patch.object(self.tree, "hide") as hide:
self.tree._hide_ignored_disks()
self.assertFalse(hide.called)

self.tree._hide_ignored_disks()
self.assertTrue(self.sda in self.tree.devices)
self.assertTrue(self.sdb in self.tree.devices)
self.assertTrue(self.sdc in self.tree.devices)
self.assertTrue(self.mpatha in self.tree.devices)

def test_exclusive_disks_multipath_3(self):
# some disks exclusive -> mpath should be hidden
self.tree.exclusive_disks = ["sda", "sdb"]
with patch.object(self.tree, "hide") as hide:
self.tree._hide_ignored_disks()
hide.assert_any_call(self.mpatha)
hide.assert_any_call(self.sdc)

# verify that hide works as expected
self.tree._hide_ignored_disks()
self.assertTrue(self.sda in self.tree.devices)
self.assertTrue(self.sdb in self.tree.devices)
self.assertFalse(self.sdc in self.tree.devices)
self.assertFalse(self.mpatha in self.tree.devices)

def test_ignored_disks_multipath_1(self):
# mpatha ignored -> disks should be hidden
self.tree.ignored_disks = ["mpatha"]
self.tree.exclusive_disks = []

with patch.object(self.tree, "hide") as hide:
self.tree._hide_ignored_disks()
hide.assert_any_call(self.mpatha)
hide.assert_any_call(self.sda)
hide.assert_any_call(self.sdb)
hide.assert_any_call(self.sdc)

self.tree._hide_ignored_disks()
self.assertFalse(self.sda in self.tree.devices)
self.assertFalse(self.sdb in self.tree.devices)
self.assertFalse(self.sdc in self.tree.devices)
self.assertFalse(self.mpatha in self.tree.devices)

def test_ignored_disks_multipath_2(self):
# all disks ignored -> mpath should be hidden
self.tree.ignored_disks = ["sda", "sdb", "sdc"]
self.tree.exclusive_disks = []

with patch.object(self.tree, "hide") as hide:
self.tree._hide_ignored_disks()
hide.assert_any_call(self.mpatha)
hide.assert_any_call(self.sda)
hide.assert_any_call(self.sdb)
hide.assert_any_call(self.sdc)

self.tree._hide_ignored_disks()
self.assertFalse(self.sda in self.tree.devices)
self.assertFalse(self.sdb in self.tree.devices)
self.assertFalse(self.sdc in self.tree.devices)
self.assertFalse(self.mpatha in self.tree.devices)

def test_ignored_disks_multipath_3(self):
# some disks ignored -> error
self.tree.ignored_disks = ["sda", "sdb"]
self.tree.exclusive_disks = []

with self.assertRaises(DeviceTreeError):
self.tree._hide_ignored_disks()

0 comments on commit 67d7908

Please sign in to comment.