Merge pull request #2860 from bcoca/lininfile_safe

makes lineinfile a bit safer by using atomic rename
reviewable/pr18780/r1
Michael DeHaan 12 years ago
commit b003aca0ba

@ -20,6 +20,7 @@
import re import re
import os import os
import tempfile
DOCUMENTATION = """ DOCUMENTATION = """
--- ---
@ -128,6 +129,14 @@ EXAMPLES = r"""
lineinfile: dest=/opt/jboss-as/bin/standalone.conf regexp='^(.*)Xms(\d+)m(.*)$' line='\\1Xms${xms}m\\3' backrefs=yes lineinfile: dest=/opt/jboss-as/bin/standalone.conf regexp='^(.*)Xms(\d+)m(.*)$' line='\\1Xms${xms}m\\3' backrefs=yes
""" """
def write_changes(module,lines,dest):
tmpfd, tmpfile = tempfile.mkstemp()
f = os.fdopen(tmpfd,'wb')
f.writelines(lines)
f.close()
module.atomic_move(tmpfile, dest)
def check_file_attrs(module, changed, message): def check_file_attrs(module, changed, message):
@ -145,9 +154,7 @@ def check_file_attrs(module, changed, message):
def present(module, dest, regexp, line, insertafter, insertbefore, create, def present(module, dest, regexp, line, insertafter, insertbefore, create,
backup, backrefs): backup, backrefs):
if os.path.isdir(dest): if not os.path.exists(dest):
module.fail_json(rc=256, msg='Destination %s is a directory !' % dest)
elif not os.path.exists(dest):
if not create: if not create:
module.fail_json(rc=257, msg='Destination %s does not exist !' % dest) module.fail_json(rc=257, msg='Destination %s does not exist !' % dest)
destpath = os.path.dirname(dest) destpath = os.path.dirname(dest)
@ -229,9 +236,7 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create,
if changed and not module.check_mode: if changed and not module.check_mode:
if backup and os.path.exists(dest): if backup and os.path.exists(dest):
module.backup_local(dest) module.backup_local(dest)
f = open(dest, 'wb') write_changes(module, lines, dest)
f.writelines(lines)
f.close()
msg, changed = check_file_attrs(module, changed, msg) msg, changed = check_file_attrs(module, changed, msg)
module.exit_json(changed=changed, msg=msg) module.exit_json(changed=changed, msg=msg)
@ -239,9 +244,7 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create,
def absent(module, dest, regexp, backup): def absent(module, dest, regexp, backup):
if os.path.isdir(dest): if not os.path.exists(dest):
module.fail_json(rc=256, msg='Destination %s is a directory !' % dest)
elif not os.path.exists(dest):
module.exit_json(changed=False, msg="file not present") module.exit_json(changed=False, msg="file not present")
msg = "" msg = ""
@ -264,9 +267,7 @@ def absent(module, dest, regexp, backup):
if changed and not module.check_mode: if changed and not module.check_mode:
if backup: if backup:
module.backup_local(dest) module.backup_local(dest)
f = open(dest, 'wb') write_changes(module, lines, dest)
f.writelines(lines)
f.close()
if changed: if changed:
msg = "%s line(s) removed" % len(found) msg = "%s line(s) removed" % len(found)
@ -299,6 +300,10 @@ def main():
backrefs = module.params['backrefs'] backrefs = module.params['backrefs']
dest = os.path.expanduser(params['dest']) dest = os.path.expanduser(params['dest'])
if os.path.isdir(dest):
module.fail_json(rc=256, msg='Destination %s is a directory !' % dest)
if params['state'] == 'present': if params['state'] == 'present':
if 'line' not in params: if 'line' not in params:
module.fail_json(msg='line= is required with state=present') module.fail_json(msg='line= is required with state=present')

Loading…
Cancel
Save