rewrite __line type for --before and --after support

Signed-off-by: Steven Armstrong <steven@icarus.ethz.ch>
remotes/origin/shellcheck
Steven Armstrong 7 years ago
parent e6b6925908
commit a3968f8313
  1. 72
      cdist/conf/type/__line/explorer/state
  2. 144
      cdist/conf/type/__line/gencode-remote
  3. 92
      cdist/conf/type/__line/man.rst
  4. 1
      cdist/conf/type/__line/parameter/default/state
  5. 6
      cdist/conf/type/__line/parameter/optional

@ -1,6 +1,6 @@
#!/bin/sh
#!/bin/sh -e
#
# 2012-2013 Nico Schottelius (nico-cdist at schottelius.org)
# 2018 Steven Armstrong (steven-cdist at armstrong.cc)
#
# This file is part of cdist.
#
@ -17,26 +17,64 @@
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
file="/$__object_id"
[ -f "$__object/parameter/file" ] && file=$(cat "$__object/parameter/file")
if [ -f "$__object/parameter/before" ]; then
position="before"
elif [ -f "$__object/parameter/after" ]; then
position="after"
fi
if [ -f "$__object/parameter/regex" ]; then
regex=$(cat "$__object/parameter/regex")
greparg=""
needle="regex"
else
if [ ! -f "$__object/parameter/line" ]; then
echo "Parameter line and regex missing - cannot explore" >&2
exit 1
fi
regex="$(cat "$__object/parameter/line")"
greparg="-F -x"
needle="line"
fi
# Allow missing file - thus 2>/dev/null
if grep -q $greparg -- "$regex" "$file" 2>/dev/null; then
echo present
if [ -f "$__object/parameter/file" ]; then
file="$(cat "$__object/parameter/file")"
else
echo absent
file="/$__object_id"
fi
awk -v position="$position" -v needle="$needle" '
BEGIN {
getline anchor < (ENVIRON["__object"] "/parameter/" position)
getline pattern < (ENVIRON["__object"] "/parameter/" needle)
state = "absent"
}
{
if (position == "after") {
if (match($0, anchor)) {
getline
if (match($0, pattern)) {
state = "present"
}
else {
state = "wrongposition"
}
exit 0
}
}
else if (position == "before") {
if (match($0, pattern)) {
getline
if (match($0, anchor)) {
state = "present"
}
else {
state = "wrongposition"
}
exit 0
}
}
else {
if (match($0, pattern)) {
state = "present"
exit 0
}
}
}
END {
print state
}
' "$file"

@ -1,7 +1,6 @@
#!/bin/sh -e
#
# 2012 Nico Schottelius (nico-cdist at schottelius.org)
# 2014 Steven Armstrong (steven-cdist at armstrong.cc)
# 2018 Steven Armstrong (steven-cdist at armstrong.cc)
#
# This file is part of cdist.
#
@ -18,76 +17,101 @@
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
#
file="/$__object_id"
regex=""
state_should="present"
[ -f "$__object/parameter/file" ] && file=$(cat "$__object/parameter/file")
[ -f "$__object/parameter/regex" ] && regex=$(cat "$__object/parameter/regex")
[ -f "$__object/parameter/state" ] && state_should=$(cat "$__object/parameter/state")
[ -f "$__object/parameter/line" ] && line=$(cat "$__object/parameter/line")
if [ -f "$__object/parameter/before" -a -f "$__object/parameter/after" ]; then
echo "Use either --before OR --after but not both." >&2
exit 1
fi
state_should="$(cat "$__object/parameter/state")"
state_is="$(cat "$__object/explorer/state")"
[ "$state_should" = "$state_is" ] && exit 0
case "$state_should" in
present)
if [ ! "$line" ]; then
echo "Required parameter \"line\" is missing" >&2
exit 1
fi
#echo "echo \"$line\" >> $file"
#line_sanitised=$(cat "$__object/parameter/line" | sed 's/"/\"/g')
# Idea: replace ' in the string:
# '"'"'
# |------> ': end the string
# |-|---> "'": create ' in the output string
# |--> ': continue the string
#
# Replace all \ so \t and other combinations are not interpreted
#
if [ "$state_should" = "$state_is" ]; then
# nothing to do
exit 0
fi
# line_sanitised=$(cat "$__object/parameter/line" | sed -e "s/'/'\"'\"'/g" -e 's/\\/\\\\/g')
# The one above does not work:
# --line "PS1='[\t] \[\033[1m\]\h\[\033[0m\]:\w\\$ '"
# becomes
# PS1='[\\t] \\[\\033[1m\\]\\h\\[\\033[0m\\]:\\w\\$ '
if [ -f "$__object/parameter/before" ]; then
position="before"
elif [ -f "$__object/parameter/after" ]; then
position="after"
else
# By default we append to the end of the file.
position="end"
fi
# Only replace ' with '"'"' and keep \ as they are
line_sanitised=$(cat "$__object/parameter/line" | sed -e "s/'/'\"'\"'/g")
printf '%s' "printf '%s\n' '$line_sanitised' >> $file"
echo "added" >> "$__messages_out"
if [ -f "$__object/parameter/regex" ]; then
needle="regex"
else
needle="line"
fi
;;
absent)
if [ "$regex" -a "$line" ]; then
echo "Mutally exclusive parameters regex and line given for state absent" >&2
exit 1
fi
if [ -f "$__object/parameter/file" ]; then
file="$(cat "$__object/parameter/file")"
else
file="/$__object_id"
fi
greparg=""
if [ "$line" ]; then
regex="$line"
greparg="-F -x"
fi
add=0
remove=0
case "$state_should" in
present)
if [ "$state_is" = "wrongposition" ]; then
echo updated >> "$__messages_out"
remove=1
else
echo added >> "$__messages_out"
fi
add=1
;;
absent)
echo removed >> "$__messages_out"
remove=1
;;
esac
cat << eof
cat << DONE
tmpfile=\$(mktemp ${file}.cdist.XXXXXXXXXX)
# preserve ownership and permissions of existing file
if [ -f "$file" ]; then
cp -p "$file" "\$tmpfile"
fi
grep -v $greparg "$regex" '$file' > \$tmpfile || true
awk -v position="$position" -v needle="$needle" -v remove=$remove -v add=$add '
BEGIN {
line_file = ENVIRON["__object"] "/parameter/line"
getline line < line_file
# Need to close line file as it may be re-read as pattern below.
close(line_file)
getline pattern < (ENVIRON["__object"] "/parameter/" needle)
getline anchor < (ENVIRON["__object"] "/parameter/" position)
}
{
if (remove) {
if (match(\$0, pattern)) {
# skip over this line -> remove it
next
}
}
if (add) {
if (anchor && match(\$0, anchor)) {
if (position == "before") {
print line
print
} else if (position == "after") {
print
print line
}
next
}
}
print
}
END {
if (add && position == "end") {
print line
}
}
' "$file" > "\$tmpfile"
mv -f "\$tmpfile" "$file"
eof
echo "removed" >> "$__messages_out"
;;
*)
echo "Unknown state: $state_should" >&2
exit 1
;;
esac
DONE

