Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
ansible
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
ansible
Commits
36bcfb5d
Commit
36bcfb5d
authored
Mar 29, 2013
by
Michael DeHaan
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'lineinfile' of
git://github.com/Tinche/ansible
into lif
parents
f9890c99
ca581840
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
71 additions
and
33 deletions
+71
-33
library/lineinfile
+71
-33
test/TestRunner.py
+0
-0
No files found.
library/lineinfile
View file @
36bcfb5d
...
@@ -25,7 +25,8 @@ DOCUMENTATION = """
...
@@ -25,7 +25,8 @@ DOCUMENTATION = """
---
---
module: lineinfile
module: lineinfile
author: Daniel Hokka Zakrisson
author: Daniel Hokka Zakrisson
short_description: Ensure a particular line is in a file
short_description: Ensure a particular line is in a file, or replace an
existing line using a back-referenced regular expression.
description:
description:
- This module will search a file for a line, and ensure that it is present or absent.
- This module will search a file for a line, and ensure that it is present or absent.
- This is primarily useful when you want to change a single line in a
- This is primarily useful when you want to change a single line in a
...
@@ -36,12 +37,13 @@ options:
...
@@ -36,12 +37,13 @@ options:
required: true
required: true
aliases: [ name, destfile ]
aliases: [ name, destfile ]
description:
description:
- The file to modify
- The file to modify
.
regexp:
regexp:
required: true
required: true
description:
description:
- The regular expression to look for in the file. For C(state=present),
- The regular expression to look for in every line of the file. For
the pattern to replace. For C(state=absent), the pattern of the line
C(state=present), the pattern to replace if found; only the last line
found will be replaced. For C(state=absent), the pattern of the line
to remove. Uses Python regular expressions; see
to remove. Uses Python regular expressions; see
U(http://docs.python.org/2/library/re.html).
U(http://docs.python.org/2/library/re.html).
state:
state:
...
@@ -55,7 +57,22 @@ options:
...
@@ -55,7 +57,22 @@ options:
required: false
required: false
description:
description:
- Required for C(state=present). The line to insert/replace into the
- Required for C(state=present). The line to insert/replace into the
file. May contain backreferences.
file. If backrefs is set, may contain backreferences that will get
expanded with the regexp capture groups if the regexp matches. The
backreferences should be double escaped (see examples).
backrefs:
required: false
default: "no"
choices: [ "yes", "no" ]
version_added: 1.1
description:
- Used with C(state=present). If set, line can contain backreferences
(both positional and named) that will get populated if the regexp
matches. This flag changes the operation of the module slightly;
insertbefore) and insertafter will be ignored, and if the regexp
doesn't match anywhere in the file, the file will be left unchanged.
If the regexp does match, the last matching line will be replaced by
the expanded line parameter.
insertafter:
insertafter:
required: false
required: false
default: EOF
default: EOF
...
@@ -63,6 +80,7 @@ options:
...
@@ -63,6 +80,7 @@ options:
- Used with C(state=present). If specified, the line will be inserted
- Used with C(state=present). If specified, the line will be inserted
after the specified regular expression. A special value is
after the specified regular expression. A special value is
available; C(EOF) for inserting the line at the end of the file.
available; C(EOF) for inserting the line at the end of the file.
May not be used with backrefs.
choices: [ 'EOF', '*regex*' ]
choices: [ 'EOF', '*regex*' ]
insertbefore:
insertbefore:
required: false
required: false
...
@@ -70,8 +88,8 @@ options:
...
@@ -70,8 +88,8 @@ options:
description:
description:
- Used with C(state=present). If specified, the line will be inserted
- Used with C(state=present). If specified, the line will be inserted
before the specified regular expression. A value is available;
before the specified regular expression. A value is available;
C(BOF) for inserting the line at the beginning of the
C(BOF) for inserting the line at the beginning of the file.
file
.
May not be used with backrefs
.
choices: [ 'BOF', '*regex*' ]
choices: [ 'BOF', '*regex*' ]
create:
create:
required: false
required: false
...
@@ -94,7 +112,7 @@ options:
...
@@ -94,7 +112,7 @@ options:
required: false
required: false
"""
"""
EXAMPLES
=
"""
EXAMPLES
=
r
"""
lineinfile: dest=/etc/selinux/config regexp=^SELINUX= line=SELINUX=disabled
lineinfile: dest=/etc/selinux/config regexp=^SELINUX= line=SELINUX=disabled
lineinfile: dest=/etc/sudoers state=absent regexp="^
%
wheel"
lineinfile: dest=/etc/sudoers state=absent regexp="^
%
wheel"
...
@@ -105,9 +123,9 @@ EXAMPLES = """
...
@@ -105,9 +123,9 @@ EXAMPLES = """
lineinfile: dest=/etc/services regexp="^# port for http" insertbefore="^www.*80/tcp" line="# port for http by default"
lineinfile: dest=/etc/services regexp="^# port for http" insertbefore="^www.*80/tcp" line="# port for http by default"
lineinfile:
\\\"
dest=/etc/sudoers state=present regexp='^
%
wheel' line ='
%
wheel ALL=(ALL) NOPASSWD: ALL'
\\\"
lineinfile:
dest=/etc/sudoers state=present regexp='^
%
wheel' line ='
%
wheel ALL=(ALL) NOPASSWD: ALL'
lineinfile
dest=/tmp/grub.conf state=present regexp='^(splashimage=.*)$' line="#
\\
1"
lineinfile
: dest=/opt/jboss-as/bin/standalone.conf state=present regexp='^(.*)Xms(\d+)m(.*)$' line='\\1Xms${xms}m\\3'
"""
"""
...
@@ -121,9 +139,11 @@ def check_file_attrs(module, changed, message):
...
@@ -121,9 +139,11 @@ def check_file_attrs(module, changed, message):
changed
=
True
changed
=
True
message
+=
"ownership, perms or SE linux context changed"
message
+=
"ownership, perms or SE linux context changed"
return
[
message
,
changed
]
return
message
,
changed
def
present
(
module
,
dest
,
regexp
,
line
,
insertafter
,
insertbefore
,
create
,
backup
):
def
present
(
module
,
dest
,
regexp
,
line
,
insertafter
,
insertbefore
,
create
,
backup
,
backrefs
):
if
os
.
path
.
isdir
(
dest
):
if
os
.
path
.
isdir
(
dest
):
module
.
fail_json
(
rc
=
256
,
msg
=
'Destination
%
s is a directory !'
%
dest
)
module
.
fail_json
(
rc
=
256
,
msg
=
'Destination
%
s is a directory !'
%
dest
)
...
@@ -143,9 +163,9 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create, backu
...
@@ -143,9 +163,9 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create, backu
mre
=
re
.
compile
(
regexp
)
mre
=
re
.
compile
(
regexp
)
if
insertafter
is
not
None
and
insertafter
not
in
(
'BOF'
,
'EOF'
):
if
insertafter
not
in
(
None
,
'BOF'
,
'EOF'
):
insre
=
re
.
compile
(
insertafter
)
insre
=
re
.
compile
(
insertafter
)
elif
insertbefore
is
not
None
and
insertbefore
not
in
(
'BOF'
):
elif
insertbefore
not
in
(
None
,
'BOF'
):
insre
=
re
.
compile
(
insertbefore
)
insre
=
re
.
compile
(
insertbefore
)
else
:
else
:
insre
=
None
insre
=
None
...
@@ -154,12 +174,12 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create, backu
...
@@ -154,12 +174,12 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create, backu
# index[1] is the line num where insertafter/inserbefore has been found
# index[1] is the line num where insertafter/inserbefore has been found
index
=
[
-
1
,
-
1
]
index
=
[
-
1
,
-
1
]
m
=
None
m
=
None
for
lineno
in
range
(
0
,
len
(
lines
)
):
for
lineno
,
cur_line
in
enumerate
(
lines
):
match_found
=
mre
.
search
(
lines
[
lineno
]
)
match_found
=
mre
.
search
(
cur_line
)
if
match_found
:
if
match_found
:
index
[
0
]
=
lineno
index
[
0
]
=
lineno
m
=
match_found
m
=
match_found
elif
insre
is
not
None
and
insre
.
search
(
lines
[
lineno
]
):
elif
insre
is
not
None
and
insre
.
search
(
cur_line
):
if
insertafter
:
if
insertafter
:
# + 1 for the next line
# + 1 for the next line
index
[
1
]
=
lineno
+
1
index
[
1
]
=
lineno
+
1
...
@@ -167,15 +187,24 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create, backu
...
@@ -167,15 +187,24 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create, backu
# + 1 for the previous line
# + 1 for the previous line
index
[
1
]
=
lineno
index
[
1
]
=
lineno
# Regexp matched a line in the file
if
index
[
0
]
!=
-
1
:
if
lines
[
index
[
0
]]
==
m
.
expand
(
line
)
+
os
.
linesep
:
msg
=
''
msg
=
''
changed
=
False
changed
=
False
# Regexp matched a line in the file
if
index
[
0
]
!=
-
1
:
if
backrefs
:
new_line
=
m
.
expand
(
line
)
else
:
else
:
lines
[
index
[
0
]]
=
m
.
expand
(
line
)
+
os
.
linesep
# Don't do backref expansion if not asked.
new_line
=
line
if
lines
[
index
[
0
]]
!=
new_line
+
os
.
linesep
:
lines
[
index
[
0
]]
=
new_line
+
os
.
linesep
msg
=
'line replaced'
msg
=
'line replaced'
changed
=
True
changed
=
True
elif
backrefs
:
# Do absolutely nothing, since it's not safe generating the line
# without the regexp matching to populate the backrefs.
pass
# Add it to the beginning of the file
# Add it to the beginning of the file
elif
insertbefore
==
'BOF'
or
insertafter
==
'BOF'
:
elif
insertbefore
==
'BOF'
or
insertafter
==
'BOF'
:
lines
.
insert
(
0
,
line
+
os
.
linesep
)
lines
.
insert
(
0
,
line
+
os
.
linesep
)
...
@@ -188,11 +217,10 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create, backu
...
@@ -188,11 +217,10 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create, backu
lines
.
append
(
line
+
os
.
linesep
)
lines
.
append
(
line
+
os
.
linesep
)
msg
=
'line added'
msg
=
'line added'
changed
=
True
changed
=
True
# Do nothing if
regexp
didn't match
# Do nothing if
insert*
didn't match
elif
index
[
1
]
==
-
1
:
elif
index
[
1
]
==
-
1
:
msg
=
''
pass
changed
=
False
# insert* matched, but not the regexp
# insertafter/insertbefore= matched
else
:
else
:
lines
.
insert
(
index
[
1
],
line
+
os
.
linesep
)
lines
.
insert
(
index
[
1
],
line
+
os
.
linesep
)
msg
=
'line added'
msg
=
'line added'
...
@@ -205,9 +233,10 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create, backu
...
@@ -205,9 +233,10 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create, backu
f
.
writelines
(
lines
)
f
.
writelines
(
lines
)
f
.
close
()
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
)
def
absent
(
module
,
dest
,
regexp
,
backup
):
def
absent
(
module
,
dest
,
regexp
,
backup
):
if
os
.
path
.
isdir
(
dest
):
if
os
.
path
.
isdir
(
dest
):
...
@@ -242,36 +271,46 @@ def absent(module, dest, regexp, backup):
...
@@ -242,36 +271,46 @@ def absent(module, dest, regexp, backup):
if
changed
:
if
changed
:
msg
=
"
%
s line(s) removed"
%
len
(
found
)
msg
=
"
%
s line(s) removed"
%
len
(
found
)
[
msg
,
changed
]
=
check_file_attrs
(
module
,
changed
,
msg
)
msg
,
changed
=
check_file_attrs
(
module
,
changed
,
msg
)
module
.
exit_json
(
changed
=
changed
,
found
=
len
(
found
),
msg
=
msg
)
module
.
exit_json
(
changed
=
changed
,
found
=
len
(
found
),
msg
=
msg
)
def
main
():
def
main
():
module
=
AnsibleModule
(
module
=
AnsibleModule
(
argument_spec
=
dict
(
argument_spec
=
dict
(
dest
=
dict
(
required
=
True
,
aliases
=
[
'name'
,
'destfile'
]),
dest
=
dict
(
required
=
True
,
aliases
=
[
'name'
,
'destfile'
]),
state
=
dict
(
default
=
'present'
,
choices
=
[
'absent'
,
'present'
]),
state
=
dict
(
default
=
'present'
,
choices
=
[
'absent'
,
'present'
]),
regexp
=
dict
(
required
=
True
),
regexp
=
dict
(
required
=
True
),
line
=
dict
(
aliases
=
[
'value'
]),
line
=
dict
(
aliases
=
[
'value'
]),
insertafter
=
dict
(
default
=
None
),
insertafter
=
dict
(
default
=
None
),
insertbefore
=
dict
(
default
=
None
),
insertbefore
=
dict
(
default
=
None
),
backrefs
=
dict
(
default
=
False
,
type
=
'bool'
),
create
=
dict
(
default
=
False
,
type
=
'bool'
),
create
=
dict
(
default
=
False
,
type
=
'bool'
),
backup
=
dict
(
default
=
False
,
type
=
'bool'
),
backup
=
dict
(
default
=
False
,
type
=
'bool'
),
),
),
mutually_exclusive
=
[[
'insertbefore'
,
'insertafter'
]],
mutually_exclusive
=
[[
'insertbefore'
,
'insertafter'
]],
add_file_common_args
=
True
,
add_file_common_args
=
True
,
supports_check_mode
=
True
supports_check_mode
=
True
)
)
params
=
module
.
params
params
=
module
.
params
create
=
module
.
params
[
'create'
]
create
=
module
.
params
[
'create'
]
backup
=
module
.
params
[
'backup'
]
backup
=
module
.
params
[
'backup'
]
backrefs
=
module
.
params
[
'backrefs'
]
dest
=
os
.
path
.
expanduser
(
params
[
'dest'
])
dest
=
os
.
path
.
expanduser
(
params
[
'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'
)
# Deal with the insertafter default value manually, to avoid errors
# because of the mutually_exclusive mechanism.
ins_bef
,
ins_aft
=
params
[
'insertbefore'
],
params
[
'insertafter'
]
if
ins_bef
is
None
and
ins_aft
is
None
:
ins_aft
=
'EOF'
present
(
module
,
dest
,
params
[
'regexp'
],
params
[
'line'
],
present
(
module
,
dest
,
params
[
'regexp'
],
params
[
'line'
],
params
[
'insertafter'
],
params
[
'insertbefore'
],
create
,
backup
)
ins_aft
,
ins_bef
,
create
,
backup
,
backrefs
)
else
:
else
:
absent
(
module
,
dest
,
params
[
'regexp'
],
backup
)
absent
(
module
,
dest
,
params
[
'regexp'
],
backup
)
...
@@ -279,4 +318,3 @@ def main():
...
@@ -279,4 +318,3 @@ def main():
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
main
()
main
()
test/TestRunner.py
View file @
36bcfb5d
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment