From ddd35b187c00e98a1a45a30a5b3c3e81ef2cf02b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Moser?= Date: Sat, 21 Sep 2013 15:07:50 +0200 Subject: [PATCH 1/3] file: implemented state=touched. Closes GH-4097 --- files/file | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/files/file b/files/file index 9ef61d0ce22..7c9290ecb7d 100644 --- a/files/file +++ b/files/file @@ -50,10 +50,12 @@ options: exist, see the M(copy) or M(template) module if you want that behavior. If C(link), the symbolic link will be created or changed. Use C(hard) for hardlinks. If C(absent), directories will be recursively deleted, - and files or symlinks will be unlinked. + and files or symlinks will be unlinked. If C(touched), existing file and + directory will change file access and modification times, not existing + file will be created. required: false default: file - choices: [ file, link, directory, hard, absent ] + choices: [ file, link, directory, hard, touched, absent ] mode: required: false default: null @@ -139,7 +141,7 @@ def main(): module = AnsibleModule( argument_spec = dict( - state = dict(choices=['file','directory','link','hard','absent'], default='file'), + state = dict(choices=['file','directory','link','hard','touched','absent'], default='file'), path = dict(aliases=['dest', 'name'], required=True), recurse = dict(default='no', type='bool'), force = dict(required=False,default=False,type='bool'), @@ -223,7 +225,7 @@ def main(): module.exit_json(path=path, changed=True) if prev_state != 'absent' and prev_state != state: - if not (force and prev_state == 'file' and state == 'link'): + if not (force and prev_state == 'file' and state == 'link') and state != 'touched': 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': @@ -307,6 +309,21 @@ def main(): changed = module.set_file_attributes_if_different(file_args, changed) module.exit_json(dest=path, src=src, changed=changed) + elif state == 'touched': + if prev_state not in ['file', 'directory', 'absent']: + module.fail_json(msg='Cannot touch other than files and directories') + if prev_state != 'absent': + try: + os.utime(path, None) + except OSError, e: + module.fail_json(path=path, msg='Error while touching existing target: %s' % str(e)) + else: + try: + open(path, 'w').close() + except OSError, e: + module.fail_json(path=path, msg='Error while touching non-existing target: %s' % str(e)) + module.exit_json(dest=path, changed=True) + else: module.fail_json(path=path, msg='unexpected position reached') From 4a61481498e24e2543a2b612e361dd2ec495a18a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Moser?= Date: Sun, 22 Sep 2013 12:53:49 +0200 Subject: [PATCH 2/3] file: skip in check_mode if state=touched --- files/file | 3 +++ 1 file changed, 3 insertions(+) diff --git a/files/file b/files/file index 7c9290ecb7d..3bda637f9a7 100644 --- a/files/file +++ b/files/file @@ -310,6 +310,9 @@ def main(): module.exit_json(dest=path, src=src, changed=changed) elif state == 'touched': + if module.check_mode: + module.exit_json(path=path, skipped=True) + if prev_state not in ['file', 'directory', 'absent']: module.fail_json(msg='Cannot touch other than files and directories') if prev_state != 'absent': From 958abc8a9a78373fb4969c5b0806562eec60cf37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Moser?= Date: Sun, 22 Sep 2013 12:54:24 +0200 Subject: [PATCH 3/3] file: added file attributes in state=touched --- files/file | 1 + 1 file changed, 1 insertion(+) diff --git a/files/file b/files/file index 3bda637f9a7..c96c081ae84 100644 --- a/files/file +++ b/files/file @@ -325,6 +325,7 @@ def main(): open(path, 'w').close() except OSError, e: module.fail_json(path=path, msg='Error while touching non-existing target: %s' % str(e)) + module.set_file_attributes_if_different(file_args, True) module.exit_json(dest=path, changed=True) else: