Merge remote branch 'immerda/master'

Conflicts:
	lib/puppet/parser/functions/gsub.rb
	lib/puppet/parser/functions/prefix_with.rb
	lib/puppet/parser/functions/sha1.rb
	lib/puppet/parser/functions/slash_escape.rb
	lib/puppet/parser/functions/substitute.rb
	manifests/classes/lsb_release.pp
	manifests/defines/concatenated_file.pp
	manifests/defines/config_file.pp
	manifests/defines/line.pp
	manifests/defines/module_dir.pp
	manifests/defines/module_file.pp
	manifests/defines/replace.pp
	manifests/init.pp
This commit is contained in:
Micah Anderson 2010-09-02 19:04:29 -04:00
commit 63a16ad8c0
19 changed files with 298 additions and 267 deletions

View file

@ -1,13 +1,9 @@
#
# A thin wrapper around the ruby gsub function.
#
# gsub($string, $pattern, $replacement)
#
# will replace all occurrences of $pattern in $string with $replacement.
# $string can be either a single value or an array. In the latter case, each
# element of the array will be processed in turn.
#
module Puppet::Parser::Functions module Puppet::Parser::Functions
# thin wrapper around the ruby gsub function
# gsub($string, $pattern, $replacement) will replace all occurrences of
# $pattern in $string with $replacement. $string can be either a singel
# value or an array. In the latter case, each element of the array will
# be processed in turn.
newfunction(:gsub, :type => :rvalue) do |args| newfunction(:gsub, :type => :rvalue) do |args|
if args[0].is_a?(Array) if args[0].is_a?(Array)
args[0].collect do |val| args[0].collect do |val|

View file

@ -0,0 +1,13 @@
# get an uniq array of ipaddresses for a hostname
require 'resolv'
module Puppet::Parser::Functions
newfunction(:hostname, :type => :rvalue) do |args|
res = Array.new
Resolv::DNS.new.each_address(args[0]){ |addr|
res << addr
}
res.uniq
end
end

View file

@ -1,15 +1,5 @@
# Prefixes arguments 2..n with first argument. # prefix arguments 2..n with first argument
#
# prefix_with(string prefix, string[] arguments) : string[]
#
# Example:
#
# prefix_with("php-", [ "blah", "foo" ])
#
# will result in this array:
#
# [ "php-blah", "php-foo" ]
#
module Puppet::Parser::Functions module Puppet::Parser::Functions
newfunction(:prefix_with, :type => :rvalue) do |args| newfunction(:prefix_with, :type => :rvalue) do |args|
prefix = args.shift prefix = args.shift

View file

@ -0,0 +1,9 @@
# return the sha1 hash
require 'digest/sha1'
module Puppet::Parser::Functions
newfunction(:sha1, :type => :rvalue) do |args|
Digest::SHA1.hexdigest(args[0])
end
end

View file

