mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge pull request #28265 from jfindlay/blockdev
fix blockdev execution and state modules
This commit is contained in:
commit
62485e567f
4 changed files with 195 additions and 46 deletions
|
@ -12,17 +12,28 @@ import subprocess
|
|||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import salt.utils.decorators as decorators
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
__func_alias__ = {
|
||||
'format_': 'format'
|
||||
}
|
||||
|
||||
__virtualname__ = 'blockdev'
|
||||
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
Only work on POSIX-like systems
|
||||
Only load this module if the blockdev utility is available
|
||||
'''
|
||||
if salt.utils.is_windows():
|
||||
return False
|
||||
return True
|
||||
return (False, ('The {0} execution module '
|
||||
'is not supported on windows'.format(__virtualname__)))
|
||||
elif not salt.utils.which('blockdev'):
|
||||
return (False, ('Cannot load the {0} execution module: '
|
||||
'blockdev utility not found'.format(__virtualname__)))
|
||||
return __virtualname__
|
||||
|
||||
|
||||
def tune(device, **kwargs):
|
||||
|
@ -33,7 +44,7 @@ def tune(device, **kwargs):
|
|||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' blockdev.tune /dev/sda1 read-ahead=1024 read-write=True
|
||||
salt '*' blockdev.tune /dev/sdX1 read-ahead=1024 read-write=True
|
||||
|
||||
Valid options are: ``read-ahead``, ``filesystem-read-ahead``,
|
||||
``read-only``, ``read-write``.
|
||||
|
@ -64,6 +75,7 @@ def tune(device, **kwargs):
|
|||
return dump(device, args)
|
||||
|
||||
|
||||
@decorators.which('wipefs')
|
||||
def wipe(device):
|
||||
'''
|
||||
Remove the filesystem information
|
||||
|
@ -72,7 +84,7 @@ def wipe(device):
|
|||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' blockdev.wipe /dev/sda1
|
||||
salt '*' blockdev.wipe /dev/sdX1
|
||||
'''
|
||||
|
||||
cmd = 'wipefs {0}'.format(device)
|
||||
|
@ -88,21 +100,38 @@ def dump(device, args=None):
|
|||
'''
|
||||
Return all contents of dumpe2fs for a specified device
|
||||
|
||||
args
|
||||
a list containing only the desired arguments to return
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' extfs.dump /dev/sda1
|
||||
salt '*' blockdev.dump /dev/sdX1
|
||||
'''
|
||||
cmd = 'blockdev --getro --getsz --getss --getpbsz --getiomin --getioopt --getalignoff --getmaxsect --getsize --getsize64 --getra --getfra {0}'.format(device)
|
||||
cmd = ['blockdev',
|
||||
'--getro',
|
||||
'--getsz',
|
||||
'--getss',
|
||||
'--getpbsz',
|
||||
'--getiomin',
|
||||
'--getioopt',
|
||||
'--getalignoff',
|
||||
'--getmaxsect',
|
||||
'--getsize',
|
||||
'--getsize64',
|
||||
'--getra',
|
||||
'--getfra',
|
||||
str(device)]
|
||||
ret = {}
|
||||
opts = [c[2:] for c in cmd.split() if c.startswith('--')]
|
||||
opts = [c[2:] for c in cmd if c.startswith('--')]
|
||||
out = __salt__['cmd.run_all'](cmd, python_shell=False)
|
||||
if out['retcode'] == 0:
|
||||
lines = [line for line in out['stdout'].splitlines() if line]
|
||||
count = 0
|
||||
for line in lines:
|
||||
ret[opts[count]] = line
|
||||
count = count+1
|
||||
count += 1
|
||||
if args:
|
||||
temp_ret = {}
|
||||
for arg in args:
|
||||
|
@ -114,6 +143,94 @@ def dump(device, args=None):
|
|||
return False
|
||||
|
||||
|
||||
@decorators.which('sync')
|
||||
@decorators.which('mkfs')
|
||||
def format_(device, fs_type='ext4', inode_size=None, lazy_itable_init=None):
|
||||
'''
|
||||
Format a filesystem onto a block device
|
||||
|
||||
.. versionadded:: 2015.8.2
|
||||
|
||||
device
|
||||
The block device in which to create the new filesystem
|
||||
|
||||
fs_type
|
||||
The type of filesystem to create
|
||||
|
||||
inode_size
|
||||
Size of the inodes
|
||||
|
||||
This option is only enabled for ext and xfs filesystems
|
||||
|
||||
lazy_itable_init
|
||||
If enabled and the uninit_bg feature is enabled, the inode table will
|
||||
not be fully initialized by mke2fs. This speeds up filesystem
|
||||
initialization noticeably, but it requires the kernel to finish
|
||||
initializing the filesystem in the background when the filesystem
|
||||
is first mounted. If the option value is omitted, it defaults to 1 to
|
||||
enable lazy inode table zeroing.
|
||||
|
||||
This option is only enabled for ext filesystems
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' blockdev.format /dev/sdX1
|
||||
'''
|
||||
cmd = ['mkfs', '-t', str(fs_type)]
|
||||
if inode_size is not None:
|
||||
if fs_type[:3] == 'ext':
|
||||
cmd.extend(['-i', str(inode_size)])
|
||||
elif fs_type == 'xfs':
|
||||
cmd.extend(['-i', 'size={0}'.format(inode_size)])
|
||||
if lazy_itable_init is not None:
|
||||
if fs_type[:3] == 'ext':
|
||||
cmd.extend(['-E', 'lazy_itable_init={0}'.format(lazy_itable_init)])
|
||||
cmd.append(str(device))
|
||||
|
||||
mkfs_success = __salt__['cmd.retcode'](cmd, ignore_retcode=True) == 0
|
||||
sync_success = __salt__['cmd.retcode']('sync', ignore_retcode=True) == 0
|
||||
|
||||
return all([mkfs_success, sync_success])
|
||||
|
||||
|
||||
@decorators.which_bin(['lsblk', 'df'])
|
||||
def fstype(device):
|
||||
'''
|
||||
Return the filesystem name of a block device
|
||||
|
||||
.. versionadded:: 2015.8.2
|
||||
|
||||
device
|
||||
The name of the block device
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' blockdev.fstype /dev/sdX1
|
||||
'''
|
||||
if salt.utils.which('lsblk'):
|
||||
lsblk_out = __salt__['cmd.run']('lsblk -o fstype {0}'.format(device)).splitlines()
|
||||
if len(lsblk_out) > 1:
|
||||
fs_type = lsblk_out[1].strip()
|
||||
if fs_type:
|
||||
return fs_type
|
||||
|
||||
if salt.utils.which('df'):
|
||||
# the fstype was not set on the block device, so inspect the filesystem
|
||||
# itself for its type
|
||||
df_out = __salt__['cmd.run']('df -T {0}'.format(device)).splitlines()
|
||||
if len(df_out) > 1:
|
||||
fs_type = df_out[1].split()[1]
|
||||
if fs_type:
|
||||
return fs_type
|
||||
|
||||
return ''
|
||||
|
||||
|
||||
@decorators.which('resize2fs')
|
||||
def resize2fs(device):
|
||||
'''
|
||||
Resizes the filesystem.
|
||||
|
@ -121,7 +238,7 @@ def resize2fs(device):
|
|||
CLI Example:
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' blockdev.resize2fs /dev/sda1
|
||||
salt '*' blockdev.resize2fs /dev/sdX1
|
||||
'''
|
||||
ret = {}
|
||||
cmd = 'resize2fs {0}'.format(device)
|
||||
|
|
|
@ -29,14 +29,17 @@ import os.path
|
|||
# Import salt libs
|
||||
import salt.utils
|
||||
|
||||
__virtualname__ = 'blockdev'
|
||||
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
Only work on POSIX-like systems
|
||||
Only load this module if the blockdev execution module is available
|
||||
'''
|
||||
if salt.utils.is_windows():
|
||||
return False
|
||||
return True
|
||||
if 'blockdev.tune' in __salt__:
|
||||
return __virtualname__
|
||||
return (False, ('Cannot load the {0} state module: '
|
||||
'blockdev execution module not found'.format(__virtualname__)))
|
||||
|
||||
|
||||
def tuned(name, **kwargs):
|
||||
|
@ -146,25 +149,8 @@ def formatted(name, fs_type='ext4', **kwargs):
|
|||
ret['result'] = None
|
||||
return ret
|
||||
|
||||
cmd = 'mkfs -t {0} '.format(fs_type)
|
||||
if 'inode_size' in kwargs:
|
||||
if fs_type[:3] == 'ext':
|
||||
cmd += '-i {0} '.format(kwargs['inode_size'])
|
||||
elif fs_type == 'xfs':
|
||||
cmd += '-i size={0} '.format(kwargs['inode_size'])
|
||||
if 'lazy_itable_init' in kwargs:
|
||||
if fs_type[:3] == 'ext':
|
||||
cmd += '-E lazy_itable_init={0} '.format(kwargs['lazy_itable_init'])
|
||||
|
||||
cmd += name
|
||||
__salt__['cmd.run'](cmd).splitlines()
|
||||
__salt__['cmd.run']('sync').splitlines()
|
||||
blk = __salt__['cmd.run']('lsblk -o fstype {0}'.format(name)).splitlines()
|
||||
|
||||
if len(blk) == 1:
|
||||
current_fs = ''
|
||||
else:
|
||||
current_fs = blk[1]
|
||||
__salt__['blockdev.format'](name, fs_type, **kwargs)
|
||||
current_fs = __salt__['blockdev.fstype'](name)
|
||||
|
||||
if current_fs == fs_type:
|
||||
ret['comment'] = ('{0} has been formatted '
|
||||
|
|
|
@ -21,37 +21,79 @@ blockdev.__salt__ = {
|
|||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
class TestBlockdevModule(TestCase):
|
||||
def test_dump(self):
|
||||
device = '/dev/sdX'
|
||||
cmd = ['blockdev',
|
||||
'--getro',
|
||||
'--getsz',
|
||||
'--getss',
|
||||
'--getpbsz',
|
||||
'--getiomin',
|
||||
'--getioopt',
|
||||
'--getalignoff',
|
||||
'--getmaxsect',
|
||||
'--getsize',
|
||||
'--getsize64',
|
||||
'--getra',
|
||||
'--getfra',
|
||||
device]
|
||||
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
||||
with patch.dict(blockdev.__salt__, {'cmd.run_all': mock}):
|
||||
blockdev.dump('/dev/sda')
|
||||
mock.assert_called_once_with(
|
||||
'blockdev --getro --getsz --getss --getpbsz --getiomin '
|
||||
'--getioopt --getalignoff --getmaxsect --getsize '
|
||||
'--getsize64 --getra --getfra /dev/sda',
|
||||
python_shell=False
|
||||
)
|
||||
blockdev.dump(device)
|
||||
mock.assert_called_once_with(cmd, python_shell=False)
|
||||
|
||||
def test_wipe(self):
|
||||
device = '/dev/sdX'
|
||||
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
||||
with patch.dict(blockdev.__salt__, {'cmd.run_all': mock}):
|
||||
blockdev.wipe('/dev/sda')
|
||||
blockdev.wipe(device)
|
||||
mock.assert_called_once_with(
|
||||
'wipefs /dev/sda',
|
||||
'wipefs {0}'.format(device),
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
def test_tune(self):
|
||||
device = '/dev/sdX'
|
||||
mock = MagicMock(return_value='712971264\n512\n512\n512\n0\n0\n88\n712971264\n365041287168\n512\n512')
|
||||
with patch.dict(blockdev.__salt__, {'cmd.run': mock}):
|
||||
mock_dump = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
||||
with patch('salt.modules.blockdev.dump', mock_dump):
|
||||
kwargs = {'read-ahead': 512, 'filesystem-read-ahead': 512}
|
||||
blockdev.tune('/dev/sda', **kwargs)
|
||||
blockdev.tune(device, **kwargs)
|
||||
mock.assert_called_once_with(
|
||||
'blockdev --setra 512 --setfra 512 /dev/sda',
|
||||
'blockdev --setra 512 --setfra 512 {0}'.format(device),
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
def test_format(self):
|
||||
'''
|
||||
unit tests for blockdev.format
|
||||
'''
|
||||
device = '/dev/sdX1'
|
||||
fs_type = 'ext4'
|
||||
mock = MagicMock(return_value=0)
|
||||
with patch.dict(blockdev.__salt__, {'cmd.retcode': mock}):
|
||||
self.assertEqual(blockdev.format_(device), True)
|
||||
|
||||
def test_fstype(self):
|
||||
'''
|
||||
unit tests for blockdev.fstype
|
||||
'''
|
||||
device = '/dev/sdX1'
|
||||
fs_type = 'ext4'
|
||||
mock = MagicMock(return_value='FSTYPE\n{0}'.format(fs_type))
|
||||
with patch.dict(blockdev.__salt__, {'cmd.run': mock}):
|
||||
self.assertEqual(blockdev.fstype(device), fs_type)
|
||||
|
||||
def test_resize2fs(self):
|
||||
'''
|
||||
unit tests for blockdev.resize2fs
|
||||
'''
|
||||
device = '/dev/sdX1'
|
||||
mock = MagicMock()
|
||||
with patch.dict(blockdev.__salt__, {'cmd.run_all': mock}):
|
||||
blockdev.resize2fs(device)
|
||||
mock.assert_called_once_with('resize2fs {0}'.format(device), python_shell=False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
|
|
|
@ -76,8 +76,12 @@ class BlockdevTestCase(TestCase):
|
|||
ret.update({'comment': comt})
|
||||
self.assertDictEqual(blockdev.formatted(name), ret)
|
||||
|
||||
mock = MagicMock(return_value='ext4')
|
||||
with patch.dict(blockdev.__salt__, {'cmd.run': mock}):
|
||||
mock_ext4 = MagicMock(return_value='ext4')
|
||||
mock_t = MagicMock(return_value=True)
|
||||
mock_e = MagicMock(return_value='')
|
||||
with patch.dict(blockdev.__salt__, {'cmd.run': mock_ext4,
|
||||
'blockdev.format': mock_t,
|
||||
'blockdev.fstype': mock_e}):
|
||||
comt = ('{0} already formatted with '.format(name))
|
||||
ret.update({'comment': comt, 'result': True})
|
||||
self.assertDictEqual(blockdev.formatted(name, fs_type=''), ret)
|
||||
|
|
Loading…
Add table
Reference in a new issue