summaryrefslogtreecommitdiff
path: root/files/concatfragments.sh
blob: c9397975325eebba82c1b489932f1e6ec1a403e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/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