Merge branch 'bugfix_type__key_value' of https://github.com/dheule/cdist

remotes/origin/feature_files_export
Nico Schottelius 11 years ago
commit 9eec4e22fb
  1. 108
      cdist/conf/type/__key_value/explorer/state
  2. 102
      cdist/conf/type/__key_value/files/remote_script.sh
  3. 62
      cdist/conf/type/__key_value/gencode-remote
  4. 37
      cdist/conf/type/__key_value/man.text
  5. 1
      cdist/conf/type/__key_value/parameter/boolean
  6. 1
      cdist/conf/type/__key_value/parameter/default/comment
  7. 1
      cdist/conf/type/__key_value/parameter/optional

@ -1,6 +1,7 @@
#!/bin/sh #!/bin/sh
# #
# 2011 Steven Armstrong (steven-cdist at armstrong.cc) # 2011 Steven Armstrong (steven-cdist at armstrong.cc)
# 2014 Daniel Heule (hda at sfs.biz)
# #
# This file is part of cdist. # This file is part of cdist.
# #
@ -18,36 +19,85 @@
# along with cdist. If not, see <http://www.gnu.org/licenses/>. # along with cdist. If not, see <http://www.gnu.org/licenses/>.
# #
key="$(cat "$__object/parameter/key" 2>/dev/null \ export key="$(cat "$__object/parameter/key" 2>/dev/null \
|| echo "$__object_id")" || echo "$__object_id")"
state="$(cat "$__object/parameter/state" 2>/dev/null \ export state="$(cat "$__object/parameter/state")"
|| echo "present")"
file="$(cat "$__object/parameter/file")" file="$(cat "$__object/parameter/file")"
delimiter="$(cat "$__object/parameter/delimiter")"
value="$(cat "$__object/parameter/value" 2>/dev/null \ if [ ! -f "$file" ]; then
echo "nosuchfile"
exit
fi
export delimiter="$(cat "$__object/parameter/delimiter")"
export value="$(cat "$__object/parameter/value" 2>/dev/null \
|| echo "__CDIST_NOTSET__")" || echo "__CDIST_NOTSET__")"
if [ -f "$__object/parameter/exact_delimiter" ]; then
export exact_delimiter=1
else
export exact_delimiter=0
fi
case "$state" in awk -f - "$file" <<"AWK_EOF"
absent) BEGIN {
if grep -q -E "^$key$delimiter+" "$file"; then state=ENVIRON["state"]
# if the key exists, with whatever value, we will have to remove it key=ENVIRON["key"]
# so report it as present delimiter=ENVIRON["delimiter"]
echo present value=ENVIRON["value"]
else exact_delimiter=ENVIRON["exact_delimiter"]
# key does not exist found=0
echo absent }
fi # enter the main loop
;; {
present) i = index($0,key)
if grep -q -E "^$key$delimiter+$value$" "$file"; then if(i == 1) {
# key exists and value is same delval = substr($0,length(key)+1)
echo present delpos = index(delval,delimiter)
elif grep -q -E "^$key$delimiter+" "$file"; then if(delpos == 0) {
# key exists, but value is empty or different # in this case, the delimiter was not found
echo wrongvalue next
else }
# key does not exist if(delpos > 1) {
echo absent spaces = substr(delval,1,delpos-1)
fi sub(/[ \t]*/,"",spaces)
;; if( length(spaces) > 0 ) {
esac # if there are not only spaces between key and delimiter,
# continue since we we are on the wrong line
next
}
if( exact_delimiter == 1) {
# we have key and delimiter, but since additional spaces are not alowed
# return wrongformat
found=1
print "wrongformat"
exit
}
}
found=1
if(state == "absent") {
# on state absent, only the ocurance is relevant, so exit here
print "present"
exit
}
linevalue=substr(delval,delpos + length(delimiter))
if(exact_delimiter == 0){
#ok, now strip tabs and whitespaces at the beginning of the value
sub(/[ \t]*/,"",linevalue)
}
# Key with separator found
if(linevalue == value) {
# exact match found, so state is present
print "present"
}
else {
print "wrongvalue"
}
exit
}
}
END {
if(found == 0)
print "absent"
}
AWK_EOF

@ -0,0 +1,102 @@
export key="$(cat "$__object/parameter/key" 2>/dev/null \
|| echo "$__object_id")"
export state="$(cat "$__object/parameter/state")"
file="$(cat "$__object/parameter/file")"
export delimiter="$(cat "$__object/parameter/delimiter")"
export value="$(cat "$__object/parameter/value" 2>/dev/null \
|| echo "__CDIST_NOTSET__")"
if [ -f "$__object/parameter/exact_delimiter" ]; then
export exact_delimiter=1
else
export exact_delimiter=0
fi
tmpfile=$(mktemp "${file}.cdist.XXXXXXXXXX")
# preserve ownership and permissions by copying existing file over tmpfile
if [ -f "$file" ]; then
cp -p "$file" "$tmpfile"
else
touch "$file"
fi
awk -f - "$file" >"$tmpfile" <<"AWK_EOF"
BEGIN {
# import variables in a secure way ..
state=ENVIRON["state"]
key=ENVIRON["key"]
delimiter=ENVIRON["delimiter"]
value=ENVIRON["value"]
comment=ENVIRON["comment"]
exact_delimiter=ENVIRON["exact_delimiter"]
inserted=0
lastline=""
lastlinepopulated=0
line=key delimiter value
}
# enter the main loop
{
# I dont use regex, this is by design, so we can match against every value without special meanings of chars ...
i = index($0,key)
if(i == 1) {
delval = substr($0,length(key)+1)
delpos = index(delval,delimiter)
if(delpos > 1) {
spaces = substr(delval,1,delpos-1)
sub(/[ \t]*/,"",spaces)
if( length(spaces) > 0 ) {
# if there are not only spaces between key and delimiter,
# continue since we we are on the wrong line
if(lastlinepopulated == 1) {
print lastline
}
lastline=$0
lastlinepopulated=1
next
}
}
if(state == "absent") {
if(lastline == comment) {
# if comment is present, clear lastlinepopulated flag
lastlinepopulated=0
}
# if absent, simple yump over this line
next
}
else {
# if comment is present and not present in last line
if (lastlinepopulated == 1) {
print lastline
if( comment != "" && lastline != comment) {
print comment
}
lastlinepopulated=0
}
inserted=1
# state is present, so insert correct line here
print line
lastline=line
next
}
}
else {
if(lastlinepopulated == 1) {
print lastline
}
lastline=$0
lastlinepopulated=1
}
}
END {
if(lastlinepopulated == 1) {
print lastline
}
if(inserted == 0 && state == "present" ) {
if(comment != "" && lastline != comment){
print comment
}
print line
}
}
AWK_EOF
mv -f "$tmpfile" "$file"

@ -2,6 +2,7 @@
# #
# 2011 Steven Armstrong (steven-cdist at armstrong.cc) # 2011 Steven Armstrong (steven-cdist at armstrong.cc)
# 2012-2014 Nico Schottelius (nico-cdist at schottelius.org) # 2012-2014 Nico Schottelius (nico-cdist at schottelius.org)
# 2014 Daniel Heule (hda at sfs.biz)
# #
# This file is part of cdist. # This file is part of cdist.
# #
@ -19,55 +20,56 @@
# along with cdist. If not, see <http://www.gnu.org/licenses/>. # along with cdist. If not, see <http://www.gnu.org/licenses/>.
# #
key="$__object_id"
[ -f "$__object/parameter/key" ] && key="$(cat "$__object/parameter/key")"
state_should="$(cat "$__object/parameter/state")" state_should="$(cat "$__object/parameter/state")"
file="$(cat "$__object/parameter/file")"
delimiter="$(cat "$__object/parameter/delimiter")"
# escape double quotes, as that is what we use ourself below
value_escaped="$(cat "$__object/parameter/value" | sed -e "s/\([\"]\)/\\\\\1/g")"
state_is="$(cat "$__object/explorer/state")" state_is="$(cat "$__object/explorer/state")"
[ "$state_is" = "$state_should" ] && exit 0 if [ "$state_is" = "$state_should" ]; then
exit 0
fi
# here we check only if the states are valid,
# emmit messages and
# let awk do the work ...
case "$state_should" in case "$state_should" in
absent) absent)
# remove lines starting with key case "$state_is" in
cat << DONE absent|nosuchfile)
tmpfile=\$(mktemp ${file}.cdist.XXXXXXXXXX) # nothing to do
# preserve ownership and permissions by copying existing file over tmpfile ;;
cp -p "$file" "\$tmpfile" wrongformat|wrongvalue|present)
sed '/^$key\($delimiter\+\)/d' "$file" > "\$tmpfile" echo "remove" >> "$__messages_out"
mv -f "\$tmpfile" "$file" ;;
DONE *)
echo "remove" >> "$__messages_out" echo "Unknown explorer state: $state_is" >&2
exit 1
;;
esac
;; ;;
present) present)
case "$state_is" in case "$state_is" in
nosuchfile)
echo "create" >> "$__messages_out"
;;
absent) absent)
# add new key and value echo "insert" >> "$__messages_out"
printf 'echo "%s%s%s" >> "%s"' "$key" "$delimiter" "$value_escaped" "$file" ;;
echo "add" >> "$__messages_out" wrongformated|wrongvalue)
echo "change" >> "$__messages_out"
;; ;;
wrongvalue) present)
# change exisiting value # nothing to do
cat << DONE
tmpfile=\$(mktemp ${file}.cdist.XXXXXXXXXX)
# preserve ownership and permissions by copying existing file over tmpfile
cp -p "$file" "\$tmpfile"
sed "s|^$key\($delimiter\+\).*|$key\\1$value_escaped|" "$file" > "\$tmpfile"
mv -f "\$tmpfile" "$file"
DONE
echo "changevalue" >> "$__messages_out"
;; ;;
*) *)
echo "Unknown explorer state: $state_is" >&2 echo "Unknown explorer state: $state_is" >&2
exit 1 exit 1
;;
esac esac
;; ;;
*) *)
echo "Unknown state: $state_should" >&2 echo "Unknown state: $state_should" >&2
exit 1 exit 1
;;
esac esac
cat "$__type/files/remote_script.sh"

@ -25,21 +25,36 @@ delimiter::
OPTIONAL PARAMETERS OPTIONAL PARAMETERS
------------------- -------------------
state:: state::
present or absent, defaults to present. If present, sets the key to value, present or absent, defaults to present. If present, sets the key to value,
if absent, removes the key from the file. if absent, removes the key from the file.
key:: key::
The key to change. Defaults to object_id. The key to change. Defaults to object_id.
value:: value::
The value for the key. Optional if state=absent, required otherwise. The value for the key. Optional if state=absent, required otherwise.
comment::
If supplied, the value will be inserted before the line with the key,
but only if the key or value must be changed.
You need to ensure yourself that the line is prefixed with the correct
comment sign. (for example # or ; or wathever ..)
BOOLEAN PARAMETERS
------------------
exact_delimiter::
If supplied, treat additional whitespaces between key, delimiter and value
as wrong value.
MESSAGES MESSAGES
-------- --------
create:: remove::
Removed existing key and value
insert::
Added key and value Added key and value
change:: change::
Changed value of existing key Changed value of existing key
remove:: create::
Removed existing key and value A new line was inserted in a new file
EXAMPLES EXAMPLES
@ -55,13 +70,19 @@ __key_value my-fancy-id --file /etc/login.defs --key SYS_UID_MAX --value 666 \
# Enable packet forwarding # Enable packet forwarding
__key_value net.ipv4.ip_forward --file /etc/sysctl.conf --value 1 \ __key_value net.ipv4.ip_forward --file /etc/sysctl.conf --value 1 \
--delimiter '=' --delimiter ' = ' --comment '# my linux kernel should act as a router'
# Remove existing key/value # Remove existing key/value
__key_value LEGACY_KEY --file /etc/somefile --state absent --delimiter '=' __key_value LEGACY_KEY --file /etc/somefile --state absent --delimiter '='
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
MORE INFORMATION
----------------
This type try to handle as many values as possible, so it doesn't use regexes.
So you need to exactly specify the key and delimiter. Delimiter can be of any lenght.
SEE ALSO SEE ALSO
-------- --------
- cdist-type(7) - cdist-type(7)

@ -1,3 +1,4 @@
key key
value value
state state
comment

Loading…
Cancel
Save