concatfragments.sh 3.9 KB

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