@ -13,72 +13,102 @@ This cdist type allows you to add lines and remove lines from files.
REQUIRED PARAMETERS
-------------------
None.
OPTIONAL PARAMETERS
-------------------
state
'present' or 'absent', defaults to 'present'
after
Insert the given line after this pattern.
before
Insert the given line before this pattern.
file
If supplied, use this as the destination file.
Otherwise the object_id is used.
line
Specifies the line which should be absent or present
Specifies the line which should be absent or present.
Must be present, if state is present.
Must not be combined with regex, if state is absent.
Must be present, if state is 'present'.
Ignored if regex is given and state is 'absent'.
regex
If state is present, search for this pattern and add
given line, if the given regular expression does not match.
If state is 'present', search for this pattern and if it matches add
the given line.
If state is 'absent', ensure all lines matching the regular expression
are absent.
The regular expression is interpreted by awk's match function.
In case of absent, ensure all lines matching the
regular expression are absent.
state
'present' or 'absent', defaults to 'present'
The regular expression is interpreted by grep.
Must not be combined with line, if state is absent.
file
If supplied, use this as the destination file.
Otherwise the object_id is used.
BOOLEAN PARAMETERS
------------------
None.
MESSAGES
--------
added
The line was added.
The line was added.
updated
The line or its position was changed.
removed
The line was removed.
The line was removed.
EXAMPLES
--------
.. code-block:: sh
# Manage the DAEMONS line in rc.conf
__line daemons --file /etc/rc.conf --line 'DAEMONS=(hwclock !network sshd crond postfix)'
# Manage a hosts entry for www.example.com.
__line /etc/hosts \
--line '127.0.0.2 www.example.com'
# Manage another hosts entry for test.example.com.
__line hosts:test.example.com \
--file /etc/hosts \
--line '127.0.0.3 test.example.com'
# Remove the line starting with TIMEZONE from the /etc/rc.conf file.
__line legacy_timezone \
--file /etc/rc.conf \
--regex 'TIMEZONE=.*' \
--state absent
# Ensure the home mount is present in /etc/fstab - explicitly make it present
__line home-fstab \
--file /etc/fstab \
--line 'filer.fs:/vol/home /home nfs defaults 0 0' \
--state present
# Insert a line before another one.
__line password-auth-local:classify \
--file /etc/pam.d/password-auth-local \
--line '-session required pam_exec.so debug log=/tmp/classify.log /usr/local/libexec/classify' \
--before '^session[[:space:]]+include[[:space:]]+password-auth-ac$'
# Removes the line specifiend in "include_www" from the file "lighttpd.conf"
__line legacy_timezone --file /etc/rc.conf --regex 'TIMEZONE=.*' --state absent
# Insert a line after another one.
__line password-auth-local:classify \
--file /etc/pam.d/password-auth-local \
--line '-session required pam_exec.so debug log=/tmp/classify.log /usr/local/libexec/classify' \
--after '^session[[:space:]]+include[[:space:]]+password-auth-ac$'
SEE ALSO
--------
:strong:`grep`\ (1)
:strong:`cdist-type`\ (7)
AUTHORS
-------
Nico Schottelius <nico-cdist--@--schottelius.org>
Steven Armstrong <steven-cdist--@--armstrong.cc>
COPYING
-------
Copyright \(C) 2012-2013 Nico Schottelius. You can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
Copyright \(C) 2018 Steven Armstrong. Free use of this software is
granted under the terms of the GNU General Public License version 3 (GPLv3).

@ -1,4 +1,6 @@
state
regex
after
before
file
line
regex
state

Loading…
Cancel
Save