Permalink
Browse files

first commit

  • Loading branch information...
0 parents commit 1cb941aca49c1264437966f6301d03edcf65d2d2 @bbangert committed Mar 19, 2012
Showing with 1,128 additions and 0 deletions.
  1. 0 README
  2. +9 −0 Vagrantfile
  3. +35 −0 manifests/pythondev.pp
  4. +58 −0 modules/apt/README
  5. +4 −0 modules/apt/files/10periodic
  6. 0 modules/apt/files/empty/.placeholder
  7. +26 −0 modules/apt/manifests/backports.pp
  8. +27 −0 modules/apt/manifests/clean.pp
  9. +19 −0 modules/apt/manifests/conf.pp
  10. +48 −0 modules/apt/manifests/init.pp
  11. +34 −0 modules/apt/manifests/key.pp
  12. +17 −0 modules/apt/manifests/params.pp
  13. +9 −0 modules/apt/manifests/ppa.pp
  14. +34 −0 modules/apt/manifests/preferences.pp
  15. +21 −0 modules/apt/manifests/sources_list.pp
  16. +5 −0 modules/apt/manifests/unattended-upgrade.pp
  17. +22 −0 modules/apt/manifests/unattended-upgrade/automatic.pp
  18. +2 −0 modules/apt/templates/ppa-list.erb
  19. +5 −0 modules/apt/templates/preferences.erb
  20. +6 −0 modules/apt/templates/unattended-upgrades.Ubuntu.erb
  21. +4 −0 modules/apt/templates/unattended-upgrades.lenny.erb
  22. +5 −0 modules/apt/templates/unattended-upgrades.squeeze.erb
  23. +30 −0 modules/common/README
  24. +1 −0 modules/common/files/empty/.ignore
  25. +1 −0 modules/common/files/modules/README
  26. +16 −0 modules/common/lib/puppet/parser/functions/basename.rb
  27. +16 −0 modules/common/lib/puppet/parser/functions/dirname.rb
  28. +17 −0 modules/common/lib/puppet/parser/functions/gsub.rb
  29. +13 −0 modules/common/lib/puppet/parser/functions/hostname.rb
  30. +30 −0 modules/common/lib/puppet/parser/functions/ip_to_cron.rb
  31. +12 −0 modules/common/lib/puppet/parser/functions/network_lookup.rb
  32. +9 −0 modules/common/lib/puppet/parser/functions/prefix_with.rb
  33. +7 −0 modules/common/lib/puppet/parser/functions/re_escape.rb
  34. +7 −0 modules/common/lib/puppet/parser/functions/slash_escape.rb
  35. +17 −0 modules/common/lib/puppet/parser/functions/split.rb
  36. +20 −0 modules/common/lib/puppet/parser/functions/substitute.rb
  37. +19 −0 modules/common/lib/puppet/parser/functions/url_get.rb
  38. +8 −0 modules/common/manifests/append_if_no_such_line.pp
  39. +41 −0 modules/common/manifests/assert_lsbdistcodename.pp
  40. +71 −0 modules/common/manifests/concatenated_file.pp
  41. +16 −0 modules/common/manifests/concatenated_file_part.pp
  42. +91 −0 modules/common/manifests/concatfilepart.pp
  43. +53 −0 modules/common/manifests/config_file.pp
  44. +15 −0 modules/common/manifests/init.pp
  45. +42 −0 modules/common/manifests/line.pp
  46. +27 −0 modules/common/manifests/modules_dir.pp
  47. +24 −0 modules/common/manifests/modules_file.pp
  48. +30 −0 modules/common/manifests/replace.pp
  49. +4 −0 modules/common/manifests/require_lsbdistcodename.pp
  50. +19 −0 modules/common/tests/concatfilepart1.pp
  51. +19 −0 modules/common/tests/concatfilepart2.pp
  52. +19 −0 modules/common/tests/concatfilepart3.pp
  53. +19 −0 modules/common/tests/concatfilepart4.pp
  54. +25 −0 modules/common/tests/run-tests.sh
