Merge pull request #1492 from alxgu/filesystem_idemponent

Make fileystem module idemponent. Compare devicesize and filesystemsize.
This commit is contained in:
Brian Coca 2016-01-25 23:55:34 -05:00
commit 1f2b6bf3fd

View file

@ -63,6 +63,50 @@ EXAMPLES = '''
- filesystem: fstype=ext4 dev=/dev/sdb1 opts="-cc" - filesystem: fstype=ext4 dev=/dev/sdb1 opts="-cc"
''' '''
def _get_dev_size(dev, module):
""" Return size in bytes of device. Returns int """
blockdev_cmd = module.get_bin_path("blockdev", required=True)
rc, devsize_in_bytes, err = module.run_command("%s %s %s" % (blockdev_cmd, "--getsize64", dev))
return int(devsize_in_bytes)
def _get_fs_size(fssize_cmd, dev, module):
""" Return size in bytes of filesystem on device. Returns int """
cmd = module.get_bin_path(fssize_cmd, required=True)
if 'tune2fs' == fssize_cmd:
# Get Block count and Block size
rc, size, err = module.run_command("%s %s %s" % (cmd, '-l', dev))
if rc == 0:
for line in size.splitlines():
if 'Block count:' in line:
block_count = int(line.split(':')[1].strip())
elif 'Block size:' in line:
block_size = int(line.split(':')[1].strip())
break
else:
module.fail_json(msg="Failed to get block count and block size of %s with %s" % (dev, cmd), rc=rc, err=err )
elif 'xfs_info' == fssize_cmd:
# Get Block count and Block size
rc, size, err = module.run_command("%s %s" % (cmd, dev))
if rc == 0:
for line in size.splitlines():
#if 'data' in line:
if 'data ' in line:
block_size = int(line.split('=')[2].split()[0])
block_count = int(line.split('=')[3].split(',')[0])
break
else:
module.fail_json(msg="Failed to get block count and block size of %s with %s" % (dev, cmd), rc=rc, err=err )
elif 'btrfs' == fssize_cmd:
#ToDo
# There is no way to get the blocksize and blockcount for btrfs filesystems
block_size = 1
block_count = 1
return block_size*block_count
def main(): def main():
module = AnsibleModule( module = AnsibleModule(
argument_spec = dict( argument_spec = dict(
@ -82,36 +126,42 @@ def main():
'grow' : 'resize2fs', 'grow' : 'resize2fs',
'grow_flag' : None, 'grow_flag' : None,
'force_flag' : '-F', 'force_flag' : '-F',
'fsinfo': 'tune2fs',
}, },
'ext3' : { 'ext3' : {
'mkfs' : 'mkfs.ext3', 'mkfs' : 'mkfs.ext3',
'grow' : 'resize2fs', 'grow' : 'resize2fs',
'grow_flag' : None, 'grow_flag' : None,
'force_flag' : '-F', 'force_flag' : '-F',
'fsinfo': 'tune2fs',
}, },
'ext4' : { 'ext4' : {
'mkfs' : 'mkfs.ext4', 'mkfs' : 'mkfs.ext4',
'grow' : 'resize2fs', 'grow' : 'resize2fs',
'grow_flag' : None, 'grow_flag' : None,
'force_flag' : '-F', 'force_flag' : '-F',
'fsinfo': 'tune2fs',
}, },
'ext4dev' : { 'ext4dev' : {
'mkfs' : 'mkfs.ext4', 'mkfs' : 'mkfs.ext4',
'grow' : 'resize2fs', 'grow' : 'resize2fs',
'grow_flag' : None, 'grow_flag' : None,
'force_flag' : '-F', 'force_flag' : '-F',
'fsinfo': 'tune2fs',
}, },
'xfs' : { 'xfs' : {
'mkfs' : 'mkfs.xfs', 'mkfs' : 'mkfs.xfs',
'grow' : 'xfs_growfs', 'grow' : 'xfs_growfs',
'grow_flag' : None, 'grow_flag' : None,
'force_flag' : '-f', 'force_flag' : '-f',
'fsinfo': 'xfs_info',
}, },
'btrfs' : { 'btrfs' : {
'mkfs' : 'mkfs.btrfs', 'mkfs' : 'mkfs.btrfs',
'grow' : 'btrfs', 'grow' : 'btrfs',
'grow_flag' : 'filesystem resize', 'grow_flag' : 'filesystem resize',
'force_flag' : '-f', 'force_flag' : '-f',
'fsinfo': 'btrfs',
} }
} }
@ -131,6 +181,7 @@ def main():
mkfscmd = fs_cmd_map[fstype]['mkfs'] mkfscmd = fs_cmd_map[fstype]['mkfs']
force_flag = fs_cmd_map[fstype]['force_flag'] force_flag = fs_cmd_map[fstype]['force_flag']
growcmd = fs_cmd_map[fstype]['grow'] growcmd = fs_cmd_map[fstype]['grow']
fssize_cmd = fs_cmd_map[fstype]['fsinfo']
if not os.path.exists(dev): if not os.path.exists(dev):
module.fail_json(msg="Device %s not found."%dev) module.fail_json(msg="Device %s not found."%dev)
@ -143,10 +194,21 @@ def main():
if fs == fstype and resizefs == False: if fs == fstype and resizefs == False:
module.exit_json(changed=False) module.exit_json(changed=False)
elif fs == fstype and resizefs == True: elif fs == fstype and resizefs == True:
cmd = module.get_bin_path(growcmd, required=True) # Get dev and fs size and compare
if module.check_mode: devsize_in_bytes = _get_dev_size(dev, module)
module.exit_json(changed=True, msg="May resize filesystem") fssize_in_bytes = _get_fs_size(fssize_cmd, dev, module)
if fssize_in_bytes < devsize_in_bytes:
fs_smaller = True
else: else:
fs_smaller = False
if module.check_mode and fs_smaller:
module.exit_json(changed=True, msg="Resizing filesystem %s on device %s" % (fstype,dev))
elif module.check_mode and not fs_smaller:
module.exit_json(changed=False, msg="%s filesystem is using the whole device %s" % (fstype, dev))
elif fs_smaller:
cmd = module.get_bin_path(growcmd, required=True)
rc,out,err = module.run_command("%s %s" % (cmd, dev)) rc,out,err = module.run_command("%s %s" % (cmd, dev))
# Sadly there is no easy way to determine if this has changed. For now, just say "true" and move on. # Sadly there is no easy way to determine if this has changed. For now, just say "true" and move on.
# in the future, you would have to parse the output to determine this. # in the future, you would have to parse the output to determine this.
@ -155,6 +217,8 @@ def main():
module.exit_json(changed=True, msg=out) module.exit_json(changed=True, msg=out)
else: else:
module.fail_json(msg="Resizing filesystem %s on device '%s' failed"%(fstype,dev), rc=rc, err=err) module.fail_json(msg="Resizing filesystem %s on device '%s' failed"%(fstype,dev), rc=rc, err=err)
else:
module.exit_json(changed=False, msg="%s filesystem is using the whole device %s" % (fstype, dev))
elif fs and not force: elif fs and not force:
module.fail_json(msg="'%s' is already used as %s, use force=yes to overwrite"%(dev,fs), rc=rc, err=err) module.fail_json(msg="'%s' is already used as %s, use force=yes to overwrite"%(dev,fs), rc=rc, err=err)
@ -180,4 +244,5 @@ def main():
# import module snippets # import module snippets
from ansible.module_utils.basic import * from ansible.module_utils.basic import *
main() if __name__ == '__main__':
main()