Add realpath to lvm.pvdisplay and use it in vg_present

Any sort of symlink could be used for inclusion into an lvm vg but lvm's
pvdisplay may show a real device name, or a mapper device name which is
a symlink.

Since we're interested in finding out if the actual device is part of
our volgroup, we test the realpath of both the device requested and the
device returned by pvdisplay to ensure they're the same device.

Fixes #26867 and #30882
This commit is contained in:
Joe Julian 2016-02-04 11:58:10 -08:00
parent 6d4fd11dd0
commit f96650f3c3
3 changed files with 35 additions and 5 deletions

View File

@ -60,10 +60,18 @@ def fullversion():
return ret
def pvdisplay(pvname=''):
def pvdisplay(pvname='', real=False):
'''
Return information about the physical volume(s)
pvname
physical device name
real
dereference any symlinks and report the real device
.. versionadded:: 2015.8.7
CLI Examples:
.. code-block:: bash
@ -84,7 +92,11 @@ def pvdisplay(pvname=''):
for line in out:
if 'is a new physical volume' not in line:
comps = line.strip().split(':')
ret[comps[0]] = {
if real:
device = os.path.realpath(comps[0])
else:
device = comps[0]
ret[device] = {
'Physical Volume Device': comps[0],
'Volume Group Name': comps[1],
'Physical Volume Size (kB)': comps[2],
@ -97,6 +109,8 @@ def pvdisplay(pvname=''):
'Free Physical Extents': comps[9],
'Allocated Physical Extents': comps[10],
}
if real:
ret[device]['Real Physical Volume Device'] = device
return ret

View File

@ -126,15 +126,15 @@ def vg_present(name, devices=None, **kwargs):
ret['comment'] = 'Volume Group {0} already present'.format(name)
for device in devices.split(','):
realdev = os.path.realpath(device)
pvs = __salt__['lvm.pvdisplay'](realdev)
pvs = __salt__['lvm.pvdisplay'](realdev, real=True)
if pvs and pvs.get(realdev, None):
if pvs[realdev]['Volume Group Name'] == name:
ret['comment'] = '{0}\n{1}'.format(
ret['comment'],
'{0} is part of Volume Group'.format(device))
elif pvs[realdev]['Volume Group Name'] == '#orphans_lvm2':
__salt__['lvm.vgextend'](name, realdev)
pvs = __salt__['lvm.pvdisplay'](realdev)
__salt__['lvm.vgextend'](name, device)
pvs = __salt__['lvm.pvdisplay'](realdev, real=True)
if pvs[realdev]['Volume Group Name'] == name:
ret['changes'].update(
{device: 'added to {0}'.format(name)})

View File

@ -71,6 +71,22 @@ class LinuxLVMTestCase(TestCase):
'Total Physical Extents': 'I',
'Volume Group Name': 'B'}})
mockpath = MagicMock(return_value='Z')
with patch.object(os.path, 'realpath', mockpath):
self.assertDictEqual(linux_lvm.pvdisplay(real=True),
{'Z': {'Allocated Physical Extents': 'K',
'Current Logical Volumes Here': 'G',
'Free Physical Extents': 'J',
'Internal Physical Volume Number': 'D',
'Physical Extent Size (kB)': 'H',
'Physical Volume (not) Allocatable': 'F',
'Physical Volume Device': 'A',
'Physical Volume Size (kB)': 'C',
'Physical Volume Status': 'E',
'Real Physical Volume Device': 'Z',
'Total Physical Extents': 'I',
'Volume Group Name': 'B'}})
def test_vgdisplay(self):
'''
Tests information about the volume group(s)