puppetlabs-concat-1.0.0/000755 000765 000024 00000000000 12203005613 015566 5ustar00hunnerstaff000000 000000 puppetlabs-concat-1.0.0/CHANGELOG000644 000765 000024 00000006202 12203005613 017000 0ustar00hunnerstaff000000 000000 2013-08-09 1.0.0 Summary: Many new features and bugfixes in this release, and if you're a heavy concat user you should test carefully before upgrading. The features should all be backwards compatible but only light testing has been done from our side before this release. Features: - New parameters in concat: - `replace`: specify if concat should replace existing files. - `ensure_newline`: controls if fragments should contain a newline at the end. - Improved README documentation. - Add rspec:system tests (rake spec:system to test concat) Bugfixes - Gracefully handle \n in a fragment resource name. - Adding more helpful message for 'pluginsync = true' - Allow passing `source` and `content` directly to file resource, rather than defining resource defaults. - Added -r flag to read so that filenames with \ will be read correctly. - sort always uses LANG=C. - Allow WARNMSG to contain/start with '#'. - Replace while-read pattern with for-do in order to support Solaris. CHANGELOG: - 2010/02/19 - initial release - 2010/03/12 - add support for 0.24.8 and newer - make the location of sort configurable - add the ability to add shell comment based warnings to top of files - add the ablity to create empty files - 2010/04/05 - fix parsing of WARN and change code style to match rest of the code - Better and safer boolean handling for warn and force - Don't use hard coded paths in the shell script, set PATH top of the script - Use file{} to copy the result and make all fragments owned by root. This means we can chnage the ownership/group of the resulting file at any time. - You can specify ensure => "/some/other/file" in concat::fragment to include the contents of a symlink into the final file. - 2010/04/16 - Add more cleaning of the fragment name - removing / from the $name - 2010/05/22 - Improve documentation and show the use of ensure => - 2010/07/14 - Add support for setting the filebucket behavior of files - 2010/10/04 - Make the warning message configurable - 2010/12/03 - Add flags to make concat work better on Solaris - thanks Jonathan Boyett - 2011/02/03 - Make the shell script more portable and add a config option for root group - 2011/06/21 - Make base dir root readable only for security - 2011/06/23 - Set base directory using a fact instead of hardcoding it - 2011/06/23 - Support operating as non privileged user - 2011/06/23 - Support dash instead of bash or sh - 2011/07/11 - Better solaris support - 2011/12/05 - Use fully qualified variables - 2011/12/13 - Improve Nexenta support - 2012/04/11 - Do not use any GNU specific extensions in the shell script - 2012/03/24 - Comply to community style guides - 2012/05/23 - Better errors when basedir isnt set - 2012/05/31 - Add spec tests - 2012/07/11 - Include concat::setup in concat improving UX - 2012/08/14 - Puppet Lint improvements - 2012/08/30 - The target path can be different from the $name - 2012/08/30 - More Puppet Lint cleanup - 2012/09/04 - RELEASE 0.2.0 - 2012/12/12 - Added (file) $replace parameter to concat puppetlabs-concat-1.0.0/files/000755 000765 000024 00000000000 12203005613 016670 5ustar00hunnerstaff000000 000000 puppetlabs-concat-1.0.0/Gemfile000644 000765 000024 00000001244 12203005613 017062 0ustar00hunnerstaff000000 000000 source 'https://rubygems.org' group :development, :test do gem 'rake', :require => false gem 'rspec-puppet', :require => false gem 'puppetlabs_spec_helper', :require => false gem 'rspec-system-puppet', :require => false gem 'puppet-lint', :require => false gem 'serverspec', :require => false gem 'rspec-system-serverspec', :require => false gem 'pry', :require => false gem 'vagrant-wrapper', :require => false end if puppetversion = ENV['PUPPET_GEM_VERSION'] gem 'puppet', puppetversion, :require => false else gem 'puppet', :require => false end # vim:ft=ruby puppetlabs-concat-1.0.0/lib/000755 000765 000024 00000000000 12203005613 016334 5ustar00hunnerstaff000000 000000 puppetlabs-concat-1.0.0/LICENSE000644 000765 000024 00000001105 12203005613 016570 0ustar00hunnerstaff000000 000000 Copyright 2012 R.I.Pienaar Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. puppetlabs-concat-1.0.0/manifests/000755 000765 000024 00000000000 12203005613 017557 5ustar00hunnerstaff000000 000000 puppetlabs-concat-1.0.0/metadata.json000644 000765 000024 00000003235 12203005613 020244 0ustar00hunnerstaff000000 000000 { "name": "puppetlabs-concat", "version": "1.0.0", "source": "git://github.com/puppetlabs/puppetlabs-concat.git", "author": "Puppetlabs", "license": "Apache 2.0", "summary": "Concat module", "description": "Concat module", "project_page": "http://github.com/puppetlabs/puppetlabs-concat", "dependencies": [ ], "types": [ ], "checksums": { "CHANGELOG": "89220fae3ab04a350132fe94d7a6ca00", "Gemfile": "a913d6f7a0420e07539d8ff1ef047ffb", "LICENSE": "f5a76685d453424cd63dde1535811cf0", "Modulefile": "f99ee2f6778b9e23635ac1027888bbd3", "README": "d15ec3400f628942dd7b7fa8c1a18da3", "README.markdown": "d82e203d729ea4785bdcaca1be166e62", "Rakefile": "0428ea3759a4692c91604396c406a9c1", "files/concatfragments.sh": "2fbba597a1513eb61229551d35d42b9f", "lib/facter/concat_basedir.rb": "e152593fafe27ef305fc473929c62ca6", "manifests/fragment.pp": "196ee8e405b3a31b84ae618ed54377ed", "manifests/init.pp": "8d0cc8e9cf145ca7a23db05a30252476", "manifests/setup.pp": "2246572410d94c68aff310f8132c55b4", "spec/defines/init_spec.rb": "35e41d4abceba0dca090d3addd92bb4f", "spec/fixtures/manifests/site.pp": "d41d8cd98f00b204e9800998ecf8427e", "spec/spec_helper.rb": "0db89c9a486df193c0e40095422e19dc", "spec/spec_helper_system.rb": "9c3742bf87d62027f080c6b9fa98b979", "spec/system/basic_spec.rb": "9135d9af6a21f16980ab59b58e91ed9a", "spec/system/concat_spec.rb": "5fe675ec42ca441d0c7e431c31bbc238", "spec/system/empty_spec.rb": "51ab1fc7c86268f1ab1cda72dc5ff583", "spec/system/replace_spec.rb": "275295e6b4f04fc840dc3f87faf56249", "spec/system/warn_spec.rb": "0ea35b44e8f0ac5352256f95115995ce" } }puppetlabs-concat-1.0.0/Modulefile000644 000765 000024 00000000377 12203005613 017605 0ustar00hunnerstaff000000 000000 name 'puppetlabs-concat' version '1.0.0' source 'git://github.com/puppetlabs/puppetlabs-concat.git' author 'Puppetlabs' license 'Apache 2.0' summary 'Concat module' description 'Concat module' project_page 'http://github.com/puppetlabs/puppetlabs-concat' puppetlabs-concat-1.0.0/Rakefile000644 000765 000024 00000000115 12203005613 017230 0ustar00hunnerstaff000000 000000 require 'puppetlabs_spec_helper/rake_tasks' require 'rspec-system/rake_task' puppetlabs-concat-1.0.0/README000644 000765 000024 00000005404 12203005613 016451 0ustar00hunnerstaff000000 000000 == Module: concat 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. You can also specify a path and use a different name for your resources: # You can make this something dynamic, based on whatever parameters your # module/class for example. $vhost_file = '/etc/httpd/vhosts/01-my-vhost.conf' concat{'apache-vhost-myvhost': path => $vhost_file, } # We don't care where the file is located, just what to put in it. concat::fragment {'apache-vhost-myvhost-main': target => 'apache-vhost-myvhost', content => '', order => 01, } concat::fragment {'apache-vhost-myvhost-close': target => 'apache-vhost-myvhost', content => '', order => 99, } === 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 /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 === Detail: We use a helper shell script called concatfragments.sh that gets placed in /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/puppetlabs/puppetlabs-concat/ === Contact: Puppetlabs, via our puppet-users@ mailing list. puppetlabs-concat-1.0.0/README.markdown000644 000765 000024 00000006502 12203005613 020272 0ustar00hunnerstaff000000 000000 What is it? =========== A Puppet module that can construct files from fragments. Please see the comments in the various .pp files for details as well as posts on my blog at http://www.devco.net/ Released under the Apache 2.0 licence Usage: ------ If you wanted a /etc/motd file that listed all the major modules on the machine. And that would be maintained automatically even if you just remove the include lines for other modules you could use code like below, a sample /etc/motd would be:
Puppet modules on this server:

    -- Apache
    -- MySQL
