@ -184,6 +184,13 @@ EXAMPLES = r'''
line : 192.168 .1 .99 foo . lab . net foo
line : 192.168 .1 .99 foo . lab . net foo
create : yes
create : yes
# Fully quoted because of the ': ' on the line. See the Gotchas in the YAML docs.
- lineinfile :
path : / etc / sudoers
state : present
regexp : ' ^ % wheel \ s '
line : ' % wheel ALL=(ALL) NOPASSWD: ALL '
# NOTE: Yaml requires escaping backslashes in double quotes but not in single quotes
# NOTE: Yaml requires escaping backslashes in double quotes but not in single quotes
- name : Ensure the JBoss memory settings are exactly as needed
- name : Ensure the JBoss memory settings are exactly as needed
lineinfile :
lineinfile :
@ -208,6 +215,7 @@ import tempfile
# import module snippets
# import module snippets
from ansible . module_utils . basic import AnsibleModule
from ansible . module_utils . basic import AnsibleModule
from ansible . module_utils . common . file import open_locked
from ansible . module_utils . six import b
from ansible . module_utils . six import b
from ansible . module_utils . _text import to_bytes , to_native
from ansible . module_utils . _text import to_bytes , to_native
@ -265,141 +273,148 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create,
os . makedirs ( b_destpath )
os . makedirs ( b_destpath )
except Exception as e :
except Exception as e :
module . fail_json ( msg = ' Error creating %s Error code: %s Error description: %s ' % ( b_destpath , e [ 0 ] , e [ 1 ] ) )
module . fail_json ( msg = ' Error creating %s Error code: %s Error description: %s ' % ( b_destpath , e [ 0 ] , e [ 1 ] ) )
# destination must exist to be able to lock it
if not module . check_mode :
open ( b_dest , ' ab ' ) . close ( )
b_lines = [ ]
b_lines = [ ]
else :
else :
with open ( b_dest , ' rb ' ) as f :
b_lines = None
b_lines = f . readlines ( )
if module . _diff :
# NOTE: Avoid opening the same file in this context !
diff [ ' before ' ] = to_native ( b ( ' ' ) . join ( b_lines ) )
with open_locked ( dest , module . check_mode ) as fd :
if b_lines is None :
b_lines = fd . readlines ( )
if regexp is not None :
if module . _diff :
bre_m = re . compile ( to_bytes ( regexp , errors = ' surrogate_or_strict ' ) )
diff [ ' before ' ] = to_native ( b ( ' ' ) . join ( b_lines ) )
if insertafter not in ( None , ' BOF ' , ' EOF ' ) :
bre_ins = re . compile ( to_bytes ( insertafter , errors = ' surrogate_or_strict ' ) )
elif insertbefore not in ( None , ' BOF ' ) :
bre_ins = re . compile ( to_bytes ( insertbefore , errors = ' surrogate_or_strict ' ) )
else :
bre_ins = None
# index[0] is the line num where regexp has been found
# index[1] is the line num where insertafter/inserbefore has been found
index = [ - 1 , - 1 ]
m = None
b_line = to_bytes ( line , errors = ' surrogate_or_strict ' )
for lineno , b_cur_line in enumerate ( b_lines ) :
if regexp is not None :
if regexp is not None :
match_found = bre_m . search ( b_cur_line )
bre_m = re . compile ( to_bytes ( regexp , errors = ' surrogate_or_strict ' ) )
else :
match_found = b_line == b_cur_line . rstrip ( b ( ' \r \n ' ) )
if match_found :
index [ 0 ] = lineno
m = match_found
elif bre_ins is not None and bre_ins . search ( b_cur_line ) :
if insertafter :
# + 1 for the next line
index [ 1 ] = lineno + 1
if firstmatch :
break
if insertbefore :
# index[1] for the previous line
index [ 1 ] = lineno
if firstmatch :
break
msg = ' '
if insertafter not in ( None , ' BOF ' , ' EOF ' ) :
changed = False
bre_ins = re . compile ( to_bytes ( insertafter , errors = ' surrogate_or_strict ' ) )
b_linesep = to_bytes ( os . linesep , errors = ' surrogate_or_strict ' )
elif insertbefore not in ( None , ' BOF ' ) :
# Exact line or Regexp matched a line in the file
bre_ins = re . compile ( to_bytes ( insertbefore , errors = ' surrogate_or_strict ' ) )
if index [ 0 ] != - 1 :
if backrefs :
b_new_line = m . expand ( b_line )
else :
else :
# Don't do backref expansion if not asked.
bre_ins = None
b_new_line = b_line
# index[0] is the line num where regexp has been found
if not b_new_line . endswith ( b_linesep ) :
# index[1] is the line num where insertafter/inserbefore has been found
b_new_line + = b_linesep
index = [ - 1 , - 1 ]
m = None
# If no regexp was given and no line match is found anywhere in the file,
b_line = to_bytes ( line , errors = ' surrogate_or_strict ' )
# insert the line appropriately if using insertbefore or insertafter
for lineno , b_cur_line in enumerate ( b_lines ) :
if regexp is None and m is None :
if regexp is not None :
match_found = bre_m . search ( b_cur_line )
# Insert lines
else :
if insertafter and insertafter != ' EOF ' :
match_found = b_line == b_cur_line . rstrip ( b ( ' \r \n ' ) )
# Ensure there is a line separator after the found string
if match_found :
# at the end of the file.
index [ 0 ] = lineno
if b_lines and not b_lines [ - 1 ] [ - 1 : ] in ( b ( ' \n ' ) , b ( ' \r ' ) ) :
m = match_found
b_lines [ - 1 ] = b_lines [ - 1 ] + b_linesep
elif bre_ins is not None and bre_ins . search ( b_cur_line ) :
if insertafter :
# If the line to insert after is at the end of the file
# + 1 for the next line
# use the appropriate index value.
index [ 1 ] = lineno + 1
if len ( b_lines ) == index [ 1 ] :
if firstmatch :
if b_lines [ index [ 1 ] - 1 ] . rstrip ( b ( ' \r \n ' ) ) != b_line :
break
b_lines . append ( b_line + b_linesep )
if insertbefore :
# index[1] for the previous line
index [ 1 ] = lineno
if firstmatch :
break
msg = ' '
changed = False
b_linesep = to_bytes ( os . linesep , errors = ' surrogate_or_strict ' )
# Exact line or Regexp matched a line in the file
if index [ 0 ] != - 1 :
if backrefs :
b_new_line = m . expand ( b_line )
else :
# Don't do backref expansion if not asked.
b_new_line = b_line
if not b_new_line . endswith ( b_linesep ) :
b_new_line + = b_linesep
# If no regexp was given and no line match is found anywhere in the file,
# insert the line appropriately if using insertbefore or insertafter
if regexp is None and m is None :
# Insert lines
if insertafter and insertafter != ' EOF ' :
# Ensure there is a line separator after the found string
# at the end of the file.
if b_lines and not b_lines [ - 1 ] [ - 1 : ] in ( b ( ' \n ' ) , b ( ' \r ' ) ) :
b_lines [ - 1 ] = b_lines [ - 1 ] + b_linesep
# If the line to insert after is at the end of the file
# use the appropriate index value.
if len ( b_lines ) == index [ 1 ] :
if b_lines [ index [ 1 ] - 1 ] . rstrip ( b ( ' \r \n ' ) ) != b_line :
b_lines . append ( b_line + b_linesep )
msg = ' line added '
changed = True
elif b_lines [ index [ 1 ] ] . rstrip ( b ( ' \r \n ' ) ) != b_line :
b_lines . insert ( index [ 1 ] , b_line + b_linesep )
msg = ' line added '
msg = ' line added '
changed = True
changed = True
elif b_lines [ index [ 1 ] ] . rstrip ( b ( ' \r \n ' ) ) != b_line :
b_lines . insert ( index [ 1 ] , b_line + b_linesep )
elif insertbefore and insertbefore != ' BOF ' :
msg = ' line added '
# If the line to insert before is at the beginning of the file
changed = True
# use the appropriate index value.
if index [ 1 ] < = 0 :
elif insertbefore and insertbefore != ' BOF ' :
if b_lines [ index [ 1 ] ] . rstrip ( b ( ' \r \n ' ) ) != b_line :
# If the line to insert before is at the beginning of the file
b_lines . insert ( index [ 1 ] , b_line + b_linesep )
# use the appropriate index value.
msg = ' line added '
if index [ 1 ] < = 0 :
changed = True
if b_lines [ index [ 1 ] ] . rstrip ( b ( ' \r \n ' ) ) != b_line :
elif b_lines [ index [ 1 ] - 1 ] . rstrip ( b ( ' \r \n ' ) ) != b_line :
b_lines . insert ( index [ 1 ] , b_line + b_linesep )
b_lines . insert ( index [ 1 ] , b_line + b_linesep )
msg = ' line added '
msg = ' line added '
changed = True
changed = True
elif b_lines [ index [ 1 ] - 1 ] . rstrip ( b ( ' \r \n ' ) ) != b_line :
elif b_lines [ index [ 0 ] ] != b_new_line :
b_lines . insert ( index [ 1 ] , b_line + b_linesep )
b_lines [ index [ 0 ] ] = b_new_line
msg = ' line added '
msg = ' line replaced '
changed = True
changed = True
elif b_lines [ index [ 0 ] ] != b_new_line :
elif backrefs :
b_lines [ index [ 0 ] ] = b_new_line
# Do absolutely nothing, since it's not safe generating the line
msg = ' line replaced '
# without the regexp matching to populate the backrefs.
pass
# Add it to the beginning of the file
elif insertbefore == ' BOF ' or insertafter == ' BOF ' :
b_lines . insert ( 0 , b_line + b_linesep )
msg = ' line added '
changed = True
changed = True
# Add it to the end of the file if requested or
# if insertafter/insertbefore didn't match anything
# (so default behaviour is to add at the end)
elif insertafter == ' EOF ' or index [ 1 ] == - 1 :
elif backrefs :
# If the file is not empty then ensure there's a newline before the added line
# Do absolutely nothing, since it's not safe generating the line
if b_lines and not b_lines [ - 1 ] [ - 1 : ] in ( b ( ' \n ' ) , b ( ' \r ' ) ) :
# without the regexp matching to populate the backrefs.
b_lines . append ( b_linesep )
pass
# Add it to the beginning of the file
elif insertbefore == ' BOF ' or insertafter == ' BOF ' :
b_lines . insert ( 0 , b_line + b_linesep )
msg = ' line added '
changed = True
# Add it to the end of the file if requested or
# if insertafter/insertbefore didn't match anything
# (so default behaviour is to add at the end)
elif insertafter == ' EOF ' or index [ 1 ] == - 1 :
# If the file is not empty then ensure there's a newline before the added line
b_lines . append ( b_line + b_linesep )
if b_lines and not b_lines [ - 1 ] [ - 1 : ] in ( b ( ' \n ' ) , b ( ' \r ' ) ) :
msg = ' line added '
b_lines . append ( b_linesep )
changed = True
# insert matched, but not the regexp
b_lines . append ( b_line + b_linesep )
else :
msg = ' line added '
b_lines . insert ( index [ 1 ] , b_line + b_linesep )
changed = True
msg = ' line added '
# insert matched, but not the regexp
changed = True
else :
b_lines . insert ( index [ 1 ] , b_line + b_linesep )
msg = ' line added '
changed = True
if module . _diff :
if module . _diff :
diff [ ' after ' ] = to_native ( b ( ' ' ) . join ( b_lines ) )
diff [ ' after ' ] = to_native ( b ( ' ' ) . join ( b_lines ) )
backupdest = " "
backupdest = " "
if changed and not module . check_mode :
if changed and not module . check_mode :
if backup and os . path . exists ( b_dest ) :
if backup and os . path . exists ( b_dest ) :
backupdest = module . backup_local ( dest )
backupdest = module . backup_local ( dest )
write_changes ( module , b_lines , dest )
write_changes ( module , b_lines , dest )
if module . check_mode and not os . path . exists ( b_dest ) :
if module . check_mode and not os . path . exists ( b_dest ) :
module . exit_json ( changed = changed , msg = msg , backup = backupdest , diff = diff )
module . exit_json ( changed = changed , msg = msg , backup = backupdest , diff = diff )
@ -426,38 +441,39 @@ def absent(module, dest, regexp, line, backup):
' before_header ' : ' %s (content) ' % dest ,
' before_header ' : ' %s (content) ' % dest ,
' after_header ' : ' %s (content) ' % dest }
' after_header ' : ' %s (content) ' % dest }
with open ( b_dest , ' rb ' ) as f :
# NOTE: Avoid opening the same file in this context !
b_lines = f . readlines ( )
with open_locked ( dest , module . check_mode ) as fd :
b_lines = fd . readlines ( )
if module . _diff :
diff [ ' before ' ] = to_native ( b ( ' ' ) . join ( b_lines ) )
if regexp is not None :
if module . _diff :
bre_c = re . compile ( to_bytes ( regexp , errors = ' surrogate_or_strict ' ) )
diff [ ' before ' ] = to_native ( b ( ' ' ) . join ( b_lines ) )
found = [ ]
b_line = to_bytes ( line , errors = ' surrogate_or_strict ' )
def matcher ( b_cur_line ) :
if regexp is not None :
if regexp is not None :
match_found = bre_c . search ( b_cur_line )
bre_c = re . compile ( to_bytes ( regexp , errors = ' surrogate_or_strict ' ) )
else :
found = [ ]
match_found = b_line == b_cur_line . rstrip ( b ( ' \r \n ' ) )
if match_found :
b_line = to_bytes ( line , errors = ' surrogate_or_strict ' )
found . append ( b_cur_line )
return not match_found
def matcher ( b_cur_line ) :
if regexp is not None :
b_lines = [ l for l in b_lines if matcher ( l ) ]
match_found = bre_c . search ( b_cur_line )
changed = len ( found ) > 0
else :
match_found = b_line == b_cur_line . rstrip ( b ( ' \r \n ' ) )
if module . _diff :
if match_found :
diff [ ' after ' ] = to_native ( b ( ' ' ) . join ( b_lines ) )
found . append ( b_cur_line )
return not match_found
backupdest = " "
if changed and not module . check_mode :
b_lines = [ l for l in b_lines if matcher ( l ) ]
if backup :
changed = len ( found ) > 0
backupdest = module . backup_local ( dest )
write_changes ( module , b_lines , dest )
if module . _diff :
diff [ ' after ' ] = to_native ( b ( ' ' ) . join ( b_lines ) )
backupdest = " "
if changed and not module . check_mode :
if backup :
backupdest = module . backup_local ( dest )
write_changes ( module , b_lines , dest )
if changed :
if changed :
msg = " %s line(s) removed " % len ( found )
msg = " %s line(s) removed " % len ( found )