summaryrefslogtreecommitdiff
path: root/puppet/modules/concat/manifests
diff options
context:
space:
mode:
Diffstat (limited to 'puppet/modules/concat/manifests')
-rw-r--r--puppet/modules/concat/manifests/fragment.pp49
-rw-r--r--puppet/modules/concat/manifests/init.pp178
-rw-r--r--puppet/modules/concat/manifests/setup.pp49
3 files changed, 276 insertions, 0 deletions
diff --git a/puppet/modules/concat/manifests/fragment.pp b/puppet/modules/concat/manifests/fragment.pp
new file mode 100644
index 00000000..943bf671
--- /dev/null
+++ b/puppet/modules/concat/manifests/fragment.pp
@@ -0,0 +1,49 @@
+# Puts a file fragment into a directory previous setup using concat
+#
+# OPTIONS:
+# - target The file that these fragments belong to
+# - content If present puts the content into the file
+# - source If content was not specified, use the source
+# - order By default all files gets a 10_ prefix in the directory
+# you can set it to anything else using this to influence the
+# order of the content in the file
+# - ensure Present/Absent or destination to a file to include another file
+# - mode Mode for the file
+# - owner Owner of the file
+# - group Owner of the file
+# - backup Controls the filebucketing behavior of the final file and
+# see File type reference for its use. Defaults to 'puppet'
+define concat::fragment($target, $content='', $source='', $order=10, $ensure = 'present', $mode = '0644', $owner = $::id, $group = $concat::setup::root_group, $backup = 'puppet') {
+ $safe_name = regsubst($name, '/', '_', 'G')
+ $safe_target_name = regsubst($target, '/', '_', 'G')
+ $concatdir = $concat::setup::concatdir
+ $fragdir = "${concatdir}/${safe_target_name}"
+
+ # if content is passed, use that, else if source is passed use that
+ # if neither passed, but $ensure is in symlink form, make a symlink
+ case $content {
+ '': {
+ case $source {
+ '': {
+ case $ensure {
+ '', 'absent', 'present', 'file', 'directory': {
+ crit('No content, source or symlink specified')
+ }
+ }
+ }
+ default: { File{ source => $source } }
+ }
+ }
+ default: { File{ content => $content } }
+ }
+
+ file{"${fragdir}/fragments/${order}_${safe_name}":
+ ensure => $ensure,
+ mode => $mode,
+ owner => $owner,
+ group => $group,
+ backup => $backup,
+ alias => "concat_fragment_${name}",
+ notify => Exec["concat_${target}"]
+ }
+}
diff --git a/puppet/modules/concat/manifests/init.pp b/puppet/modules/concat/manifests/init.pp
new file mode 100644
index 00000000..0b3ed564
--- /dev/null
+++ b/puppet/modules/concat/manifests/init.pp
@@ -0,0 +1,178 @@
+# 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 uses the fact concat_basedir to define the variable
+# $concatdir, where all the temporary files and fragments will be
+# durably stored. The fact concat_basedir will be set up on the client to
+# <Puppet[:vardir]>/concat, so you will be able to run different setup/flavours
+# of puppet clients.
+# However, since this requires the file lib/facter/concat_basedir.rb to be
+# deployed on the clients, so you will have to set "pluginsync = true" on
+# both the master and client, at least for the first run.
+#
+# 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 <Puppet[:vardir]>/concat/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 = $::id, $group = $concat::setup::root_group, $warn = false, $force = false, $backup = 'puppet', $gnu = undef, $order='alpha') {
+ $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}") }
+ }
+
+ case $order {
+ numeric: { $orderflag = '-n' }
+ alpha: { $orderflag = '' }
+ default: { fail("Improper 'order' value given to concat: ${order}") }
+ }
+
+ File{
+ owner => $::id,
+ group => $group,
+ 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}":
+ notify => File[$name],
+ subscribe => File[$fragdir],
+ alias => "concat_${fragdir}",
+ require => [ File[$fragdir], File["${fragdir}/fragments"], File["${fragdir}/fragments.concat"] ],
+ unless => "${concat::setup::concatdir}/bin/concatfragments.sh -o ${fragdir}/${concat_name} -d ${fragdir} -t ${warnflag} ${forceflag} ${orderflag}",
+ command => "${concat::setup::concatdir}/bin/concatfragments.sh -o ${fragdir}/${concat_name} -d ${fragdir} ${warnflag} ${forceflag} ${orderflag}",
+ }
+ if $::id == 'root' {
+ Exec["concat_${name}"]{
+ user => root,
+ group => $group,
+ }
+ }
+}
diff --git a/puppet/modules/concat/manifests/setup.pp b/puppet/modules/concat/manifests/setup.pp
new file mode 100644
index 00000000..38aeb964
--- /dev/null
+++ b/puppet/modules/concat/manifests/setup.pp
@@ -0,0 +1,49 @@
+# Sets up the concat system.
+#
+# $concatdir is where the fragments live and is set on the fact concat_basedir.
+# Since puppet should always manage files in $concatdir and they should
+# not be deleted ever, /tmp is not an option.
+#
+# $puppetversion should be either 24 or 25 to enable a 24 compatible
+# mode, in 24 mode you might see phantom notifies this is a side effect
+# of the method we use to clear the fragments directory.
+#
+# The regular expression below will try to figure out your puppet version
+# but this code will only work in 0.24.8 and newer.
+#
+# It also copies out the concatfragments.sh file to ${concatdir}/bin
+class concat::setup {
+ $id = $::id
+ $root_group = $id ? {
+ root => 0,
+ default => $id
+ }
+
+ if $::concat_basedir {
+ $concatdir = $::concat_basedir
+ } else {
+ fail ("\$concat_basedir not defined. Try running again with pluginsync enabled")
+ }
+
+ $majorversion = regsubst($::puppetversion, '^[0-9]+[.]([0-9]+)[.][0-9]+$', '\1')
+
+ file{"${concatdir}/bin/concatfragments.sh":
+ owner => $id,
+ group => $root_group,
+ mode => '0755',
+ source => $majorversion ? {
+ 24 => 'puppet:///concat/concatfragments.sh',
+ default => 'puppet:///modules/concat/concatfragments.sh'
+ };
+
+ [ $concatdir, "${concatdir}/bin" ]:
+ ensure => directory,
+ owner => $id,
+ group => $root_group,
+ mode => '0750';
+
+ ## Old versions of this module used a different path.
+ '/usr/local/bin/concatfragments.sh':
+ ensure => absent;
+ }
+}