Local sysadmins can also append to the file by just editing /etc/motd.local their changes will be incorporated into the puppet managed motd.
# class to setup basic motd, include on all nodes
class motd {
   $motd = "/etc/motd"

   concat{$motd:
      owner => root,
      group => root,
      mode  => '0644',
   }

   concat::fragment{"motd_header":
      target => $motd,
      content => "\nPuppet modules on this server:\n\n",
      order   => 01,
   }

   # local users on the machine can append to motd by just creating
   # /etc/motd.local
   concat::fragment{"motd_local":
      target => $motd,
      ensure  => "/etc/motd.local",
      order   => 15
   }
}

# used by other modules to register themselves in the motd
define motd::register($content="", $order=10) {
   if $content == "" {
      $body = $name
   } else {
      $body = $content
   }

   concat::fragment{"motd_fragment_$name":
      target  => "/etc/motd",
      content => "    -- $body\n"
   }
}

# a sample apache module
class apache {
   include apache::install, apache::config, apache::service

   motd::register{"Apache": }
}
Detailed documentation of the class options can be found in the manifest files. Known Issues: ------------- * Since puppet-concat now relies on a fact for the concat directory, you will need to set up pluginsync = true on the [master] section of your node's '/etc/puppet/puppet.conf' for at least the first run. You have this issue if puppet fails to run on the client and you have a message similar to "err: Failed to apply catalog: Parameter path failed: File paths must be fully qualified, not 'undef' at [...]/concat/manifests/setup.pp:44". Contributors: ------------- **Paul Elliot** * Provided 0.24.8 support, shell warnings and empty file creation support. **Chad Netzer** * Various patches to improve safety of file operations * Symlink support **David Schmitt** * Patch to remove hard coded paths relying on OS path * Patch to use file{} to copy the resulting file to the final destination. This means Puppet client will show diffs and that hopefully we can change file ownerships now **Peter Meier** * Basedir as a fact * Unprivileged user support **Sharif Nassar** * Solaris/Nexenta support * Better error reporting **Christian G. Warden** * Style improvements **Reid Vandewiele** * Support non GNU systems by default **Erik Dalén** * Style improvements **Gildas Le Nadan** * Documentation improvements **Paul Belanger** * Testing improvements and Travis support **Branan Purvine-Riley** * Support Puppet Module Tool better **Dustin J. Mitchell** * Always include setup when using the concat define **Andreas Jaggi** * Puppet Lint support **Jan Vansteenkiste** * Configurable paths Contact: -------- puppet-users@ mailing list. puppetlabs-concat-1.0.0/spec/000755 000765 000024 00000000000 12203005613 016520 5ustar00hunnerstaff000000 000000 puppetlabs-concat-1.0.0/spec/defines/000755 000765 000024 00000000000 12203005613 020135 5ustar00hunnerstaff000000 000000 puppetlabs-concat-1.0.0/spec/fixtures/000755 000765 000024 00000000000 12203005613 020371 5ustar00hunnerstaff000000 000000 puppetlabs-concat-1.0.0/spec/spec_helper.rb000644 000765 000024 00000000064 12203005613 021336 0ustar00hunnerstaff000000 000000 require 'puppetlabs_spec_helper/module_spec_helper' puppetlabs-concat-1.0.0/spec/spec_helper_system.rb000644 000765 000024 00000001230 12203005613 022736 0ustar00hunnerstaff000000 000000 require 'rspec-system/spec_helper' require 'rspec-system-puppet/helpers' require 'rspec-system-serverspec/helpers' include Serverspec::Helper::RSpecSystem include Serverspec::Helper::DetectOS include RSpecSystemPuppet::Helpers RSpec.configure do |c| # Project root proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) # Enable colour c.tty = true c.include RSpecSystemPuppet::Helpers # This is where we 'setup' the nodes before running our tests c.before :suite do # Install puppet puppet_install # Install modules and dependencies puppet_module_install(:source => proj_root, :module_name => 'concat') end end puppetlabs-concat-1.0.0/spec/system/000755 000765 000024 00000000000 12203005613 020044 5ustar00hunnerstaff000000 000000 puppetlabs-concat-1.0.0/spec/system/basic_spec.rb000644 000765 000024 00000000705 12203005613 022466 0ustar00hunnerstaff000000 000000 require 'spec_helper_system' # Here we put the more basic fundamental tests, ultra obvious stuff. describe "basic tests:" do context 'make sure we have copied the module across' do # No point diagnosing any more if the module wasn't copied properly context shell 'ls /etc/puppet/modules/concat' do its(:stdout) { should =~ /Modulefile/ } its(:stderr) { should be_empty } its(:exit_code) { should be_zero } end end end puppetlabs-concat-1.0.0/spec/system/concat_spec.rb000644 000765 000024 00000002462 12203005613 022656 0ustar00hunnerstaff000000 000000 require 'spec_helper_system' describe 'basic concat test' do context 'should run successfully' do pp=" concat { '/tmp/file': owner => root, group => root, mode => '0644', } concat::fragment { '1': target => '/tmp/file', content => '1', order => '01', } concat::fragment { '2': target => '/tmp/file', content => '2', order => '02', } " context puppet_apply(pp) do its(:stderr) { should be_empty } its(:exit_code) { should_not == 1 } its(:refresh) { should be_nil } its(:stderr) { should be_empty } its(:exit_code) { should be_zero } end describe file('/tmp/file') do it { should be_file } it { should contain '1' } it { should contain '2' } end # Test that all the relevant bits exist on disk after it # concats. describe file('/var/lib/puppet/concat') do it { should be_directory } end describe file('/var/lib/puppet/concat/_tmp_file') do it { should be_directory } end describe file('/var/lib/puppet/concat/_tmp_file/fragments') do it { should be_directory } end describe file('/var/lib/puppet/concat/_tmp_file/fragments.concat') do it { should be_file } end end end puppetlabs-concat-1.0.0/spec/system/empty_spec.rb000644 000765 000024 00000001136 12203005613 022542 0ustar00hunnerstaff000000 000000 require 'spec_helper_system' describe 'basic concat test' do context 'should run successfully' do pp=" concat { '/tmp/file': owner => root, group => root, mode => '0644', force => true, } " context puppet_apply(pp) do its(:stderr) { should be_empty } its(:exit_code) { should_not == 1 } its(:refresh) { should be_nil } its(:stderr) { should be_empty } its(:exit_code) { should be_zero } end describe file('/tmp/file') do it { should be_file } it { should_not contain '1\n2' } end end end puppetlabs-concat-1.0.0/spec/system/replace_spec.rb000644 000765 000024 00000001420 12203005613 023013 0ustar00hunnerstaff000000 000000 require 'spec_helper_system' describe 'file should not replace' do shell('echo "file exists" >> /tmp/file') context 'should fail' do pp=" concat { '/tmp/file': owner => root, group => root, mode => '0644', replace => false, } concat::fragment { '1': target => '/tmp/file', content => '1', order => '01', } concat::fragment { '2': target => '/tmp/file', content => '2', order => '02', } " context puppet_apply(pp) do its(:stderr) { should be_empty } its(:exit_code) { should_not == 1 } its(:refresh) { should be_nil } its(:stderr) { should be_empty } its(:exit_code) { should be_zero } end end end puppetlabs-concat-1.0.0/spec/system/warn_spec.rb000644 000765 000024 00000001664 12203005613 022361 0ustar00hunnerstaff000000 000000 require 'spec_helper_system' describe 'basic concat test' do context 'should run successfully' do pp=" concat { '/tmp/file': owner => root, group => root, mode => '0644', warn => true, } concat::fragment { '1': target => '/tmp/file', content => '1', order => '01', } concat::fragment { '2': target => '/tmp/file', content => '2', order => '02', } " context puppet_apply(pp) do its(:stderr) { should be_empty } its(:exit_code) { should_not == 1 } its(:refresh) { should be_nil } its(:stderr) { should be_empty } its(:exit_code) { should be_zero } end describe file('/tmp/file') do it { should be_file } it { should contain '# This file is managed by Puppet. DO NOT EDIT.' } it { should contain '1' } it { should contain '2' } end end end puppetlabs-concat-1.0.0/spec/fixtures/manifests/000755 000765 000024 00000000000 12203005613 022362 5ustar00hunnerstaff000000 000000 puppetlabs-concat-1.0.0/spec/fixtures/manifests/site.pp000644 000765 000024 00000000000 12203005613 023655 0ustar00hunnerstaff000000 000000 puppetlabs-concat-1.0.0/spec/defines/init_spec.rb000644 000765 000024 00000004465 12203005613 022450 0ustar00hunnerstaff000000 000000 require 'spec_helper' describe 'concat' do basedir = '/var/lib/puppet/concat' let(:title) { '/etc/foo.bar' } let(:facts) { { :concat_basedir => '/var/lib/puppet/concat', :id => 'root', } } let :pre_condition do 'include concat::setup' end directories = [ "#{basedir}/_etc_foo.bar", "#{basedir}/_etc_foo.bar/fragments", ] directories.each do |dirs| it do should contain_file(dirs).with({ 'ensure' => 'directory', 'backup' => 'puppet', 'group' => 0, 'mode' => '0644', 'owner' => 'root', }) end end files = [ "/etc/foo.bar", "#{basedir}/_etc_foo.bar/fragments.concat", ] files.each do |file| it do should contain_file(file).with({ 'ensure' => 'present', 'backup' => 'puppet', 'group' => 0, 'mode' => '0644', 'owner' => 'root', }) end end it do should contain_exec("concat_/etc/foo.bar").with_command( "#{basedir}/bin/concatfragments.sh " + "-o #{basedir}/_etc_foo.bar/fragments.concat.out " + "-d #{basedir}/_etc_foo.bar " ) end end describe 'concat' do basedir = '/var/lib/puppet/concat' let(:title) { 'foobar' } let(:target) { '/etc/foo.bar' } let(:facts) { { :concat_basedir => '/var/lib/puppet/concat', :id => 'root', } } let :pre_condition do 'include concat::setup' end directories = [ "#{basedir}/foobar", "#{basedir}/foobar/fragments", ] directories.each do |dirs| it do should contain_file(dirs).with({ 'ensure' => 'directory', 'backup' => 'puppet', 'group' => 0, 'mode' => '0644', 'owner' => 'root', }) end end files = [ "foobar", "#{basedir}/foobar/fragments.concat", ] files.each do |file| it do should contain_file(file).with({ 'ensure' => 'present', 'backup' => 'puppet', 'group' => 0, 'mode' => '0644', 'owner' => 'root', }) end end it do should contain_exec("concat_foobar").with_command( "#{basedir}/bin/concatfragments.sh " + "-o #{basedir}/foobar/fragments.concat.out " + "-d #{basedir}/foobar " ) end end # vim:sw=2:ts=2:expandtab:textwidth=79 puppetlabs-concat-1.0.0/manifests/fragment.pp000644 000765 000024 00000003557 12203005613 021735 0ustar00hunnerstaff000000 000000 # == Define: concat::fragment # # 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=undef, $source=undef, $order=10, $ensure = 'present', $mode = '0644', $owner = $::id, $group = $concat::setup::root_group, $backup = 'puppet') { $safe_name = regsubst($name, '[/\n]', '_', 'GM') $safe_target_name = regsubst($target, '[/\n]', '_', 'GM') $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 $ensure { '', 'absent', 'present', 'file', 'directory': { if ! ($content or $source) { crit('No content, source or symlink specified') } } default: { # do nothing, make puppet-lint happy } } file{"${fragdir}/fragments/${order}_${safe_name}": ensure => $ensure, mode => $mode, owner => $owner, group => $group, source => $source, content => $content, backup => $backup, alias => "concat_fragment_${name}", notify => Exec["concat_${target}"] } } puppetlabs-concat-1.0.0/manifests/init.pp000644 000765 000024 00000011440 12203005613 021063 0ustar00hunnerstaff000000 000000 # == Define: concat # # Sets up so that you can use fragments to build a final config file, # # === Options: # # [*path*] # The path to the final file. Use this in case you want to differentiate # between the name of a resource and the file path. Note: Use the name you # provided in the target of your fragments. # [*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' # [*replace*] # Whether to replace a file that already exists on the local system # # === 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( $path = $name, $owner = $::id, $group = $concat::setup::root_group, $mode = '0644', $warn = false, $force = false, $backup = 'puppet', $replace = true, $gnu = undef, $order='alpha', $ensure_newline = false ) { include concat::setup $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}") } } case $ensure_newline { 'true', true, yes, on: { $newlineflag = '-l' } 'false', false, no, off: { $newlineflag = '' } default: { fail("Improper 'ensure_newline' value given to concat: ${ensure_newline}") } } File { owner => $::id, group => $group, mode => $mode, backup => $backup, replace => $replace } file { $fragdir: ensure => directory, } $source_real = $version ? { 24 => 'puppet:///concat/null', default => undef, } file { "${fragdir}/fragments": ensure => directory, force => true, ignore => ['.svn', '.git', '.gitignore'], notify => Exec["concat_${name}"], purge => true, recurse => true, source => $source_real, } file { "${fragdir}/fragments.concat": ensure => present, } file { "${fragdir}/${concat_name}": ensure => present, } file { $name: ensure => present, path => $path, alias => "concat_${name}", group => $group, mode => $mode, owner => $owner, source => "${fragdir}/${concat_name}", } exec { "concat_${name}": alias => "concat_${fragdir}", command => "${concat::setup::concatdir}/bin/concatfragments.sh -o ${fragdir}/${concat_name} -d ${fragdir} ${warnflag} ${forceflag} ${orderflag} ${newlineflag}", notify => File[$name], require => [ File[$fragdir], File["${fragdir}/fragments"], File["${fragdir}/fragments.concat"], ], subscribe => File[$fragdir], unless => "${concat::setup::concatdir}/bin/concatfragments.sh -o ${fragdir}/${concat_name} -d ${fragdir} -t ${warnflag} ${forceflag} ${orderflag} ${newlineflag}", } if $::id == 'root' { Exec["concat_${name}"] { user => root, group => $group, } } } # vim:sw=2:ts=2:expandtab:textwidth=79 puppetlabs-concat-1.0.0/manifests/setup.pp000644 000765 000024 00000003163 12203005613 021263 0ustar00hunnerstaff000000 000000 # === Class: concat::setup # # 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=true on the [master] section of your node's '/etc/puppet/puppet.conf'.") } $majorversion = regsubst($::puppetversion, '^[0-9]+[.]([0-9]+)[.][0-9]+$', '\1') $fragments_source = $majorversion ? { 24 => 'puppet:///concat/concatfragments.sh', default => 'puppet:///modules/concat/concatfragments.sh' } file{"${concatdir}/bin/concatfragments.sh": owner => $id, group => $root_group, mode => '0755', source => $fragments_source; [ $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; } } puppetlabs-concat-1.0.0/lib/facter/000755 000765 000024 00000000000 12203005613 017600 5ustar00hunnerstaff000000 000000 puppetlabs-concat-1.0.0/lib/facter/concat_basedir.rb000644 000765 000024 00000000334 12203005613 023065 0ustar00hunnerstaff000000 000000 # == Fact: concat_basedir # # A custom fact that sets the default location for fragments # # "${::vardir}/concat/" # Facter.add("concat_basedir") do setcode do File.join(Puppet[:vardir],"concat") end end puppetlabs-concat-1.0.0/files/concatfragments.sh000755 000765 000024 00000007523 12203005613 022414 0ustar00hunnerstaff000000 000000 #!/bin/sh # Script to concat files to a config file. # # Given a directory like this: # /path/to/conf.d # |-- fragments # | |-- 00_named.conf # | |-- 10_domain.net # | `-- zz_footer # # The script supports a test option that will build the concat file to a temp location and # use /usr/bin/cmp to verify if it should be run or not. This would result in the concat happening # twice on each run but gives you the option to have an unless option in your execs to inhibit rebuilds. # # Without the test option and the unless combo your services that depend on the final file would end up # restarting on each run, or in other manifest models some changes might get missed. # # OPTIONS: # -o The file to create from the sources # -d The directory where the fragments are kept # -t Test to find out if a build is needed, basically concats the files to a temp # location and compare with what's in the final location, return codes are designed # for use with unless on an exec resource # -w Add a shell style comment at the top of the created file to warn users that it # is generated by puppet # -f Enables the creation of empty output files when no fragments are found # -n Sort the output numerically rather than the default alpha sort # # the command: # # concatfragments.sh -o /path/to/conffile.cfg -d /path/to/conf.d # # creates /path/to/conf.d/fragments.concat and copies the resulting # file to /path/to/conffile.cfg. The files will be sorted alphabetically # pass the -n switch to sort numerically. # # The script does error checking on the various dirs and files to make # sure things don't fail. OUTFILE="" WORKDIR="" TEST="" FORCE="" WARN="" SORTARG="" ENSURE_NEWLINE="" PATH=/sbin:/usr/sbin:/bin:/usr/bin ## Well, if there's ever a bad way to do things, Nexenta has it. ## http://nexenta.org/projects/site/wiki/Personalities unset SUN_PERSONALITY while getopts "o:s:d:tnw:fl" options; do case $options in o ) OUTFILE=$OPTARG;; d ) WORKDIR=$OPTARG;; n ) SORTARG="-n";; w ) WARNMSG="$OPTARG";; f ) FORCE="true";; t ) TEST="true";; l ) ENSURE_NEWLINE="true";; * ) echo "Specify output file with -o and fragments directory with -d" exit 1;; esac done # do we have -o? if [ x${OUTFILE} = "x" ]; then echo "Please specify an output file with -o" exit 1 fi # do we have -d? if [ x${WORKDIR} = "x" ]; then echo "Please fragments directory with -d" exit 1 fi # can we write to -o? if [ -f ${OUTFILE} ]; then if [ ! -w ${OUTFILE} ]; then echo "Cannot write to ${OUTFILE}" exit 1 fi else if [ ! -w `dirname ${OUTFILE}` ]; then echo "Cannot write to `dirname ${OUTFILE}` to create ${OUTFILE}" exit 1 fi fi # do we have a fragments subdir inside the work dir? if [ ! -d "${WORKDIR}/fragments" ] && [ ! -x "${WORKDIR}/fragments" ]; then echo "Cannot access the fragments directory" exit 1 fi # are there actually any fragments? if [ ! "$(ls -A ${WORKDIR}/fragments)" ]; then if [ x${FORCE} = "x" ]; then echo "The fragments directory is empty, cowardly refusing to make empty config files" exit 1 fi fi cd ${WORKDIR} if [ "x${WARNMSG}" = "x" ]; then : > "fragments.concat" else printf '%s\n' "$WARNMSG" > "fragments.concat" fi if [ x${ENSURE_NEWLINE} != x ]; then find fragments/ -type f -follow -print0 | xargs -0 -I '{}' sh -c 'if [ -n "$(tail -c 1 < {} )" ]; then echo >> {} ; fi' fi # find all the files in the fragments directory, sort them numerically and concat to fragments.concat in the working dir IFS_BACKUP=$IFS IFS=' ' for fragfile in `find fragments/ -type f -follow | LANG=C sort ${SORTARG}` do cat $fragfile >> "fragments.concat" done IFS=$IFS_BACKUP if [ x${TEST} = "x" ]; then # This is a real run, copy the file to outfile cp fragments.concat ${OUTFILE} RETVAL=$? else # Just compare the result to outfile to help the exec decide cmp ${OUTFILE} fragments.concat RETVAL=$? fi exit $RETVAL puppetlabs-concat-1.0.0/files/null/000755 000765 000024 00000000000 12203005613 017642 5ustar00hunnerstaff000000 000000 puppetlabs-concat-1.0.0/files/null/.gitignore000644 000765 000024 00000000000 12203005613 021620 0ustar00hunnerstaff000000 000000