init.pp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. # == Define: concat
  2. #
  3. # Sets up so that you can use fragments to build a final config file,
  4. #
  5. # === Options:
  6. #
  7. # [*ensure*]
  8. # Present/Absent
  9. # [*path*]
  10. # The path to the final file. Use this in case you want to differentiate
  11. # between the name of a resource and the file path. Note: Use the name you
  12. # provided in the target of your fragments.
  13. # [*owner*]
  14. # Who will own the file
  15. # [*group*]
  16. # Who will own the file
  17. # [*mode*]
  18. # The mode of the final file
  19. # [*force*]
  20. # Enables creating empty files if no fragments are present
  21. # [*warn*]
  22. # Adds a normal shell style comment top of the file indicating that it is
  23. # built by puppet
  24. # [*force*]
  25. # [*backup*]
  26. # Controls the filebucketing behavior of the final file and see File type
  27. # reference for its use. Defaults to 'puppet'
  28. # [*replace*]
  29. # Whether to replace a file that already exists on the local system
  30. # [*order*]
  31. # [*ensure_newline*]
  32. # [*gnu*]
  33. # Deprecated
  34. #
  35. # === Actions:
  36. # * Creates fragment directories if it didn't exist already
  37. # * Executes the concatfragments.rb script to build the final file, this
  38. # script will create directory/fragments.concat. Execution happens only
  39. # when:
  40. # * The directory changes
  41. # * fragments.concat != final destination, this means rebuilds will happen
  42. # whenever someone changes or deletes the final file. Checking is done
  43. # using /usr/bin/cmp.
  44. # * The Exec gets notified by something else - like the concat::fragment
  45. # define
  46. # * Copies the file over to the final destination using a file resource
  47. #
  48. # === Aliases:
  49. #
  50. # * The exec can notified using Exec["concat_/path/to/file"] or
  51. # Exec["concat_/path/to/directory"]
  52. # * The final file can be referenced as File["/path/to/file"] or
  53. # File["concat_/path/to/file"]
  54. #
  55. define concat(
  56. $ensure = 'present',
  57. $path = $name,
  58. $owner = undef,
  59. $group = undef,
  60. $mode = '0644',
  61. $warn = false,
  62. $force = false,
  63. $backup = 'puppet',
  64. $replace = true,
  65. $order = 'alpha',
  66. $ensure_newline = false,
  67. $validate_cmd = undef,
  68. $gnu = undef
  69. ) {
  70. validate_re($ensure, '^present$|^absent$')
  71. validate_absolute_path($path)
  72. validate_string($owner)
  73. validate_string($group)
  74. validate_string($mode)
  75. if ! (is_string($warn) or $warn == true or $warn == false) {
  76. fail('$warn is not a string or boolean')
  77. }
  78. validate_bool($force)
  79. if ! concat_is_bool($backup) and ! is_string($backup) {
  80. fail('$backup must be string or bool!')
  81. }
  82. validate_bool($replace)
  83. validate_re($order, '^alpha$|^numeric$')
  84. validate_bool($ensure_newline)
  85. if $validate_cmd and ! is_string($validate_cmd) {
  86. fail('$validate_cmd must be a string')
  87. }
  88. if $gnu {
  89. warning('The $gnu parameter to concat is deprecated and has no effect')
  90. }
  91. include concat::setup
  92. $safe_name = regsubst($name, '[/:]', '_', 'G')
  93. $concatdir = $concat::setup::concatdir
  94. $fragdir = "${concatdir}/${safe_name}"
  95. $concat_name = 'fragments.concat.out'
  96. $script_command = $concat::setup::script_command
  97. $default_warn_message = '# This file is managed by Puppet. DO NOT EDIT.'
  98. $bool_warn_message = 'Using stringified boolean values (\'true\', \'yes\', \'on\', \'false\', \'no\', \'off\') to represent boolean true/false as the $warn parameter to concat is deprecated and will be treated as the warning message in a future release'
  99. case $warn {
  100. true: {
  101. $warn_message = $default_warn_message
  102. }
  103. 'true', 'yes', 'on': {
  104. warning($bool_warn_message)
  105. $warn_message = $default_warn_message
  106. }
  107. false: {
  108. $warn_message = ''
  109. }
  110. 'false', 'no', 'off': {
  111. warning($bool_warn_message)
  112. $warn_message = ''
  113. }
  114. default: {
  115. $warn_message = $warn
  116. }
  117. }
  118. $warnmsg_escaped = regsubst($warn_message, '\'', '\'\\\'\'', 'G')
  119. $warnflag = $warnmsg_escaped ? {
  120. '' => '',
  121. default => "-w '${warnmsg_escaped}'"
  122. }
  123. $forceflag = $force ? {
  124. true => '-f',
  125. false => '',
  126. }
  127. $orderflag = $order ? {
  128. 'numeric' => '-n',
  129. 'alpha' => '',
  130. }
  131. $newlineflag = $ensure_newline ? {
  132. true => '-l',
  133. false => '',
  134. }
  135. File {
  136. backup => false,
  137. }
  138. # reset poisoned Exec defaults
  139. Exec {
  140. user => undef,
  141. group => undef,
  142. }
  143. if $ensure == 'present' {
  144. file { $fragdir:
  145. ensure => directory,
  146. mode => '0750',
  147. }
  148. file { "${fragdir}/fragments":
  149. ensure => directory,
  150. mode => '0750',
  151. force => true,
  152. ignore => ['.svn', '.git', '.gitignore'],
  153. notify => Exec["concat_${name}"],
  154. purge => true,
  155. recurse => true,
  156. }
  157. file { "${fragdir}/fragments.concat":
  158. ensure => present,
  159. mode => '0640',
  160. }
  161. file { "${fragdir}/${concat_name}":
  162. ensure => present,
  163. mode => '0640',
  164. }
  165. file { $name:
  166. ensure => present,
  167. owner => $owner,
  168. group => $group,
  169. mode => $mode,
  170. replace => $replace,
  171. path => $path,
  172. alias => "concat_${name}",
  173. source => "${fragdir}/${concat_name}",
  174. backup => $backup,
  175. }
  176. # Only newer versions of puppet 3.x support the validate_cmd parameter
  177. if $validate_cmd {
  178. File[$name] {
  179. validate_cmd => $validate_cmd,
  180. }
  181. }
  182. # remove extra whitespace from string interpolation to make testing easier
  183. $command = strip(regsubst("${script_command} -o \"${fragdir}/${concat_name}\" -d \"${fragdir}\" ${warnflag} ${forceflag} ${orderflag} ${newlineflag}", '\s+', ' ', 'G'))
  184. # make sure ruby is in the path for PE
  185. if $::is_pe {
  186. if $::kernel == 'windows' {
  187. $command_path = "${::env_windows_installdir}/bin:${::path}"
  188. } else {
  189. $command_path = "/opt/puppet/bin:${::path}"
  190. }
  191. } else {
  192. $command_path = $::path
  193. }
  194. # if puppet is running as root, this exec should also run as root to allow
  195. # the concatfragments.rb script to potentially be installed in path that
  196. # may not be accessible by a target non-root owner.
  197. exec { "concat_${name}":
  198. alias => "concat_${fragdir}",
  199. command => $command,
  200. notify => File[$name],
  201. subscribe => File[$fragdir],
  202. unless => "${command} -t",
  203. path => $command_path,
  204. require => [
  205. File[$fragdir],
  206. File["${fragdir}/fragments"],
  207. File["${fragdir}/fragments.concat"],
  208. ],
  209. }
  210. } else {
  211. file { [
  212. $fragdir,
  213. "${fragdir}/fragments",
  214. "${fragdir}/fragments.concat",
  215. "${fragdir}/${concat_name}"
  216. ]:
  217. ensure => absent,
  218. force => true,
  219. }
  220. file { $path:
  221. ensure => absent,
  222. backup => $backup,
  223. }
  224. $absent_exec_command = $::kernel ? {
  225. 'windows' => 'cmd.exe /c exit 0',
  226. default => 'true',
  227. }
  228. $absent_exec_path = $::kernel ? {
  229. 'windows' => $::path,
  230. default => '/bin:/usr/bin',
  231. }
  232. # Need to have an unless here for idempotency.
  233. exec { "concat_${name}":
  234. alias => "concat_${fragdir}",
  235. command => $absent_exec_command,
  236. unless => $absent_exec_command,
  237. path => $absent_exec_path,
  238. }
  239. }
  240. }
  241. # vim:sw=2:ts=2:expandtab:textwidth=79