From d98d76aeaeabc320780b58fe1938bd8aefc62e26 Mon Sep 17 00:00:00 2001 From: James Cammarata Date: Tue, 16 Sep 2014 12:03:40 -0500 Subject: [PATCH] Adding "follow" param for file/copy options Also modifies the template action plugin to use this new param when executing the file/copy modules for templating so that links are preserved correctly. Fixes #8998 --- files/copy | 3 +++ files/file | 14 ++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/files/copy b/files/copy index 5aef3d72221..eff46dae982 100644 --- a/files/copy +++ b/files/copy @@ -160,6 +160,7 @@ def main(): force = module.params['force'] original_basename = module.params.get('original_basename',None) validate = module.params.get('validate',None) + follow = module.params['follow'] if not os.path.exists(src): module.fail_json(msg="Source %s failed to transfer" % (src)) @@ -187,6 +188,8 @@ def main(): adjust_recursive_directory_permissions(pre_existing_dir, new_directory_list, module, directory_args, changed) if os.path.exists(dest): + if os.path.islink(dest) and follow: + dest = os.path.realpath(dest) if not force: module.exit_json(msg="file already exists", src=src, dest=dest, changed=False) if (os.path.isdir(dest)): diff --git a/files/file b/files/file index 8bfd94dd98a..e25278fded7 100644 --- a/files/file +++ b/files/file @@ -125,6 +125,7 @@ def main(): force = params['force'] diff_peek = params['diff_peek'] src = params['src'] + follow = params['follow'] # modify source as we later reload and pass, specially relevant when used by other modules. params['path'] = path = os.path.expanduser(params['path']) @@ -177,15 +178,20 @@ def main(): params['path'] = path = os.path.join(path, basename) else: if state in ['link','hard']: - module.fail_json(msg='src and dest are required for creating links') - - file_args = module.load_file_common_arguments(params) - changed = False + if follow: + # use the current target of the link as the source + src = os.readlink(path) + else: + module.fail_json(msg='src and dest are required for creating links') + # make sure the target path is a directory when we're doing a recursive operation recurse = params['recurse'] if recurse and state != 'directory': module.fail_json(path=path, msg="recurse option requires state to be 'directory'") + file_args = module.load_file_common_arguments(params) + changed = False + if state == 'absent': if state != prev_state: if not module.check_mode: