9b0be4131283507118547dc3fdb9013bea71deb6
[mirror/dsa-puppet.git] / modules / concat / files / concatfragments.sh
1 #!/bin/sh
2
3 # Script to concat files to a config file.
4 #
5 # Given a directory like this:
6 # /path/to/conf.d
7 # |-- fragments
8 # |   |-- 00_named.conf
9 # |   |-- 10_domain.net
10 # |   `-- zz_footer
11 #
12 # The script supports a test option that will build the concat file to a temp location and 
13 # use /usr/bin/cmp to verify if it should be run or not.  This would result in the concat happening
14 # twice on each run but gives you the option to have an unless option in your execs to inhibit rebuilds.
15
16 # Without the test option and the unless combo your services that depend on the final file would end up 
17 # restarting on each run, or in other manifest models some changes might get missed.
18 #
19 # OPTIONS:
20 #  -o   The file to create from the sources
21 #  -d   The directory where the fragments are kept
22 #  -t   Test to find out if a build is needed, basically concats the files to a temp
23 #       location and compare with what's in the final location, return codes are designed
24 #       for use with unless on an exec resource
25 #  -w   Add a shell style comment at the top of the created file to warn users that it 
26 #       is generated by puppet
27 #  -f   Enables the creation of empty output files when no fragments are found
28 #  -n   Sort the output numerically rather than the default alpha sort
29 #
30 # the command: 
31 #
32 #   concatfragments.sh -o /path/to/conffile.cfg -d /path/to/conf.d
33 #
34 # creates /path/to/conf.d/fragments.concat and copies the resulting 
35 # file to /path/to/conffile.cfg.  The files will be sorted alphabetically
36 # pass the -n switch to sort numerically.
37
38 # The script does error checking on the various dirs and files to make
39 # sure things don't fail.
40
41 OUTFILE=""
42 WORKDIR=""
43 TEST=""
44 FORCE=""
45 WARN=""
46 SORTARG=""
47
48 PATH=/sbin:/usr/sbin:/bin:/usr/bin
49
50 ## Well, if there's ever a bad way to do things, Nexenta has it.
51 ## http://nexenta.org/projects/site/wiki/Personalities
52 unset SUN_PERSONALITY
53
54 while getopts "o:s:d:tnw:f" options; do
55         case $options in
56                 o ) OUTFILE=$OPTARG;;
57                 d ) WORKDIR=$OPTARG;;
58                 n ) SORTARG="-n";;
59                 w ) WARNMSG="$OPTARG";;
60                 f ) FORCE="true";;
61                 t ) TEST="true";;
62                 * ) echo "Specify output file with -o and fragments directory with -d"
63                     exit 1;;
64         esac
65 done
66
67 # do we have -o?
68 if [ x${OUTFILE} = "x" ]; then
69         echo "Please specify an output file with -o"
70         exit 1
71 fi
72
73 # do we have -d?
74 if [ x${WORKDIR} = "x" ]; then
75         echo "Please fragments directory with -d"
76         exit 1
77 fi
78
79 # can we write to -o?
80 if [ -f ${OUTFILE} ]; then
81         if [ ! -w ${OUTFILE} ]; then
82                 echo "Cannot write to ${OUTFILE}"
83                 exit 1
84         fi
85 else
86         if [ ! -w `dirname ${OUTFILE}` ]; then
87                 echo "Cannot write to `dirname ${OUTFILE}` to create ${OUTFILE}"
88                 exit 1
89         fi
90 fi
91
92 # do we have a fragments subdir inside the work dir?
93 if [ ! -d "${WORKDIR}/fragments" ]  && [ ! -x "${WORKDIR}/fragments" ]; then
94         echo "Cannot access the fragments directory"
95         exit 1
96 fi
97
98 # are there actually any fragments?
99 if [ ! "$(ls -A ${WORKDIR}/fragments)" ]; then
100         if [ x${FORCE} = "x" ]; then
101                 echo "The fragments directory is empty, cowardly refusing to make empty config files"
102                 exit 1
103         fi
104 fi
105
106 cd ${WORKDIR}
107
108 if [ x${WARNMSG} = "x" ]; then
109         : > "fragments.concat"
110 else
111         printf '%s\n' "$WARNMSG" > "fragments.concat"
112 fi
113
114 # find all the files in the fragments directory, sort them numerically and concat to fragments.concat in the working dir
115 find fragments/ -type f -follow | sort ${SORTARG} | while read -r fragfile; do
116         cat "$fragfile" >> "fragments.concat"
117 done
118
119 if [ x${TEST} = "x" ]; then
120         # This is a real run, copy the file to outfile
121         cp fragments.concat ${OUTFILE}
122         RETVAL=$?
123 else
124         # Just compare the result to outfile to help the exec decide
125         cmp ${OUTFILE} fragments.concat
126         RETVAL=$?
127 fi
128
129 exit $RETVAL