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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
# A system to construct files using fragments from other files or templates.
#
# This requires at least puppet 0.25 to work correctly as we use some
# enhancements in recursive directory management and regular expressions
# to do the work here.
#
# USAGE:
# The basic use case is as below:
#
# concat{"/etc/named.conf":
# notify => Service["named"]
# }
#
# concat::fragment{"foo.com_config":
# target => "/etc/named.conf",
# order => 10,
# content => template("named_conf_zone.erb")
# }
#
# # add a fragment not managed by puppet so local users
# # can add content to managed file
# concat::fragment{"foo.com_user_config":
# target => "/etc/named.conf",
# order => 12,
# ensure => "/etc/named.conf.local"
# }
#
# This will use the template named_conf_zone.erb to build a single
# bit of config up and put it into the fragments dir. The file
# will have an number prefix of 10, you can use the order option
# to control that and thus control the order the final file gets built in.
#
# SETUP:
# The class concat::setup defines a variable $concatdir - you should set this
# to a directory where you want all the temporary files and fragments to be
# stored. Avoid placing this somewhere like /tmp since you should never
# delete files here, puppet will manage them.
#
# There's some regular expression magic to figure out the puppet version but
# if you're on an older 0.24 version just set $puppetversion = 24
#
# Before you can use any of the concat features you should include the
# class concat::setup somewhere on your node first.
#
# DETAIL:
# We use a helper shell script called concatfragments.sh that gets placed
# in /usr/local/bin to do the concatenation. While this might seem more
# complex than some of the one-liner alternatives you might find on the net
# we do a lot of error checking and safety checks in the script to avoid
# problems that might be caused by complex escaping errors etc.
#
# LICENSE:
# Apache Version 2
#
# LATEST:
# http://github.com/ripienaar/puppet-concat/
#
# CONTACT:
# R.I.Pienaar <rip@devco.net>
# Volcane on freenode
# @ripienaar on twitter
# www.devco.net
# Sets up so that you can use fragments to build a final config file,
#
# OPTIONS:
# - mode The mode of the final file
# - owner Who will own the file
# - group Who will own the file
# - force Enables creating empty files if no fragments are present
# - warn Adds a normal shell style comment top of the file indicating
# that it is built by puppet
# - backup Controls the filebucketing behavior of the final file and
# see File type reference for its use. Defaults to 'puppet'
#
# ACTIONS:
# - Creates fragment directories if it didn't exist already
# - Executes the concatfragments.sh script to build the final file, this script will create
# directory/fragments.concat. Execution happens only when:
# * The directory changes
# * fragments.concat != final destination, this means rebuilds will happen whenever
# someone changes or deletes the final file. Checking is done using /usr/bin/cmp.
# * The Exec gets notified by something else - like the concat::fragment define
# - Copies the file over to the final destination using a file resource
#
# ALIASES:
# - The exec can notified using Exec["concat_/path/to/file"] or Exec["concat_/path/to/directory"]
# - The final file can be referened as File["/path/to/file"] or File["concat_/path/to/file"]
define concat($mode = 0644, $owner = "root", $group = "root", $warn = "false", $force = "false", $backup = "puppet") {
$safe_name = regsubst($name, '/', '_', 'G')
$concatdir = $concat::setup::concatdir
$version = $concat::setup::majorversion
$fragdir = "${concatdir}/${safe_name}"
$concat_name = "fragments.concat.out"
$default_warn_message = '# This file is managed by Puppet. DO NOT EDIT.'
case $warn {
'true',true,yes,on: { $warnmsg = "$default_warn_message" }
'false',false,no,off: { $warnmsg = "" }
default: { $warnmsg = "$warn" }
}
$warnmsg_escaped = regsubst($warnmsg, "'", "'\\\\''", 'G')
$warnflag = $warnmsg_escaped ? {
'' => '',
default => "-w '$warnmsg_escaped'"
}
case $force {
'true',true,yes,on: { $forceflag = "-f" }
'false',false,no,off: { $forceflag = "" }
default: { fail("Improper 'force' value given to concat: $force") }
}
File{
owner => root,
group => root,
mode => $mode,
backup => $backup
}
file{$fragdir:
ensure => directory;
"${fragdir}/fragments":
ensure => directory,
recurse => true,
purge => true,
force => true,
ignore => [".svn", ".git", ".gitignore"],
source => $version ? {
24 => "puppet:///concat/null",
default => undef,
},
notify => Exec["concat_${name}"];
"${fragdir}/fragments.concat":
ensure => present;
"${fragdir}/${concat_name}":
ensure => present;
$name:
ensure => present,
source => "${fragdir}/${concat_name}",
owner => $owner,
group => $group,
checksum => md5,
mode => $mode,
alias => "concat_${name}";
}
exec{"concat_${name}":
user => root,
group => root,
notify => File[$name],
subscribe => File[$fragdir],
alias => "concat_${fragdir}",
require => [ File["/usr/local/bin/concatfragments.sh"], File[$fragdir], File["${fragdir}/fragments"], File["${fragdir}/fragments.concat"] ],
unless => "/usr/local/bin/concatfragments.sh -o ${fragdir}/${concat_name} -d ${fragdir} -t ${warnflag} ${forceflag}",
command => "/usr/local/bin/concatfragments.sh -o ${fragdir}/${concat_name} -d ${fragdir} ${warnflag} ${forceflag}",
}
}
|