0 README
No changes.
9 Vagrantfile
@@ -0,0 +1,9 @@
+Vagrant::Config.run do |config|
+ config.vm.box = "lucid64"
+ config.vm.provision :puppet do |puppet|
+ puppet.manifests_path = "manifests"
+ puppet.manifest_file = "pythondev.pp"
+ puppet.module_path = "modules"
+ end
+ config.vm.customize ["modifyvm", :id, "--memory", "512"]
+end
35 manifests/pythondev.pp
@@ -0,0 +1,35 @@
+Exec { path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/ruby/bin/' }
+include common
+include apt
+package { ["libevent-dev", "git-core"]: ensure => "installed" }
+
+$package_file = "/etc/apt/sources.list.d/python_packages.list"
+
+$packages = [
+# Python versions to include, uncomment the desired versions
+#
+#'python2.4', 'python2.4-dev',
+#'python2.5', 'python2.5-dev',
+#'python2.6', 'python2.6-dev',
+'python2.7', 'python2.7-dev',
+#'python3.1', 'python3.1-dev',
+'python3.2', 'python3.2-dev',
+] # End the packages array
+
+define install_python_package {
+ case $name {
+ /^(.*)-dev/: { package { $name: ensure => latest, require => Package[$1] } }
+ default: { package { $name: ensure => latest, require => File[$package_file] } }
+ }
+}
+
+apt::key {"DB82666C":
+ source => "http://keyserver.ubuntu.com:11371/pks/lookup?op=get&search=0x5BB92C09DB82666C"
+}
+
+apt::sources_list {"python_packages":
+ ensure => present,
+ content => "deb http://ppa.launchpad.net/fkrull/deadsnakes/ubuntu lucid main",
+}
+
+install_python_package { $packages: }
58 modules/apt/README
@@ -0,0 +1,58 @@
+= apt puppet module =
+
+Manages apt configuration under Debian or Ubuntu.
+
+== Classes ==
+
+ * apt
+ * apt::backports
+ * apt::clean
+ * apt::params
+ * apt::unattended-upgrade
+ * apt::unattended-upgrade::automatic
+
+=== apt::clean ===
+
+Variables
+*$apt_clean_minutes*: cronjob minutes - default uses ip_to_cron from module "common"
+*$apt_clean_hours*: cronjob hours - default to 0
+*$apt_clean_mday*: cronjob monthday - default uses ip_to_cron from module "common"
+
+Require:
+- module common (http://github.com/camptocamp/puppet-common)
+
+== Definitions ==
+
+ * apt::conf
+ * apt::key
+ * apt::preferences
+ * apt::sources_list
+
+=== apt::conf ==
+
+apt::conf{"99unattended-upgrade":
+ ensure => present,
+ content => "APT::Periodic::Unattended-Upgrade \"1\";\n",
+}
+
+=== apt::key ===
+
+apt::key {"A37E4CF5":
+ source => "http://dev.camptocamp.com/packages/debian/pub.key",
+}
+
+=== apt::preferences ===
+
+apt::preferences {"${lsbdistcodename}-backports":
+ ensure => present,
+ package => "*",
+ pin => "release a=${lsbdistcodename}-backports",
+ priority => 400,
+}
+
+=== apt::sources_list ===
+
+apt::sources_list {"camptocamp":
+ ensure => present,
+ content => "deb http://dev.camptocamp.com/packages/ etch puppet",
+}
4 modules/apt/files/10periodic
@@ -0,0 +1,4 @@
+// Unattended-Upgrade::Mail "root";
+APT::Periodic::Update-Package-Lists "1";
+APT::Periodic::Download-Upgradeable-Packages "0";
+APT::Periodic::AutocleanInterval "1";
0 modules/apt/files/empty/.placeholder
No changes.
26 modules/apt/manifests/backports.pp
@@ -0,0 +1,26 @@
+class apt::backports {
+
+ apt::sources_list{"backports":
+ ensure => present,
+ content => $operatingsystem ? {
+ Debian => "deb http://backports.debian.org/debian-backports ${lsbdistcodename}-backports main contrib non-free\n",
+ Ubuntu => "deb http://archive.ubuntu.com/ubuntu ${lsbdistcodename}-backports main universe multiverse restricted\n",
+ }
+ }
+
+ apt::preferences {"${lsbdistcodename}-backports":
+ ensure => present,
+ package => "*",
+ pin => "release a=${lsbdistcodename}-backports",
+ priority => 400,
+ }
+
+ case $lsbdistid {
+ "Debian" : {
+ apt::key {"16BA136C":
+ ensure => absent,
+ source => "http://backports.org/debian/archive.key",
+ }
+ }
+ }
+}
27 modules/apt/manifests/clean.pp
@@ -0,0 +1,27 @@
+/*
+
+== Class: apt::clean
+create a cronjob which will run "apt-get clean" once a month.
+
+Arguments:
+*$apt_clean_minutes*: cronjob minutes - default uses ip_to_cron from module "common"
+*$apt_clean_hours*: cronjob hours - default to 0
+*$apt_clean_mday*: cronjob monthday - default uses ip_to_cron from module "common"
+
+Require:
+- module common (http://github.com/camptocamp/puppet-common)
+
+*/
+class apt::clean {
+ $minutes = $apt_clean_minutes? {'' => ip_to_cron(1, 59), default => $apt_clean_minutes }
+ $hours = $apt_clean_hours? {'' => "0", default => $apt_clean_hours }
+ $monthday = $apt_clean_mday? {'' => ip_to_cron(1, 28), default => $apt_clean_mday }
+
+ cron {"cleanup APT cache - prevents diskfull":
+ ensure => present,
+ command => "apt-get clean",
+ hour => $hours,
+ minute => $minutes,
+ monthday => $monthday,
+ }
+}
19 modules/apt/manifests/conf.pp
@@ -0,0 +1,19 @@
+define apt::conf($ensure, $content = false, $source = false) {
+ if $content {
+ file {"/etc/apt/apt.conf.d/${name}":
+ ensure => $ensure,
+ content => $content,
+ before => Exec["apt-get_update"],
+ notify => Exec["apt-get_update"],
+ }
+ }
+
+ if $source {
+ file {"/etc/apt/apt.conf.d/${name}":
+ ensure => $ensure,
+ source => $source,
+ before => Exec["apt-get_update"],
+ notify => Exec["apt-get_update"],
+ }
+ }
+}
48 modules/apt/manifests/init.pp
@@ -0,0 +1,48 @@
+class apt {
+
+ include apt::params
+
+ Package {
+ require => Exec["apt-get_update"]
+ }
+
+ # apt support preferences.d since version >= 0.7.22
+ case $lsbdistcodename {
+ /lucid|squeeze/ : {
+
+ file {"/etc/apt/preferences":
+ ensure => absent,
+ }
+
+ file {"/etc/apt/preferences.d":
+ ensure => directory,
+ owner => root,
+ group => root,
+ mode => 755,
+ recurse => "${apt::params::manage_preferences}",
+ purge => "${apt::params::manage_preferences}",
+ force => "${apt::params::manage_preferences}",
+ }
+ }
+ }
+
+ # ensure only files managed by puppet be present in this directory.
+ file { "/etc/apt/sources.list.d":
+ ensure => directory,
+ source => "puppet:///modules/apt/empty/",
+ recurse => "${apt::params::manage_sourceslist}",
+ purge => "${apt::params::manage_sourceslist}",
+ force => "${apt::params::manage_sourceslist}",
+ ignore => $apt::params::ignore_sourceslist,
+ }
+
+ apt::conf {"10periodic":
+ ensure => present,
+ source => "puppet:///modules/apt/10periodic",
+ }
+
+ exec { "apt-get_update":
+ command => "/usr/bin/apt-get update",
+ refreshonly => true,
+ }
+}
34 modules/apt/manifests/key.pp
@@ -0,0 +1,34 @@
+define apt::key($ensure=present, $source="", $content="") {
+
+ case $ensure {
+
+ present: {
+ if $content == "" {
+ if $source == "" {
+ $thekey = "gpg --keyserver pgp.mit.edu --recv-key '${name}' && gpg --export --armor '${name}'"
+ }
+ else {
+ $thekey = "wget -O - '${source}'"
+ }
+ }
+ else {
+ $thekey = "echo '${content}'"
+ }
+
+
+ exec { "import gpg key ${name}":
+ command => "${thekey} | apt-key add -",
+ unless => "apt-key list | grep -Fqe '${name}'",
+ before => Exec["apt-get_update"],
+ notify => Exec["apt-get_update"],
+ }
+ }
+
+ absent: {
+ exec {"apt-key del ${name}":
+ onlyif => "apt-key list | grep -Fqe '${name}'",
+ }
+ }
+
+ }
+}
17 modules/apt/manifests/params.pp
@@ -0,0 +1,17 @@
+class apt::params {
+
+ $manage_preferences = $apt_manage_preferences ? {
+ "" => true,
+ default => $apt_manage_preferences,
+ }
+
+ $manage_sourceslist = $apt_manage_sourceslist ? {
+ "" => true,
+ default => $apt_manage_sourceslist,
+ }
+
+ $ignore_sourceslist = $apt_ignore_sourceslist ? {
+ "" => ".placeholder",
+ default => $apt_ignore_sourceslist,
+ }
+}
9 modules/apt/manifests/ppa.pp
@@ -0,0 +1,9 @@
+define apt::ppa($key, $ppa="ppa", $ensure = present) {
+ apt::key { $key:
+ ensure => $ensure,
+ }
+ apt::sources_list {"${name}-${ppa}-${lsbdistcodename}":
+ ensure => $ensure,
+ content => template("apt/ppa-list.erb"),
+ }
+}
34 modules/apt/manifests/preferences.pp
@@ -0,0 +1,34 @@
+define apt::preferences($ensure="present", $package="", $pin, $priority) {
+
+ $pkg = $package ? {
+ "" => $name,
+ default => $package,
+ }
+
+ $fname = regsubst($name, '\.', '-', 'G')
+
+ # apt support preferences.d since version >= 0.7.22
+ if ($lsbdistid == "Debian" and versioncmp($lsbdistrelease, "6.0") >= 0) or
+ ($lsbdistid == "Ubuntu" and versioncmp($lsbdistrelease, "10.04") >= 0) {
+ file {"/etc/apt/preferences.d/$fname":
+ ensure => $ensure,
+ owner => root,
+ group => root,
+ mode => 644,
+ content => template("apt/preferences.erb"),
+ before => Exec["apt-get_update"],
+ notify => Exec["apt-get_update"],
+ }
+ }
+ else {
+ common::concatfilepart { $fname:
+ ensure => $ensure,
+ manage => true,
+ file => "/etc/apt/preferences",
+ content => template("apt/preferences.erb"),
+ before => Exec["apt-get_update"],
+ notify => Exec["apt-get_update"],
+ }
+ }
+
+}
21 modules/apt/manifests/sources_list.pp
@@ -0,0 +1,21 @@
+define apt::sources_list (
+ $ensure = present,
+ $source = false,
+ $content = false) {
+
+ if $source {
+ file {"/etc/apt/sources.list.d/${name}.list":
+ ensure => $ensure,
+ source => $source,
+ before => Exec["apt-get_update"],
+ notify => Exec["apt-get_update"],
+ }
+ } else {
+ file {"/etc/apt/sources.list.d/${name}.list":
+ ensure => $ensure,
+ content => $content,
+ before => Exec["apt-get_update"],
+ notify => Exec["apt-get_update"],
+ }
+ }
+}
5 modules/apt/manifests/unattended-upgrade.pp
@@ -0,0 +1,5 @@
+class apt::unattended-upgrade {
+ package {"unattended-upgrades":
+ ensure => present,
+ }
+}
22 modules/apt/manifests/unattended-upgrade/automatic.pp
@@ -0,0 +1,22 @@
+class apt::unattended-upgrade::automatic inherits apt::unattended-upgrade {
+ apt::conf{"99unattended-upgrade":
+ ensure => present,
+ content => "APT::Periodic::Unattended-Upgrade \"1\";\n",
+ }
+
+ case $lsbdistid {
+ 'Debian': {
+ apt::conf{'50unattended-upgrades':
+ ensure => present,
+ content => template("apt/unattended-upgrades.${lsbdistcodename}.erb"),
+ }
+ }
+ 'Ubuntu': {
+ apt::conf{'50unattended-upgrades':
+ ensure => present,
+ content => template("apt/unattended-upgrades.${lsbdistid}.erb"),
+ }
+ }
+ }
+
+}
2 modules/apt/templates/ppa-list.erb
@@ -0,0 +1,2 @@
+deb http://ppa.launchpad.net/<%= name %>/<%= ppa %>/ubuntu <%= lsbdistcodename %> main
+deb-src http://ppa.launchpad.net/<%= name %>/<%= ppa %>/ubuntu <%= lsbdistcodename %> main
5 modules/apt/templates/preferences.erb
@@ -0,0 +1,5 @@
+# file managed by puppet
+Package: <%= pkg %>
+Pin: <%= pin %>
+Pin-Priority: <%= priority %>
+
6 modules/apt/templates/unattended-upgrades.Ubuntu.erb
@@ -0,0 +1,6 @@
+Unattended-Upgrade::Allowed-Origins {
+ "Ubuntu <%= lsbdistcodename %>-security";
+ "Ubuntu <%= lsbdistcodename %>-updates";
+ "Ubuntu <%= lsbdistcodename %>";
+ "Canonical <%= lsbdistcodename %>";
+};
4 modules/apt/templates/unattended-upgrades.lenny.erb
@@ -0,0 +1,4 @@
+// file managed by puppet
+Unattended-Upgrade::Allowed-Origins {
+ "Debian oldstable";
+};
5 modules/apt/templates/unattended-upgrades.squeeze.erb
@@ -0,0 +1,5 @@
+// file managed by puppet
+Unattended-Upgrade::Allowed-Origins {
+ "Debian stable";
+ "Debian squeeze-security";
+};
30 modules/common/README
@@ -0,0 +1,30 @@
+puppet module common
+====================
+
+written by David Schmitt
+Copyright (C) 2007 David Schmitt
+<david@schmitt.edv-bus.at>
+
+adapted by immerda project group
+admin+puppet(at)immerda.ch
+
+#################################################
+
+The common module installs various functions that are
+required by other modules. This module should be
+installed before any of the other module.
+
+To use this module, follow these directions:
+
+1. Your modules directory will need all the files
+ included in this repository placed under a directory
+ called "common"
+
+2. Add the following line to manifests/site.pp:
+
+ import "modules.pp"
+
+3. Add the following line to manifests/modules.pp:
+
+ import "common"
+
1 modules/common/files/empty/.ignore
@@ -0,0 +1 @@
+# A placeholder to nail this directory into git
1 modules/common/files/modules/README
@@ -0,0 +1 @@
+this directory contains various data collected for system wide configurations
16 modules/common/lib/puppet/parser/functions/basename.rb
@@ -0,0 +1,16 @@
+# basename(string) : string
+# basename(string[]) : string[]
+#
+# Returns the last component of the filename given as argument, which must be
+# formed using forward slashes (``/..) regardless of the separator used on the
+# local file system.
+module Puppet::Parser::Functions
+ newfunction(:basename, :type => :rvalue) do |args|
+ if args[0].is_a?(Array)
+ args.collect do |a| File.basename(a) end
+ else
+ File.basename(args[0])
+ end
+ end
+end
+
16 modules/common/lib/puppet/parser/functions/dirname.rb
@@ -0,0 +1,16 @@
+# dirname(string) : string
+# dirname(string[]) : string[]
+#
+# Returns all components of the filename given as argument except the last
+# one. The filename must be formed using forward slashes (``/..) regardless of
+# the separator used on the local file system.
+module Puppet::Parser::Functions
+ newfunction(:dirname, :type => :rvalue) do |args|
+ if args[0].is_a?(Array)
+ args.collect do |a| File.dirname(a) end
+ else
+ File.dirname(args[0])
+ end
+ end
+end
+
17 modules/common/lib/puppet/parser/functions/gsub.rb
@@ -0,0 +1,17 @@
+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|
+ 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
+
13 modules/common/lib/puppet/parser/functions/hostname.rb
@@ -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
+
30 modules/common/lib/puppet/parser/functions/ip_to_cron.rb
@@ -0,0 +1,30 @@
+# Downloaded from http://reductivelabs.com/trac/puppet/wiki/Recipes/cron
+#
+# provides a "random" value to cron based on the last bit of the machine IP address.
+# used to avoid starting a certain cron job at the same time on all servers.
+# if used with no parameters, it will return a single value between 0-59
+# first argument is the occournce within a timeframe, for example if you want it to run 2 times per hour
+# the second argument is the timeframe, by default its 60 minutes, but it could also be 24 hours etc
+#
+# example usage
+# ip_to_cron() - returns one value between 0..59
+# ip_to_cron(2) - returns an array of two values between 0..59
+# ip_to_cron(2,24) - returns an array of two values between 0..23
+require 'ipaddr'
+module Puppet::Parser::Functions
+ newfunction(:ip_to_cron, :type => :rvalue) do |args|
+ occours = (args[0] || 1).to_i
+ scope = (args[1] || 60).to_i
+ ip = IPAddr.new(lookupvar('ipaddress')).to_s.split('.')[3].to_i
+ base = ip % scope
+ if occours == 1
+ base
+ else
+ cron = Array.new
+ (1..occours).each do |i|
+ cron << ((base - (scope / occours * i)) % scope)
+ end
+ return cron.sort
+ end
+ end
+end
12 modules/common/lib/puppet/parser/functions/network_lookup.rb
@@ -0,0 +1,12 @@
+module Puppet::Parser::Functions
+ newfunction(:network_lookup, :type => :rvalue) do |args|
+ case args[0]
+ when "ip" then
+ IPSocket::getaddress(lookupvar('fqdn'))
+ when "netmask" then
+ "255.255.255.0"
+ when "gateway" then
+ IPSocket::getaddress(lookupvar('fqdn')).gsub(/\.\d+$/, '.1')
+ end
+ end
+end
9 modules/common/lib/puppet/parser/functions/prefix_with.rb
@@ -0,0 +1,9 @@
+# prefix arguments 2..n with first argument
+
+module Puppet::Parser::Functions
+ newfunction(:prefix_with, :type => :rvalue) do |args|
+ prefix = args.shift
+ args.collect {|v| "%s%s" % [prefix, v] }
+ end
+end
+
7 modules/common/lib/puppet/parser/functions/re_escape.rb
@@ -0,0 +1,7 @@
+# apply regexp escaping to a string
+module Puppet::Parser::Functions
+ newfunction(:re_escape, :type => :rvalue) do |args|
+ Regexp.escape(args[0])
+ end
+end
+
7 modules/common/lib/puppet/parser/functions/slash_escape.rb
@@ -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
+
17 modules/common/lib/puppet/parser/functions/split.rb
@@ -0,0 +1,17 @@
+# split($string, $delimiter) : $string
+# split($string[], $delimiter) : $string[][]
+#
+# Split the first argument(s) on every $delimiter. $delimiter 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(:split, :type => :rvalue) do |args|
+ if args[0].is_a?(Array)
+ args.collect do |a| a.split(/#{args[1]}/) end
+ else
+ args[0].split(/#{args[1]}/)
+ end
+ end
+end
20 modules/common/lib/puppet/parser/functions/substitute.rb
@@ -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
+
19 modules/common/lib/puppet/parser/functions/url_get.rb
@@ -0,0 +1,19 @@
+# Returns the content at given URL
+
+module Puppet::Parser::Functions
+ newfunction(:url_get, :type => :rvalue) do |args|
+ require 'open-uri'
+
+ url = args[0]
+
+ begin
+ data = open(url, :proxy => nil)
+ # Ignore header
+ data.readline
+ data.readline.chomp
+ rescue OpenURI::HTTPError => error
+ fail "Fetching URL #{url} failed with status #{error.message}"
+ end
+ end
+end
+
8 modules/common/manifests/append_if_no_such_line.pp
@@ -0,0 +1,8 @@
+define common::append_if_no_such_line($file, $line, $refreshonly = 'false') {
+ exec { "/bin/echo '$line' >> '$file'":
+ unless => "/bin/grep -Fxqe '$line' '$file'",
+ path => "/bin",
+ refreshonly => $refreshonly,
+ subscribe => File[$file],
+ }
+}
41 modules/common/manifests/assert_lsbdistcodename.pp
@@ -0,0 +1,41 @@
+# 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
+class common::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 }
+ }
+ '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 }
+ }
+ default: {
+ exec { "true # assert_lsbdistcodename": alias => assert_lsbdistcodename }
+ exec { "true # require_lsbdistcodename": alias => require_lsbdistcodename }
+ }
+ }
+
+}
71 modules/common/manifests/concatenated_file.pp
@@ -0,0 +1,71 @@
+# common/manifests/defines/concatenated_file.pp -- create a file from snippets
+# stored in a directory
+#
+# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
+# See LICENSE for the full license granted to you.
+
+# TODO:
+# * create the directory in _part too
+
+# Usage:
+# concatenated_file { "/etc/some.conf":
+# dir => "/etc/some.conf.d",
+# }
+# Use Exec["concat_$name"] as Semaphor
+define common::concatenated_file (
+ # where the snippets are located
+ $dir = '',
+ # a file with content to prepend
+ $header = '',
+ # a file with content to append
+ $footer = '',
+ $mode = 0644, $owner = root, $group = 0
+ )
+{
+
+ $dir_real = $dir ? { '' => "${name}.d", default => $dir }
+
+ if defined(File[$dir_real]) {
+ debug("${dir_real} already defined")
+ } else {
+ file {
+ $dir_real:
+ source => "puppet://$server/common/empty",
+ checksum => mtime,
+ ignore => '\.ignore',
+ recurse => true, purge => true, force => true,
+ mode => $mode, owner => $owner, group => $group,
+ notify => Exec["concat_${name}"];
+ }
+ }
+
+ file {
+ $name:
+ ensure => present, checksum => md5,
+ mode => $mode, owner => $owner, group => $group;
+ }
+
+ # if there is a header or footer file, add it
+ $additional_cmd = $header ? {
+ '' => $footer ? {
+ '' => '',
+ default => "| cat - '${footer}' "
+ },
+ default => $footer ? {
+ '' => "| cat '${header}' - ",
+ default => "| cat '${header}' - '${footer}' "
+ }
+ }
+
+ # use >| to force clobbering the target file
+ exec { "concat_${name}":
+ command => "/usr/bin/find ${dir_real} -maxdepth 1 -type f ! -name '*puppettmp' -print0 | sort -z | xargs -0 cat ${additional_cmd} >| ${name}",
+ refreshonly => true,
+ subscribe => [ File[$dir_real] ],
+ before => File[$name],
+ refreshonly => true,
+ subscribe => [ File[$dir_real] ],
+ before => File[$name],
+ alias => [ "concat_${dir_real}"] ,
+ }
+}
16 modules/common/manifests/concatenated_file_part.pp
@@ -0,0 +1,16 @@
+# Add a snippet called $name to the concatenated_file at $dir.
+# The file can be referenced as File["cf_part_${name}"]
+define common::concatenated_file_part (
+ $dir, $content = '', $ensure = present,
+ $mode = 0644, $owner = root, $group = 0
+ )
+{
+
+ file { "${dir}/${name}":
+ ensure => $ensure, content => $content,
+ mode => $mode, owner => $owner, group => $group,
+ alias => "cf_part_${name}",
+ notify => Exec["concat_${dir}"],
+ }
+
+}
91 modules/common/manifests/concatfilepart.pp
@@ -0,0 +1,91 @@
+# Inspired by David Schmitt's concatenated_file.pp
+
+define common::concatfilepart (
+ $ensure = present,
+ $file,
+ $content = false,
+ $source = false,
+ $manage = false
+) {
+
+ # Resulting file
+ if defined(File[$file]) {
+ debug("${file} already defined")
+ } else {
+ file {$file:
+ ensure => present,
+ }
+ }
+
+ # Directory containing file parts
+ $dir = "${file}.d"
+
+ if defined(File[$dir]) {
+ debug("${dir} already defined")
+ } else {
+ file {$dir:
+ ensure => directory,
+ mode => 0600,
+ source => "puppet:///modules/common/empty/",
+ recurse => $manage,
+ purge => $manage,
+ force => $manage,
+ ignore => '.ignore',
+ }
+ }
+
+ if $notify {
+ if $content {
+ file {"${dir}/${name}":
+ ensure => $ensure,
+ content => $content,
+ mode => 0600,
+ notify => [Exec["${file} concatenation"], $notify],
+ }
+ } else {
+ file {"${dir}/${name}":
+ ensure => $ensure,
+ source => $source,
+ mode => 0600,
+ notify => [Exec["${file} concatenation"], $notify],
+ }
+ }
+ } else {
+ if $content {
+ file {"${dir}/${name}":
+ ensure => $ensure,
+ content => $content,
+ mode => 0600,
+ notify => Exec["${file} concatenation"],
+ }
+ } else {
+ file {"${dir}/${name}":
+ ensure => $ensure,
+ source => $source,
+ mode => 0600,
+ notify => Exec["${file} concatenation"],
+ }
+ }
+ }
+
+ # The actual file generation
+ if defined(Exec["${file} concatenation"]) {
+
+ debug("Blah")
+ #Exec["${file} concatenation"] {
+ # require +> File["${dir}/${name}"],
+ #}
+
+ } else {
+ # use >| to force clobbering the target file
+ exec { "${file} concatenation":
+ command => "/usr/bin/find ${dir} -maxdepth 1 -type f ! -name '*puppettmp' -print0 | sort -z | xargs -0 cat >| ${file}",
+ refreshonly => true,
+ subscribe => File[$dir],
+ before => File[$file],
+ # require => File["${dir}/${name}"],
+ #alias => [ "concat_${name}", "concat_${dir}"] ,
+ }
+ }
+
+}
53 modules/common/manifests/config_file.pp
@@ -0,0 +1,53 @@
+# common/manifests/defines/config_file.pp -- create a config file with default permissions
+# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
+# See LICENSE for the full license granted to you.
+
+# Usage:
+# config_file { filename:
+# content => "....\n",
+# }
+#
+# Examples:
+#
+# To create the file /etc/vservers/${vs_name}/context with specific
+# content:
+#
+# config_file { "/etc/vservers/${vs_name}/context":
+# content => "${context}\n",
+# notify => Exec["vs_restart_${vs_name}"],
+# require => Exec["vs_create_${vs_name}"];
+# }
+#
+# To create the file /etc/apache2/sites-available/munin-stats with the
+# content pulled from a template:
+#
+# config_file { "/etc/apache2/sites-available/munin-stats":
+# content => template("apache/munin-stats"),
+# require => Package["apache2"],
+# notify => Exec["reload-apache2"]
+# }
+
+define config_file ($content = '', $source = '', $ensure = 'present') {
+ file { $name:
+ 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 } }
+ }
+
+}
+
+
15 modules/common/manifests/init.pp
@@ -0,0 +1,15 @@
+# common/manifests/init.pp - Define common infrastructure for modules
+# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
+# See LICENSE for the full license granted to you.
+class common {
+ file {
+ # Module programmers can use /var/lib/puppet/modules/$modulename to save
+ # module-local data, e.g. for constructing config files
+ "/var/lib/puppet/modules":
+ ensure => directory,
+ source => "puppet://$server/common/modules/",
+ ignore => ".ignore",
+ recurse => true, purge => true, force => true,
+ mode => 0755, owner => root, group => 0;
+ }
+}
42 modules/common/manifests/line.pp
@@ -0,0 +1,42 @@
+# common/manifests/defines/line.pp -- a trivial mechanism to ensure a line exists in a file
+# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
+# See LICENSE for the full license granted to you.
+
+# Usage:
+# line { description:
+# file => "filename",
+# line => "content",
+# ensure => {absent,*present*}
+# }
+#
+# Example:
+# The following ensures that the line "allow ^$munin_host$" exists
+# in /etc/munin/munin-node.conf, and if there are any changes notify the service for
+# a restart
+#
+# line { allow_munin_host:
+# file => "/etc/munin/munin-node.conf",
+# line => "allow ^$munin_host$",
+# ensure => present,
+# notify => Service[munin-node],
+# require => Package[munin-node],
+# }
+#
+#
+define common::line($file, $line, $ensure = 'present') {
+ case $ensure {
+ default : { err ( "unknown ensure value '${ensure}'" ) }
+ present: {
+ exec { "echo '${line}' >> '${file}'":
+ unless => "grep -qFx '${line}' '${file}'"
+ }
+ }
+ absent: {
+ exec { "perl -ni -e 'print if \$_ ne \"${line}\n\";' '${file}'":
+ onlyif => "grep -qFx '${line}' '${file}'"
+ }
+ }
+ }
+}
+
+
27 modules/common/manifests/modules_dir.pp
@@ -0,0 +1,27 @@
+# common/manifests/defines/modules_dir.pp -- create a default directory
+# for storing module specific information
+#
+# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
+# See LICENSE for the full license granted to you.
+
+# Usage:
+# modules_dir { ["common", "common/dir1", "common/dir2" ]: }
+define modules_dir (
+ $mode = 0644, $owner = root, $group = 0
+ )
+{
+ $dir = "/var/lib/puppet/modules/${name}"
+ if defined(File[$dir]) {
+ debug("${dir} already defined")
+ } else {
+ file {
+ "/var/lib/puppet/modules/${name}":
+ source => [ "puppet:///modules/${name}/modules_dir", "puppet:///modules/common/empty"],
+ checksum => mtime,
+ # ignore the placeholder
+ ignore => '\.ignore',
+ recurse => true, purge => true, force => true,
+ mode => $mode, owner => $owner, group => $group;
+ }
+ }
+}
24 modules/common/manifests/modules_file.pp
@@ -0,0 +1,24 @@
+# common/manifests/defines/modules_file.pp -- use a modules_dir to store module
+# specific files
+#
+# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
+# See LICENSE for the full license granted to you.
+
+# Usage:
+# modules_file { "module/file":
+# source => "puppet://..",
+# mode => 644, # default
+# owner => root, # default
+# group => root, # default
+# }
+define common::modules_file (
+ $source,
+ $mode = 0644, $owner = root, $group = root
+ )
+{
+ file {
+ "/var/lib/puppet/modules/${name}":
+ source => $source,
+ mode => $mode, owner => $owner, group => $group;
+ }
+}
30 modules/common/manifests/replace.pp
@@ -0,0 +1,30 @@
+# common/manifests/defines/replace.pp -- replace a pattern in a file with a string
+# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
+# See LICENSE for the full license granted to you.
+
+# Usage:
+#
+# replace { description:
+# file => "filename",
+# pattern => "regexp",
+# replacement => "replacement"
+#
+# Example:
+# To replace the current port in /etc/munin/munin-node.conf
+# with a new port, but only disturbing the file when needed:
+#
+# replace { set_munin_node_port:
+# file => "/etc/munin/munin-node.conf",
+# pattern => "^port (?!$port)[0-9]*",
+# replacement => "port $port"
+# }
+
+define common::replace($file, $pattern, $replacement) {
+ $pattern_no_slashes = slash_escape($pattern)
+ $replacement_no_slashes = slash_escape($replacement)
+ 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",
+ }
+}
4 modules/common/manifests/require_lsbdistcodename.pp
@@ -0,0 +1,4 @@
+# To fail the complete compilation, include this class
+class common::require_lsbdistcodename inherits common::assert_lsbdistcodename {
+ exec { "false # require_lsbdistcodename": require => Exec[require_lsbdistcodename], }
+}
19 modules/common/tests/concatfilepart1.pp
@@ -0,0 +1,19 @@
+import "../manifests/concatfilepart.pp"
+
+common::concatfilepart{"0_header":
+ ensure => present,
+ content => "A",
+ file => "/tmp/test-concat.txt",
+}
+
+common::concatfilepart{"1_body":
+ ensure => present,
+ content => "B",
+ file => "/tmp/test-concat.txt",
+}
+
+common::concatfilepart{"9_footer":
+ ensure => present,
+ content => "C",
+ file => "/tmp/test-concat.txt",
+}
19 modules/common/tests/concatfilepart2.pp
@@ -0,0 +1,19 @@
+import "../manifests/concatfilepart.pp"
+
+common::concatfilepart{"0_header":
+ ensure => absent,
+ content => "A",
+ file => "/tmp/test-concat.txt",
+}
+
+common::concatfilepart{"1_body":
+ ensure => present,
+ content => "B",
+ file => "/tmp/test-concat.txt",
+}
+
+common::concatfilepart{"9_footer":
+ ensure => present,
+ content => "C",
+ file => "/tmp/test-concat.txt",
+}
19 modules/common/tests/concatfilepart3.pp
@@ -0,0 +1,19 @@
+import "../manifests/concatfilepart.pp"
+
+common::concatfilepart{"0_blah":
+ ensure => present,
+ content => "Z",
+ file => "/tmp/test-concat.txt",
+}
+
+common::concatfilepart{"1_body":
+ ensure => present,
+ content => "B",
+ file => "/tmp/test-concat.txt",
+}
+
+common::concatfilepart{"9_footer":
+ ensure => present,
+ content => "C",
+ file => "/tmp/test-concat.txt",
+}
19 modules/common/tests/concatfilepart4.pp
@@ -0,0 +1,19 @@
+import "../manifests/concatfilepart.pp"
+
+common::concatfilepart{"0_blah":
+ ensure => absent,
+ content => "Z",
+ file => "/tmp/test-concat.txt",
+}
+
+common::concatfilepart{"1_body":
+ ensure => absent,
+ content => "B",
+ file => "/tmp/test-concat.txt",
+}
+
+common::concatfilepart{"9_footer":
+ ensure => absent,
+ content => "C",
+ file => "/tmp/test-concat.txt",
+}
25 modules/common/tests/run-tests.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+error() {
+ echo "Error"
+ exit 1
+}
+
+TF="/tmp/test-concat.txt"
+
+echo "concatfilepart"
+echo
+
+rm -r /tmp/test-concat.txt*
+
+puppet concatfilepart1.pp
+echo "ABC =? $(cat /tmp/test-concat.txt)"
+
+puppet concatfilepart2.pp
+echo "BC =? $(cat /tmp/test-concat.txt)"
+
+puppet concatfilepart3.pp
+echo "ZBC =? $(cat /tmp/test-concat.txt)"
+
+puppet concatfilepart4.pp
+echo " =? $(cat /tmp/test-concat.txt)"

0 comments on commit 1cb941a

Please sign in to comment.