module-concat/files/concatfragments.sh
Reid Vandewiele 81d5ee80f3 Remove the gnu parameter from concat
Previously, the concatfragments.sh script was would default to using
GNU-specific flags for find, sort, and xargs. This necessitated
explicit passing of a "gnu = false" parameter to the concat define in
order to successfully run the script without GNU-specific flags when
working with systems that do not by default include GNU versions of the
utilities (solaris, for example).

This commit modifies the concatfragments script such that GNU versions
of the utilities are not needed at all. It does this while preserving
the original use case for the GNU flags, which was to allow special
characters (like spaces) in the filenames, which it accomplished by
using GNU flags to separate fields using null characters instead of
newlines.

In order to preserve backwards-compatibility with existing puppet
installations that make use of the "gnu = false" parameter, the
parameter list for the concat define has not been changed. Rather, the
gnu parameter is now deprecated and ignored.
2012-04-17 12:02:38 -07:00

129 lines
3.6 KiB
Bash
Executable file

#!/bin/sh
# Script to concat files to a config file.
#
# Given a directory like this:
# /path/to/conf.d
# |-- fragments
# | |-- 00_named.conf
# | |-- 10_domain.net
# | `-- zz_footer
#
# The script supports a test option that will build the concat file to a temp location and
# use /usr/bin/cmp to verify if it should be run or not. This would result in the concat happening
# twice on each run but gives you the option to have an unless option in your execs to inhibit rebuilds.
#
# Without the test option and the unless combo your services that depend on the final file would end up
# restarting on each run, or in other manifest models some changes might get missed.
#
# OPTIONS:
# -o The file to create from the sources
# -d The directory where the fragments are kept
# -t Test to find out if a build is needed, basically concats the files to a temp
# location and compare with what's in the final location, return codes are designed
# for use with unless on an exec resource
# -w Add a shell style comment at the top of the created file to warn users that it
# is generated by puppet
# -f Enables the creation of empty output files when no fragments are found
# -n Sort the output numerically rather than the default alpha sort
#
# the command:
#
# concatfragments.sh -o /path/to/conffile.cfg -d /path/to/conf.d
#
# creates /path/to/conf.d/fragments.concat and copies the resulting
# file to /path/to/conffile.cfg. The files will be sorted alphabetically
# pass the -n switch to sort numerically.
#
# The script does error checking on the various dirs and files to make
# sure things don't fail.
OUTFILE=""
WORKDIR=""
TEST=""
FORCE=""
WARN=""
SORTARG=""
PATH=/sbin:/usr/sbin:/bin:/usr/bin
## Well, if there's ever a bad way to do things, Nexenta has it.
## http://nexenta.org/projects/site/wiki/Personalities
unset SUN_PERSONALITY
while getopts "o:s:d:tnw:f" options; do
case $options in
o ) OUTFILE=$OPTARG;;
d ) WORKDIR=$OPTARG;;
n ) SORTARG="-n";;
w ) WARNMSG="$OPTARG";;
f ) FORCE="true";;
t ) TEST="true";;
* ) echo "Specify output file with -o and fragments directory with -d"
exit 1;;
esac
done
# do we have -o?
if [ x${OUTFILE} = "x" ]; then
echo "Please specify an output file with -o"
exit 1
fi
# do we have -d?
if [ x${WORKDIR} = "x" ]; then
echo "Please fragments directory with -d"
exit 1
fi
# can we write to -o?
if [ -f ${OUTFILE} ]; then
if [ ! -w ${OUTFILE} ]; then
echo "Cannot write to ${OUTFILE}"
exit 1
fi
else
if [ ! -w `dirname ${OUTFILE}` ]; then
echo "Cannot write to `dirname ${OUTFILE}` to create ${OUTFILE}"
exit 1
fi
fi
# do we have a fragments subdir inside the work dir?
if [ ! -d "${WORKDIR}/fragments" ] && [ ! -x "${WORKDIR}/fragments" ]; then
echo "Cannot access the fragments directory"
exit 1
fi
# are there actually any fragments?
if [ ! "$(ls -A ${WORKDIR}/fragments)" ]; then
if [ x${FORCE} = "x" ]; then
echo "The fragments directory is empty, cowardly refusing to make empty config files"
exit 1
fi
fi
cd ${WORKDIR}
if [ x${WARNMSG} = "x" ]; then
: > "fragments.concat"
else
printf '%s\n' "$WARNMSG" > "fragments.concat"
fi
# find all the files in the fragments directory, sort them numerically and concat to fragments.concat in the working dir
find fragments/ -type f -follow | sort ${SORTARG} | while read fragfile; do
cat "$fragfile" >> "fragments.concat"
done
if [ x${TEST} = "x" ]; then
# This is a real run, copy the file to outfile
cp fragments.concat ${OUTFILE}
RETVAL=$?
else
# Just compare the result to outfile to help the exec decide
cmp ${OUTFILE} fragments.concat
RETVAL=$?
fi
exit $RETVAL