1 |
# A system to construct files using fragments from other files or templates. |
2 |
# |
3 |
# This requires at least puppet 0.25 to work correctly as we use some |
4 |
# enhancements in recursive directory management and regular expressions |
5 |
# to do the work here. |
6 |
# |
7 |
# USAGE: |
8 |
# The basic use case is as below: |
9 |
# |
10 |
# concat{"/etc/named.conf": |
11 |
# notify => Service["named"] |
12 |
# } |
13 |
# |
14 |
# concat::fragment{"foo.com_config": |
15 |
# target => "/etc/named.conf", |
16 |
# order => 10, |
17 |
# content => template("named_conf_zone.erb") |
18 |
# } |
19 |
# |
20 |
# # add a fragment not managed by puppet so local users |
21 |
# # can add content to managed file |
22 |
# concat::fragment{"foo.com_user_config": |
23 |
# target => "/etc/named.conf", |
24 |
# order => 12, |
25 |
# ensure => "/etc/named.conf.local" |
26 |
# } |
27 |
# |
28 |
# This will use the template named_conf_zone.erb to build a single |
29 |
# bit of config up and put it into the fragments dir. The file |
30 |
# will have an number prefix of 10, you can use the order option |
31 |
# to control that and thus control the order the final file gets built in. |
32 |
# |
33 |
# SETUP: |
34 |
# The class concat::setup defines a variable $concatdir - you should set this |
35 |
# to a directory where you want all the temporary files and fragments to be |
36 |
# stored. Avoid placing this somewhere like /tmp since you should never |
37 |
# delete files here, puppet will manage them. |
38 |
# |
39 |
# There's some regular expression magic to figure out the puppet version but |
40 |
# if you're on an older 0.24 version just set $puppetversion = 24 |
41 |
# |
42 |
# Before you can use any of the concat features you should include the |
43 |
# class concat::setup somewhere on your node first. |
44 |
# |
45 |
# DETAIL: |
46 |
# We use a helper shell script called concatfragments.sh that gets placed |
47 |
# in /usr/local/bin to do the concatenation. While this might seem more |
48 |
# complex than some of the one-liner alternatives you might find on the net |
49 |
# we do a lot of error checking and safety checks in the script to avoid |
50 |
# problems that might be caused by complex escaping errors etc. |
51 |
# |
52 |
# LICENSE: |
53 |
# Apache Version 2 |
54 |
# |
55 |
# LATEST: |
56 |
# http://github.com/ripienaar/puppet-concat/ |
57 |
# |
58 |
# CONTACT: |
59 |
# R.I.Pienaar <rip@devco.net> |
60 |
# Volcane on freenode |
61 |
# @ripienaar on twitter |
62 |
# www.devco.net |
63 |
|
64 |
|
65 |
# Sets up so that you can use fragments to build a final config file, |
66 |
# |
67 |
# OPTIONS: |
68 |
# - mode The mode of the final file |
69 |
# - owner Who will own the file |
70 |
# - group Who will own the file |
71 |
# - force Enables creating empty files if no fragments are present |
72 |
# - warn Adds a normal shell style comment top of the file indicating |
73 |
# that it is built by puppet |
74 |
# - backup Controls the filebucketing behavior of the final file and |
75 |
# see File type reference for its use. Defaults to 'puppet' |
76 |
# |
77 |
# ACTIONS: |
78 |
# - Creates fragment directories if it didn't exist already |
79 |
# - Executes the concatfragments.sh script to build the final file, this script will create |
80 |
# directory/fragments.concat. Execution happens only when: |
81 |
# * The directory changes |
82 |
# * fragments.concat != final destination, this means rebuilds will happen whenever |
83 |
# someone changes or deletes the final file. Checking is done using /usr/bin/cmp. |
84 |
# * The Exec gets notified by something else - like the concat::fragment define |
85 |
# - Copies the file over to the final destination using a file resource |
86 |
# |
87 |
# ALIASES: |
88 |
# - The exec can notified using Exec["concat_/path/to/file"] or Exec["concat_/path/to/directory"] |
89 |
# - The final file can be referened as File["/path/to/file"] or File["concat_/path/to/file"] |
90 |
define concat($mode = 0644, $owner = "root", $group = "root", $warn = "false", $force = "false", $backup = "puppet") { |
91 |
$safe_name = regsubst($name, '/', '_', 'G') |
92 |
$concatdir = $concat::setup::concatdir |
93 |
$version = $concat::setup::majorversion |
94 |
$fragdir = "${concatdir}/${safe_name}" |
95 |
$concat_name = "fragments.concat.out" |
96 |
$default_warn_message = '# This file is managed by Puppet. DO NOT EDIT.' |
97 |
|
98 |
case $warn { |
99 |
'true',true,yes,on: { $warnmsg = "$default_warn_message" } |
100 |
'false',false,no,off: { $warnmsg = "" } |
101 |
default: { $warnmsg = "$warn" } |
102 |
} |
103 |
|
104 |
$warnmsg_escaped = regsubst($warnmsg, "'", "'\\\\''", 'G') |
105 |
$warnflag = $warnmsg_escaped ? { |
106 |
'' => '', |
107 |
default => "-w '$warnmsg_escaped'" |
108 |
} |
109 |
|
110 |
case $force { |
111 |
'true',true,yes,on: { $forceflag = "-f" } |
112 |
'false',false,no,off: { $forceflag = "" } |
113 |
default: { fail("Improper 'force' value given to concat: $force") } |
114 |
} |
115 |
|
116 |
File{ |
117 |
owner => root, |
118 |
group => root, |
119 |
mode => $mode, |
120 |
backup => $backup |
121 |
} |
122 |
|
123 |
file{$fragdir: |
124 |
ensure => directory; |
125 |
|
126 |
"${fragdir}/fragments": |
127 |
ensure => directory, |
128 |
recurse => true, |
129 |
purge => true, |
130 |
force => true, |
131 |
ignore => [".svn", ".git", ".gitignore"], |
132 |
source => $version ? { |
133 |
24 => "puppet:///concat/null", |
134 |
default => undef, |
135 |
}, |
136 |
notify => Exec["concat_${name}"]; |
137 |
|
138 |
"${fragdir}/fragments.concat": |
139 |
ensure => present; |
140 |
|
141 |
"${fragdir}/${concat_name}": |
142 |
ensure => present; |
143 |
|
144 |
$name: |
145 |
source => "${fragdir}/${concat_name}", |
146 |
owner => $owner, |
147 |
group => $group, |
148 |
checksum => md5, |
149 |
mode => $mode, |
150 |
ensure => present, |
151 |
alias => "concat_${name}"; |
152 |
} |
153 |
|
154 |
exec{"concat_${name}": |
155 |
user => root, |
156 |
group => root, |
157 |
notify => File[$name], |
158 |
subscribe => File[$fragdir], |
159 |
alias => "concat_${fragdir}", |
160 |
require => [ File["/usr/local/bin/concatfragments.sh"], File[$fragdir], File["${fragdir}/fragments"], File["${fragdir}/fragments.concat"] ], |
161 |
unless => "/usr/local/bin/concatfragments.sh -o ${fragdir}/${concat_name} -d ${fragdir} -t ${warnflag} ${forceflag}", |
162 |
command => "/usr/local/bin/concatfragments.sh -o ${fragdir}/${concat_name} -d ${fragdir} ${warnflag} ${forceflag}", |
163 |
} |
164 |
} |