now correctly detects hard links

simplified check_mode
simplified other file attribute handling in link mode
made conditionals clearer

Signed-off-by: Brian Coca <briancoca+dev@gmail.com>
This commit is contained in:
Brian Coca 2013-08-15 23:39:02 -04:00
parent a32f1cac8d
commit 0121b96b1a

View file

@ -132,15 +132,6 @@ EXAMPLES = '''
- file: src=/file/to/link/to dest=/path/to/symlink owner=foo group=foo state=link
'''
def dolink(src, path, state, module):
try:
if state == 'hard':
os.link(src,path)
else:
os.symlink(src, path)
except OSError, e:
module.fail_json(path=path, msg='Error while linking: %s' % str(e))
def main():
# FIXME: pass this around, should not use global
@ -203,7 +194,10 @@ def main():
prev_state = 'link'
elif os.path.isdir(path):
prev_state = 'directory'
elif os.stat(path).st_nlink > 1:
prev_state = 'hard'
else:
# could be many other tings, but defaulting to file
prev_state = 'file'
if prev_state != 'absent' and state == 'absent':
@ -229,9 +223,7 @@ def main():
module.exit_json(path=path, changed=True)
if prev_state != 'absent' and prev_state != state:
if force and prev_state == 'file' and state == 'link':
pass
else:
if not (force and prev_state == 'file' and state == 'link'):
module.fail_json(path=path, msg='refusing to convert between %s and %s for %s' % (prev_state, state, src))
if prev_state == 'absent' and state == 'absent':
@ -279,42 +271,43 @@ def main():
module.fail_json(path=path, src=src, msg='src file does not exist')
if prev_state == 'absent':
if module.check_mode:
module.exit_json(changed=True)
dolink(src, path, state, module)
changed = True
elif prev_state == 'link':
old_src = os.readlink(path)
if not os.path.isabs(old_src):
old_src = os.path.join(os.path.dirname(path), old_src)
if old_src != src:
if module.check_mode:
module.exit_json(changed=True)
os.unlink(path)
dolink(src, path, state, module)
changed = True
elif prev_state == 'hard':
if not (state == 'hard' and os.stat(path).st_ino == os.stat(src).st_ino):
if not force:
module.fail_json(dest=path, src=src, msg='Cannot link, different hard link exists at destination')
changed = True
elif prev_state == 'file':
if not force:
module.fail_json(dest=path, src=src, msg='Cannot link, file exists at destination')
else:
if module.check_mode:
module.exit_json(changed=True)
os.unlink(path)
dolink(src, path, state, module)
changed = True
else:
module.fail_json(dest=path, src=src, msg='unexpected position reached')
# set modes owners and context as needed
file_args = module.load_file_common_arguments(module.params)
changed = module.set_context_if_different(path, file_args['secontext'], changed)
changed = module.set_owner_if_different(path, file_args['owner'], changed)
changed = module.set_group_if_different(path, file_args['group'], changed)
changed = module.set_mode_if_different(path, file_args['mode'], changed)
if changed and not module.check_mode:
if prev_state != 'absent':
try:
os.unlink(path)
except OSError, e:
module.fail_json(path=path, msg='Error while removing existing target: %s' % str(e))
try:
if state == 'hard':
os.link(src,path)
else:
os.symlink(src, path)
except OSError, e:
module.fail_json(path=path, msg='Error while linking: %s' % str(e))
changed = module.set_file_attributes_if_different(file_args, changed)
module.exit_json(dest=path, src=src, changed=changed)
else:
module.fail_json(path=path, msg='unexpected position reached')
# this is magic, see lib/ansible/module_common.py