From cf4a6b39ccec3108d501897a7fd8fd1b943c82d9 Mon Sep 17 00:00:00 2001 From: Richard C Isaacson Date: Fri, 28 Feb 2014 01:14:32 -0600 Subject: [PATCH 1/3] Copy Module: Add the ability to set directory attributes on recursive copy. Closes GH-6194. These changes pass attribute modifications through to new directories during a recursive copy with an addition allowing for the directory mode to be set independantly. --- library/files/copy | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/library/files/copy b/library/files/copy index d961764772a..62cb4dcfafc 100644 --- a/library/files/copy +++ b/library/files/copy @@ -76,6 +76,12 @@ options: required: false default: "" version_added: "1.2" + directory_mode: + description: + - When doing a recursive copy set the mode for the directories. If this is not set we will default to the file + permissions if set. + required: false + version_added: "1.5" others: description: - all arguments accepted by the M(file) module also work here @@ -97,6 +103,23 @@ EXAMPLES = ''' - copy: src=/mine/sudoers dest=/etc/sudoers validate='visudo -cf %s' ''' +def split_pre_existing_dir(dirname): + head, tail = os.path.split(dirname) + if not os.path.exists(head): + (pre_existing_dir, new_directory_list) = split_pre_existing_dir(head) + else: + return (head, [ tail ]) + new_directory_list.insert(0, tail) + return (pre_existing_dir, new_directory_list) + +def adjust_recursive_directory_permissions(pre_existing_dir, new_directory_list, module, directory_args, changed): + if len(new_directory_list) > 0: + working_dir = os.path.join(pre_existing_dir, new_directory_list.pop(0)) + directory_args['path'] = working_dir + changed = module.set_directory_attributes_if_different(directory_args, changed) + changed = adjust_recursive_directory_permissions(working_dir, new_directory_list, module, directory_args, changed) + return changed + def main(): module = AnsibleModule( @@ -109,6 +132,7 @@ def main(): backup = dict(default=False, type='bool'), force = dict(default=True, aliases=['thirsty'], type='bool'), validate = dict(required=False, type='str'), + directory_mode = dict(required=False) ), add_file_common_args=True, ) @@ -128,12 +152,20 @@ def main(): md5sum_src = module.md5(src) md5sum_dest = None + changed = False + # Special handling for recursive copy - create intermediate dirs if original_basename and dest.endswith("/"): dest = os.path.join(dest, original_basename) dirname = os.path.dirname(dest) if not os.path.exists(dirname): + (pre_existing_dir, new_directory_list) = split_pre_existing_dir(dirname) os.makedirs(dirname) + directory_args = module.load_file_common_arguments(module.params) + directory_mode = module.params["directory_mode"] + if directory_mode is not None: + directory_args['mode'] = directory_mode + adjust_recursive_directory_permissions(pre_existing_dir, new_directory_list, module, directory_args, changed) if os.path.exists(dest): if not force: From 890202e4c0c29613febdc4691618626ad9991f69 Mon Sep 17 00:00:00 2001 From: Richard C Isaacson Date: Fri, 28 Feb 2014 10:00:54 -0600 Subject: [PATCH 2/3] copy module: cleanup and if directory_mode not set default to umask --- library/files/copy | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/library/files/copy b/library/files/copy index 62cb4dcfafc..c99fb1522aa 100644 --- a/library/files/copy +++ b/library/files/copy @@ -103,7 +103,12 @@ EXAMPLES = ''' - copy: src=/mine/sudoers dest=/etc/sudoers validate='visudo -cf %s' ''' + def split_pre_existing_dir(dirname): + ''' + Return the first pre-existing directory and a list of the new directories that will be created. + ''' + head, tail = os.path.split(dirname) if not os.path.exists(head): (pre_existing_dir, new_directory_list) = split_pre_existing_dir(head) @@ -112,7 +117,12 @@ def split_pre_existing_dir(dirname): new_directory_list.insert(0, tail) return (pre_existing_dir, new_directory_list) + def adjust_recursive_directory_permissions(pre_existing_dir, new_directory_list, module, directory_args, changed): + ''' + Walk the new directories list and make sure that permissions are as we would expect + ''' + if len(new_directory_list) > 0: working_dir = os.path.join(pre_existing_dir, new_directory_list.pop(0)) directory_args['path'] = working_dir @@ -120,6 +130,7 @@ def adjust_recursive_directory_permissions(pre_existing_dir, new_directory_list, changed = adjust_recursive_directory_permissions(working_dir, new_directory_list, module, directory_args, changed) return changed + def main(): module = AnsibleModule( @@ -132,7 +143,7 @@ def main(): backup = dict(default=False, type='bool'), force = dict(default=True, aliases=['thirsty'], type='bool'), validate = dict(required=False, type='str'), - directory_mode = dict(required=False) + directory_mode = dict(required=False) ), add_file_common_args=True, ) @@ -165,6 +176,8 @@ def main(): directory_mode = module.params["directory_mode"] if directory_mode is not None: directory_args['mode'] = directory_mode + else: + directory_args['mode'] = None adjust_recursive_directory_permissions(pre_existing_dir, new_directory_list, module, directory_args, changed) if os.path.exists(dest): From 7b6c7366d13e45b79406d21642b6d2c2e4ff2a5a Mon Sep 17 00:00:00 2001 From: Richard C Isaacson Date: Fri, 28 Feb 2014 10:04:05 -0600 Subject: [PATCH 3/3] Minor cleanup. --- library/files/copy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/files/copy b/library/files/copy index c99fb1522aa..dbf9c71b4f6 100644 --- a/library/files/copy +++ b/library/files/copy @@ -78,8 +78,8 @@ options: version_added: "1.2" directory_mode: description: - - When doing a recursive copy set the mode for the directories. If this is not set we will default to the file - permissions if set. + - When doing a recursive copy set the mode for the directories. If this is not set we will default the system + defaults. required: false version_added: "1.5" others: