diff --git a/cdist/conf/type/__block/explorer/block b/cdist/conf/type/__block/explorer/block new file mode 100755 index 00000000..6c35bc46 --- /dev/null +++ b/cdist/conf/type/__block/explorer/block @@ -0,0 +1,21 @@ +#!/bin/sh +# 2013 Steven Armstrong (steven-cdist at armstrong.cc) + +file="$(cat "$__object/parameter/file" 2>/dev/null || echo "/$__object_id")" + +# file does not exist, nothing we could do +[ -f "$file" ] || exit 0 + +prefix=$(cat "$__object/parameter/prefix" 2>/dev/null || echo "#cdist:__block/$__object_id") +suffix=$(cat "$__object/parameter/suffix" 2>/dev/null || echo "#/cdist:__block/$__object_id") +awk -v prefix="$prefix" -v suffix="$suffix" '{ + if (index($0,prefix)) { + triggered=1 + } + if (triggered) { + if (index($0,suffix)) { + triggered=0 + } + print + } +}' "$file" diff --git a/cdist/conf/type/__ssh_authorized_keys/gencode-remote b/cdist/conf/type/__block/gencode-remote similarity index 61% rename from cdist/conf/type/__ssh_authorized_keys/gencode-remote rename to cdist/conf/type/__block/gencode-remote index 7fcb59c6..0a5eea18 100755 --- a/cdist/conf/type/__ssh_authorized_keys/gencode-remote +++ b/cdist/conf/type/__block/gencode-remote @@ -1,6 +1,6 @@ #!/bin/sh # -# 2012-2013 Steven Armstrong (steven-cdist at armstrong.cc) +# 2013 Steven Armstrong (steven-cdist at armstrong.cc) # # This file is part of cdist. # @@ -18,38 +18,34 @@ # along with cdist. If not, see . # -owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")" -if [ -f "$__object/parameter/file" ]; then - file="$(cat "$__object/parameter/file")" -else - home="$(cut -d':' -f 6 "$__object/explorer/passwd")" - file="$home/.ssh/authorized_keys" -fi +file="$(cat "$__object/parameter/file" 2>/dev/null || echo "/$__object_id")" +state_should=$(cat "$__object/parameter/state") +prefix=$(cat "$__object/parameter/prefix" 2>/dev/null || echo "#cdist:__block/$__object_id") +suffix=$(cat "$__object/parameter/suffix" 2>/dev/null || echo "#/cdist:__block/$__object_id") -entry="$__object/files/entry" -if [ ! -s "$__object/explorer/entry" ]; then +block="$__object/files/block" +if [ ! -s "$__object/explorer/block" ]; then state_is='absent' else - state_is=$(diff -q "$entry" "$__object/explorer/entry" >/dev/null \ + state_is=$(diff -q "$block" "$__object/explorer/block" >/dev/null \ && echo present \ || echo changed ) fi -state_should="$(cat "$__object/parameter/state" 2>/dev/null || echo present)" +state_should="$(cat "$__object/parameter/state")" if [ "$state_should" = "$state_is" ]; then # Nothing to do, move along exit 0 fi -remove_entry() { - # NOTE: keep variables in sync in manifest/explorer/gencode-* - prefix="#cdist:$__object_name" - suffix="#/cdist:$__object_name" +remove_block() { cat << DONE tmpfile=\$(mktemp ${file}.cdist.XXXXXXXXXX) -# preserve ownership and permissions by copying existing file over tmpfile -cp -p "$file" "\$tmpfile" +# preserve ownership and permissions of existing file +if [ -f "$file" ]; then + cp -p "$file" "\$tmpfile" +fi awk -v prefix="$prefix" -v suffix="$suffix" ' { if (index(\$0,prefix)) { @@ -70,15 +66,19 @@ DONE case "$state_should" in present) if [ "$state_is" = "changed" ]; then - remove_entry + echo update >> "$__messages_out" + remove_block + else + echo add >> "$__messages_out" fi cat << DONE cat >> "$file" << ${__type##*/}_DONE -$(cat "$entry") +$(cat "$block") ${__type##*/}_DONE DONE ;; absent) - remove_entry + echo remove >> "$__messages_out" + remove_block ;; esac diff --git a/cdist/conf/type/__block/man.text b/cdist/conf/type/__block/man.text new file mode 100644 index 00000000..2312d293 --- /dev/null +++ b/cdist/conf/type/__block/man.text @@ -0,0 +1,82 @@ +cdist-type__block(7) +==================== +Steven Armstrong + + +NAME +---- +cdist-type__block - Manage blocks of text in files + + +DESCRIPTION +----------- +Manage a block of text in an existing file. +The block is identified using the prefix and suffix parameters. +Everything between prefix and suffix is considered to be a managed block +of text. + + +REQUIRED PARAMETERS +------------------- +text:: + the text to manage. + If text is '-' (dash), take what was written to stdin as the text. + + +OPTIONAL PARAMETERS +------------------- +file:: + the file in which to manage the text block. + Defaults to object_id. + +prefix:: + the prefix to add before the text. + Defaults to #cdist:__block/$__object_id + +suffix:: + the prefix to add after the text. + Defaults to #/cdist:__block/$__object_id + +state:: + 'present' or 'absent', defaults to 'present' + + +MESSAGES +-------- +add:: + block was added +update:: + block was updated/changed +remove:: + block was removed + + +EXAMPLES +-------- + +-------------------------------------------------------------------------------- +# text from argument +__block /path/to/file \ + --prefix '#start' \ + --suffix '#end' \ + --text 'some\nblock of\ntext' + +# text from stdin +__block some-id \ + --file /path/to/file \ + --text - << DONE +here some block +of text +DONE +-------------------------------------------------------------------------------- + + +SEE ALSO +-------- +- cdist-type(7) + + +COPYING +------- +Copyright \(C) 2013 Steven Armstrong. Free use of this software is +granted under the terms of the GNU General Public License version 3 (GPLv3). diff --git a/cdist/conf/type/__block/manifest b/cdist/conf/type/__block/manifest new file mode 100755 index 00000000..1fc9ec79 --- /dev/null +++ b/cdist/conf/type/__block/manifest @@ -0,0 +1,36 @@ +#!/bin/sh +# +# 2013-2014 Steven Armstrong (steven-cdist at armstrong.cc) +# +# This file is part of cdist. +# +# cdist is free software: 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. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + + +file="$(cat "$__object/parameter/file" 2>/dev/null || echo "/$__object_id")" +prefix=$(cat "$__object/parameter/prefix" 2>/dev/null || echo "#cdist:__block/$__object_id") +suffix=$(cat "$__object/parameter/suffix" 2>/dev/null || echo "#/cdist:__block/$__object_id") +text=$(cat "$__object/parameter/text") + +mkdir "$__object/files" +# Generate text block for inclusion in file +block="$__object/files/block" +echo "$prefix" > "$block" +if [ "$text" = "-" ]; then + cat "$__object/stdin" >> "$block" +else + cat "$text" >> "$block" +fi +echo "$suffix" >> "$block" diff --git a/cdist/conf/type/__block/parameter/default/state b/cdist/conf/type/__block/parameter/default/state new file mode 100644 index 00000000..e7f6134f --- /dev/null +++ b/cdist/conf/type/__block/parameter/default/state @@ -0,0 +1 @@ +present diff --git a/cdist/conf/type/__block/parameter/optional b/cdist/conf/type/__block/parameter/optional new file mode 100644 index 00000000..fa3abebf --- /dev/null +++ b/cdist/conf/type/__block/parameter/optional @@ -0,0 +1,4 @@ +file +prefix +state +suffix diff --git a/cdist/conf/type/__block/parameter/required b/cdist/conf/type/__block/parameter/required new file mode 100644 index 00000000..8e27be7d --- /dev/null +++ b/cdist/conf/type/__block/parameter/required @@ -0,0 +1 @@ +text diff --git a/cdist/conf/type/__cron/gencode-remote b/cdist/conf/type/__cron/gencode-remote index 712eb1a1..77a63b9b 100755 --- a/cdist/conf/type/__cron/gencode-remote +++ b/cdist/conf/type/__cron/gencode-remote @@ -78,8 +78,9 @@ DONE case "$state_should" in present) + # if we insert new entry, filter also all entrys out with the same id echo "(" - echo "crontab -u $user -l 2>/dev/null | grep -v -E \"$filter\" 2>/dev/null || true" + echo "crontab -u $user -l 2>/dev/null | grep -v -E \"$filter\" | grep -v \"# $name\\$\" 2>/dev/null || true" echo "echo '$entry'" echo ") | crontab -u $user -" ;; diff --git a/cdist/conf/type/__group/man.text b/cdist/conf/type/__group/man.text index c57ae337..def0232f 100644 --- a/cdist/conf/type/__group/man.text +++ b/cdist/conf/type/__group/man.text @@ -26,6 +26,18 @@ password:: see above +MESSAGES +-------- +mod:: + group is modified +add:: + New group added +change :: + Changed group property from current_value to new_value +set :: + set property to new value, property was not set bevore + + EXAMPLES -------- diff --git a/cdist/conf/type/__mount/explorer/mounted b/cdist/conf/type/__mount/explorer/mounted new file mode 100755 index 00000000..81f8e454 --- /dev/null +++ b/cdist/conf/type/__mount/explorer/mounted @@ -0,0 +1,27 @@ +#!/bin/sh +# +# 2014 Steven Armstrong (steven-cdist at armstrong.cc) +# +# This file is part of cdist. +# +# cdist is free software: 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. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + +path="$(cat "$__object/parameter/path" 2>/dev/null || echo "/$__object_id")" + +if mountpoint -q "$path"; then + echo yes +else + echo no +fi diff --git a/cdist/conf/type/__mount/gencode-remote b/cdist/conf/type/__mount/gencode-remote new file mode 100755 index 00000000..2626f3de --- /dev/null +++ b/cdist/conf/type/__mount/gencode-remote @@ -0,0 +1,51 @@ +#!/bin/sh +# +# 2014 Steven Armstrong (steven-cdist at armstrong.cc) +# +# This file is part of cdist. +# +# cdist is free software: 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. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + +path="$(cat "$__object/parameter/path" 2>/dev/null || echo "/$__object_id")" +state_should="$(cat "$__object/parameter/state")" +state_is="$(grep -q -x yes "$__object/explorer/mounted" && echo present || echo absent)" + +if [ "$state_should" = "$state_is" ]; then + # nothing to do + exit 0 +fi + +case "$state_should" in + present) + if [ -f "$__object/parameter/nofstab" ]; then + # mount manually + printf 'mount' + if [ -f "$__object/parameter/type" ]; then + printf ' -t %s' "$(cat "$__object/parameter/type")" + fi + if [ -f "$__object/parameter/options" ]; then + printf ' -o %s' "$(cat "$__object/parameter/options")" + fi + printf ' %s' "$(cat "$__object/parameter/device")" + printf " %s\n" "$path" + else + # mount using existing fstab entry + printf 'mount "%s"\n' "$path" + fi + ;; + absent) + printf 'umount "%s"\n' "$path" + ;; +esac diff --git a/cdist/conf/type/__mount/man.text b/cdist/conf/type/__mount/man.text new file mode 100644 index 00000000..7299bdf3 --- /dev/null +++ b/cdist/conf/type/__mount/man.text @@ -0,0 +1,84 @@ +cdist-type__mount(7) +==================== +Steven Armstrong + + +NAME +---- +cdist-type__mount - manage filesystem mounts + + +DESCRIPTION +----------- +Manage filesystem mounts either via /etc/fstab or manually. + + +REQUIRED PARAMETERS +------------------- +None. + + +OPTIONAL PARAMETERS +------------------- +device:: + device to mount at path, defaults to 'none'. see mount(8) + +dump:: + value for the dump field in fstab. see fstab(5) + defaults to 0. + + This parameter is ignored, if the nofstab parameter is given. + +options:: + comma separated string of options, see mount(8) + +pass:: + value for the pass field in fstab. see fstab(5) + defaults to 0. + + This parameter is ignored, if the nofstab parameter is given. + +path:: + mount point where to mount the device, see mount(8). + Defaults to __object_id + +state:: + either present or absent. Defaults to present. + +type:: + vfstype, see mount(8) + + +BOOLEAN PARAMETERS +------------------ +nofstab:: + do not manage an entry in /etc/fstab + + +EXAMPLES +-------- + +-------------------------------------------------------------------------------- +__mount /some/dir \ + --device /dev/sdc3 \ + --type xfs \ + --options "defaults,ro" + --dump 0 \ + --pass 1 + +__mount /var/lib/one \ + --device mfsmount \ + --type fuse \ + --options "mfsmaster=mfsmaster.domain.tld,mfssubfolder=/one,nonempty,_netdev" +-------------------------------------------------------------------------------- + + +SEE ALSO +-------- +- cdist-type(7) + + +COPYING +------- +Copyright \(C) 2014 Steven Armstrong. Free use of this software is +granted under the terms of the GNU General Public License version 3 (GPLv3). diff --git a/cdist/conf/type/__mount/manifest b/cdist/conf/type/__mount/manifest new file mode 100755 index 00000000..8a1fa234 --- /dev/null +++ b/cdist/conf/type/__mount/manifest @@ -0,0 +1,42 @@ +#!/bin/sh +# +# 2014 Steven Armstrong (steven-cdist at armstrong.cc) +# +# This file is part of cdist. +# +# cdist is free software: 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. +# +# cdist is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cdist. If not, see . +# + +path="$(cat "$__object/parameter/path" 2>/dev/null || echo "/$__object_id")" +state="$(cat "$__object/parameter/state")" + +if [ ! -f "$__object/parameter/nofstab" ]; then + # Generate an entry for /etc/fstab + ( +printf "%s" "$(cat "$__object/parameter/device")" +printf " %s" "$path" +type="$(cat "$__object/parameter/type" 2>/dev/null || echo "auto")" +printf " %s" "$type" +options="$(cat "$__object/parameter/options" 2>/dev/null || echo "defaults")" +printf " %s" "$options" +printf " %s" "$(cat "$__object/parameter/dump")" +printf " %s\n" "$(cat "$__object/parameter/pass")" +) | \ +__block "$__object_name" \ + --file "/etc/fstab" \ + --prefix "#cdist:$__object_name" \ + --suffix "#/cdist:$__object_name" \ + --state "$state" \ + --text - +fi diff --git a/cdist/conf/type/__mount/parameter/boolean b/cdist/conf/type/__mount/parameter/boolean new file mode 100644 index 00000000..ac6f41a8 --- /dev/null +++ b/cdist/conf/type/__mount/parameter/boolean @@ -0,0 +1 @@ +nofstab diff --git a/cdist/conf/type/__mount/parameter/default/device b/cdist/conf/type/__mount/parameter/default/device new file mode 100644 index 00000000..621e94f0 --- /dev/null +++ b/cdist/conf/type/__mount/parameter/default/device @@ -0,0 +1 @@ +none diff --git a/cdist/conf/type/__mount/parameter/default/dump b/cdist/conf/type/__mount/parameter/default/dump new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/cdist/conf/type/__mount/parameter/default/dump @@ -0,0 +1 @@ +0 diff --git a/cdist/conf/type/__mount/parameter/default/pass b/cdist/conf/type/__mount/parameter/default/pass new file mode 100644 index 00000000..573541ac --- /dev/null +++ b/cdist/conf/type/__mount/parameter/default/pass @@ -0,0 +1 @@ +0 diff --git a/cdist/conf/type/__mount/parameter/default/state b/cdist/conf/type/__mount/parameter/default/state new file mode 100644 index 00000000..e7f6134f --- /dev/null +++ b/cdist/conf/type/__mount/parameter/default/state @@ -0,0 +1 @@ +present diff --git a/cdist/conf/type/__mount/parameter/optional b/cdist/conf/type/__mount/parameter/optional new file mode 100644 index 00000000..29d3e5ef --- /dev/null +++ b/cdist/conf/type/__mount/parameter/optional @@ -0,0 +1,7 @@ +device +dump +options +pass +path +state +type diff --git a/cdist/conf/type/__ssh_authorized_keys/explorer/entry b/cdist/conf/type/__ssh_authorized_keys/explorer/entry deleted file mode 100755 index 9992d32d..00000000 --- a/cdist/conf/type/__ssh_authorized_keys/explorer/entry +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/sh -# -# 2012 Steven Armstrong (steven-cdist at armstrong.cc) -# -# This file is part of cdist. -# -# cdist is free software: 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. -# -# cdist is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with cdist. If not, see . -# - -owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")" -if [ -f "$__object/parameter/file" ]; then - file="$(cat "$__object/parameter/file")" -else - home="$("$__type_explorer/passwd" | cut -d':' -f 6)" - file="$home/.ssh/authorized_keys" -fi - -# no authorized_keys file, nothing we could do -[ -f "$file" ] || exit 0 - -# NOTE: keep variables in sync in manifest/explorer/gencode-* -prefix="#cdist:$__object_name" -suffix="#/cdist:$__object_name" -awk -v prefix="$prefix" -v suffix="$suffix" '{ - if (index($0,prefix)) { - triggered=1 - } - if (triggered) { - if (index($0,suffix)) { - triggered=0 - } - print - } -}' "$file" diff --git a/cdist/conf/type/__ssh_authorized_keys/manifest b/cdist/conf/type/__ssh_authorized_keys/manifest index 47cdf746..5a9cfbb3 100755 --- a/cdist/conf/type/__ssh_authorized_keys/manifest +++ b/cdist/conf/type/__ssh_authorized_keys/manifest @@ -19,7 +19,7 @@ # owner="$(cat "$__object/parameter/owner" 2>/dev/null || echo "$__object_id")" -state="$(cat "$__object/parameter/state" 2>/dev/null || echo "present")" +state="$(cat "$__object/parameter/state" 2>/dev/null)" if [ -f "$__object/parameter/file" ]; then file="$(cat "$__object/parameter/file")" else @@ -39,7 +39,7 @@ if [ ! -f "$__object/parameter/noparent" -o ! -f "$__object/parameter/nofile" ]; fi if [ ! -f "$__object/parameter/noparent" ]; then - # Ensure that the directory in which the authorized_keys shall be exists and + # Ensure that the directory in which the authorized_keys shall be exists and # has the right permissions. ssh_directory="${file%/*}" __directory "$ssh_directory" --state present --parents \ @@ -56,19 +56,16 @@ if [ ! -f "$__object/parameter/noparent" -o ! -f "$__object/parameter/nofile" ]; fi fi -# NOTE: keep variables in sync in manifest/explorer/gencode-* -prefix="#cdist:$__object_name" -suffix="#/cdist:$__object_name" - -mkdir "$__object/files" - # Generate entry for inclusion in authorized_keys file -entry="$__object/files/entry" -echo "$prefix" > "$entry" +( if [ -f "$__object/parameter/comment" ]; then - echo "# $(cat "$__object/parameter/comment")" >> "$entry" + echo "# $(cat "$__object/parameter/comment")" fi -cat "$__object/parameter/key" >> "$entry" -# ensure we have a newline after keys -echo >> "$entry" -echo "$suffix" >> "$entry" +cat "$__object/parameter/key" +) | \ +__block "$__object_name" \ + --file "$file" \ + --prefix "#cdist:$__object_name" \ + --suffix "#/cdist:$__object_name" \ + --state "$state" \ + --text - diff --git a/cdist/conf/type/__ssh_authorized_keys/parameter/default/state b/cdist/conf/type/__ssh_authorized_keys/parameter/default/state new file mode 100644 index 00000000..e7f6134f --- /dev/null +++ b/cdist/conf/type/__ssh_authorized_keys/parameter/default/state @@ -0,0 +1 @@ +present diff --git a/cdist/conf/type/__user/man.text b/cdist/conf/type/__user/man.text index 47e63d3d..be70ec12 100644 --- a/cdist/conf/type/__user/man.text +++ b/cdist/conf/type/__user/man.text @@ -44,6 +44,15 @@ create-home:: remove-home:: see userdel(8), apply only on user delete + +MESSAGES +-------- +mod:: + User is modified +add:: + New user added + + EXAMPLES -------- diff --git a/cdist/emulator.py b/cdist/emulator.py index b70ef956..63d3bbbc 100644 --- a/cdist/emulator.py +++ b/cdist/emulator.py @@ -192,9 +192,11 @@ class Emulator(object): try: cdist_object = self.cdist_object.object_from_name(requirement) except core.cdist_type.NoSuchTypeError as e: - self.log.error("%s requires object %s, but type %s does not exist (definded at %s)" % (self.cdist_object.name, requirement, e.name, self.object_source)) + self.log.error("%s requires object %s, but type %s does not exist. Defined at %s" % (self.cdist_object.name, requirement, e.name, self.object_source)) + raise + except core.cdist_object.MissingObjectIdError as e: + self.log.error("%s requires object %s without object id. Defined at %s" % (self.cdist_object.name, requirement, self.object_source)) raise - self.log.debug("Recording requirement: " + requirement) diff --git a/docs/changelog b/docs/changelog index c0cb9d65..a3d5c4fd 100644 --- a/docs/changelog +++ b/docs/changelog @@ -4,7 +4,18 @@ Changelog * Changes are always commented with their author in (braces) * Exception: No braces means author == Nico Schottelius -3.0.1: +3.0.3: + * Core: Enhance error message when requirement is missing object id + +3.0.2: 2014-01-19 + * Documentation: Document all messages sent by types (Daniel Heule) + * New Type: __block (Steven Armstrong) + * New Type: __mount (Steven Armstrong) + * Type __cron: Replace existing entry when changing it (Daniel Heule) + * Type __ssh_authorized_keys: Use new type __block (Steven Armstrong) + + +3.0.1: 2014-01-14 * Core: Copy only files, not directories (Steven Armstrong) * Core: Allow hostnames to start with / * Type __line: Remove unecessary backslash escape diff --git a/setup.py b/setup.py index 25fc4820..32d734b8 100644 --- a/setup.py +++ b/setup.py @@ -5,6 +5,11 @@ import os def data_finder(data_dir): entries = [] for name in os.listdir(data_dir): + + # Skip .gitignore files + if name == ".gitignore": + continue + entry = os.path.join(data_dir, name) if os.path.isdir(entry): entries.extend(data_finder(entry))