@ -0,0 +1,7 @@
# escape slashes in a String
module Puppet::Parser::Functions
newfunction(:slash_escape, :type => :rvalue) do |args|
args[0].gsub(/\//, '\\/')
end
end

View file

@ -0,0 +1,6 @@
module Puppet::Parser::Functions
newfunction(:strlength, :type => :rvalue) do |args|
args[0].to_s.length
end
end

View file

@ -0,0 +1,20 @@
# subsititute($string, $regex, $replacement) : $string
# subsititute($string[], $regex, $replacement) : $string[]
#
# Replace all ocurrences of $regex in $string by $replacement.
# $regex is interpreted as Ruby regular expression.
#
# For long-term portability it is recommended to refrain from using Ruby's
# extended RE features.
module Puppet::Parser::Functions
newfunction(:substitute, :type => :rvalue) do |args|
if args[0].is_a?(Array)
args[0].collect do |val|
val.gsub(/#{args[1]}/, args[2])
end
else
args[0].gsub(/#{args[1]}/, args[2])
end
end
end

View file

@ -1,49 +0,0 @@
# common/manifests/classes/lsb_release.pp -- request the installation of
# lsb_release to get to lsbdistcodename, which is used throughout the manifests
#
# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
# See LICENSE for the full license granted to you.
# Changelog:
# 2007-08-26: micah <micah@riseup.net> reported, that lsb_release can report
# nonsensical values for lsbdistcodename; assert_lsbdistcodename now
# recognises "n/a" and acts accordingly
# This lightweight class only asserts that $lsbdistcodename is set.
# If the assertion fails, an error is printed on the server
#
# To fail individual resources on a missing lsbdistcodename, require
# Exec[assert_lsbdistcodename] on the specific resource
#
# This is just one example of how you could avoid evaluation of parts of the
# manifest, before a bootstrapping class has enabled all the necessary goodies.
class assert_lsbdistcodename {
case $lsbdistcodename {
'': {
err("Please install lsb_release or set facter_lsbdistcodename in the environment of $fqdn")
exec { "false # assert_lsbdistcodename": alias => assert_lsbdistcodename, loglevel => err }
}
'n/a': {
case $operatingsystem {
"Debian": {
err("lsb_release was unable to report your distcodename; This seems to indicate a broken apt/sources.list on $fqdn")
}
default: {
err("lsb_release was unable to report your distcodename; please set facter_lsbdistcodename in the environment of $fqdn")
}
}
exec { "false # assert_lsbdistcodename": alias => assert_lsbdistcodename, loglevel => err }
}
default: {
exec { "true # assert_lsbdistcodename": alias => assert_lsbdistcodename, loglevel => debug }
exec { "true # require_lsbdistcodename": alias => require_lsbdistcodename, loglevel => debug }
}
}
}
# To fail the complete compilation on a missing $lsbdistcodename, include this class
class require_lsbdistcodename inherits assert_lsbdistcodename {
exec { "false # require_lsbdistcodename": require => Exec[require_lsbdistcodename], loglevel => err }
}

View file

@ -4,8 +4,6 @@
# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at> # Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
# See LICENSE for the full license granted to you. # See LICENSE for the full license granted to you.
module_dir { "common/cf": }
# TODO: # TODO:
# * create the directory in _part too # * create the directory in _part too
@ -24,77 +22,78 @@ module_dir { "common/cf": }
# #
# Depend on File[$name] to change if and only if its contents change. Notify # Depend on File[$name] to change if and only if its contents change. Notify
# Exec["concat_${name}"] if you want to force an update. # Exec["concat_${name}"] if you want to force an update.
# #
# Usage: # Usage:
# concatenated_file { "/etc/some.conf": # concatenated_file { "/etc/some.conf":
# dir => "/etc/some.conf.d", # dir => "/etc/some.conf.d",
# } # }
define concatenated_file ( define concatenated_file (
# where the snippets are located # where the snippets are located
$dir = '', $dir = '',
# a file with content to prepend # a file with content to prepend
$header = '', $header = '',
# a file with content to append # a file with content to append
$footer = '', $footer = '',
# default permissions for the target file # default permissions for the target file
$mode = 0644, $owner = root, $group = 0 $mode = 0644, $owner = root, $group = 0
) )
{ {
include common::moduledir::common::cf
$dir_real = $dir ? { '' => "${name}.d", default => $dir } $dir_real = $dir ? { '' => "${name}.d", default => $dir }
$tmp_file_name = regsubst($dir_real, '/', '_', 'G') $tmp_file_name = regsubst($dir_real, '/', '_', 'G')
$tmp_file = "${module_dir_path}/${tmp_file_name}" $tmp_file = "${common::moduledir::module_dir_path}/${tmp_file_name}"
if defined(File[$dir_real]) { if defined(File[$dir_real]) {
debug("${dir_real} already defined") debug("${dir_real} already defined")
} else { } else {
file { file {
$dir_real: $dir_real:
source => "puppet://$server/modules/common/empty", source => "puppet:///modules/common/empty",
checksum => mtime, checksum => mtime,
ignore => '.ignore', ignore => '.ignore',
recurse => true, purge => true, force => true, recurse => true, purge => true, force => true,
mode => $mode, owner => $owner, group => $group, mode => $mode, owner => $owner, group => $group,
notify => Exec["concat_${name}"]; notify => Exec["concat_${name}"];
} }
} }
file { file {
$tmp_file: $tmp_file:
ensure => present, checksum => md5, ensure => present, checksum => md5,
mode => $mode, owner => $owner, group => $group; mode => $mode, owner => $owner, group => $group;
# decouple the actual file from the generation process by using a # decouple the actual file from the generation process by using a
# temporary file and puppet's source mechanism. This ensures that events # temporary file and puppet's source mechanism. This ensures that events
# for notify/subscribe will only be generated when there is an actual # for notify/subscribe will only be generated when there is an actual
# change. # change.
$name: $name:
ensure => present, checksum => md5, ensure => present, checksum => md5,
source => $tmp_file, source => $tmp_file,
mode => $mode, owner => $owner, group => $group, mode => $mode, owner => $owner, group => $group,
require => File[$tmp_file]; require => File[$tmp_file];
} }
# if there is a header or footer file, add it # if there is a header or footer file, add it
$additional_cmd = $header ? { $additional_cmd = $header ? {
'' => $footer ? { '' => $footer ? {
'' => '', '' => '',
default => "| cat - '${footer}' " default => "| cat - '${footer}' "
}, },
default => $footer ? { default => $footer ? {
'' => "| cat '${header}' - ", '' => "| cat '${header}' - ",
default => "| cat '${header}' - '${footer}' " default => "| cat '${header}' - '${footer}' "
} }
} }
# use >| to force clobbering the target file # use >| to force clobbering the target file
exec { "concat_${name}": exec { "concat_${name}":
command => "/usr/bin/find ${dir_real} -maxdepth 1 -type f ! -name '*puppettmp' -print0 | sort -z | xargs -0 cat ${additional_cmd} >| ${tmp_file}", command => "/usr/bin/find ${dir_real} -maxdepth 1 -type f ! -name '*puppettmp' -print0 | sort -z | xargs -0 cat ${additional_cmd} >| ${tmp_file}",
subscribe => [ File[$dir_real] ], subscribe => [ File[$dir_real] ],
before => File[$tmp_file], before => File[$tmp_file],
alias => [ "concat_${dir_real}"], alias => [ "concat_${dir_real}"],
loglevel => info loglevel => info
} }
} }
@ -102,16 +101,17 @@ define concatenated_file (
# Add a snippet called $name to the concatenated_file at $dir. # Add a snippet called $name to the concatenated_file at $dir.
# The file can be referenced as File["cf_part_${name}"] # The file can be referenced as File["cf_part_${name}"]
define concatenated_file_part ( define concatenated_file_part (
$dir, $content = '', $ensure = present, $dir, $content = '', $ensure = present,
$mode = 0644, $owner = root, $group = 0 $mode = 0644, $owner = root, $group = 0
) )
{ {
file { "${dir}/${name}": file { "${dir}/${name}":
ensure => $ensure, content => $content, ensure => $ensure, content => $content,
mode => $mode, owner => $owner, group => $group, mode => $mode, owner => $owner, group => $group,
alias => "cf_part_${name}", alias => "cf_part_${name}",
notify => Exec["concat_${dir}"], notify => Exec["concat_${dir}"],
} }
} }

View file

@ -3,56 +3,53 @@
# See LICENSE for the full license granted to you. # See LICENSE for the full license granted to you.
# A simple wrapper to give all configuration files common defaults. # A simple wrapper to give all configuration files common defaults.
#
# Usage:
# config_file { filename:
# content => "....\n",
# }
# #
# Examples: # Usage:
# config_file { filename:
# content => "....\n",
# }
#
# Examples:
# #
# To create the file /etc/vservers/${vs_name}/context with specific # To create the file /etc/vservers/${vs_name}/context with specific
# content: # content:
# #
# config_file { # config_file { "/etc/vservers/${vs_name}/context":
# "/etc/vservers/${vs_name}/context": # content => "${context}\n",
# content => "${context}\n", # notify => Exec["vs_restart_${vs_name}"],
# notify => Exec["vs_restart_${vs_name}"], # require => Exec["vs_create_${vs_name}"];
# require => Exec["vs_create_${vs_name}"];
# } # }
# #
# To create the file /etc/apache2/sites-available/munin-stats with the # To create the file /etc/apache2/sites-available/munin-stats with the
# content pulled from a template: # content pulled from a template:
# #
# config_file { # config_file { "/etc/apache2/sites-available/munin-stats":
# "/etc/apache2/sites-available/munin-stats": # content => template("apache/munin-stats"),
# content => template("apache/munin-stats"), # require => Package["apache2"],
# require => Package["apache2"], # notify => Exec["reload-apache2"]
# notify => Exec["reload-apache2"]; # }
# }
define config_file (
$content = '',
$source = '',
$ensure = 'present')
{
file { $name:
ensure => $ensure,
# default permissions for config files
mode => 0644, owner => root, group => 0,
# really detect changes to this file
checksum => md5,
}
case $source { define config_file ($content = '', $source = '', $ensure = 'present') {
'': { } file { $name:
default: { File[$name] { source => $source } } ensure => $ensure,
} # keep old versions on the server
backup => server,
# default permissions for config files
mode => 0644, owner => root, group => 0,
# really detect changes to this file
checksum => md5,
}
case $source {
'': { }
default: { File[$name] { source => $source } }
}
case $content {
'': { }
default: { File[$name] { content => $content } }
}
case $content {
'': { }
default: { File[$name] { content => $content } }
}
} }

View file

@ -34,24 +34,21 @@
# notify => Service[munin-node], # notify => Service[munin-node],
# require => Package[munin-node]; # require => Package[munin-node];
# } # }
define line( define line($file, $line, $ensure = 'present') {
$file, case $ensure {
$line, default : { err ( "unknown ensure value '${ensure}'" ) }
$ensure = 'present' present: {
) { exec { "echo '${line}' >> '${file}'":
case $ensure { unless => "grep -qFx '${line}' '${file}'"
default : { err ( "unknown ensure value '${ensure}'" ) } }
present: { }
exec { "echo '${line}' >> '${file}'": absent: {
unless => "grep -qFx '${line}' '${file}'" $subst_line = regsubst($line,'(/|\.)','\\\1','G')
} exec { "sed -i '/${subst_line}/d' '${file}'":
} onlyif => "grep -qFx '${line}' '${file}'"
absent: { }
exec { "perl -ni -e 'print if \$_ ne \"${line}\n\";' '${file}'": }
onlyif => "grep -qFx '${line}' '${file}'" }
}
}
}
} }

12
manifests/defines/link.pp Normal file
View file

@ -0,0 +1,12 @@
# common/manifests/defines/link.pp -- create a link
#
# Copyleft (C) 2009 immerdaadmin <admin@immerda.ch>
# See LICENSE for the full license granted to you.
# Usage:
# link { "/usr/bin/convert": target => "/usr/local/bin/convert" }
# e.g. equivalent to bash# ln -s /usr/bin/convert /usr/local/bin/convert
define link($target = absent) {
file{$name: ensure => $target; }
}

View file

@ -1,4 +1,4 @@
# common/manifests/defines/module_dir.pp -- create a default directory # common/manifests/defines/modules_dir.pp -- create a default directory
# for storing module specific information # for storing module specific information
# #
# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at> # Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
@ -14,29 +14,37 @@
# purged so that modules do not have to worry about removing cruft. # purged so that modules do not have to worry about removing cruft.
# #
# Usage: # Usage:
# module_dir { ["common", "common/dir1", "common/dir2" ]: } # include common::moduledir
# module_dir { ["common", "common/dir1", "common/dir2" ]: }
#
# You may refer to a file in module_dir by using :
# file { "${common::moduledir::module_dir_path}/somedir/somefile": }
define module_dir ( define module_dir (
$mode = 0644, $mode = 0644, $owner = root, $group = 0
$owner = root, )
$group = 0
)
{ {
$dir = "${module_dir_path}/${name}" include common::moduledir
if defined(File[$dir]) { $dir = "${common::moduledir::module_dir_path}/${name}"
debug("${dir} already defined") if defined(File[$dir]) {
} else { debug("${dir} already defined")
file { } else {
$dir: file {
source => [ "puppet://$server/modules/${name}/module_dir", "puppet://$server/modules/common/empty"], $dir:
checksum => mtime, source => [ "puppet:///modules/${name}/modules_dir", "puppet:///modules/common/empty"],
# ignore the placeholder checksum => mtime,
ignore => '\.ignore', # ignore the placeholder
recurse => true, purge => true, force => true, ignore => '.ignore',
mode => $mode, owner => $owner, group => $group; recurse => true, purge => true, force => true,
} mode => $mode, owner => $owner, group => $group;
} }
}
} }
# Use this variable to reference the base path. Thus you are safe from any # alias for compatibility
# changes. define modules_dir (
$module_dir_path = '/var/lib/puppet/modules' $mode = 0644, $owner = root, $group = 0
)
{
module_dir { $name: mode => $mode, owner => $owner, group => $group }
}

View file

@ -1,5 +1,5 @@
# common/manifests/defines/module_file.pp -- use an already defined module_dir # common/manifests/defines/modules_file.pp -- use a modules_dir to store module
# to store module specific files # specific files
# #
# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at> # Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
# See LICENSE for the full license granted to you. # See LICENSE for the full license granted to you.
@ -7,18 +7,41 @@
# Put a file into module-local storage. # Put a file into module-local storage.
# #
# Usage: # Usage:
# module_file { # modules_file { "module/file":
# "module/file": # source => "puppet:///...",
# source => "puppet://..", # mode => 644, # default
# owner => root, # default
# group => 0, # default
# } # }
define module_file ( define module_file (
$source, $source,
$mode = 0644, $owner = root, $group = 0 $ensure = present,
) $alias = undef,
$mode = 0644, $owner = root, $group = 0
)
{ {
file { include common::moduledir
"${module_dir_path}/${name}": file {
source => $source, "${common::moduledir::module_dir_path}/${name}":
mode => $mode, owner => $owner, group => $group; source => $source,
} ensure => $ensure,
alias => $alias,
mode => $mode, owner => $owner, group => $group;
}
}
# alias for compatibility
define modules_file (
$source,
$ensure = present,
$alias = undef,
$mode = 0644, $owner = root, $group = 0
)
{
module_file { $name:
source => $source,
ensure => $ensure,
alias => $alias,
mode => $mode, owner => $owner, group => $group
}
} }

View file

@ -14,7 +14,7 @@
# #
# Usage: # Usage:
# #
# replace { description: # replace { description:
# file => "filename", # file => "filename",
# pattern => "regexp", # pattern => "regexp",
# replacement => "replacement" # replacement => "replacement"
@ -23,19 +23,18 @@
# To replace the current port in /etc/munin/munin-node.conf # To replace the current port in /etc/munin/munin-node.conf
# with a new port, but only disturbing the file when needed: # with a new port, but only disturbing the file when needed:
# #
# replace { # replace { set_munin_node_port:
# set_munin_node_port: # file => "/etc/munin/munin-node.conf",
# file => "/etc/munin/munin-node.conf", # pattern => "^port (?!$port)[0-9]*",
# pattern => "^port (?!$port)[0-9]*", # replacement => "port $port"
# replacement => "port $port" # }
# }
define replace($file, $pattern, $replacement) {
$pattern_no_slashes = regsubst($pattern, '/', '\\/', 'G', 'U')
$replacement_no_slashes = regsubst($replacement, '/', '\\/', 'G', 'U')
exec { "replace_${pattern}_${file}": define replace($file, $pattern, $replacement) {
command => "/usr/bin/perl -pi -e 's/${pattern_no_slashes}/${replacement_no_slashes}/' '${file}'", $pattern_no_slashes = slash_escape($pattern)
onlyif => "/usr/bin/perl -ne 'BEGIN { \$ret = 1; } \$ret = 0 if /${pattern_no_slashes}/ && ! /\\Q${replacement_no_slashes}\\E/; END { exit \$ret; }' '${file}'", $replacement_no_slashes = slash_escape($replacement)
alias => "exec_$name", exec { "replace_${pattern}_${file}":
} command => "/usr/bin/perl -pi -e 's/${pattern_no_slashes}/${replacement_no_slashes}/' '${file}'",
onlyif => "/usr/bin/perl -ne 'BEGIN { \$ret = 1; } \$ret = 0 if /${pattern_no_slashes}/ && ! /\\Q${replacement_no_slashes}\\E/; END { exit \$ret; }' '${file}'",
alias => "exec_$name",
}
} }

View file

@ -3,23 +3,4 @@
# See LICENSE for the full license granted to you. # See LICENSE for the full license granted to you.
import "defines/*.pp" import "defines/*.pp"
import "classes/*.pp"
module_dir { [ 'common' ]: }
file {
# Module programmers can use /var/lib/puppet/modules/$modulename to save
# module-local data, e.g. for constructing config files. See module_dir
# for details
"/var/lib/puppet/modules":
ensure => directory,
source => "puppet://$server/modules/common/modules",
ignore => ".ignore",
recurse => true, purge => true, force => true,
mode => 0755, owner => root, group => 0;
}
# common packages
class pkg::openssl { package { openssl: ensure => installed } }
class pkg::rsync { package { rsync: ensure => installed } }

15
manifests/moduledir.pp Normal file
View file

@ -0,0 +1,15 @@
class common::moduledir {
# Use this variable to reference the base path. Thus you are safe from any
# changes.
$module_dir_path = '/var/lib/puppet/modules'
# Module programmers can use /var/lib/puppet/modules/$modulename to save
# module-local data, e.g. for constructing config files
file{$module_dir_path:
ensure => directory,
source => "puppet:///modules/common/modules/",
ignore => '.ignore',
recurse => true, purge => true, force => true,
mode => 0755, owner => root, group => 0;
}
}

View file

@ -0,0 +1,3 @@
class common::moduledir::common{
module_dir{'common': }
}

View file

@ -0,0 +1,4 @@
class common::moduledir::common::cf {
include ::common::moduledir::common
module_dir{'common/cf': }
}