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