diff options
Diffstat (limited to 'puppet/modules/concat/manifests')
-rw-r--r-- | puppet/modules/concat/manifests/fragment.pp | 49 | ||||
-rw-r--r-- | puppet/modules/concat/manifests/init.pp | 178 | ||||
-rw-r--r-- | puppet/modules/concat/manifests/setup.pp | 49 |
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; + } +} |