Add a bunch more cookbooks
authorTom Hughes <tom@compton.nu>
Thu, 30 May 2013 22:01:17 +0000 (23:01 +0100)
committerTom Hughes <tom@compton.nu>
Thu, 30 May 2013 22:01:17 +0000 (23:01 +0100)
134 files changed:
cookbooks/bind/README.md [new file with mode: 0644]
cookbooks/bind/attributes/default.rb [new file with mode: 0644]
cookbooks/bind/metadata.rb [new file with mode: 0644]
cookbooks/bind/recipes/default.rb [new file with mode: 0644]
cookbooks/bind/templates/default/db.10.erb [new file with mode: 0644]
cookbooks/bind/templates/default/named.local.erb [new file with mode: 0644]
cookbooks/bind/templates/default/named.options.erb [new file with mode: 0644]
cookbooks/blog/README.rdoc [new file with mode: 0644]
cookbooks/blog/metadata.rb [new file with mode: 0644]
cookbooks/blog/recipes/default.rb [new file with mode: 0644]
cookbooks/blog/templates/default/opengeodata.erb [new file with mode: 0644]
cookbooks/chef/README.rdoc [new file with mode: 0644]
cookbooks/chef/attributes/default.rb [new file with mode: 0644]
cookbooks/chef/definitions/ohai_plugin.rb [new file with mode: 0644]
cookbooks/chef/files/default/knife.rb [new file with mode: 0644]
cookbooks/chef/libraries/git.rb [new file with mode: 0644]
cookbooks/chef/libraries/subversion.rb [new file with mode: 0644]
cookbooks/chef/metadata.rb [new file with mode: 0644]
cookbooks/chef/recipes/default.rb [new file with mode: 0644]
cookbooks/chef/recipes/gems.rb [new file with mode: 0644]
cookbooks/chef/recipes/repository.rb [new file with mode: 0644]
cookbooks/chef/recipes/server.rb [new file with mode: 0644]
cookbooks/chef/templates/default/apache.erb [new file with mode: 0644]
cookbooks/chef/templates/default/chef-client.conf.erb [new file with mode: 0644]
cookbooks/chef/templates/default/client.rb.erb [new file with mode: 0644]
cookbooks/chef/templates/default/logrotate.erb [new file with mode: 0644]
cookbooks/chef/templates/default/post-receive.erb [new file with mode: 0644]
cookbooks/chef/templates/default/report.rb.erb [new file with mode: 0644]
cookbooks/chef/templates/default/server.rb.erb [new file with mode: 0644]
cookbooks/devices/README.rdoc [new file with mode: 0644]
cookbooks/devices/attributes/default.rb [new file with mode: 0644]
cookbooks/devices/metadata.rb [new file with mode: 0644]
cookbooks/devices/recipes/default.rb [new file with mode: 0644]
cookbooks/devices/templates/default/udev.rules.erb [new file with mode: 0644]
cookbooks/geodns/README.rdoc [new file with mode: 0644]
cookbooks/geodns/metadata.rb [new file with mode: 0644]
cookbooks/geodns/recipes/default.rb [new file with mode: 0644]
cookbooks/geodns/templates/default/cron.erb [new file with mode: 0644]
cookbooks/geodns/templates/default/geo.conf.erb [new file with mode: 0644]
cookbooks/geodns/templates/default/tile.conf.erb [new file with mode: 0644]
cookbooks/memcached/README.rdoc [new file with mode: 0644]
cookbooks/memcached/attributes/default.rb [new file with mode: 0644]
cookbooks/memcached/metadata.rb [new file with mode: 0644]
cookbooks/memcached/recipes/default.rb [new file with mode: 0644]
cookbooks/memcached/templates/default/memcached.conf.erb [new file with mode: 0644]
cookbooks/memcached/templates/default/munin.erb [new file with mode: 0644]
cookbooks/munin/README.rdoc [new file with mode: 0644]
cookbooks/munin/attributes/default.rb [new file with mode: 0644]
cookbooks/munin/definitions/munin_plugin.rb [new file with mode: 0644]
cookbooks/munin/definitions/munin_plugin_conf.rb [new file with mode: 0644]
cookbooks/munin/files/default/plugin-conf.d/api [new file with mode: 0644]
cookbooks/munin/files/default/plugin-conf.d/hpasmcli [new file with mode: 0644]
cookbooks/munin/files/default/plugin-conf.d/passenger [new file with mode: 0644]
cookbooks/munin/files/default/plugins/apcpdu_ [new file with mode: 0755]
cookbooks/munin/files/default/plugins/api_calls_ [new file with mode: 0755]
cookbooks/munin/files/default/plugins/api_calls_num [new file with mode: 0755]
cookbooks/munin/files/default/plugins/api_waits_ [new file with mode: 0755]
cookbooks/munin/files/default/plugins/fw_conntrack [new file with mode: 0755]
cookbooks/munin/files/default/plugins/hpasmcli_fans [new file with mode: 0755]
cookbooks/munin/files/default/plugins/hpasmcli_temp [new file with mode: 0755]
cookbooks/munin/files/default/plugins/memcached_ [new file with mode: 0755]
cookbooks/munin/files/default/plugins/memcached_multi_ [new file with mode: 0755]
cookbooks/munin/files/default/plugins/mod_tile_fresh [new file with mode: 0755]
cookbooks/munin/files/default/plugins/mod_tile_response [new file with mode: 0755]
cookbooks/munin/files/default/plugins/nominatim_lag [new file with mode: 0755]
cookbooks/munin/files/default/plugins/nominatim_query_speed [new file with mode: 0755]
cookbooks/munin/files/default/plugins/nominatim_query_volume [new file with mode: 0755]
cookbooks/munin/files/default/plugins/passenger_memory [new file with mode: 0755]
cookbooks/munin/files/default/plugins/passenger_processes [new file with mode: 0755]
cookbooks/munin/files/default/plugins/passenger_queues [new file with mode: 0755]
cookbooks/munin/files/default/plugins/passenger_requests [new file with mode: 0755]
cookbooks/munin/files/default/plugins/postgres_replication [new file with mode: 0755]
cookbooks/munin/files/default/plugins/renderd_processed [new file with mode: 0755]
cookbooks/munin/files/default/plugins/renderd_queue [new file with mode: 0755]
cookbooks/munin/files/default/plugins/renderd_zoom [new file with mode: 0755]
cookbooks/munin/files/default/plugins/renderd_zoom_time [new file with mode: 0755]
cookbooks/munin/files/default/plugins/replication_delay [new file with mode: 0755]
cookbooks/munin/files/default/plugins/squid_delay_pools [new file with mode: 0755]
cookbooks/munin/files/default/plugins/squid_times [new file with mode: 0755]
cookbooks/munin/libraries/expand.rb [new file with mode: 0644]
cookbooks/munin/metadata.rb [new file with mode: 0644]
cookbooks/munin/recipes/default.rb [new file with mode: 0644]
cookbooks/munin/recipes/server.rb [new file with mode: 0644]
cookbooks/munin/templates/default/apache.erb [new file with mode: 0644]
cookbooks/munin/templates/default/munin-node.conf.erb [new file with mode: 0644]
cookbooks/munin/templates/default/munin.conf.erb [new file with mode: 0644]
cookbooks/nodejs/README.rdoc [new file with mode: 0644]
cookbooks/nodejs/metadata.rb [new file with mode: 0644]
cookbooks/nodejs/providers/package.rb [new file with mode: 0644]
cookbooks/nodejs/recipes/default.rb [new file with mode: 0644]
cookbooks/nodejs/resources/package.rb [new file with mode: 0644]
cookbooks/ntp/README.md [new file with mode: 0644]
cookbooks/ntp/attributes/default.rb [new file with mode: 0644]
cookbooks/ntp/metadata.rb [new file with mode: 0644]
cookbooks/ntp/recipes/default.rb [new file with mode: 0644]
cookbooks/ntp/templates/default/ntp.conf.erb [new file with mode: 0644]
cookbooks/openssh/metadata.rb [new file with mode: 0644]
cookbooks/openssh/recipes/default.rb [new file with mode: 0644]
cookbooks/openssh/templates/default/ssh_config.erb [new file with mode: 0644]
cookbooks/openssh/templates/default/ssh_known_hosts.erb [new file with mode: 0644]
cookbooks/ssl/README.rdoc [new file with mode: 0644]
cookbooks/ssl/files/default/openstreetmap.pem [new file with mode: 0644]
cookbooks/ssl/files/default/rapidssl.pem [new file with mode: 0644]
cookbooks/ssl/metadata.rb [new file with mode: 0644]
cookbooks/ssl/recipes/default.rb [new file with mode: 0644]
cookbooks/stateofthemap/README.rdoc [new file with mode: 0644]
cookbooks/stateofthemap/metadata.rb [new file with mode: 0644]
cookbooks/stateofthemap/recipes/default.rb [new file with mode: 0644]
cookbooks/sysctl/README.rdoc [new file with mode: 0644]
cookbooks/sysctl/metadata.rb [new file with mode: 0644]
cookbooks/sysctl/recipes/default.rb [new file with mode: 0644]
cookbooks/sysctl/templates/default/chef.conf.erb [new file with mode: 0644]
cookbooks/sysctl/templates/default/sysctl.conf.erb [new file with mode: 0644]
cookbooks/sysfs/README.rdoc [new file with mode: 0644]
cookbooks/sysfs/attributes/default.rb [new file with mode: 0644]
cookbooks/sysfs/metadata.rb [new file with mode: 0644]
cookbooks/sysfs/recipes/default.rb [new file with mode: 0644]
cookbooks/sysfs/templates/default/sysfs.conf.erb [new file with mode: 0644]
cookbooks/tools/README.rdoc [new file with mode: 0644]
cookbooks/tools/libraries/content_from_file.rb [new file with mode: 0644]
cookbooks/tools/libraries/random_password.rb [new file with mode: 0644]
cookbooks/tools/metadata.rb [new file with mode: 0644]
cookbooks/tools/recipes/default.rb [new file with mode: 0644]
cookbooks/trac/README.rdoc [new file with mode: 0644]
cookbooks/trac/files/default/htdocs/osm.ico [new file with mode: 0644]
cookbooks/trac/files/default/htdocs/osm.png [new file with mode: 0644]
cookbooks/trac/files/default/htdocs/robots.txt [new file with mode: 0644]
cookbooks/trac/files/default/templates/site.html [new file with mode: 0644]
cookbooks/trac/files/default/trac-authenticate [new file with mode: 0755]
cookbooks/trac/metadata.rb [new file with mode: 0644]
cookbooks/trac/recipes/default.rb [new file with mode: 0644]
cookbooks/trac/templates/default/apache.erb [new file with mode: 0644]
cookbooks/trac/templates/default/sudoers.erb [new file with mode: 0644]
cookbooks/trac/templates/default/trac.ini.erb [new file with mode: 0644]

diff --git a/cookbooks/bind/README.md b/cookbooks/bind/README.md
new file mode 100644 (file)
index 0000000..6b08769
--- /dev/null
@@ -0,0 +1,57 @@
+DESCRIPTION
+===========
+
+Configures networking.
+
+USAGE
+=====
+
+Set the networking attributes in a role, for example from my base.rb:
+
+    :networking => {
+      :nameservers => [ "10.13.37.120", "10.13.37.40" ],
+      :search => [ "int.example.org". "example.org" ]
+    }
+
+The resulting /etc/resolv.conf will look like:
+
+    search int.example.org example.org
+    nameserver 10.13.37.120
+    nameserver 10.13.37.40
+
+LICENSE AND AUTHOR
+==================
+
+Author:: OpenStreetMap Administrators (<admins@openstreetmap.org>)
+
+Copyright 2010, OpenStreetMap Foundation.
+
+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.
+
+Based on resolver cookbook:
+
+Author:: Joshua Timberman (<joshua@opscode.com>)
+
+Copyright 2009, Opscode, Inc.
+
+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.
diff --git a/cookbooks/bind/attributes/default.rb b/cookbooks/bind/attributes/default.rb
new file mode 100644 (file)
index 0000000..29b1d6b
--- /dev/null
@@ -0,0 +1 @@
+default[:bind] = { }
diff --git a/cookbooks/bind/metadata.rb b/cookbooks/bind/metadata.rb
new file mode 100644 (file)
index 0000000..6cca4b1
--- /dev/null
@@ -0,0 +1,17 @@
+maintainer        "OpenStreetMap Administrators"
+maintainer_email  "admins@openstreetmap.org"
+license           "Apache 2.0"
+description       "Configures bind"
+long_description  IO.read(File.join(File.dirname(__FILE__), 'README.md'))
+version           "1.0.0"
+depends           "networking"
+
+attribute "bind",
+  :display_name => "bind",
+  :description => "Hash of bind attributes",
+  :type => "hash"
+
+attribute "bind/forwarders",
+  :display_name => "bind",
+  :description => "Array of resolvers to forward to",
+  :type => "array"
diff --git a/cookbooks/bind/recipes/default.rb b/cookbooks/bind/recipes/default.rb
new file mode 100644 (file)
index 0000000..80dee1d
--- /dev/null
@@ -0,0 +1,69 @@
+#
+# Cookbook Name:: bind
+# Recipe:: default
+#
+# Copyright 2011, OpenStreetMap Foundation
+#
+# 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.
+#
+
+include_recipe "networking"
+
+package "bind9"
+
+service "bind9" do
+  action [ :enable, :start ]
+  supports :status => true, :restart => true, :reload => true
+end
+
+template "/etc/bind/named.conf.local" do
+  source "named.local.erb"
+  owner "root"
+  group "root"
+  mode 0644
+  notifies :restart, resources(:service => "bind9")
+end
+
+template "/etc/bind/named.conf.options" do
+  source "named.options.erb"
+  owner "root"
+  group "root"
+  mode 0644
+  notifies :restart, resources(:service => "bind9")
+end
+
+template "/etc/bind/db.10" do
+  source "db.10.erb"
+  owner "root"
+  group "root"
+  mode 0644
+  notifies :reload, resources(:service => "bind9")
+end
+
+firewall_rule "accept-dns-udp" do
+  action :accept
+  source "net"
+  dest "fw"
+  proto "udp"
+  dest_ports "domain"
+  source_ports "-"
+end
+
+firewall_rule "accept-dns-tcp" do
+  action :accept
+  source "net"
+  dest "fw"
+  proto "tcp:syn"
+  dest_ports "domain"
+  source_ports "-"
+end
diff --git a/cookbooks/bind/templates/default/db.10.erb b/cookbooks/bind/templates/default/db.10.erb
new file mode 100644 (file)
index 0000000..98eef8a
--- /dev/null
@@ -0,0 +1,39 @@
+; DO NOT EDIT - This file is being maintained by Chef
+
+$TTL   604800
+@      IN      SOA     <%= node[:fdqn] %>. root.openstreetmap.org. (
+                    2012100902         ; Serial
+                        604800         ; Refresh
+                         86400         ; Retry
+                       2419200         ; Expire
+                        604800 )       ; Negative Cache TTL
+
+@      IN      NS      <%= node[:fdqn] %>.
+
+3.0.0  IN      PTR     ridley.ucl.openstreetmap.org.
+5.0.0  IN      PTR     norbert.ucl.openstreetmap.org.
+6.0.0  IN      PTR     urmel.ucl.openstreetmap.org.
+7.0.0  IN      PTR     faffy.ucl.openstreetmap.org.
+8.0.0  IN      PTR     zark.ucl.openstreetmap.org.
+9.0.0  IN      PTR     eustace.ucl.openstreetmap.org.
+11.0.0 IN      PTR     draco.ucl.openstreetmap.org.
+12.0.0 IN      PTR     sarel.ucl.openstreetmap.org.
+14.0.0 IN      PTR     errol.ucl.openstreetmap.org.
+15.0.0 IN      PTR     yevaud.ucl.openstreetmap.org.
+
+49.0.0 IN      PTR     apc1.ucl.openstreetmap.org.
+50.0.0  IN      PTR     apc2.ucl.openstreetmap.org.
+51.0.0 IN      PTR     apc3.ucl.openstreetmap.org.
+
+5.1.0  IN      PTR     norbert.oob.openstreetmap.org.
+6.1.0  IN      PTR     urmel.oob.openstreetmap.org.
+7.1.0  IN      PTR     faffy.oob.openstreetmap.org.
+8.1.0  IN      PTR     soup.oob.openstreetmap.org.
+9.1.0  IN      PTR     eustace.oob.openstreetmap.org.
+11.1.0 IN      PTR     draco.oob.openstreetmap.org.
+12.1.0 IN      PTR     sarel.oob.openstreetmap.org.
+14.1.0 IN      PTR     errol.oob.openstreetmap.org.
+15.1.0 IN      PTR     yevaud.oob.openstreetmap.org.
+
+251.0.0        IN      PTR     shenron.internal.openstreetmap.org.
+252.0.0        IN      PTR     konqi.internal.openstreetmap.org.
diff --git a/cookbooks/bind/templates/default/named.local.erb b/cookbooks/bind/templates/default/named.local.erb
new file mode 100644 (file)
index 0000000..4c6c95b
--- /dev/null
@@ -0,0 +1,6 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+zone "10.in-addr.arpa" {
+       type master;
+       file "/etc/bind/db.10";
+};
diff --git a/cookbooks/bind/templates/default/named.options.erb b/cookbooks/bind/templates/default/named.options.erb
new file mode 100644 (file)
index 0000000..a2bd23d
--- /dev/null
@@ -0,0 +1,37 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+acl "osm" {
+       127.0.0.1/32;
+<% node.interfaces(:family => :inet).each do |interface| -%>
+       <%= interface[:network] %>/<%= interface[:prefix] %>;
+<% end -%>
+
+       ::1/128;
+<% node.interfaces(:family => :inet6).each do |interface| -%>
+       <%= interface[:network] %>/<%= interface[:prefix] %>;
+<% end -%>
+};
+
+options {
+        # Directory to use for any working files
+       directory "/var/cache/bind";
+
+<% if node[:bind][:forwarders] -%>
+       # Forward any queries we can't answer
+       forwarders {
+<% node[:bind][:forwarders].each do |forwarder| -%>
+               <%= forwarder %>;
+<% end -%>
+       };
+<% end -%>
+
+       # Only allow queries from our machines
+       allow-query { osm; };
+
+       # Don't allow transfers
+       allow-transfer { none; };
+
+       # Listen on any IPv6 interfaces
+       listen-on-v6 { any; };
+};
+
diff --git a/cookbooks/blog/README.rdoc b/cookbooks/blog/README.rdoc
new file mode 100644 (file)
index 0000000..3de2ec7
--- /dev/null
@@ -0,0 +1,8 @@
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
diff --git a/cookbooks/blog/metadata.rb b/cookbooks/blog/metadata.rb
new file mode 100644 (file)
index 0000000..e5d7f75
--- /dev/null
@@ -0,0 +1,7 @@
+maintainer        "OpenStreetMap Administrators"
+maintainer_email  "admins@openstreetmap.org"
+license           "Apache 2.0"
+description       "Installs and configures Blog services"
+long_description  IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
+version           "1.0.0"
+depends           "wordpress"
diff --git a/cookbooks/blog/recipes/default.rb b/cookbooks/blog/recipes/default.rb
new file mode 100644 (file)
index 0000000..3a363bc
--- /dev/null
@@ -0,0 +1,88 @@
+#
+# Cookbook Name:: blog
+# Recipe:: default
+#
+# Copyright 2013, OpenStreetMap Foundation
+#
+# 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.
+#
+
+include_recipe "wordpress"
+
+passwords = data_bag_item("blog", "passwords")
+
+directory "/srv/blog.openstreetmap.org" do
+  owner "wordpress"
+  group "wordpress"
+  mode 0755
+end
+
+wordpress_site "blog.openstreetmap.org" do
+  aliases "blog.osm.org", "blog.openstreetmap.com",
+          "blog.openstreetmap.net", "blog.openstreetmaps.org",
+          "blog.osmfoundation.org"
+  directory "/srv/blog.openstreetmap.org/wp"
+  database_name "osm-blog"
+  database_user "osm-blog-user"
+  database_password passwords["osm-blog-user"]
+  urls "/casts" => "/srv/blog.openstreetmap.org/casts",
+       "/images" => "/srv/blog.openstreetmap.org/images",
+       "/news" => "/srv/blog.openstreetmap.org/news"
+end
+
+wordpress_theme "osmblog-wp-theme" do
+  site "blog.openstreetmap.org"
+  repository "git://github.com/harry-wood/osmblog-wp-theme.git"
+end
+
+wordpress_plugin "google-analytics-for-wordpress" do
+  site "blog.openstreetmap.org"
+end
+
+wordpress_plugin "google-sitemap-generator" do
+  site "blog.openstreetmap.org"
+end
+
+wordpress_plugin "shareadraft" do
+  site "blog.openstreetmap.org"
+end
+
+wordpress_plugin "sitepress-multilingual-cms" do
+  site "blog.openstreetmap.org"
+  source "plugins/sitepress-multilingual-cms"
+end
+
+wordpress_plugin "wordpress-importer" do
+  site "blog.openstreetmap.org"
+end
+
+git "/srv/blog.openstreetmap.org/casts" do
+  action :sync
+  repository "git://github.com/openstreetmap/opengeodata-podcasts.git"
+  depth 1
+  user "wordpress"
+  group "wordpress"
+end
+
+git "/srv/blog.openstreetmap.org/images" do
+  action :sync
+  repository "git://github.com/openstreetmap/opengeodata-images.git"
+  depth 1
+  user "wordpress"
+  group "wordpress"
+end
+
+apache_site "opengeodata.org" do
+  template "opengeodata.erb"
+  directory "/srv/opengeodata.org"
+end
diff --git a/cookbooks/blog/templates/default/opengeodata.erb b/cookbooks/blog/templates/default/opengeodata.erb
new file mode 100644 (file)
index 0000000..43dbf01
--- /dev/null
@@ -0,0 +1,17 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+<VirtualHost *:80>
+  ServerName opengeodata.org
+  ServerAlias www.opengeodata.org
+  ServerAlias old.opengeodata.org
+
+  ServerAdmin webmaster@openstreetmap.org
+
+  CustomLog /var/log/apache2/<%= @name %>-access.log combined
+  ErrorLog /var/log/apache2/<%= @name %>-error.log
+
+  RewriteEngine on
+  RewriteRule ^(.*/)index\.html$ http://blog.openstreetmap.org/$1 [R,L]
+
+  RedirectPermanent / http://blog.openstreetmap.org/
+</VirtualHost>
diff --git a/cookbooks/chef/README.rdoc b/cookbooks/chef/README.rdoc
new file mode 100644 (file)
index 0000000..3de2ec7
--- /dev/null
@@ -0,0 +1,8 @@
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
diff --git a/cookbooks/chef/attributes/default.rb b/cookbooks/chef/attributes/default.rb
new file mode 100644 (file)
index 0000000..8107adf
--- /dev/null
@@ -0,0 +1,8 @@
+# Add the opscode APT source for chef
+default[:apt][:sources] = node[:apt][:sources] | [ "opscode" ]
+
+# Set the default client version
+default[:chef][:client][:version] = "11.4.4-1"
+
+# A list of gems needed by chef recipes
+default[:chef][:gems] = []
diff --git a/cookbooks/chef/definitions/ohai_plugin.rb b/cookbooks/chef/definitions/ohai_plugin.rb
new file mode 100644 (file)
index 0000000..06e9d30
--- /dev/null
@@ -0,0 +1,41 @@
+#
+# Cookbook Name:: chef
+# Definition:: ohai_plugin
+#
+# Copyright 2012, OpenStreetMap Foundation
+#
+# 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.
+#
+
+define :ohai_plugin, :action => [ :create, :delete ] do
+  plugin_name = params[:name]
+  plugin_action = params[:action]
+
+  if plugin_action.include?(:create)
+    ohai plugin_name do
+      action :nothing
+    end
+
+    template "/etc/chef/ohai/#{plugin_name}.rb" do
+      source params[:template]
+      owner "root"
+      group "root"
+      mode 0644
+      notifies :reload, resources(:ohai => plugin_name)
+    end
+  elsif plugin_action.include?(:delete)
+    template "/etc/chef/ohai/#{plugin_name}.rb" do
+      action :delete
+    end
+  end
+end
diff --git a/cookbooks/chef/files/default/knife.rb b/cookbooks/chef/files/default/knife.rb
new file mode 100644 (file)
index 0000000..1827695
--- /dev/null
@@ -0,0 +1,11 @@
+node_name 'chef-git'
+client_key 'client.pem'
+validation_client_name 'chef-validator'
+validation_key '/etc/chef/validation.pem'
+chef_server_url 'https://chef.openstreetmap.org'
+cache_type 'BasicFile'
+cache_options( :path => '.chef/checksums' )
+cookbook_path [ 'cookbooks' ]
+cookbook_copyright 'OpenStreetMap Administrators'
+cookbook_email 'admins@openstreetmap.org'
+cookbook_license 'apachev2'
diff --git a/cookbooks/chef/libraries/git.rb b/cookbooks/chef/libraries/git.rb
new file mode 100644 (file)
index 0000000..a5aa58c
--- /dev/null
@@ -0,0 +1,16 @@
+class Chef
+  class Provider
+    class Git
+      def remote_resolve_reference
+        Chef::Log.debug("#{@new_resource} resolving remote reference")
+        command = git('ls-remote', @new_resource.repository, @new_resource.revision, "#{@new_resource.revision}^{}")
+        @resolved_reference = shell_out!(command, run_options).stdout.split("\n").last
+        if  @resolved_reference =~ /^([0-9a-f]{40})\s+(\S+)/
+          $1
+        else
+          nil
+        end
+      end
+    end
+  end
+end
diff --git a/cookbooks/chef/libraries/subversion.rb b/cookbooks/chef/libraries/subversion.rb
new file mode 100644 (file)
index 0000000..952037f
--- /dev/null
@@ -0,0 +1,49 @@
+class Chef
+  class Provider
+    class Subversion
+      def sync_command
+        if current_repository_matches_target_repository?
+          c = scm :update, @new_resource.svn_arguments, verbose, authentication, "-r#{revision_int}", @new_resource.destination
+          Chef::Log.debug "#{@new_resource} updated working copy #{@new_resource.destination} to revision #{@new_resource.revision}"
+        else
+          c = scm :switch, @new_resource.svn_arguments, verbose, authentication, "-r#{revision_int}", @new_resource.repository, @new_resource.destination
+          Chef::Log.debug "#{@new_resource} updated working copy #{@new_resource.destination} to #{@new_resource.repository} revision #{@new_resource.revision}"
+        end
+        c
+      end
+
+      def current_repository
+        @current_repository ||= repo_attrs['URL']
+      end
+
+      def current_repository_matches_target_repository?
+        (!current_repository.nil?) && (@new_resource.repository == current_repository)
+      end
+
+      def repo_attrs
+        return {} unless ::File.exist?(::File.join(@new_resource.destination, ".svn"))
+
+        @repo_attrs ||= svn_info.lines.inject({}) do |attrs, line|
+          if line =~ SVN_INFO_PATTERN
+            property, value = $1, $2
+            attrs[property] = value
+          else
+            raise "Could not parse `svn info` data: #{line}"
+          end
+          attrs
+        end
+      end
+
+      def svn_info
+        command = scm(:info)
+        status, svn_info, error_message = output_of_command(command, run_options(:cwd => cwd))
+
+        unless [0,1].include?(status.exitstatus)
+          handle_command_failures(status, "STDOUT: #{svn_info}\nSTDERR: #{error_message}")
+        end
+
+        svn_info
+      end
+    end
+  end
+end
diff --git a/cookbooks/chef/metadata.rb b/cookbooks/chef/metadata.rb
new file mode 100644 (file)
index 0000000..ccf0e61
--- /dev/null
@@ -0,0 +1,9 @@
+maintainer        "OpenStreetMap Administrators"
+maintainer_email  "admins@openstreetmap.org"
+license           "Apache 2.0"
+description       "Installs and configures chef"
+long_description  IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
+version           "1.0.0"
+depends           "apache"
+depends           "apt"
+depends           "git"
diff --git a/cookbooks/chef/recipes/default.rb b/cookbooks/chef/recipes/default.rb
new file mode 100644 (file)
index 0000000..bbd9750
--- /dev/null
@@ -0,0 +1,107 @@
+#
+# Cookbook Name:: chef
+# Recipe:: default
+#
+# Copyright 2010, OpenStreetMap Foundation
+#
+# 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.
+#
+
+chef_gem "pony"
+
+chef_package = "chef_#{node[:chef][:client][:version]}.ubuntu.11.04_amd64.deb"
+
+directory "/var/cache/chef" do
+  owner "root"
+  group "root"
+  mode 0755
+end
+
+Dir.glob("/var/cache/chef/chef_*.ubuntu.11.04_amd64.deb").each do |deb|
+  if deb != "/var/cache/chef/#{chef_package}"
+    file deb do
+      action :delete
+      backup false
+    end
+  end
+end
+
+remote_file "/var/cache/chef/#{chef_package}" do
+  action :create_if_missing
+  source "https://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/11.04/x86_64/#{chef_package}"
+  owner "root"
+  group "root"
+  mode 0644
+  backup false
+end
+
+dpkg_package "chef" do
+  source "/var/cache/chef/#{chef_package}"
+  version node[:chef][:client][:version]
+end
+
+template "/etc/init/chef-client.conf" do
+  source "chef-client.conf.erb"
+  owner "root"
+  group "root"
+  mode 0644
+end
+
+template "/etc/chef/client.rb" do
+  source "client.rb.erb"
+  owner "root"
+  group "root"
+  mode 0640
+end
+
+file "/etc/chef/client.pem" do
+  owner "root"
+  group "root"
+  mode 0400
+end
+
+template "/etc/chef/report.rb" do
+  source "report.rb.erb"
+  owner "root"
+  group "root"
+  mode 0644
+end
+
+template "/etc/logrotate.d/chef" do
+  source "logrotate.erb"
+  owner "root"
+  group "root"
+  mode 0644
+end
+
+directory "/etc/chef/ohai" do
+  owner "root"
+  group "root"
+  mode 0755
+end
+
+directory "/var/log/chef" do
+  owner "root"
+  group "root"
+  mode 0755
+end
+
+service "chef-client" do
+  provider Chef::Provider::Service::Upstart
+  action [ :enable, :start ]
+  supports :status => true, :restart => true, :reload => true
+  subscribes :restart, "dpkg_package[chef]"
+  subscribes :restart, "template[/etc/init/chef-client.conf]"
+  subscribes :restart, "template[/etc/chef/client.rb]"
+  subscribes :restart, "template[/etc/chef/report.rb]"
+end
diff --git a/cookbooks/chef/recipes/gems.rb b/cookbooks/chef/recipes/gems.rb
new file mode 100644 (file)
index 0000000..ddbd394
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# Cookbook Name:: chef
+# Recipe:: gems
+#
+# Copyright 2013, OpenStreetMap Foundation
+#
+# 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.
+#
+
+node[:chef][:gems].each do |gem|
+  chef_gem gem
+  require gem
+end
diff --git a/cookbooks/chef/recipes/repository.rb b/cookbooks/chef/recipes/repository.rb
new file mode 100644 (file)
index 0000000..b4bd2fa
--- /dev/null
@@ -0,0 +1,63 @@
+#
+# Cookbook Name:: chef
+# Recipe:: repository
+#
+# Copyright 2013, OpenStreetMap Foundation
+#
+# 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.
+#
+
+include_recipe "git"
+
+keys = data_bag_item("chef", "keys")
+
+directory "/var/lib/chef" do
+  owner "chefrepo"
+  group "chefrepo"
+  mode 02775
+end
+
+git "/var/lib/chef" do
+  action :checkout
+  repository node[:chef][:repository]
+  revision "master"
+  user "chefrepo"
+  group "chefrepo"
+end
+
+directory "/var/lib/chef/.chef" do
+  owner "chefrepo"
+  group "chefrepo"
+  mode 02775
+end
+
+file "/var/lib/chef/.chef/client.pem" do
+  content keys["chef-git"].join("\n")
+  owner "chefrepo"
+  group "chefrepo"
+  mode 0660
+end
+
+cookbook_file "/var/lib/chef/.chef/knife.rb" do
+  source "knife.rb"
+  owner "chefrepo"
+  group "chefrepo"
+  mode 0660
+end
+
+template "#{node[:chef][:repository]}/hooks/post-receive" do
+  source "post-receive.erb"
+  owner "chefrepo"
+  group "chefrepo"
+  mode 0750
+end
diff --git a/cookbooks/chef/recipes/server.rb b/cookbooks/chef/recipes/server.rb
new file mode 100644 (file)
index 0000000..2c33218
--- /dev/null
@@ -0,0 +1,48 @@
+#
+# Cookbook Name:: chef
+# Recipe:: server
+#
+# Copyright 2010, OpenStreetMap Foundation
+#
+# 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.
+#
+
+include_recipe "apache::ssl"
+
+service "chef-server-runsvdir" do
+  provider Chef::Provider::Service::Upstart
+  action [ :enable, :start ]
+  supports :status => true, :restart => true, :reload => true
+end
+
+apache_module "alias"
+apache_module "proxy_http"
+
+execute "chef-server-reconfigure" do
+  action :nothing
+  command "chef-server-ctl reconfigure"
+  user "root"
+  group "root"
+end
+
+template "/etc/chef-server/chef-server.rb" do
+  source "server.rb.erb"
+  owner "root"
+  group "root"
+  mode 0644
+  notifies :run, "execute[chef-server-reconfigure]"
+end
+
+apache_site "chef.openstreetmap.org" do
+  template "apache.erb"
+end
diff --git a/cookbooks/chef/templates/default/apache.erb b/cookbooks/chef/templates/default/apache.erb
new file mode 100644 (file)
index 0000000..f758e98
--- /dev/null
@@ -0,0 +1,30 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+<VirtualHost *:80>
+       ServerName chef.openstreetmap.org
+       ServerAlias chef.osm.org
+       ServerAdmin webmaster@openstreetmap.org
+
+       CustomLog /var/log/apache2/chef.openstreetmap.org-access.log combined
+       ErrorLog /var/log/apache2/chef.openstreetmap.org-error.log
+
+       Redirect permanent / https://chef.openstreetmap.org/
+</VirtualHost>
+
+<VirtualHost *:443>
+       ServerName chef.openstreetmap.org
+       ServerAdmin webmaster@openstreetmap.org
+
+       SSLEngine on
+       SSLProtocol all -SSLv2
+       SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
+       SSLCertificateFile /etc/ssl/certs/openstreetmap.pem
+       SSLCertificateKeyFile /etc/ssl/private/openstreetmap.key
+
+       CustomLog /var/log/apache2/chef.openstreetmap.org-access.log combined
+       ErrorLog /var/log/apache2/chef.openstreetmap.org-error.log
+
+       SSLProxyEngine on
+
+       ProxyPass / https://127.0.0.1:4443/
+</VirtualHost>
diff --git a/cookbooks/chef/templates/default/chef-client.conf.erb b/cookbooks/chef/templates/default/chef-client.conf.erb
new file mode 100644 (file)
index 0000000..9414e05
--- /dev/null
@@ -0,0 +1,16 @@
+# chef-client
+#
+# Startup script for chef-client
+
+description "starts up chef-client in daemon mode"
+
+start on (net-device-up
+          and local-filesystems
+          and runlevel [2345])
+stop on runlevel [!2345]
+
+script
+        exec /usr/bin/chef-client -i 1800 -s 20
+end script
+
+respawn
diff --git a/cookbooks/chef/templates/default/client.rb.erb b/cookbooks/chef/templates/default/client.rb.erb
new file mode 100644 (file)
index 0000000..e4bba92
--- /dev/null
@@ -0,0 +1,43 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+# Configuration File For Chef (chef-client)
+#
+# The chef-client program will connect the local system to the specified
+# server URLs through a RESTful API to retrieve its configuration.
+
+# Force the default external encoding to UTF-8
+
+Encoding.default_external = Encoding::UTF_8
+
+# Load supporting code for report handlers
+
+require "/etc/chef/report"
+
+# Log at level info
+
+log_level :info
+
+# Set the location of the log file
+
+log_location "/var/log/chef/client.log"
+
+# Don't verify SSL certificates
+
+ssl_verify_mode :verify_none
+
+# Set the URL for the chef server
+
+chef_server_url "https://chef.openstreetmap.org"
+
+# Create report handler
+
+email_handler = Chef::Handler::Email.new(:to => "tom@compton.nu")
+
+# Configure report handlers
+
+exception_handlers << email_handler
+report_handlers << email_handler
+
+# Make our plugins visible to ohai
+
+Ohai::Config[:plugin_path] << "/etc/chef/ohai"
diff --git a/cookbooks/chef/templates/default/logrotate.erb b/cookbooks/chef/templates/default/logrotate.erb
new file mode 100644 (file)
index 0000000..0257a83
--- /dev/null
@@ -0,0 +1,10 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+/var/log/chef/client.log {
+  rotate 12
+  weekly
+  compress
+  postrotate
+       restart chef-client > /dev/null
+  endscript
+}
diff --git a/cookbooks/chef/templates/default/post-receive.erb b/cookbooks/chef/templates/default/post-receive.erb
new file mode 100644 (file)
index 0000000..58646ff
--- /dev/null
@@ -0,0 +1,66 @@
+#!/bin/zsh
+
+# DO NOT EDIT - This file is being maintained by Chef
+
+umask 0002
+unset GIT_DIR
+
+while read oldrev newrev refname
+do
+  if [[ "$refname" = "refs/heads/master" ]]
+  then
+    cd /var/lib/chef
+
+    rm -f cookbooks/*/metadata.json(N)
+
+    git pull --rebase --quiet
+
+    oldrev=$(git merge-base $oldrev $newrev)
+
+    for change in "${(f)$(git diff --name-status $oldrev..$newrev)}"
+    do
+      action=${change[1]}
+      file=${change[3,-1]}
+
+      if [[ $file == roles/*.rb ]]
+      then
+        case "$action" in
+          A|M) knife role from file "${file}";;
+          D) knife role delete -y "${file:t:r}";;
+        esac
+      elif [[ $file == data_bags/*/*.json ]]
+      then
+        case "$action" in
+          A|M) 
+            knife data bag create "${file:h:t}"
+            knife data bag from file "${file:h:t}" "${file:t}";;
+          D)
+            knife data bag delete -y "${file:h:t}" "${file:t:r}";;
+        esac
+      elif [[ $file == cookbooks/* ]]
+      then
+        cookbook="${${file#[^/]*/}%%/*}"
+    
+        if [[ -d "cookbooks/${cookbook}" ]]
+        then
+          updated_cookbooks+=("$cookbook")
+        else
+          deleted_cookbooks+=("$cookbook")
+        fi
+      fi
+    done
+
+    if [[ -n "$updated_cookbooks" ]]
+    then
+      knife cookbook upload "${(ou)updated_cookbooks[@]}"
+    fi
+
+    if [[ -n "$deleted_cookbooks" ]]
+    then
+      for cookbook in "${(ou)deleted_cookbooks[@]}"
+      do
+        knife cookbook delete -y "$cookbook"
+      done
+    fi
+  fi
+done
diff --git a/cookbooks/chef/templates/default/report.rb.erb b/cookbooks/chef/templates/default/report.rb.erb
new file mode 100644 (file)
index 0000000..5e78860
--- /dev/null
@@ -0,0 +1,35 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+require "rubygems"
+require "pony"
+class Chef
+  class Handler
+    class Email < Chef::Handler
+      attr_reader :config
+
+      def initialize(config={})
+        @config = config
+        @config[:from] ||= "root@openstreetmap.org"
+        @config
+      end
+      def report
+        if failed? and not exception.is_a? SystemExit
+          subject = "Chef run failed on #{node.name}"
+          message = "#{run_status.formatted_exception}\n"
+        elsif elapsed_time > 300
+          subject = "Chef run took #{elapsed_time} on #{node.name}"
+          message = ""
+        end
+        
+        if subject
+          message << Array(backtrace).join("\n")
+
+          Pony.mail(:to => @config[:to], :from => @config[:from],
+                    :subject => subject, :body => message, :via => :smtp)
+        end
+      end
+    end
+  end
+end
diff --git a/cookbooks/chef/templates/default/server.rb.erb b/cookbooks/chef/templates/default/server.rb.erb
new file mode 100644 (file)
index 0000000..1ec1424
--- /dev/null
@@ -0,0 +1,11 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+nginx['enable_non_ssl'] = true
+nginx['non_ssl_port'] = 4000
+nginx['ssl_port'] = 4443
+nginx['server_name'] = "chef.openstreetmap.org"
+nginx['url'] = "http://chef.openstreetmap.org:4000"
+bookshelf['url'] = "http://chef.openstreetmap.org:4000"
+bookshelf['vip'] = "chef.openstreetmap.org"
+lb['api_fqdn'] = "chef.openstreetmap.org"
+lb['web_ui_fqdn'] = "chef.openstreetmap.org"
diff --git a/cookbooks/devices/README.rdoc b/cookbooks/devices/README.rdoc
new file mode 100644 (file)
index 0000000..3de2ec7
--- /dev/null
@@ -0,0 +1,8 @@
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
diff --git a/cookbooks/devices/attributes/default.rb b/cookbooks/devices/attributes/default.rb
new file mode 100644 (file)
index 0000000..d5af885
--- /dev/null
@@ -0,0 +1 @@
+default[:devices] = {}
diff --git a/cookbooks/devices/metadata.rb b/cookbooks/devices/metadata.rb
new file mode 100644 (file)
index 0000000..bc3bd92
--- /dev/null
@@ -0,0 +1,11 @@
+maintainer       "Tom Hughes"
+maintainer_email "tom@compton.nu"
+license          "Apache 2.0"
+description      "Configures devices"
+long_description IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
+version          "0.1"
+
+attribute "devices",
+  :display_name => "Kernel Parameters",
+  :description => "Hash of devices",
+  :type => "hash"
diff --git a/cookbooks/devices/recipes/default.rb b/cookbooks/devices/recipes/default.rb
new file mode 100644 (file)
index 0000000..73c1a4e
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# Cookbook Name:: devices
+# Recipe:: default
+#
+# Copyright 2012, OpenStreetMap Foundation
+#
+# 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.
+#
+
+execute "udevadm-trigger" do
+  action :nothing
+  command "/sbin/udevadm trigger --action=add"
+end
+
+template "/etc/udev/rules.d/99-chef.rules" do
+  source "udev.rules.erb"
+  owner "root"
+  group "root"
+  mode 0644
+  notifies :run, resources(:execute => "udevadm-trigger")
+end
diff --git a/cookbooks/devices/templates/default/udev.rules.erb b/cookbooks/devices/templates/default/udev.rules.erb
new file mode 100644 (file)
index 0000000..27951c4
--- /dev/null
@@ -0,0 +1,25 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+# HP Smart Array configuration
+ACTION=="add", SUBSYSTEM=="block", ENV{ID_VENDOR}=="HP", ENV{ID_MODEL}=="LOGICAL_VOLUME", ATTR{queue/scheduler}="noop"
+ACTION=="add", SUBSYSTEM=="block", ENV{ID_VENDOR}=="HP", ENV{ID_MODEL}=="LOGICAL_VOLUME", ATTR{queue/nr_requests}="512"
+<% node[:devices].each do |name,device| -%>
+
+# <%= device[:comment] %>
+<% if device[:type] == "block" -%>
+<% if device[:owner] -%>
+SUBSYSTEM=="block", ENV{ID_BUS}=="<%= device[:bus] %>", ENV{ID_SERIAL}=="<%= device[:serial] %>", OWNER="<%= device[:owner] %>"
+<% end -%>
+<% if device[:group] -%>
+SUBSYSTEM=="block", ENV{ID_BUS}=="<%= device[:bus] %>", ENV{ID_SERIAL}=="<%= device[:serial] %>", GROUP="<%= device[:group] %>"
+<% end -%>
+<% if device[:mode] -%>
+SUBSYSTEM=="block", ENV{ID_BUS}=="<%= device[:bus] %>", ENV{ID_SERIAL}=="<%= device[:serial] %>", MODE="<%= device[:mode] %>"
+<% end -%>
+<% if device[:attrs] -%>
+<% device[:attrs].each do |name,value| -%>
+ACTION=="add", SUBSYSTEM=="block", ENV{ID_BUS}=="<%= device[:bus] %>", ENV{ID_SERIAL}=="<%= device[:serial] %>", ATTR{<%= name %>}="<%= value %>"
+<% end -%>
+<% end -%>
+<% end -%>
+<% end -%>
diff --git a/cookbooks/geodns/README.rdoc b/cookbooks/geodns/README.rdoc
new file mode 100644 (file)
index 0000000..3de2ec7
--- /dev/null
@@ -0,0 +1,8 @@
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
diff --git a/cookbooks/geodns/metadata.rb b/cookbooks/geodns/metadata.rb
new file mode 100644 (file)
index 0000000..924f7f1
--- /dev/null
@@ -0,0 +1,6 @@
+maintainer        "OpenStreetMap Administrators"
+maintainer_email  "admins@openstreetmap.org"
+license           "Apache 2.0"
+description       "Installs and configures a geographic DNS server"
+long_description  IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
+version           "1.0.0"
diff --git a/cookbooks/geodns/recipes/default.rb b/cookbooks/geodns/recipes/default.rb
new file mode 100644 (file)
index 0000000..0bd74fb
--- /dev/null
@@ -0,0 +1,83 @@
+#
+# Cookbook Name:: geodns
+# Recipe:: default
+#
+# Copyright 2011, OpenStreetMap Foundation
+#
+# 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.
+#
+
+package "pdns-server"
+package "pdns-backend-geo"
+
+service "pdns" do
+  action [ :enable, :start ]
+  supports :status => true, :restart => true, :reload => true
+end
+
+file "/etc/powerdns/pdns.d/pdns.simplebind" do
+  action :delete
+  notifies :reload, resources(:service => "pdns")
+end
+
+template "/etc/powerdns/pdns.d/geo.conf" do
+  source "geo.conf.erb"
+  owner "root"
+  group "root"
+  mode "0600"
+  notifies :reload, resources(:service => "pdns")
+end
+
+directory "/etc/powerdns/zones.d" do
+  owner "root"
+  group "root"
+  mode "0755"
+end
+
+template "/etc/powerdns/zones.d/tile.conf" do
+  source "tile.conf.erb"
+  owner "root"
+  group "root"
+  mode "0644"
+  notifies :reload, resources(:service => "pdns")
+end
+
+template "/etc/cron.weekly/geodns-update" do
+  source "cron.erb"
+  owner "root"
+  group "root"
+  mode "0755"
+end
+
+execute "geodns-sync-countries" do
+  command "rsync -z rsync://countries-ns.mdc.dk/zone/zz.countries.nerd.dk.rbldnsd /etc/powerdns/countries.conf"
+  user "root"
+  group "root"
+  not_if { File.exist?("/etc/powerdns/countries.conf") }
+end
+
+firewall_rule "accept-dns-udp" do
+  action :accept
+  source "net"
+  dest "fw"
+  proto "udp"
+  dest_ports "domain"
+end
+
+firewall_rule "accept-dns-tcp" do
+  action :accept
+  source "net"
+  dest "fw"
+  proto "tcp:syn"
+  dest_ports "domain"
+end
diff --git a/cookbooks/geodns/templates/default/cron.erb b/cookbooks/geodns/templates/default/cron.erb
new file mode 100644 (file)
index 0000000..5ab93ae
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+rsync -zt rsync://countries-ns.mdc.dk/zone/zz.countries.nerd.dk.rbldnsd /etc/powerdns/countries.conf
+pdns_control rediscover >/dev/null
diff --git a/cookbooks/geodns/templates/default/geo.conf.erb b/cookbooks/geodns/templates/default/geo.conf.erb
new file mode 100644 (file)
index 0000000..360e5b6
--- /dev/null
@@ -0,0 +1,25 @@
+# Launch the geo backend
+launch=geo
+
+# Make sure we don't cache anything as we give everybody a unique answer
+query-cache-ttl=0
+cache-ttl=0
+
+# Turn off wildcards for performance
+#Disable wildcard parameter as no longer compatible with recent pdns
+#wildcards=no
+
+# The zone we are managing
+geo-zone=geo.openstreetmap.org
+
+# The SOA record for the zone
+geo-soa-values=a.ns.openstreetmap.org,hostmaster.openstreetmap.org
+
+# The NS records for the zone
+geo-ns-records=a.ns.openstreetmap.org
+
+# Map IP addresses to geographic zones
+geo-ip-map-zonefile=/etc/powerdns/countries.conf
+
+# Map geographic zones to responses
+geo-maps=/etc/powerdns/zones.d
diff --git a/cookbooks/geodns/templates/default/tile.conf.erb b/cookbooks/geodns/templates/default/tile.conf.erb
new file mode 100644 (file)
index 0000000..79c1236
--- /dev/null
@@ -0,0 +1,498 @@
+# Name (within geo.openstreetmap.org) we are handling
+$RECORD tile
+# Domain within which our responses lie
+$ORIGIN tile.openstreetmap.org.
+# Afghanistan
+4 af
+# Åland Islands
+248 ax
+# Albania
+8 al
+# Algeria
+12 dz
+# American Samoa
+16 as
+# Andorra
+20 ad
+# Angola
+24 ao
+# Anguilla
+660 ai
+# Antarctica
+10 aq
+# Antigua and Barbuda
+28 ag
+# Argentina
+32 ar
+# Armenia
+51 am
+# Aruba
+533 aw
+# Australia
+36 au
+# Austria
+40 at
+# Azerbaijan
+31 az
+# Bahamas
+44 bs
+# Bahrain
+48 bh
+# Bangladesh
+50 bd
+# Barbados
+52 bb
+# Belarus
+112 by
+# Belgium
+56 be
+# Belize
+84 bz
+# Benin
+204 bj
+# Bermuda
+60 bm
+# Bhutan
+64 bt
+# Bolivia, Plurinational State of
+68 bo
+# Bosnia and Herzegovina
+70 ba
+# Botswana
+72 bw
+# Bouvet Island
+74 bv
+# Brazil
+76 br
+# British Indian Ocean Territory
+86 io
+# Brunei Darussalam
+96 bn
+# Bulgaria
+100 bg
+# Burkina Faso
+854 bf
+# Burundi
+108 bi
+# Cambodia
+116 kh
+# Cameroon
+120 cm
+# Canada
+124 ca
+# Cape Verde
+132 cv
+# Cayman Islands
+136 ky
+# Central African Republic
+140 cf
+# Chad
+148 td
+# Chile
+152 cl
+# China
+156 cn
+# Christmas Island
+162 cx
+# Cocos (Keeling) Islands
+166 cc
+# Colombia
+170 co
+# Comoros
+174 km
+# Congo
+178 cg
+# Congo, The Democratic Republic of the
+180 cd
+# Cook Islands
+184 ck
+# Costa Rica
+188 cr
+# Côte d'Ivoire
+384 ci
+# Croatia
+191 hr
+# Cuba
+192 cu
+# Cyprus
+196 cy
+# Czech Republic
+203 cz
+# Denmark
+208 dk
+# Djibouti
+262 dj
+# Dominica
+212 dm
+# Dominican Republic
+214 do
+# Ecuador
+218 ec
+# Egypt
+818 eg
+# El Salvador
+222 sv
+# Equatorial Guinea
+226 gq
+# Eritrea
+232 er
+# Estonia
+233 ee
+# Ethiopia
+231 et
+# Falkland Islands (Malvinas)
+238 fk
+# Faroe Islands
+234 fo
+# Fiji
+242 fj
+# Finland
+246 fi
+# France
+250 fr
+# French Guiana
+254 gf
+# French Polynesia
+258 pf
+# French Southern Territories
+260 tf
+# Gabon
+266 ga
+# Gambia
+270 gm
+# Georgia
+268 ge
+# Germany
+276 de
+# Ghana
+288 gh
+# Gibraltar
+292 gi
+# Greece
+300 gr
+# Greenland
+304 gl
+# Grenada
+308 gd
+# Guadeloupe
+312 gp
+# Guam
+316 gu
+# Guatemala
+320 gt
+# Guernsey
+831 gg
+# Guinea
+324 gn
+# Guinea-Bissau
+624 gw
+# Guyana
+328 gy
+# Haiti
+332 ht
+# Heard Island and McDonald Islands
+334 hm
+# Holy See (Vatican City State)
+336 va
+# Honduras
+340 hn
+# Hong Kong
+344 hk
+# Hungary
+348 hu
+# Iceland
+352 is
+# India
+356 in
+# Indonesia
+360 id
+# Iran, Islamic Republic of
+364 ir
+# Iraq
+368 iq
+# Ireland
+372 ie
+# Isle of Man
+833 im
+# Israel
+376 il
+# Italy
+380 it
+# Jamaica
+388 jm
+# Japan
+392 jp
+# Jersey
+832 je
+# Jordan
+400 jo
+# Kazakhstan
+398 kz
+# Kenya
+404 ke
+# Kiribati
+296 ki
+# Korea, Democratic People's Republic of
+408 kp
+# Korea, Republic of
+410 kr
+# Kuwait
+414 kw
+# Kyrgyzstan
+417 kg
+# Lao People's Democratic Republic
+418 la
+# Latvia
+428 lv
+# Lebanon
+422 lb
+# Lesotho
+426 ls
+# Liberia
+430 lr
+# Libyan Arab Jamahiriya
+434 ly
+# Liechtenstein
+438 li
+# Lithuania
+440 lt
+# Luxembourg
+442 lu
+# Macao
+446 mo
+# Macedonia, Republic of
+807 mk
+# Madagascar
+450 mg
+# Malawi
+454 mw
+# Malaysia
+458 my
+# Maldives
+462 mv
+# Mali
+466 ml
+# Malta
+470 mt
+# Marshall Islands
+584 mh
+# Martinique
+474 mq
+# Mauritania
+478 mr
+# Mauritius
+480 mu
+# Mayotte
+175 yt
+# Mexico
+484 mx
+# Micronesia, Federated States of
+583 fm
+# Moldova, Republic of
+498 md
+# Monaco
+492 mc
+# Mongolia
+496 mn
+# Montenegro
+499 me
+# Montserrat
+500 ms
+# Morocco
+504 ma
+# Mozambique
+508 mz
+# Myanmar
+104 mm
+# Namibia
+516 na
+# Nauru
+520 nr
+# Nepal
+524 np
+# Netherlands
+528 nl
+# Netherlands Antilles
+530 an
+# New Caledonia
+540 nc
+# New Zealand
+554 nz
+# Nicaragua
+558 ni
+# Niger
+562 ne
+# Nigeria
+566 ng
+# Niue
+570 nu
+# Norfolk Island
+574 nf
+# Northern Mariana Islands
+580 mp
+# Norway
+578 no
+# Oman
+512 om
+# Pakistan
+586 pk
+# Palau
+585 pw
+# Palestinian Territory, Occupied
+275 ps
+# Panama
+591 pa
+# Papua New Guinea
+598 pg
+# Paraguay
+600 py
+# Peru
+604 pe
+# Philippines
+608 ph
+# Pitcairn
+612 pn
+# Poland
+616 pl
+# Portugal
+620 pt
+# Puerto Rico
+630 pr
+# Qatar
+634 qa
+# Reunion
+638 re
+# Romania
+642 ro
+# Russian Federation
+643 ru
+# Rwanda
+646 rw
+# Saint Barthélemy
+652 bl
+# Saint Helena
+654 sh
+# Saint Kitts and Nevis
+659 kn
+# Saint Lucia
+662 lc
+# Saint Martin (French part)
+663 mf
+# Saint Pierre and Miquelon
+666 pm
+# Saint Vincent and the Grenadines
+670 vc
+# Samoa
+882 ws
+# San Marino
+674 sm
+# Sao Tome and Principe
+678 st
+# Saudi Arabia
+682 sa
+# Senegal
+686 sn
+# Serbia
+688 rs
+# Seychelles
+690 sc
+# Sierra Leone
+694 sl
+# Singapore
+702 sg
+# Slovakia
+703 sk
+# Slovenia
+705 si
+# Solomon Islands
+90 sb
+# Somalia
+706 so
+# South Africa
+710 za
+# South Georgia and the South Sandwich Islands
+239 gs
+# Spain
+724 es
+# Sri Lanka
+144 lk
+# Sudan
+736 sd
+# Suriname
+740 sr
+# Svalbard and Jan Mayen
+744 sj
+# Swaziland
+748 sz
+# Sweden
+752 se
+# Switzerland
+756 ch
+# Syrian Arab Republic
+760 sy
+# Taiwan, Province of China
+158 tw
+# Tajikistan
+762 tj
+# Tanzania, United Republic of
+834 tz
+# Thailand
+764 th
+# Timor-Leste
+626 tl
+# Togo
+768 tg
+# Tokelau
+772 tk
+# Tonga
+776 to
+# Trinidad and Tobago
+780 tt
+# Tunisia
+788 tn
+# Turkey
+792 tr
+# Turkmenistan
+795 tm
+# Turks and Caicos Islands
+796 tc
+# Tuvalu
+798 tv
+# Uganda
+800 ug
+# Ukraine
+804 ua
+# United Arab Emirates
+784 ae
+# United Kingdom
+826 gb
+# United States
+840 us
+# United States Minor Outlying Islands
+581 um
+# Uruguay
+858 uy
+# Uzbekistan
+860 uz
+# Vanuatu
+548 vu
+# Venezuela, Bolivarian republic of
+862 ve
+# Viet Nam
+704 vn
+# Virgin Islands, British
+92 vg
+# Virgin Islands, U.S.
+850 vi
+# Wallis and Futuna
+876 wf
+# Western Sahara
+732 eh
+# Yemen
+887 ye
+# Zambia
+894 zm
+# Zimbabwe
+716 zw
+# Default response
+0 xx
diff --git a/cookbooks/memcached/README.rdoc b/cookbooks/memcached/README.rdoc
new file mode 100644 (file)
index 0000000..3de2ec7
--- /dev/null
@@ -0,0 +1,8 @@
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
diff --git a/cookbooks/memcached/attributes/default.rb b/cookbooks/memcached/attributes/default.rb
new file mode 100644 (file)
index 0000000..01a556c
--- /dev/null
@@ -0,0 +1,6 @@
+default[:memcached][:memory_limit] = "256"
+default[:memcached][:connection_limit] = "1024"
+default[:memcached][:ip_address] = "127.0.0.1"
+default[:memcached][:tcp_port] = "11211"
+default[:memcached][:chunk_growth_factor] = "1.25"
+default[:memcached][:min_item_size] = "48"
diff --git a/cookbooks/memcached/metadata.rb b/cookbooks/memcached/metadata.rb
new file mode 100644 (file)
index 0000000..1c803e6
--- /dev/null
@@ -0,0 +1,6 @@
+maintainer        "OpenStreetMap Administrators"
+maintainer_email  "admins@openstreetmap.org"
+license           "Apache 2.0"
+description       "Installs and configures memcached"
+long_description  IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
+version           "1.0.0"
diff --git a/cookbooks/memcached/recipes/default.rb b/cookbooks/memcached/recipes/default.rb
new file mode 100644 (file)
index 0000000..d8d1434
--- /dev/null
@@ -0,0 +1,61 @@
+#
+# Cookbook Name:: memcached
+# Recipe:: default
+#
+# Copyright 2011, OpenStreetMap Foundation
+#
+# 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.
+#
+
+package "memcached"
+
+service "memcached" do
+  action [ :enable, :start ]
+  supports :status => true, :restart => true
+end
+
+template "/etc/memcached.conf" do
+  source "memcached.conf.erb"
+  owner "root"
+  group "root"
+  mode 0644
+  notifies :restart, resources(:service => "memcached")
+end
+
+munin_plugin_conf "memcached_multi" do
+  template "munin.erb"
+end
+
+munin_plugin "memcached_multi_bytes" do
+  target "memcached_multi_"
+end
+
+munin_plugin "memcached_multi_commands" do
+  target "memcached_multi_"
+end
+
+munin_plugin "memcached_multi_conns" do
+  target "memcached_multi_"
+end
+
+munin_plugin "memcached_multi_evictions" do
+  target "memcached_multi_"
+end
+
+munin_plugin "memcached_multi_items" do
+  target "memcached_multi_"
+end
+
+munin_plugin "memcached_multi_memory" do
+  target "memcached_multi_"
+end
diff --git a/cookbooks/memcached/templates/default/memcached.conf.erb b/cookbooks/memcached/templates/default/memcached.conf.erb
new file mode 100644 (file)
index 0000000..44a4ee8
--- /dev/null
@@ -0,0 +1,31 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+# Run memcached as a daemon
+-d
+
+# Run as user nobody
+-u nobody
+
+# Log memcached's output to /var/log/memcached
+logfile /var/log/memcached.log
+
+# Limit the size of the cache to <%= node[:memcached][:memory_limit] %>Mb
+-m <%= node[:memcached][:memory_limit] %>
+
+# Configure where we listen for requests
+-l <%= node[:memcached][:ip_address] %>
+<% if node[:memcached][:tcp_port] -%>
+-p <%= node[:memcached][:tcp_port] %>
+<% end -%>
+<% if node[:memcached][:udp_port] -%>
+-U <%= node[:memcached][:udp_port] %>
+<% end -%>
+
+# Limit the number of simultaneous connections
+-c <%= node[:memcached][:connection_limit] %>
+
+# Set chunk growth factor
+-f <%= node[:memcached][:chunk_growth_factor] %>
+
+# Set minimum item size
+-n <%= node[:memcached][:min_item_size] %>
diff --git a/cookbooks/memcached/templates/default/munin.erb b/cookbooks/memcached/templates/default/munin.erb
new file mode 100644 (file)
index 0000000..40d4348
--- /dev/null
@@ -0,0 +1,6 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+[memcached_multi_*]
+user nobody
+env.host <%= node[:memcached][:ip_address] %>
+env.port <%= node[:memcached][:tcp_port] %>
diff --git a/cookbooks/munin/README.rdoc b/cookbooks/munin/README.rdoc
new file mode 100644 (file)
index 0000000..3de2ec7
--- /dev/null
@@ -0,0 +1,8 @@
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
diff --git a/cookbooks/munin/attributes/default.rb b/cookbooks/munin/attributes/default.rb
new file mode 100644 (file)
index 0000000..a1eb792
--- /dev/null
@@ -0,0 +1,3 @@
+default[:munin][:allow] = []
+default[:munin][:graphs] = {}
+default[:munin][:plugins] = {}
diff --git a/cookbooks/munin/definitions/munin_plugin.rb b/cookbooks/munin/definitions/munin_plugin.rb
new file mode 100644 (file)
index 0000000..a44da4f
--- /dev/null
@@ -0,0 +1,59 @@
+#
+# Cookbook Name:: munin
+# Definition:: munin_plugin
+#
+# Copyright 2010, OpenStreetMap Foundation
+#
+# 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.
+#
+
+define :munin_plugin, :action => :create do
+  target = params[:target] || params[:name]
+
+  if File.exists?("/usr/local/share/munin/plugins/#{target}")
+    target_path = "/usr/local/share/munin/plugins/#{target}"
+  elsif File.exists?("/usr/share/munin/plugins/#{target}")
+    target_path = "/usr/share/munin/plugins/#{target}"
+  else
+    target_path = nil
+  end
+
+  if target_path.nil? or params[:action] == :delete
+    link "/etc/munin/plugins/#{params[:name]}" do
+      action :delete
+    end
+  else
+    link "/etc/munin/plugins/#{params[:name]}" do
+      action params[:action]
+      to target_path
+      notifies :restart, resources(:service => "munin-node")
+    end
+  end
+
+  if params[:conf]
+    conf_template = params[:conf]
+    conf_cookbook = params[:conf_cookbook]
+    conf_variables = params[:conf_variables]
+
+    munin_plugin_conf params[:name] do
+      action params[:action]
+      template conf_template
+      if conf_cookbook
+        cookbook conf_cookbook
+      end
+      if conf_variables
+        variables conf_variables
+      end
+    end
+  end
+end
diff --git a/cookbooks/munin/definitions/munin_plugin_conf.rb b/cookbooks/munin/definitions/munin_plugin_conf.rb
new file mode 100644 (file)
index 0000000..63cecd0
--- /dev/null
@@ -0,0 +1,38 @@
+#
+# Cookbook Name:: munin
+# Definition:: munin_plugin_conf
+#
+# Copyright 2012, OpenStreetMap Foundation
+#
+# 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.
+#
+
+define :munin_plugin_conf, :action => :create, :variables => {} do
+  if params[:action] == :create
+    template "/etc/munin/plugin-conf.d/#{params[:name]}" do
+      if params[:cookbook]
+        cookbook params[:cookbook]
+      end
+      source params[:template]
+      owner "root"
+      group "root"
+      mode 0644
+      variables params[:variables].merge(:name => params[:name])
+      notifies :restart, resources(:service => "munin-node")
+    end
+  else
+    file "/etc/munin/plugin-conf.d/#{params[:name]}" do
+      action :delete
+    end
+  end
+end
diff --git a/cookbooks/munin/files/default/plugin-conf.d/api b/cookbooks/munin/files/default/plugin-conf.d/api
new file mode 100644 (file)
index 0000000..614696e
--- /dev/null
@@ -0,0 +1,2 @@
+[api_calls_num]
+user root
diff --git a/cookbooks/munin/files/default/plugin-conf.d/hpasmcli b/cookbooks/munin/files/default/plugin-conf.d/hpasmcli
new file mode 100644 (file)
index 0000000..50b3763
--- /dev/null
@@ -0,0 +1,2 @@
+[hpasmcli_*]
+user root
diff --git a/cookbooks/munin/files/default/plugin-conf.d/passenger b/cookbooks/munin/files/default/plugin-conf.d/passenger
new file mode 100644 (file)
index 0000000..d09a160
--- /dev/null
@@ -0,0 +1,2 @@
+[passenger_*]
+user root
diff --git a/cookbooks/munin/files/default/plugins/apcpdu_ b/cookbooks/munin/files/default/plugins/apcpdu_
new file mode 100755 (executable)
index 0000000..7fada28
--- /dev/null
@@ -0,0 +1,128 @@
+#!/usr/bin/perl
+#
+# Copyright (c) 2009 - Rune Nordbøe Skillingstad
+# Copyright (c) 2009 - Kai Ove Gran
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; version 2 dated June,
+# 1991.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+
+#      snmp_host_apcpdu - For APC PDUs. Graphs total current throughput.
+#
+#%# family=snmpauto
+#%# capabilities=snmpconf
+
+use strict;
+use Net::SNMP;
+
+my $DEBUG     = $ENV{DEBUG}     || 0;
+my $host      = $ENV{host}      || undef;
+my $port      = $ENV{port}      || 161;
+my $community = $ENV{community} || "public";
+my $iface     = $ENV{interface} || undef;
+my $timeout   = $ENV{timeout}   || 1;
+my $snmp_ver  = $ENV{version}   || 1;
+
+if($0 =~ /^(?:|.*\/)apcpdu_([^_]+)$/) {
+    $host = $1;
+    if($host =~ /^([^:]+):(\d+)$/) {
+       $host = $1;
+       $port = $2;
+    }
+} elsif(!defined($host)) {
+    die "# Error: couldn't understand what I'm supposed to monitor."; 
+}
+
+my @oidsList =  (
+    '1.3.6.1.4.1.318.1.1.12.2.3.1.1.2.1',
+    '1.3.6.1.4.1.318.1.1.12.2.2.1.1.3.1',
+    '1.3.6.1.4.1.318.1.1.12.1.7.0'    
+);
+
+if(defined $ARGV[0] and $ARGV[0] eq "snmpconf") {
+    for(my $i = 0; $i < @oidsList; $i++) {
+       print "require " . $oidsList[$i] . "[0-9]\n"; 
+    }
+    exit 0;
+}
+
+my ($session, $error) = Net::SNMP->session(
+    -hostname  => $host,
+    -community => $community,
+    -port      => $port,
+    -timeout   => $timeout,
+    -version   => $snmp_ver,
+);
+
+if(!defined ($session)) {
+    die "# Croaking: $error";
+}
+
+if($ARGV[0] and $ARGV[0] eq "config") {
+    my $name = &get_single($session, '1.3.6.1.4.1.318.1.1.4.3.3.0');
+    if($name) {
+#      print "host_name $host\n" unless $host eq 'localhost';
+       print "graph_title Current for $name\n";
+       print "graph_args --base 1000 -l 0\n";
+       print "graph_vlabel Amps\n";
+       print "graph_category Ups\n";
+       print "graph_info This graph shows the total throughput of the PDU\n";
+       print "graph_order load threshold rating\n";
+       print "load.label Load\n";
+       print "load.type GAUGE\n";
+       print "load.info Current load in amps.\n";
+       print "load.draw LINE2\n";
+       print "threshold.label Threshold\n";
+       print "threshold.type GAUGE\n";
+       print "threshold.info Near overload threshold.\n";
+       print "threshold.draw LINE2\n";
+       print "rating.label Rating\n";
+       print "rating.type GAUGE\n";
+       print "rating.info Rating (Max amps).\n";
+       print "rating.draw LINE2\n";
+    }
+    exit 0;                                
+}
+
+my @response = &get_multiple($session, @oidsList);
+
+printf "load.value %.02f\n", $response[0] / 10;
+printf "threshold.value %d\n", $response[1];
+printf "rating.value %d\n", $response[2];
+
+
+sub get_multiple {
+    my $handle = shift;
+    my @oids = @_;
+
+    my @result;
+    foreach my $oid (@oids) {
+       push(@result, &get_single($handle,$oid));
+    }
+    chomp @result;
+    return @result;
+}
+
+sub get_single {
+    my ($handle, $oid) = @_;
+    
+    my $response = $handle->get_request ($oid);
+    if(!defined $response->{$oid}) {
+       print "# No response\n" if $DEBUG;
+       return "";
+    } else {
+       print "# Got response \"".$response->{$oid}."\"\n" if $DEBUG;
+       return $response->{$oid};
+    }
+}
diff --git a/cookbooks/munin/files/default/plugins/api_calls_ b/cookbooks/munin/files/default/plugins/api_calls_
new file mode 100755 (executable)
index 0000000..179c07f
--- /dev/null
@@ -0,0 +1,70 @@
+#!/usr/bin/ruby
+
+require 'rubygems'
+require 'date'
+require 'hpricot'
+require 'open-uri'
+
+def uris_from_status(server) 
+  file = open("http://#{server}/server-status").read
+  doc = Hpricot.parse(file)
+  tables = doc / 'table'
+  rows = (tables[0] / 'tr')[1..-1]
+  data = rows.collect {|r| (r  / 'td').collect {|x| x.inner_html} }
+  # filter where the PID is numeric, status is 'W' and host matches the server
+  matching_data = data.select {|r| (r[1].to_i > 0) && r[3].match(/W/) && r[11].match(server)}
+  # return only the URI part
+  matching_data.collect {|r| r[12]}
+end
+
+CALL_TYPES = {
+  :map => "Map API calls", 
+  :upload => "Changeset diff uploads", 
+  :amf => "AMF API calls", 
+  :history => "Element history fetches", 
+  :full => "Full element fetches",
+  :trkpts => "GPX trackpoints calls",
+  :web => "Web site traffic", 
+  :other => "Other API calls"
+}
+
+def categorise_uri(line)
+  uri = line.split(" ")[1]
+  
+  case uri
+  when /api\/0\.6\/map/ then :map
+  when /api\/0\.6\/changeset\/[0-9]*\/upload/ then :upload
+  when /api\/0\.6\/amf/ then :amf
+  when /api\/0\.6\/(node|way|relation)\/[0-9]*\/history/ then :history
+  when /api\/0\.6\/(node|way|relation)\/[0-9]*\/full/ then :full
+  when /api\/0\.6\/trackpoints/ then :trkpts
+  when /api\/0\.6\// then :other
+  else :web
+  end
+end
+
+server = $0.match("api_calls_(.*)")[1]
+
+if ARGV[0] == 'config'
+  puts "graph_title Active requests"
+  puts "graph_vlabel Number of requests"
+  puts "graph_category api"
+  CALL_TYPES.each { |k, v| puts "#{k}.label #{v}" }
+
+else
+  counts = uris_from_status(server).
+      collect {|x| categorise_uri(x)}.
+      inject(Hash.new) do |h, e|
+    if h.has_key? e
+      h[e] += 1
+    else
+      h[e] = 1
+    end
+    h
+  end
+  
+  CALL_TYPES.keys.each do |type|
+    count = counts[type] || 0
+    puts "#{type}.value #{count}"
+  end
+end
diff --git a/cookbooks/munin/files/default/plugins/api_calls_num b/cookbooks/munin/files/default/plugins/api_calls_num
new file mode 100755 (executable)
index 0000000..b0c2366
--- /dev/null
@@ -0,0 +1,80 @@
+#!/usr/bin/ruby
+
+require 'rubygems'
+require 'date'
+gem 'home_run', '>= 0'
+require 'apache_log_regex'
+
+NUM_LINES = 10000
+
+def uris_from_logs
+  lines = Array.new
+  max_time = nil
+  min_time = nil
+  parser = ApacheLogRegex.new('%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %x')
+  IO.popen("tail -n #{NUM_LINES} /var/log/apache2/access.log").each_line do |line|
+    begin
+      hash = parser.parse(line)
+      uri = hash["%r"]
+      t = DateTime.strptime(hash["%t"], "[%d/%b/%Y:%H:%M:%S %z]")
+      min_time = [min_time, t].compact.min
+      max_time = [max_time, t].compact.max
+      lines << uri
+    rescue ApacheLogRegex::ParseError => e
+      # nil
+    end
+  end
+  [min_time, max_time, lines]
+end
+
+CALL_TYPES = {
+  :map => "Map API calls", 
+  :upload => "Changeset diff uploads", 
+  :amf => "AMF API calls", 
+  :history => "Element history fetches", 
+  :full => "Full element fetches",
+  :trkpts => "GPX trackpoints calls",
+  :web => "Web site traffic", 
+  :other => "Other API calls"
+}
+
+def categorise_uri(line)
+  uri = line.split(" ")[1]
+  
+  case uri
+  when /api\/0\.6\/map/ then :map
+  when /api\/0\.6\/changeset\/[0-9]*\/upload/ then :upload
+  when /api\/0\.6\/amf/ then :amf
+  when /api\/0\.6\/(node|way|relation)\/[0-9]*\/history/ then :history
+  when /api\/0\.6\/(node|way|relation)\/[0-9]*\/full/ then :full
+  when /api\/0\.6\/trackpoints/ then :trkpts
+  when /api\/0\.6\// then :other
+  else :web
+  end
+end
+
+if ARGV[0] == 'config'
+  puts "graph_title Requests processed"
+  puts "graph_vlabel Number of requests per minute"
+  puts "graph_category api"
+  CALL_TYPES.each { |k, v| puts "#{k}.label #{v}" }
+
+else
+  min_time, max_time, lines = uris_from_logs
+  delta_t = (max_time - min_time).to_f * 24 * 60
+  counts = lines.
+      collect {|x| categorise_uri(x)}.
+      inject(Hash.new) do |h, e|
+    if h.has_key? e
+      h[e] += 1
+    else
+      h[e] = 1
+    end
+    h
+  end
+  
+  CALL_TYPES.keys.each do |type|
+    count = counts[type] || 0
+    puts "#{type}.value #{count / delta_t}"
+  end
+end
diff --git a/cookbooks/munin/files/default/plugins/api_waits_ b/cookbooks/munin/files/default/plugins/api_waits_
new file mode 100755 (executable)
index 0000000..029c9f4
--- /dev/null
@@ -0,0 +1,72 @@
+#!/usr/bin/ruby
+
+require 'rubygems'
+require 'date'
+require 'hpricot'
+require 'open-uri'
+
+def uri_and_times_from_status(server) 
+  file = open("http://#{server}/server-status").read
+  doc = Hpricot.parse(file)
+  tables = doc / 'table'
+  rows = (tables[0] / 'tr')[1..-1]
+  data = rows.collect {|r| (r  / 'td').collect {|x| x.inner_html} }
+  # filter where the PID is numeric, status is 'W' and host matches the server
+  matching_data = data.select {|r| (r[1].to_i > 0) && r[3].match(/W/) && r[11].match(server)}
+  # return URI and number of seconds processing for each request
+  matching_data.collect {|r| [r[12], r[5].to_i]}
+end
+
+CALL_TYPES = {
+  :map => "Map API calls", 
+  :upload => "Changeset diff uploads", 
+  :amf => "AMF API calls", 
+  :history => "Element history fetches", 
+  :full => "Full element fetches",
+  :trkpts => "GPX trackpoints calls",
+  :web => "Web site traffic", 
+  :other => "Other API calls"
+}
+
+def categorise_uri(line)
+  uri = line.split(" ")[1]
+  
+  case uri
+  when /api\/0\.6\/map/ then :map
+  when /api\/0\.6\/changeset\/[0-9]*\/upload/ then :upload
+  when /api\/0\.6\/amf/ then :amf
+  when /api\/0\.6\/(node|way|relation)\/[0-9]*\/history/ then :history
+  when /api\/0\.6\/(node|way|relation)\/[0-9]*\/full/ then :full
+  when /api\/0\.6\/trackpoints/ then :trkpts
+  when /api\/0\.6\// then :other
+  else :web
+  end
+end
+
+server = $0.match("api_waits_(.*)")[1]
+
+if ARGV[0] == 'config'
+  puts "graph_title Wait times for active requests"
+  puts "graph_vlabel Average time of requests"
+  puts "graph_category api"
+  CALL_TYPES.each { |k, v| puts "#{k}.label #{v}" }
+
+else
+  counts = uri_and_times_from_status(server).
+      collect {|x,y| [categorise_uri(x), y]}.
+      inject(Hash.new) do |h, e|
+    category, time = e
+    if h.has_key? category
+      h[category] += [time]
+    else
+      h[category] = [time]
+    end
+    h
+  end
+  
+  CALL_TYPES.keys.each do |type|
+    count = counts[type] || [0]
+    avg = count.inject(0){|x,y|x+y} / (1.0 * count.length)
+    puts "#{type}.value #{avg}"
+  end
+end
diff --git a/cookbooks/munin/files/default/plugins/fw_conntrack b/cookbooks/munin/files/default/plugins/fw_conntrack
new file mode 100755 (executable)
index 0000000..1a1b59f
--- /dev/null
@@ -0,0 +1,191 @@
+#!/bin/sh
+# -*- sh -*-
+
+: << =cut
+
+=head1 NAME
+
+fw_conntrack - Plugin to monitor the number of tracked connections
+through a Linux 2.4/2.6 firewall
+
+=head1 CONFIGURATION
+
+This plugin must run with root privileges
+
+=head2 CONFIGURATION EXAMPLE
+
+/etc/munin/plugin-conf.d/global or other file in that dir must contain:
+
+ [fw*]
+  user root
+
+=head1 NOTES
+
+ESTABLISHED+FIN_WAIT+TIME_WAIT+SYN_SENT+UDP is the most interesting
+connections.
+
+The total list also includes SYN_RECV, CLOSE, CLOSE_WAIT, LAST_ACK and
+LISTEN, but these were not (often) observed on my firewall.
+
+TOTAL is the total number of tracked connections.
+
+ASSURED and UNREPLIED connections are complimentary subsets of
+ESTABLISHED.
+
+ASSURED is after ACK is seen after SYN_RECV.  Therefore ASSURED is
+plotted but not UNREPLIED.
+
+NATed will almost always be the same as the total
+
+=head1 BUGS
+
+=over 4
+
+=item full connection table
+
+The connections tables can run full, but where is the limits found?
+If we can find them then we can send warnings to nagios.
+
+=back
+
+=head1 AUTHORS
+
+2004.05.05: Initial version by Nicolai Langfeldt, Linpro AS, Oslo, Norway
+
+=head2 CONTRIBUTORS
+
+=over 4
+
+=item Xavier
+
+2004.05.06: Enhanced to count NATed connections after input from Xavier on munin-users list
+
+=back
+
+=head1 LICENSE
+
+GPL
+
+=head1 MAGIC MARKERS
+
+ #%# family=auto
+ #%# capabilities=autoconf
+
+=cut
+
+case $1 in
+    config)
+
+        cat <<EOF
+graph_title Connections through firewall
+graph_vlabel Connections
+graph_category network
+graph_args -l 0
+established.label Established
+established.type GAUGE
+established.draw AREA
+fin_wait.label FIN_WAIT
+fin_wait.type GAUGE
+fin_wait.draw STACK
+time_wait.label TIME_WAIT
+time_wait.type GAUGE
+time_wait.draw STACK
+syn_sent.label SYN_SENT
+syn_sent.type GAUGE
+syn_sent.draw STACK
+udp.label UDP connections
+udp.type GAUGE
+udp.draw STACK
+assured.label Assured
+assured.type GAUGE
+assured.draw LINE2
+nated.label NATed
+nated.type GAUGE
+nated.draw LINE1
+total.label Total
+total.type GAUGE
+total.graph no
+EOF
+        if [ -f /proc/sys/net/ipv4/ip_conntrack_max ] ; then
+            MAX=`cat /proc/sys/net/ipv4/ip_conntrack_max`
+        elif [ -f /proc/sys/net/ipv4/netfilter/ip_conntrack_max ]; then
+            MAX=`cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max`
+        fi
+        if [ -n "$MAX" ]; then
+           echo total.warning `expr $MAX \* 8 / 10`
+           echo total.critical `expr $MAX \* 9 / 10`
+       fi
+        exit 0
+       ;;
+    autoconf)
+        if [ -r /proc/net/ip_conntrack -o -r /proc/net/nf_conntrack ] ; then
+           echo yes
+           exit 0
+       else
+           echo no
+           exit 0
+       fi
+esac
+
+# Do the work, perform the deed
+
+# INPUT /proc/net/ip_conntrack:
+# tcp      6 225790 ESTABLISHED src=10.0.0.4 dst=198.144.194.12 sport=48580 dport=6667 src=198.144.194.12 dst=80.111.68.163 sport=6667 dport=48580 [ASSURED] use=1
+# tcp      6 431918 ESTABLISHED src=10.0.0.2 dst=209.58.150.153 sport=33018 dport=6667 src=209.58.150.153 dst=80.111.68.163 sport=6667 dport=33018 [ASSURED] use=1
+# tcp      6 123109 ESTABLISHED src=10.0.0.5 dst=198.144.194.12 sport=33846 dport=6667 [UNREPLIED] src=198.144.194.12 dst=80.111.68.163 sport=6667 dport=33846 use=1
+# udp      17 53 src=80.111.68.163 dst=62.179.100.29 sport=34153 dport=53 src=62.179.100.29 dst=80.111.68.163 sport=53 dport=34153 [ASSURED] use=1
+#
+# INPUT /proc/net/nf_conntrack:
+# ipv4     2 tcp      6 424416 ESTABLISHED src=192.168.1.53 dst=196.203.198.11 sport=1584 dport=22146 packets=13659 bytes=5426603 src=196.203.198.11 dst=83.24.222.252 sport=22146 dport=1584 packets=14757 bytes=15342572 [ASSURED] mark=0 use=1
+
+if [ -f /proc/net/ip_conntrack ]; then
+  cat /proc/net/ip_conntrack | awk '
+  BEGIN  { STATE["ESTABLISHED"]=STATE["FIN_WAIT"]=STATE["TIME_WAIT"]=0;
+          TOTAL=ASSURED=NOREPLY=NATED=STATE["SYN_SENT"]=STATE["UDP"]=0; }
+  /^tcp/ { STATE[$4]++; }
+  /^udp/ { STATE["UDP"]++; }
+  /ASSURED/ { ASSURED++; }
+  {
+      TOTAL++;
+      src1 = substr($5, 5); src2 = substr($9, 5);
+      dst1 = substr($6, 5); dst2 = substr($10, 5);
+      if (src1 != dst2 || dst1 != src2) NATED++;
+  }
+  END    { print "established.value " STATE["ESTABLISHED"];
+           print "fin_wait.value " STATE["FIN_WAIT"];
+          print "time_wait.value " STATE["TIME_WAIT"];
+          print "syn_sent.value " STATE["SYN_SENT"];
+          print "udp.value " STATE["UDP"];
+          print "assured.value " ASSURED;
+          print "nated.value " NATED;
+          print "total.value " TOTAL;
+        }'
+else
+  cat /proc/net/nf_conntrack | awk '
+  BEGIN  { STATE["ESTABLISHED"]=STATE["FIN_WAIT"]=STATE["TIME_WAIT"]=0;
+          TOTAL=ASSURED=NOREPLY=NATED=STATE["SYN_SENT"]=STATE["UDP"]=0; }
+  / tcp / { STATE[$6]++; }
+  / udp / { STATE["UDP"]++; }
+  /ASSURED/ { ASSURED++; }
+  {
+      TOTAL++;
+      src1 = substr($7, 5); src2 = substr($14, 5);
+      dst1 = substr($8, 5); dst2 = substr($15, 5);
+      if (src1 != dst2 || dst1 != src2) NATED++;
+  }
+  END    { print "established.value " STATE["ESTABLISHED"];
+           print "fin_wait.value " STATE["FIN_WAIT"];
+          print "time_wait.value " STATE["TIME_WAIT"];
+          print "syn_sent.value " STATE["SYN_SENT"];
+          print "udp.value " STATE["UDP"];
+          print "assured.value " ASSURED;
+          print "nated.value " NATED;
+          print "total.value " TOTAL;
+        }'
+fi
+
+# Hum, the total.value should be possible to do as a cdef.
+# Or to use the builtin "total" support.
+
+#  LocalWords:  expr
+
diff --git a/cookbooks/munin/files/default/plugins/hpasmcli_fans b/cookbooks/munin/files/default/plugins/hpasmcli_fans
new file mode 100755 (executable)
index 0000000..e440c3f
--- /dev/null
@@ -0,0 +1,54 @@
+#! /usr/bin/perl -w
+#
+# Graph fans on Proliant Servers 
+# 
+
+use strict;
+
+my $hpasmcli = "/sbin/hpasmcli";
+my $cmd = "$hpasmcli -s \"show fans\"";
+# C/F : graph temp in celsius or fahrenheit
+
+my @result = `$cmd`;
+my %val;
+
+#(-f $hpasmcli) || exit(1);
+
+foreach my $line (@result) {
+
+    if ($line =~ /^#/) {
+        $line =~ s/\s+/ /g;
+        $line =~ s/^\s//g;
+        my ($sensor, $loc, $present, $speed_state, $speed, $redundant) = split(/\s/, $line);
+        next if ($speed eq "-");
+        $loc =~ s/\/|#//g;
+        $speed =~ s/\%//g;
+        
+        $sensor =~s/#//g;
+        $val{$sensor} = {location => lc($loc),
+                         speed     => $speed
+                         };
+     }
+    
+}
+
+
+if ($ARGV[0] && $ARGV[0] eq "config") {
+
+    print "graph_title Fans\n";
+    print "graph_vlabel fans speed as % of max\n";
+    print "graph_category sensors\n";
+    while (my ($k, $hashref) = each (%val)) {
+        print "$hashref->{location}.label $hashref->{location}\n";
+        print "$hashref->{location}.warning 85\n";
+        print "$hashref->{location}.critical 100\n";
+    }
+
+}
+else {
+    while (my ($k, $hashref) = each (%val)) {
+        print "$hashref->{location}.value $hashref->{speed}\n";    
+    }
+}
+exit(0);
+
diff --git a/cookbooks/munin/files/default/plugins/hpasmcli_temp b/cookbooks/munin/files/default/plugins/hpasmcli_temp
new file mode 100755 (executable)
index 0000000..0884bb1
--- /dev/null
@@ -0,0 +1,61 @@
+#! /usr/bin/perl -w
+#
+# Graph temperature on Proliant Servers 
+# 
+
+use strict;
+
+my $hpasmcli = "/sbin/hpasmcli";
+my $cmd = "$hpasmcli -s \"show temp\"";
+# C/F : graph temp in celsius or fahrenheit
+my $degree = "C";
+
+my @result = `$cmd`;
+my %val;
+
+#(-f $hpasmcli) || exit(1);
+
+foreach my $line (@result) {
+
+    if ($line =~ /^#/) {
+        $line =~ s/\s+/ /g;
+        $line =~ s/^\s//g;
+        my ($sensor, $loc, $temp, $threshold) = split(/\s/, $line);
+        next if ($temp eq "-");
+        $loc =~ s/\/|#//g;
+        $temp = $degree eq "C" ? (split(/\//, $temp))[0] : (split(/\//, $temp))[1];
+        $temp =~ s/C|F//g;
+        $threshold = $degree eq "C" ? (split(/\//, $threshold))[0] : (split(/\//, $threshold))[1];
+        $threshold =~ s/C|F//g;
+        
+        $sensor =~s/#//g;
+        $val{$sensor} = {location => lc($loc),
+                         temp     => $temp,
+                         threshold => $threshold
+                         };
+     }
+    
+}
+
+
+if ($ARGV[0] && $ARGV[0] eq "config") {
+
+    print "graph_title Temperature\n";
+    print "graph_vlabel temperature in °$degree\n";
+    print "graph_category sensors\n";
+    while (my ($k, $hashref) = each (%val)) {
+        print "$hashref->{location}.label $hashref->{location}\n";
+        print "$hashref->{location}.warning ".($hashref->{threshold} - 5) ."\n";
+        print "$hashref->{location}.critical $hashref->{threshold}\n";
+    }
+
+}
+else {
+    while (my ($k, $hashref) = each (%val)) {
+        print "$hashref->{location}.value $hashref->{temp}\n";    
+    }
+}
+exit(0);
+
+
+
diff --git a/cookbooks/munin/files/default/plugins/memcached_ b/cookbooks/munin/files/default/plugins/memcached_
new file mode 100755 (executable)
index 0000000..4ee6229
--- /dev/null
@@ -0,0 +1,382 @@
+#!/usr/bin/perl
+#
+=head1 NAME
+
+Memcached - A Plugin to monitor Memcached Servers
+
+=head1 MUNIN CONFIGURATION
+
+[memcached_*]
+ env.host 127.0.0.1     *default*
+ env.port 11211         *default*
+
+=head2 MUNIN ENVIRONMENT CONFIGURATION EXPLANATION
+
+ host = host we are going to monitor
+ port = port we are connecting to, in order to gather stats
+
+=head1 NODE CONFIGURATION
+
+Please make sure you can telnet to your memcache servers and issue the
+ following commands: stats
+
+Available Graphs contained in this Plugin
+
+bytes => This graphs the current network traffic in and out
+
+commands => This graphs the current commands being issued to the memcache machine.
+
+conns => This graphs the current, max connections as well as avg conns per sec avg conns per sec is derived from total_conns / uptime.
+
+evictions => This graphs the current evictions on the node.
+
+items => This graphs the current items and total items in the memcached node.
+
+memory => This graphs the current and max memory allocation. 
+
+The following example holds true for all graphing options in this plugin.
+ Example: ln -s /usr/share/munin/plugins/memcached_ /etc/munin/plugins/memcached_bytes
+
+=head1 ACKNOWLEDGEMENTS
+
+The core of this plugin is based on the mysql_ plugin maintained by Kjell-Magne Ãierud
+
+Thanks to dormando as well for putting up with me ;)
+
+=head1 AUTHOR
+
+Matt West < https://code.google.com/p/memcached-munin-plugin/ >
+
+=head1 LICENSE
+
+GPLv2
+
+=head1 MAGIC MARKERS
+
+    #%# family=manual
+    #%# capabilities=autoconf suggest
+
+=cut
+
+use strict;
+use IO::Socket;
+
+my $host = $ENV{host} || "127.0.0.1";
+my $port = $ENV{port} || 11211;
+
+my %stats;
+# This hash contains the information contained in two memcache commands
+# stats and stats settings.
+
+# So I was trying to figure out how to build this up, and looking at some good examples
+# I decided to use the format, or for the most part, the format from the mysql_ munin plugin
+# for Innodb by Kjell-Magne Ãierud, it just spoke ease of flexibility especially with multigraphs
+# thanks btw ;)
+#
+# %graphs   is a container for all of the graph definition information. In here is where you'll
+#           find the configuration information for munin's graphing procedure.
+#   Format:
+#
+#   $graph{graph_name} => {
+#       config => {
+#           # You'll find keys and values stored here for graph manipulation
+#       },
+#       datasrc => [
+#           # Name: name given to data value
+#           # Attr: Attribute for given value
+#           { name => 'Name', (Attr) },
+#           { ... },
+#       ],
+#   }
+my %graphs;
+
+$graphs{items} = {
+    config => {
+        args => '--base 1000 --lower-limit 0',
+        vlabel => 'Items in Memcached',
+        category => 'memcached',
+        title => 'Items',
+        info => 'This graph shows the number of items in use by memcached',
+    },
+    datasrc => [
+        { name => 'curr_items', label => 'Current Items', min => '0' },
+        { name => 'total_items', label => 'New Items', min => '0', type => 'DERIVE' },
+    ],
+};
+
+$graphs{memory} = {
+    config => {
+        args => '--base 1024 --lower-limit 0',
+        vlabel => 'Bytes Used',
+        category => 'memcached',
+        title => 'Memory Usage',
+        info => 'This graph shows the memory consumption of memcached',
+    },
+    datasrc => [
+        { name => 'limit_maxbytes', draw => 'AREA', label => 'Maximum Bytes Allocated', min => '0' },
+        { name => 'bytes', draw => 'AREA', label => 'Current Bytes Used', min => '0' },
+    ],
+};
+
+$graphs{bytes} = {
+    config => {
+        args => '--base 1000',
+        vlabel => 'bits in (-) / out (+)',
+        title => 'Network Traffic',
+        category => 'memcached',
+        info => 'This graph shows the network traffic in (-) / out (+) of the machine',
+        order => 'bytes_read bytes_written',
+    },
+    datasrc => [
+        { name => 'bytes_read', type => 'DERIVE', label => 'Network Traffic coming in (-)', graph => 'no', cdef => 'bytes_read,8,*', min => '0' },
+        { name => 'bytes_written', type => 'DERIVE', label => 'Traffic in (-) / out (+)', negative => 'bytes_read', cdef => 'bytes_written,8,*', min => '0' },
+    ],
+};
+
+$graphs{conns} = {
+    config => {
+        args => '--base 1000 --lower-limit 0',
+        vlabel => 'Connections per ${graph_period}',
+        category => 'memcached',
+        title => 'Connections',
+        info => 'This graph shows the number of connections being handled by memcached',
+        order => 'curr_conns avg_conns',
+    },
+    datasrc => [
+        { name => 'curr_conns', label => 'Current Connections', min => '0' },
+        { name => 'avg_conns' , label => 'Avg Connections', min => '0' },
+    ],
+};
+
+$graphs{commands} = {
+    config => {
+        args => '--base 1000 --lower-limit 0',
+        vlabel => 'Commands per ${graph_period}',
+        category => 'memcached',
+        title => 'Commands',
+        info => 'This graph shows the number of commands being handled by memcached',
+    },
+    datasrc => [
+        { name => 'cmd_get', type => 'DERIVE', label => 'Gets', info => 'Cumulative number of retrieval reqs', min => '0' },
+        { name => 'cmd_set', type => 'DERIVE', label => 'Sets', info => 'Cumulative number of storage reqs', min => '0' },
+        { name => 'get_hits', type => 'DERIVE', label => 'Get Hits', info => 'Number of keys that were requested and found', min => '0' },
+        { name => 'get_misses', type => 'DERIVE', label => 'Get Misses', info => 'Number of keys there were requested and not found', min => '0' },
+    ],
+};
+
+$graphs{evictions} = {
+    config => {
+        args => '--base 1000 --lower-limit 0',
+        vlabel => 'Evictions per ${graph_period}',
+        category => 'memcached',
+        title => 'Evictions',
+        info => 'This graph shows the number of evictions per second',
+    },
+    datasrc => [
+        { name => 'evictions', label => 'Evictions', info => 'Cumulative Evictions Across All Slabs', type => 'DERIVE', min => '0' },
+    ],
+};
+
+##
+#### Config Check ####
+##
+
+if (defined $ARGV[0] && $ARGV[0] eq 'config') {
+
+    $0 =~ /memcached_(.+)*/;
+    my $plugin = $1;
+
+    die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
+
+    # We need to fetch the stats before we do any config, cause its needed for multigraph
+    fetch_stats();
+
+    # Now lets go ahead and print out our config.
+       do_config($plugin);
+       exit 0;
+}
+
+##
+#### Autoconf Check ####
+##
+
+if (defined $ARGV[0] && $ARGV[0] eq 'autoconf') {
+
+    my $s = IO::Socket::INET->new(
+        Proto    => "tcp",
+        PeerAddr => $host,
+        PeerPort => $port,
+    );
+
+    if (defined($s)) {
+        print "yes\n";
+        exit 0;
+    } else {
+        print "no (unable to connect to $host\[:$port\])\n";
+        exit 0;
+    }
+}
+
+##
+#### Suggest Check ####
+##
+
+if (defined $ARGV[0] && $ARGV[0] eq 'suggest') {
+
+    my $s = IO::Socket::INET->new(
+        Proto    => "tcp",
+        PeerAddr => $host,
+        PeerPort => $port,
+    );
+
+    if (defined($s)) {
+        my @rootplugins = ('bytes','conns','commands','evictions','items','memory');
+        foreach my $plugin (@rootplugins) {
+            print "$plugin\n";
+        }
+        exit 0;
+    } else {
+        print "no (unable to connect to $host\[:$port\])\n";
+        exit 0;
+    }
+}
+
+##
+#### Well We aren't running (auto)config/suggest so lets print some stats ####
+##
+
+fetch_output();
+
+##
+#### Subroutines for printing info gathered from memcached ####
+##
+
+##
+#### This subroutine performs the bulk processing for printing statistics.
+##
+
+sub fetch_output {
+
+    $0 =~ /memcached_(.+)*/;
+    my $plugin = $1;
+
+    die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
+
+    # Well we need to actually fetch the stats before we do anything to them.
+    fetch_stats();
+    
+    # Now lets go ahead and print out our output.
+    print_root_output($plugin);
+
+    return;
+}
+
+##
+#### This subroutine is for the root non-multigraph graphs which render on the main node page ####
+##
+
+sub print_root_output {
+    my ($plugin) = (@_);
+
+    my $graph = $graphs{$plugin};
+
+    #print "graph memcached_$plugin\n";
+
+    if ($plugin ne 'conns') {
+        foreach my $dsrc (@{$graph->{datasrc}}) {
+            my %datasrc = %$dsrc;
+            while ( my ($key, $value) = each(%datasrc)) {
+                next if ($key ne 'name');
+                my $output = $stats{$value};
+                print "$dsrc->{name}.value $output\n";
+            }
+        }
+    } else {
+        my $output;
+        foreach my $dsrc (@{$graph->{datasrc}}) {
+            my %datasrc = %$dsrc;
+            while ( my ($key, $value) = each(%datasrc)) {
+                if ($value eq 'curr_conns') {
+                    $output = $stats{curr_connections};
+                } elsif ($value eq 'avg_conns') {
+                    $output = sprintf("%02d", $stats{total_connections} / $stats{uptime});
+                } else {
+                    next;
+                }
+                print "$dsrc->{name}.value $output\n";
+            }
+        }
+    }
+
+    return;
+}
+
+##
+#### Subroutines for printing out config information for graphs ####
+##
+
+##
+#### This subroutine does the bulk printing the config info per graph ####
+##
+
+sub do_config {
+    my ($plugin) = (@_);
+    print_root_config($plugin);
+
+    return;
+}
+
+##
+#### This subroutine is for the config info for non multigraph graphs which render on the main node page ####
+##
+
+sub print_root_config {
+    my ($plugin) = (@_);
+
+    die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
+
+    my $graph = $graphs{$plugin};
+
+    my %graphconf = %{$graph->{config}};
+
+    #print "graph memcached_$plugin\n";
+
+    while ( my ($key, $value) = each(%graphconf)) {
+        print "graph_$key $value\n";
+    }
+
+    foreach my $dsrc (@{$graph->{datasrc}}) {
+        my %datasrc = %$dsrc;
+        while ( my ($key, $value) = each(%datasrc)) {
+            next if ($key eq 'name');
+            print "$dsrc->{name}.$key $value\n";
+        }
+    }
+
+    return;
+}
+
+##
+#### This subroutine actually performs the data fetch for us ####
+#### These commands do not lock up Memcache at all ####
+##
+
+sub fetch_stats {
+    my $s = IO::Socket::INET->new(
+        Proto    => "tcp",
+        PeerAddr => $host,
+        PeerPort => $port,
+    );
+
+    die "Error: Unable to Connect to $host\[:$port\]\n" unless $s;
+
+    print $s "stats\r\n";
+
+    while (my $line = <$s>) {
+        if ($line =~ /STAT\s(.+?)\s(\d+)/) {
+            my ($skey,$svalue) = ($1,$2);
+            $stats{$skey} = $svalue;
+        }
+        last if $line =~ /^END/;
+    }
+}
diff --git a/cookbooks/munin/files/default/plugins/memcached_multi_ b/cookbooks/munin/files/default/plugins/memcached_multi_
new file mode 100755 (executable)
index 0000000..a202899
--- /dev/null
@@ -0,0 +1,768 @@
+#!/usr/bin/perl
+#
+=head1 NAME
+
+Memcached - A Plugin to monitor Memcached Servers (Multigraph)
+
+=head1 MUNIN CONFIGURATION
+
+[memcached_*]
+ env.host 127.0.0.1     *default*
+ env.port 11211         *default*
+ env.timescale 3        *default*
+
+=head2 MUNIN ENVIRONMENT CONFIGURATION EXPLANATION
+
+ host = host we are going to monitor
+ port = port we are connecting to, in order to gather stats
+ timescale = what time frame do we want to format our graphs too
+
+=head1 NODE CONFIGURATION
+
+Please make sure you can telnet to your memcache servers and issue the
+ following commands: stats, stats settings, stats items and stats slabs.
+
+Available Graphs contained in this Plugin
+
+bytes => This graphs the current network traffic in and out
+
+commands => I<MULTIGRAPH> This graphs the current commands being issued to the memcache machine. B<Multigraph breaks this down to per slab.>
+
+conns => This graphs the current, max connections as well as avg conns per sec avg conns per sec is derived from total_conns / uptime.
+
+evictions => I<MULTIGRAPH> This graphs the current evictions on the node. B<Multigraph breaks this down to per slab.>
+
+items => I<MULTIGRAPH> This graphs the current items and total items in the memcached node. B<Multigraph breaks this down to per slab.>
+
+memory => I<MULTIGRAPH> This graphs the current and max memory allocation B<Multigraph breaks this down to per slab.>
+
+The following example holds true for all graphing options in this plugin.
+ Example: ln -s /usr/share/munin/plugins/memcached_multi_ /etc/munin/plugins/memcached_multi_bytes
+
+=head1 ADDITIONAL INFORMATION
+
+You will find that some of the graphs have LEI on them. This was done in order to save room
+on space for text and stands for B<Last Evicted Item>.
+
+The B<Timescale> variable formats certain graphs based on the following guidelines.
+ 1 => Seconds
+ 2 => Minutes
+ 3 => Hours  B<*Default*>
+ 4 => Days
+
+=head1 ACKNOWLEDGEMENTS
+
+The core of this plugin is based on the mysql_ plugin maintained by Kjell-Magne Ãierud
+
+Thanks to dormando as well for putting up with me ;)
+
+=head1 AUTHOR
+
+Matt West < https://code.google.com/p/memcached-munin-plugin/ >
+
+=head1 LICENSE
+
+GPLv2
+
+=head1 MAGIC MARKERS
+
+    #%# family=auto
+    #%# capabilities=autoconf suggest
+
+=cut
+
+use strict;
+use IO::Socket;
+use Munin::Plugin;
+
+need_multigraph();
+
+my $host = $ENV{host} || "127.0.0.1";
+my $port = $ENV{port} || 11211;
+
+my %stats;
+# This hash contains the information contained in two memcache commands
+# stats and stats settings.
+
+my %items;
+# This gives us eviction rates and other hit stats per slab
+# We track this so we can see if something was evicted earlier than necessary
+
+my %chnks;
+# This gives us the memory size and usage per slab
+# We track this so we can see what slab is being used the most and has no free chunks 
+# so we can re-tune memcached to allocate more pages for the specified chunk size
+
+my $timescale = $ENV{timescale} || 3;
+# This gives us the ability to control the timescale our graphs are displaying.
+# The default it set to divide by hours, if you want to get seconds set it to 1.
+# Options: 1 = seconds, 2 = minutes, 3 = hours, 4 = days
+
+# So I was trying to figure out how to build this up, and looking at some good examples
+# I decided to use the format, or for the most part, the format from the mysql_ munin plugin
+# for Innodb by Kjell-Magne Ãierud, it just spoke ease of flexibility especially with multigraphs
+# thanks btw ;)
+#
+# %graphs   is a container for all of the graph definition information. In here is where you'll
+#           find the configuration information for munin's graphing procedure.
+#   Format:
+#
+#   $graph{graph_name} => {
+#       config => {
+#           # You'll find keys and values stored here for graph manipulation
+#       },
+#       datasrc => [
+#           # Name: name given to data value
+#           # Attr: Attribute for given value
+#           { name => 'Name', (Attr) },
+#           { ... },
+#       ],
+#   }
+my %graphs;
+
+$graphs{items} = {
+    config => {
+        args => '--base 1000 --lower-limit 0',
+        vlabel => 'Items in Memcached',
+        category => 'memcached',
+        title => 'Items',
+        info => 'This graph shows the number of items in use by memcached',
+    },
+    datasrc => [
+        { name => 'curr_items', label => 'Current Items', min => '0' },
+        { name => 'total_items', label => 'New Items', min => '0', type => 'DERIVE' },
+    ],
+};
+
+$graphs{memory} = {
+    config => {
+        args => '--base 1024 --lower-limit 0',
+        vlabel => 'Bytes Used',
+        category => 'memcached',
+        title => 'Memory Usage',
+        info => 'This graph shows the memory consumption of memcached',
+    },
+    datasrc => [
+        { name => 'limit_maxbytes', draw => 'AREA', label => 'Maximum Bytes Allocated', min => '0' },
+        { name => 'bytes', draw => 'AREA', label => 'Current Bytes Used', min => '0' },
+    ],
+};
+
+$graphs{bytes} = {
+    config => {
+        args => '--base 1000',
+        vlabel => 'bits in (-) / out (+)',
+        title => 'Network Traffic',
+        category => 'memcached',
+        info => 'This graph shows the network traffic in (-) / out (+) of the machine',
+        order => 'bytes_read bytes_written',
+    },
+    datasrc => [
+        { name => 'bytes_read', type => 'DERIVE', label => 'Network Traffic coming in (-)', graph => 'no', cdef => 'bytes_read,8,*', min => '0' },
+        { name => 'bytes_written', type => 'DERIVE', label => 'Traffic in (-) / out (+)', negative => 'bytes_read', cdef => 'bytes_written,8,*', min => '0' },
+    ],
+};
+
+$graphs{conns} = {
+    config => {
+        args => '--base 1000 --lower-limit 0',
+        vlabel => 'Connections per ${graph_period}',
+        category => 'memcached',
+        title => 'Connections',
+        info => 'This graph shows the number of connections being handled by memcached',
+        order => 'max_conns curr_conns avg_conns',
+    },
+    datasrc => [
+        { name => 'curr_conns', label => 'Current Connections', min => '0' },
+        { name => 'max_conns', label => 'Max Connections', min => '0' },
+        { name => 'avg_conns' , label => 'Avg Connections', min => '0' },
+    ],
+};
+
+$graphs{commands} = {
+    config => {
+        args => '--base 1000 --lower-limit 0',
+        vlabel => 'Commands per ${graph_period}',
+        category => 'memcached',
+        title => 'Commands',
+        info => 'This graph shows the number of commands being handled by memcached',
+    },
+    datasrc => [
+        { name => 'cmd_get', type => 'DERIVE', label => 'Gets', info => 'Cumulative number of retrieval reqs', min => '0' },
+        { name => 'cmd_set', type => 'DERIVE', label => 'Sets', info => 'Cumulative number of storage reqs', min => '0' },
+        { name => 'get_hits', type => 'DERIVE', label => 'Get Hits', info => 'Number of keys that were requested and found', min => '0' },
+        { name => 'get_misses', type => 'DERIVE', label => 'Get Misses', info => 'Number of keys there were requested and not found', min => '0' },
+        { name => 'delete_hits', type => 'DERIVE', label => 'Delete Hits', info => 'Number of delete requests that resulted in a deletion of a key', min => '0' },
+        { name => 'delete_misses', type => 'DERIVE', label => 'Delete Misses', info => 'Number of delete requests for missing key', min => '0' },
+        { name => 'incr_hits', type => 'DERIVE', label => 'Increment Hits', info => 'Number of successful increment requests', min => '0' },
+        { name => 'incr_misses', type => 'DERIVE', label => 'Increment Misses', info => 'Number of unsuccessful increment requests', min => '0' },
+        { name => 'decr_hits', type => 'DERIVE', label => 'Decrement Hits', info => 'Number of successful decrement requests', min => '0' },
+        { name => 'decr_misses', type => 'DERIVE', label => 'Decrement Misses', info => 'Number of unsuccessful decrement requests', min => '0' },
+    ],
+};
+
+$graphs{evictions} = {
+    config => {
+        args => '--base 1000 --lower-limit 0',
+        vlabel => 'Evictions per ${graph_period}',
+        category => 'memcached',
+        title => 'Evictions',
+        info => 'This graph shows the number of evictions per second',
+    },
+    datasrc => [
+        { name => 'evictions', label => 'Evictions', info => 'Cumulative Evictions Across All Slabs', type => 'DERIVE', min => '0' },
+        { name => 'evicted_nonzero', label => 'Evictions prior to Expire', info => 'Cumulative Evictions forced to expire prior to expiration', type => 'DERIVE', min => '0' },
+        { name => 'reclaimed', label => 'Reclaimed Items', info => 'Cumulative Reclaimed Item Entries Across All Slabs', type => 'DERIVE', min => '0' },
+    ],
+};
+
+$graphs{slabchnks} = {
+    config => {
+        args => '--base 1000 --lower-limit 0',
+        vlabel => 'Available Chunks for this Slab',
+        category => 'memcached',
+        title => 'Chunk Usage for Slab: ',
+        info => 'This graph shows you the chunk usage for this memory slab.',
+    },
+    datasrc => [
+        { name => 'total_chunks', label => 'Total Chunks Available', min => '0' },
+        { name => 'used_chunks', label => 'Total Chunks in Use', min => '0' },
+        { name => 'free_chunks', label => 'Total Chunks Not in Use (Free)', min => '0' },
+    ],
+};
+
+$graphs{slabhits} = {
+    config => {
+        args => '--base 1000 --lower-limit 0',
+        vlabel => 'Hits per Slab per ${graph_period}',
+        category => 'memcached',
+        title => 'Hits for Slab: ',
+        info => 'This graph shows you the successful hit rate for this memory slab.',
+    },
+    datasrc => [
+        { name => 'get_hits', label => 'Get Requests', type => 'DERIVE', min => '0' },
+        { name => 'cmd_set', label => 'Set Requests', type => 'DERIVE', min => '0' },
+        { name => 'delete_hits', label => 'Delete Requests', type => 'DERIVE', min => '0' },
+        { name => 'incr_hits', label => 'Increment Requests', type => 'DERIVE', min => '0' },
+        { name => 'decr_hits', label => 'Decrement Requests', type => 'DERIVE', min => '0' },
+    ],
+};
+
+$graphs{slabevics} = {
+    config => {
+        args => '--base 1000 --lower-limit 0',
+        vlabel => 'Evictions per Slab per ${graph_period}',
+        category => 'memcached',
+        title => 'Evictions for Slab: ',
+        info => 'This graph shows you the eviction rate for this memory slab.',
+    },
+    datasrc => [
+        { name => 'evicted', label => 'Total Evictions', type => 'DERIVE', min => '0' },
+        { name => 'evicted_nonzero', label => 'Evictions from LRU Prior to Expire', type => 'DERIVE', min => '0' },
+        { name => 'reclaimed', label => 'Reclaimed Expired Items', info => 'This is number of times items were stored in expired entry memory space', type => 'DERIVE', min => '0' },
+    ],
+};
+
+$graphs{slabevictime} = {
+    config => {
+        args => '--base 1000 --lower-limit 0',
+        vlabel => ' since Request for LEI',
+        category => 'memcached',
+        title => 'Eviction Request Time for Slab: ',
+        info => 'This graph shows you the time since we requested the last evicted item',
+    },
+    datasrc => [
+        { name => 'evicted_time', label => 'Eviction Time (LEI)', info => 'Time Since Request for Last Evicted Item', min => '0' },
+    ],
+};
+
+$graphs{slabitems} = {
+    config => {
+        args => '--base 1000 --lower-limit 0',
+        vlabel => 'Items per Slab',
+        category => 'memcached',
+        title => 'Items in Slab: ',
+        info => 'This graph shows you the number of items and reclaimed items per slab.',
+    },
+    datasrc => [
+        { name => 'number', label => 'Items', info => 'This is the amount of items stored in this slab', min => '0' },
+    ],
+};
+
+$graphs{slabitemtime} = {
+    config => {
+        args => '--base 1000 --lower-limit 0',
+        vlabel => ' since item was stored',
+        category => 'memcached',
+        title => 'Age of Eldest Item in Slab: ',
+        info => 'This graph shows you the time of the eldest item in this slab',
+    },
+    datasrc => [
+        { name => 'age', label => 'Eldest Item\'s Age', min => '0' },
+    ],
+};
+
+##
+#### Config Check ####
+##
+
+if (defined $ARGV[0] && $ARGV[0] eq 'config') {
+
+    $0 =~ /memcached_multi_(.+)*/;
+    my $plugin = $1;
+
+    die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
+
+    # We need to fetch the stats before we do any config, cause its needed for multigraph
+    fetch_stats();
+
+    # Now lets go ahead and print out our config.
+       do_config($plugin);
+       exit 0;
+}
+
+##
+#### Autoconf Check ####
+##
+
+if (defined $ARGV[0] && $ARGV[0] eq 'autoconf') {
+
+    my $s = IO::Socket::INET->new(
+        Proto    => "tcp",
+        PeerAddr => $host,
+        PeerPort => $port,
+    );
+
+    if (defined($s)) {
+        print "yes\n";
+        exit 0;
+    } else {
+        print "no (unable to connect to $host\[:$port\])\n";
+        exit 0;
+    }
+}
+
+##
+#### Suggest Check ####
+##
+
+if (defined $ARGV[0] && $ARGV[0] eq 'suggest') {
+
+    my $s = IO::Socket::INET->new(
+        Proto    => "tcp",
+        PeerAddr => $host,
+        PeerPort => $port,
+    );
+
+    if (defined($s)) {
+        my @rootplugins = ('bytes','conns','commands','evictions','items','memory');
+        foreach my $plugin (@rootplugins) {
+            print "$plugin\n";
+        }
+        exit 0;
+    } else {
+        print "no (unable to connect to $host\[:$port\])\n";
+        exit 0;
+    }
+}
+
+##
+#### Well We aren't running (auto)config/suggest so lets print some stats ####
+##
+
+fetch_output();
+
+##
+#### Subroutines for printing info gathered from memcached ####
+##
+
+##
+#### This subroutine performs the bulk processing for printing statistics.
+##
+
+sub fetch_output {
+
+    $0 =~ /memcached_multi_(.+)*/;
+    my $plugin = $1;
+
+    die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
+
+    # Well we need to actually fetch the stats before we do anything to them.
+    fetch_stats();
+    
+    # Now lets go ahead and print out our output.
+    my @subgraphs;
+    if ($plugin eq 'memory') {
+        @subgraphs = ('slabchnks');
+        foreach my $slabid(sort{$a <=> $b} keys %chnks) {
+            print_submulti_output($slabid,$plugin,@subgraphs);
+        }
+        print_rootmulti_output($plugin);
+    } elsif ($plugin eq 'commands') {
+        @subgraphs = ('slabhits');
+        foreach my $slabid(sort{$a <=> $b} keys %chnks) {
+            print_submulti_output($slabid,$plugin,@subgraphs);
+        }
+        print_rootmulti_output($plugin);
+    } elsif ($plugin eq 'evictions') {
+        @subgraphs = ('slabevics','slabevictime');
+        foreach my $slabid (sort{$a <=> $b} keys %items) {
+            print_submulti_output($slabid,$plugin,@subgraphs);
+        }
+        print_rootmulti_output($plugin);
+    } elsif ($plugin eq 'items') {
+        @subgraphs = ('slabitems','slabitemtime');
+        foreach my $slabid (sort{$a <=> $b} keys %items) {
+            print_submulti_output($slabid,$plugin,@subgraphs);
+        }
+        print_rootmulti_output($plugin);
+    } else {
+        print_root_output($plugin);
+    }
+
+    return;
+}
+
+##
+#### This subroutine is for the root non-multigraph graphs which render on the main node page ####
+##
+
+sub print_root_output {
+    my ($plugin) = (@_);
+
+    my $graph = $graphs{$plugin};
+
+    print "graph memcached_$plugin\n";
+
+    if ($plugin ne 'conns') {
+        foreach my $dsrc (@{$graph->{datasrc}}) {
+            my %datasrc = %$dsrc;
+            while ( my ($key, $value) = each(%datasrc)) {
+                next if ($key ne 'name');
+                my $output = $stats{$value};
+                print "$dsrc->{name}.value $output\n";
+            }
+        }
+    } else {
+        my $output;
+        foreach my $dsrc (@{$graph->{datasrc}}) {
+            my %datasrc = %$dsrc;
+            while ( my ($key, $value) = each(%datasrc)) {
+                if ($value eq 'max_conns') {
+                    $output = $stats{maxconns};
+                } elsif ($value eq 'curr_conns') {
+                    $output = $stats{curr_connections};
+                } elsif ($value eq 'avg_conns') {
+                    $output = sprintf("%02d", $stats{total_connections} / $stats{uptime});
+                } else {
+                    next;
+                }
+                print "$dsrc->{name}.value $output\n";
+            }
+        }
+    }
+
+    return;
+}
+
+##
+#### This subroutine is for the root multigraph graphs which render on the main node page ####
+##
+
+sub print_rootmulti_output {
+    my ($plugin) = (@_);
+
+    my $graph = $graphs{$plugin};
+
+    print "multigraph memcached_$plugin\n";
+    
+    foreach my $dsrc (@{$graph->{datasrc}}) {
+        my $output = 0;
+        my %datasrc = %$dsrc;
+        while ( my ($key, $value) = each(%datasrc)) {
+            next if ($key ne 'name');
+            if (($plugin eq 'evictions') && ($value eq 'evicted_nonzero')) {
+                foreach my $slabid (sort{$a <=> $b} keys %items) {
+                    $output += $items{$slabid}->{evicted_nonzero};
+                }
+            } else {
+                $output = $stats{$value};
+            }
+            print "$dsrc->{name}.value $output\n";
+        }
+    }
+
+    return;
+}
+
+##
+#### This subroutine is for the sub multigraph graphs created via the multigraph plugin ####
+##
+
+sub print_submulti_output {
+    my ($slabid,$plugin,@subgraphs) = (@_);
+    my $currslab = undef;
+
+    foreach my $sgraph (@subgraphs) {
+
+        my $graph = $graphs{$sgraph};
+
+        print "multigraph memcached_$plugin.$sgraph\_$slabid\n";
+
+        if ($plugin eq 'evictions') {
+            $currslab = $items{$slabid};
+        } elsif ($plugin eq 'memory') {
+            $currslab = $chnks{$slabid};
+        } elsif ($plugin eq 'commands') {
+            $currslab = $chnks{$slabid};
+        } elsif ($plugin eq 'items') {
+            $currslab = $items{$slabid};
+        } else {
+            return;
+        }
+
+        foreach my $dsrc (@{$graph->{datasrc}}) {
+            my %datasrc = %$dsrc;
+            while ( my ($key, $value) = each(%datasrc)) {
+                next if ($key ne 'name');
+                my $output = $currslab->{$value};
+                if (($sgraph eq 'slabevictime') || ($sgraph eq 'slabitemtime')) {
+                    $output = time_scale('data',$output); ;
+                }
+                print "$dsrc->{name}.value $output\n";
+            }
+        }
+    }
+
+    return;
+}
+
+##
+#### Subroutines for printing out config information for graphs ####
+##
+
+##
+#### This subroutine does the bulk printing the config info per graph ####
+##
+
+sub do_config {
+    my ($plugin) = (@_);
+    my @subgraphs;
+    if ($plugin eq 'memory') {
+        @subgraphs = ('slabchnks');
+        foreach my $slabid (sort{$a <=> $b} keys %chnks) {
+            print_submulti_config($slabid,$plugin,@subgraphs);
+        }
+        print_rootmulti_config($plugin);
+    } elsif ($plugin eq 'commands') {
+        @subgraphs = ('slabhits');
+        foreach my $slabid (sort{$a <=> $b} keys %chnks) {
+            print_submulti_config($slabid,$plugin,@subgraphs);
+        }
+        print_rootmulti_config($plugin);
+    } elsif ($plugin eq 'evictions') {
+        @subgraphs = ('slabevics','slabevictime');
+        foreach my $slabid (sort{$a <=> $b}  keys %items) {
+            print_submulti_config($slabid,$plugin,@subgraphs);
+        }
+        print_rootmulti_config($plugin);
+    } elsif ($plugin eq 'items') {
+        @subgraphs = ('slabitems','slabitemtime');
+        foreach my $slabid (sort{$a <=> $b} keys %items) {
+            print_submulti_config($slabid,$plugin,@subgraphs);
+        }
+        print_rootmulti_config($plugin);
+    } else {
+        print_root_config($plugin);
+    }
+
+    return;
+}
+
+##
+#### This subroutine is for the config info for sub multigraph graphs created via the multigraph plugin ####
+##
+
+sub print_submulti_config {
+    my ($slabid,$plugin,@subgraphs) = (@_);
+    my ($slabitems,$slabchnks) = undef;
+
+    foreach my $sgraph (@subgraphs) {
+
+        my $graph = $graphs{$sgraph};
+
+        my %graphconf = %{$graph->{config}};
+        
+        print "multigraph memcached_$plugin.$sgraph\_$slabid\n";
+
+        while ( my ($key, $value) = each(%graphconf)) {
+               if ($key eq 'title') {
+                   print "graph_$key $value" . "$slabid" . " ($chnks{$slabid}->{chunk_size} Bytes)\n";
+               } elsif (($key eq 'vlabel') && (($sgraph eq 'slabevictime') || ($sgraph eq 'slabitemtime'))) {
+                $value = time_scale('config',$value);
+                print "graph_$key $value\n";
+            } else {
+                print "graph_$key $value\n";
+               }
+        }
+
+        foreach my $dsrc (@{$graph->{datasrc}}) {
+            my %datasrc = %$dsrc;
+            while ( my ($key, $value) = each(%datasrc)) {
+                next if ($key eq 'name');
+                print "$dsrc->{name}.$key $value\n";
+            }
+        }
+    }
+
+    return;
+}
+
+##
+#### This subroutine is for the config info for root multigraph graphs which render on the main node page ####
+##
+
+sub print_rootmulti_config {
+    my ($plugin) = (@_);
+
+    die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
+
+    my $graph = $graphs{$plugin};
+
+    my %graphconf = %{$graph->{config}};
+
+    print "multigraph memcached_$plugin\n";
+
+    while ( my ($key, $value) = each(%graphconf)) {
+        print "graph_$key $value\n";
+    }
+
+    foreach my $dsrc (@{$graph->{datasrc}}) {
+        my %datasrc = %$dsrc;
+        while ( my ($key, $value) = each(%datasrc)) {
+            next if ($key eq 'name');
+            print "$dsrc->{name}.$key $value\n";
+        }
+    }
+
+    return;
+}
+
+##
+#### This subroutine is for the config info for non multigraph graphs which render on the main node page ####
+##
+
+sub print_root_config {
+    my ($plugin) = (@_);
+
+    die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
+
+    my $graph = $graphs{$plugin};
+
+    my %graphconf = %{$graph->{config}};
+
+    print "graph memcached_$plugin\n";
+
+    while ( my ($key, $value) = each(%graphconf)) {
+        print "graph_$key $value\n";
+    }
+
+    foreach my $dsrc (@{$graph->{datasrc}}) {
+        my %datasrc = %$dsrc;
+        while ( my ($key, $value) = each(%datasrc)) {
+            next if ($key eq 'name');
+            print "$dsrc->{name}.$key $value\n";
+        }
+    }
+
+    return;
+}
+
+##
+#### This subroutine actually performs the data fetch for us ####
+#### These commands do not lock up Memcache at all ####
+##
+
+sub fetch_stats {
+    my $s = IO::Socket::INET->new(
+        Proto    => "tcp",
+        PeerAddr => $host,
+        PeerPort => $port,
+    );
+
+    die "Error: Unable to Connect to $host\[:$port\]\n" unless $s;
+
+    print $s "stats\r\n";
+
+    while (my $line = <$s>) {
+        if ($line =~ /STAT\s(.+?)\s(\d+)/) {
+            my ($skey,$svalue) = ($1,$2);
+            $stats{$skey} = $svalue;
+        }
+        last if $line =~ /^END/;
+    }
+
+    print $s "stats settings\r\n";
+
+    while (my $line = <$s>) {
+        if ($line =~ /STAT\s(.+?)\s(\d+)/) {
+            my ($skey,$svalue) = ($1,$2);
+            $stats{$skey} = $svalue;
+        }
+        last if $line =~ /^END/;
+    }
+
+    print $s "stats slabs\r\n";
+
+    while (my $line = <$s>) {
+        if ($line =~ /STAT\s(\d+):(.+)\s(\d+)/) {
+            my ($slabid,$slabkey,$slabvalue) = ($1,$2,$3);
+            $chnks{$slabid}->{$slabkey} = $slabvalue;
+        }
+        last if $line =~ /^END/;
+    }
+
+    print $s "stats items\r\n";
+
+    while (my $line = <$s>) {
+        if ($line =~ /STAT\sitems:(\d+):(.+?)\s(\d+)/) {
+            my ($itemid,$itemkey,$itemvalue) = ($1,$2,$3);
+            $items{$itemid}->{$itemkey} = $itemvalue;
+        }
+        last if $line =~ /^END/;
+    }
+}
+
+##
+#### This subroutine is to help manage the time_scale settings for the graph
+##
+
+sub time_scale {
+    my ($configopt,$origvalue) = (@_);
+    my $value;
+
+    if ($configopt eq 'config') {
+        if ($timescale == 1) {
+            $value = "Seconds" . $origvalue;
+        } elsif ($timescale == 2) {
+            $value = "Minutes" . $origvalue;
+        } elsif (($timescale == 3) || ($timescale > 4) || (!defined($timescale))) {
+            $value = "Hours" . $origvalue;
+        } elsif ($timescale == 4) {
+            $value = "Days" . $origvalue;
+        }
+    } elsif ($configopt eq 'data') {
+        if ($timescale == 1) {
+            $value = sprintf("%02.2f", $origvalue / 1);
+        } elsif ($timescale == 2) {
+            $value = sprintf("%02.2f", $origvalue / 60);
+        } elsif (($timescale == 3) || ($timescale > 4) || (!defined($timescale))) {
+            $value = sprintf("%02.2f", $origvalue / 3600);
+        } elsif ($timescale == 4) {
+            $value = sprintf("%02.2f", $origvalue / 86400);
+        }
+    } else {
+        die "Unknown time_scale option given: either [config/data]\n";
+    }
+    return $value;
+}
diff --git a/cookbooks/munin/files/default/plugins/mod_tile_fresh b/cookbooks/munin/files/default/plugins/mod_tile_fresh
new file mode 100755 (executable)
index 0000000..55aef14
--- /dev/null
@@ -0,0 +1,47 @@
+#!/bin/sh
+#
+# Plugin to monitor the state / freshness  of the tiles returned by mod_tile
+#
+# Parameters: 
+#
+#      config   (required)
+#      autoconf (optional - used by munin-config)
+#
+
+if [ "$1" = "config" ]; then
+
+       echo 'graph_title freshness of served tiles'
+       echo 'graph_args --base 1000 -l 0'
+       echo 'graph_vlabel tiles per ${graph_period}'
+       echo 'graph_category mod_tile'
+       echo 'fresh.label Fresh from disk'
+       echo 'fresh.draw AREA'
+       echo 'fresh.type DERIVE'
+       echo 'fresh.min 0'
+       echo 'freshrender.label Freshly rendered'
+       echo 'freshrender.draw STACK'
+       echo 'freshrender.type DERIVE'
+       echo 'freshrender.min 0'
+       echo 'old.label Old from disk'
+       echo 'old.draw STACK'
+       echo 'old.type DERIVE'
+       echo 'old.min 0'
+       echo 'oldrender.label Old tile, attempted render'
+       echo 'oldrender.draw STACK'
+       echo 'oldrender.type DERIVE'
+       echo 'oldrender.min 0'
+
+       exit 0
+fi
+
+data=`wget -q http://localhost/mod_tile -O -`
+
+fresh=`expr match "$data" '.*NoFreshCache: \([0-9]*\)'`
+freshRender=`expr match "$data" '.*NoFreshRender: \([0-9]*\)'`
+old=`expr match "$data" '.*NoOldCache: \([0-9]*\)'`
+oldRender=`expr match "$data" '.*NoOldRender: \([0-9]*\)'`
+
+echo "fresh.value " $fresh
+echo "freshrender.value " $freshRender
+echo "old.value " $old
+echo "oldrender.value " $oldRender
diff --git a/cookbooks/munin/files/default/plugins/mod_tile_response b/cookbooks/munin/files/default/plugins/mod_tile_response
new file mode 100755 (executable)
index 0000000..2a098af
--- /dev/null
@@ -0,0 +1,48 @@
+#!/bin/sh
+#
+# Plugin to monitor the response codes of tiles returned by mod_tile
+#
+# Parameters: 
+#
+#      config   (required)
+#      autoconf (optional - used by munin-config)
+#
+
+if [ "$1" = "config" ]; then
+
+       echo 'graph_title mod_tile HTTP response codes'
+       echo 'graph_args --base 1000 -l 0'
+       echo 'graph_vlabel responses per ${graph_period}'
+       echo 'graph_category mod_tile'
+       echo 'response200.label 200 OK'
+       echo 'response200.draw AREA'
+       echo 'response200.type DERIVE'
+       echo 'response200.min 0'
+       echo 'response304.label 304 Not Modified'
+       echo 'response304.draw STACK'
+       echo 'response304.type DERIVE'
+       echo 'response304.min 0'
+       echo 'response404.label 404 Not Found'
+       echo 'response404.draw STACK'
+       echo 'response404.type DERIVE'
+       echo 'response404.min 0'
+       echo 'response500.label 500 Internal Error'
+       echo 'response500.draw STACK'
+       echo 'response500.type DERIVE'
+       echo 'response500.min 0'
+
+       exit 0
+fi
+
+
+data=`wget -q http://localhost/mod_tile -O -`
+
+ok_resp=`expr match "$data" '.*NoResp200: \([0-9]*\)'`
+nm_resp=`expr match "$data" '.*NoResp304: \([0-9]*\)'`
+fnf_resp=`expr match "$data" '.*NoResp404: \([0-9]*\)'`
+error_resp=`expr match "$data" '.*NoResp5XX: \([0-9]*\)'`
+
+echo "response200.value " $ok_resp
+echo "response304.value " $nm_resp
+echo "response404.value " $fnf_resp
+echo "response500.value " $error_resp
diff --git a/cookbooks/munin/files/default/plugins/nominatim_lag b/cookbooks/munin/files/default/plugins/nominatim_lag
new file mode 100755 (executable)
index 0000000..5afa44b
--- /dev/null
@@ -0,0 +1,135 @@
+#!/usr/bin/perl -w
+# Plugin to monitor pg_stat_*_tables (user by default)
+#
+# Copyright Dalibo <cedric.villemain@dalibo.com> 2007
+# Based on a plugin (postgres_block_read_) from Björn Ruberg <bjorn@linpro.no>
+#
+# Licenced under GPL v2.
+#
+# Usage:
+#
+#       Symlink into /etc/munin/plugins/ and add the monitored
+#       database to the filename. e.g.:
+#
+#       ln -s /usr/share/munin/plugins/pg__stat_tables \
+#         /etc/munin/plugins/pg_<databasename>_stat_tables
+#       This should, however, be given through autoconf and suggest.
+#
+#       If required, give username, password and/or Postgresql server
+#       host through environment variables.
+#
+#       You must also activate Postgresql statistics. See
+#       http://www.postgresql.org/docs/8.1/interactive/monitoring-stats.html
+#       for how to enable this. Specifically, the following lines must
+#       exist in your postgresql.conf:
+#
+#           stats_start_collector = true
+#           stats_block_level = true
+#
+#
+# Parameters:
+#
+#       config   (required)
+#
+# Config variables:
+#
+#       dbhost     - Which database server to use. Defaults to
+#                    'localhost'.
+#       dbname     - Which database to use. Defaults to template1
+#       dbuser     - A Postgresql user account with read permission to
+#                    the given database. Defaults to
+#                    'postgres'. Anyway, Munin must be told which user
+#                    this plugin should be run as.
+#       dbpass     - The corresponding password, if
+#                    applicable. Default to undef. Remember that
+#                    pg_hba.conf must be configured accordingly.
+#
+# Magic markers
+#%# family=auto
+#%# capabilities=autoconf
+
+use strict;
+use DBI;
+use vars qw ( $debug $configure  );
+use constant _PGMINI => 70400;
+
+my $dbhost = $ENV{'dbhost'} || '';
+my $dbname = $ENV{'dbname'} || 'template1';
+my $dbuser = $ENV{'dbuser'} || 'postgres';
+my $dbport = $ENV{'dbport'} || '5432';
+my $dbpass = $ENV{'dbpass'} || '';
+my $statscope = $ENV{'statscope'} || 'user';
+
+my $dsn = "DBI:Pg:dbname=$dbname";
+$dsn   .=";host=$dbhost;port=$dbport" if $dbhost;
+my $pg_server_version;
+
+if (exists $ARGV[0]) {
+  if ($ARGV[0] eq 'autoconf') {
+    # Check for DBD::Pg
+    if (! eval "require DBD::Pg;") {
+      print "no (DBD::Pg not found)";
+      exit 1;
+    }
+    my $dbh = DBI->connect ($dsn,
+                            $dbuser,
+                            $dbpass,
+                            {RaiseError =>1});
+    if ($dbh) {
+      $pg_server_version = $dbh->{'pg_server_version'};
+      if ($pg_server_version < (_PGMINI)) {
+        $pg_server_version =~ /(\d)(\d){2,2}(\d){2,2}/;
+        print "PostgreSQL Server version " . (_PGMINI) . " or above is needed. Current is $1.$2.$3 \n";
+                               exit 1;
+      }
+      print "yes\n";
+      exit 0;
+    } else {
+      print "no Unable to access Database $dbname on host $dbhost as user $dbuser.\nError returned was: ". $DBI::errstr;
+      exit 1;
+    }
+  } elsif ($ARGV[0] eq 'debug') {
+    # Set debug flag
+    $debug = 1;
+  } elsif ($ARGV[0] eq 'config') {
+    # Set config flag
+    $configure = 1;
+  }
+}
+
+print "# $dsn\n" if $debug;
+my $dbh = DBI->connect ($dsn,
+                        $dbuser,
+                        $dbpass,
+                        {RaiseError =>1});
+
+die ("no Unable to access Database $dbname on host $dbhost as user $dbuser.\nError returned was: ". $DBI::errstr."\n") unless($dbh);
+$pg_server_version = $dbh->{'pg_server_version'};
+
+if ($configure) {
+  print "graph_title Total Nominatim Lag Time\n";
+  print "graph_vlabel Lag\n";
+  print "graph_category Nominatim \n";
+  print "graph_period minute\n";
+  print "graph_args --base 1000\n";
+
+  print "lag.label Lag\n";
+  print "lag.draw LINE\n";
+  print "lag.type GAUGE\n";
+  print "lag.min 0\n";
+
+} else {
+
+  my $sql = "select round(extract('epoch' from 'now'::timestamp with time zone - lastimportdate)) from import_status";
+  print "# $sql\n" if $debug;
+  my $sth = $dbh->prepare($sql);
+  $sth->execute();
+  printf ("# Rows: %d\n",  $sth->rows) if $debug;
+  if ($sth->rows > 0) {
+    my ($lag) = $sth->fetchrow_array();
+    print "lag.value $lag\n";
+  }
+}
+
+exit 0;
+
diff --git a/cookbooks/munin/files/default/plugins/nominatim_query_speed b/cookbooks/munin/files/default/plugins/nominatim_query_speed
new file mode 100755 (executable)
index 0000000..811df0e
--- /dev/null
@@ -0,0 +1,151 @@
+#!/usr/bin/perl -w
+# Plugin to monitor pg_stat_*_tables (user by default)
+#
+# Copyright Dalibo <cedric.villemain@dalibo.com> 2007
+# Based on a plugin (postgres_block_read_) from Björn Ruberg <bjorn@linpro.no>
+#
+# Licenced under GPL v2.
+#
+# Usage:
+#
+#       Symlink into /etc/munin/plugins/ and add the monitored
+#       database to the filename. e.g.:
+#
+#       ln -s /usr/share/munin/plugins/pg__stat_tables \
+#         /etc/munin/plugins/pg_<databasename>_stat_tables
+#       This should, however, be given through autoconf and suggest.
+#
+#       If required, give username, password and/or Postgresql server
+#       host through environment variables.
+#
+#       You must also activate Postgresql statistics. See
+#       http://www.postgresql.org/docs/8.1/interactive/monitoring-stats.html
+#       for how to enable this. Specifically, the following lines must
+#       exist in your postgresql.conf:
+#
+#           stats_start_collector = true
+#           stats_block_level = true
+#
+#
+# Parameters:
+#
+#       config   (required)
+#
+# Config variables:
+#
+#       dbhost     - Which database server to use. Defaults to
+#                    'localhost'.
+#       dbname     - Which database to use. Defaults to template1
+#       dbuser     - A Postgresql user account with read permission to
+#                    the given database. Defaults to
+#                    'postgres'. Anyway, Munin must be told which user
+#                    this plugin should be run as.
+#       dbpass     - The corresponding password, if
+#                    applicable. Default to undef. Remember that
+#                    pg_hba.conf must be configured accordingly.
+#
+# Magic markers
+#%# family=auto
+#%# capabilities=autoconf
+
+use strict;
+use DBI;
+use vars qw ( $debug $configure  );
+use constant _PGMINI => 70400;
+
+my $dbhost = $ENV{'dbhost'} || '';
+my $dbname = $ENV{'dbname'} || 'template1';
+my $dbuser = $ENV{'dbuser'} || 'postgres';
+my $dbport = $ENV{'dbport'} || '5432';
+my $dbpass = $ENV{'dbpass'} || '';
+my $statscope = $ENV{'statscope'} || 'user';
+
+my $dsn = "DBI:Pg:dbname=$dbname";
+$dsn   .=";host=$dbhost;port=$dbport" if $dbhost;
+my $pg_server_version;
+
+if (exists $ARGV[0]) {
+  if ($ARGV[0] eq 'autoconf') {
+    # Check for DBD::Pg
+    if (! eval "require DBD::Pg;") {
+      print "no (DBD::Pg not found)";
+      exit 1;
+    }
+    my $dbh = DBI->connect ($dsn,
+                            $dbuser,
+                            $dbpass,
+                            {RaiseError =>1});
+    if ($dbh) {
+      $pg_server_version = $dbh->{'pg_server_version'};
+      if ($pg_server_version < (_PGMINI)) {
+        $pg_server_version =~ /(\d)(\d){2,2}(\d){2,2}/;
+        print "PostgreSQL Server version " . (_PGMINI) . " or above is needed. Current is $1.$2.$3 \n";
+                               exit 1;
+      }
+      print "yes\n";
+      exit 0;
+    } else {
+      print "no Unable to access Database $dbname on host $dbhost as user $dbuser.\nError returned was: ". $DBI::errstr;
+      exit 1;
+    }
+  } elsif ($ARGV[0] eq 'debug') {
+    # Set debug flag
+    $debug = 1;
+  } elsif ($ARGV[0] eq 'config') {
+    # Set config flag
+    $configure = 1;
+  }
+}
+
+print "# $dsn\n" if $debug;
+my $dbh = DBI->connect ($dsn,
+                        $dbuser,
+                        $dbpass,
+                        {RaiseError =>1});
+
+die ("no Unable to access Database $dbname on host $dbhost as user $dbuser.\nError returned was: ". $DBI::errstr."\n") unless($dbh);
+$pg_server_version = $dbh->{'pg_server_version'};
+
+if ($configure) {
+  print "graph_title Total Nominatim response time\n";
+  print "graph_vlabel Time to response\n";
+  print "graph_category Nominatim \n";
+  print "graph_period minute\n";
+  print "graph_args --base 1000\n";
+
+  print "avg.label Average time to response\n";
+  print "avg.draw LINE\n";
+  print "avg.type GAUGE\n";
+  print "avg.min 0\n";
+  print "avg.info Moving 5 minute average time to perform search\n";
+  print "avg.label Average time to response\n";
+
+  print "min.label Fastest time to response\n";
+  print "min.draw LINE\n";
+  print "min.type GAUGE\n";
+  print "min.min 0\n";
+  print "min.info Fastest query in last 5 minutes\n";
+
+  print "max.label Slowest time to response\n";
+  print "max.draw LINE\n";
+  print "max.type GAUGE\n";
+  print "max.min 0\n";
+  print "max.info Slowest query in last 5 minutes\n";
+
+} else {
+
+  my $sql = "select TO_CHAR(avg(endtime-starttime),'SS.MS'),TO_CHAR(min(endtime-starttime),'SS.MS'),TO_CHAR(max(endtime-starttime),'SS.MS') from query_log where starttime > 'now'::timestamp - '5 minutes'::interval";
+  print "# $sql\n" if $debug;
+  my $sth = $dbh->prepare($sql);
+  $sth->execute();
+  printf ("# Rows: %d\n",  $sth->rows) if $debug;
+  if ($sth->rows > 0) {
+    my ($avg, $min, $max) = $sth->fetchrow_array();
+    print "avg.value $avg\n";
+    print "min.value $min\n";
+    print "max.value $max\n";
+  }
+}
+
+exit 0;
+
diff --git a/cookbooks/munin/files/default/plugins/nominatim_query_volume b/cookbooks/munin/files/default/plugins/nominatim_query_volume
new file mode 100755 (executable)
index 0000000..3d95336
--- /dev/null
@@ -0,0 +1,148 @@
+#!/usr/bin/perl -w
+# Plugin to monitor pg_stat_*_tables (user by default)
+#
+# Copyright Dalibo <cedric.villemain@dalibo.com> 2007
+# Based on a plugin (postgres_block_read_) from Björn Ruberg <bjorn@linpro.no>
+#
+# Licenced under GPL v2.
+#
+# Usage:
+#
+#       Symlink into /etc/munin/plugins/ and add the monitored
+#       database to the filename. e.g.:
+#
+#       ln -s /usr/share/munin/plugins/pg__stat_tables \
+#         /etc/munin/plugins/pg_<databasename>_stat_tables
+#       This should, however, be given through autoconf and suggest.
+#
+#       If required, give username, password and/or Postgresql server
+#       host through environment variables.
+#
+#       You must also activate Postgresql statistics. See
+#       http://www.postgresql.org/docs/8.1/interactive/monitoring-stats.html
+#       for how to enable this. Specifically, the following lines must
+#       exist in your postgresql.conf:
+#
+#           stats_start_collector = true
+#           stats_block_level = true
+#
+#
+# Parameters:
+#
+#       config   (required)
+#
+# Config variables:
+#
+#       dbhost     - Which database server to use. Defaults to
+#                    'localhost'.
+#       dbname     - Which database to use. Defaults to template1
+#       dbuser     - A Postgresql user account with read permission to
+#                    the given database. Defaults to
+#                    'postgres'. Anyway, Munin must be told which user
+#                    this plugin should be run as.
+#       dbpass     - The corresponding password, if
+#                    applicable. Default to undef. Remember that
+#                    pg_hba.conf must be configured accordingly.
+#
+# Magic markers
+#%# family=auto
+#%# capabilities=autoconf
+
+use strict;
+use DBI;
+use vars qw ( $debug $configure  );
+use constant _PGMINI => 70400;
+
+my $dbhost = $ENV{'dbhost'} || '';
+my $dbname = $ENV{'dbname'} || 'template1';
+my $dbuser = $ENV{'dbuser'} || 'postgres';
+my $dbport = $ENV{'dbport'} || '5432';
+my $dbpass = $ENV{'dbpass'} || '';
+my $statscope = $ENV{'statscope'} || 'user';
+
+my $dsn = "DBI:Pg:dbname=$dbname";
+$dsn   .=";host=$dbhost;port=$dbport" if $dbhost;
+my $pg_server_version;
+
+if (exists $ARGV[0]) {
+  if ($ARGV[0] eq 'autoconf') {
+    # Check for DBD::Pg
+    if (! eval "require DBD::Pg;") {
+      print "no (DBD::Pg not found)";
+      exit 1;
+    }
+    my $dbh = DBI->connect ($dsn,
+                            $dbuser,
+                            $dbpass,
+                            {RaiseError =>1});
+    if ($dbh) {
+      $pg_server_version = $dbh->{'pg_server_version'};
+      if ($pg_server_version < (_PGMINI)) {
+        $pg_server_version =~ /(\d)(\d){2,2}(\d){2,2}/;
+        print "PostgreSQL Server version " . (_PGMINI) . " or above is needed. Current is $1.$2.$3 \n";
+                               exit 1;
+      }
+      print "yes\n";
+      exit 0;
+    } else {
+      print "no Unable to access Database $dbname on host $dbhost as user $dbuser.\nError returned was: ". $DBI::errstr;
+      exit 1;
+    }
+  } elsif ($ARGV[0] eq 'debug') {
+    # Set debug flag
+    $debug = 1;
+  } elsif ($ARGV[0] eq 'config') {
+    # Set config flag
+    $configure = 1;
+  }
+}
+
+print "# $dsn\n" if $debug;
+my $dbh = DBI->connect ($dsn,
+                        $dbuser,
+                        $dbpass,
+                        {RaiseError =>1});
+
+die ("no Unable to access Database $dbname on host $dbhost as user $dbuser.\nError returned was: ". $DBI::errstr."\n") unless($dbh);
+$pg_server_version = $dbh->{'pg_server_version'};
+
+if ($configure) {
+  print "graph_title Total Nominatim queries processed\n";
+  print "graph_vlabel Number / \${graph_period}\n";
+  print "graph_category Nominatim \n";
+  print "graph_args --base 1000\n";
+
+  print "search.label Queries performed\n";
+  print "search.draw LINE\n";
+  print "search.type DERIVE\n";
+  print "search.min 0\n";
+  print "search.info Number of search queries performed\n";
+
+  print "search_completed.label Queries completed\n";
+  print "search_completed.draw LINE\n";
+  print "search_completed.type DERIVE\n";
+  print "search_completed.min 0\n";
+  print "search_completed.info Number of search queries completed\n";
+
+  print "search_failed.label Queries failed\n";
+  print "search_failed.draw LINE\n";
+  print "search_failed.type DERIVE\n";
+  print "search_failed.min 0\n";
+  print "search_failed.info Number of search queries failed to find a match\n";
+} else {
+
+  my $sql = "select count(*),sum(case when results > 0 THEN 1 ELSE 0 END),sum(case when results = 0 THEN 1 ELSE 0 END) from query_log";
+  print "# $sql\n" if $debug;
+  my $sth = $dbh->prepare($sql);
+  $sth->execute();
+  printf ("# Rows: %d\n",  $sth->rows) if $debug;
+  if ($sth->rows > 0) {
+    my ($search, $search_completed, $search_failed) = $sth->fetchrow_array();
+    print "search.value $search\n";
+    print "search_completed.value $search_completed\n";
+    print "search_failed.value $search_failed\n";
+  }
+}
+
+exit 0;
+
diff --git a/cookbooks/munin/files/default/plugins/passenger_memory b/cookbooks/munin/files/default/plugins/passenger_memory
new file mode 100755 (executable)
index 0000000..a894afc
--- /dev/null
@@ -0,0 +1,32 @@
+#!/usr/bin/env ruby
+# put in /etc/munin/plugins and restart munin-node
+# by Dan Manges, http://www.dcmanges.com/blog/rails-application-visualization-with-munin
+# NOTE: you might need to add munin to allow passwordless sudo for passenger-memory-stats 
+def output_config
+  puts <<-END
+graph_args --base 1024 -l 0 --vertical-label bytes --upper-limit 4056231936
+graph_category passenger
+graph_title Passenger memory
+
+memory.label memory
+END
+  exit 0
+end
+def output_values
+  status = `/usr/sbin/passenger-memory-stats | tail -1` 
+  unless $?.success?
+    $stderr.puts "failed executing passenger-memory-stats"
+    exit 1
+  end
+  status =~ /(\d+\.\d+)/
+  puts "memory.value #{($1.to_f * 1024 * 1024).round}"
+end
+if ARGV[0] == "config"
+  output_config
+else
+  output_values
+end
+
diff --git a/cookbooks/munin/files/default/plugins/passenger_processes b/cookbooks/munin/files/default/plugins/passenger_processes
new file mode 100755 (executable)
index 0000000..d89d041
--- /dev/null
@@ -0,0 +1,36 @@
+#!/usr/bin/env ruby
+
+def output_config
+  puts <<-END
+graph_category passenger
+graph_title Passenger processes
+graph_order active inactive
+graph_vlabel processes
+graph_total total
+
+active.label busy servers
+active.draw AREA
+inactive.label idle servers
+inactive.draw STACK
+END
+  exit 0
+end
+
+def output_values
+  status = `/usr/sbin/passenger-status`
+  unless $?.success?
+    $stderr.puts "failed executing passenger-status"
+    exit 1
+  end
+  status =~ /active\s+=\s+(\d+)/
+  puts "active.value #{$1}"
+
+  status =~ /inactive\s+=\s+(\d+)/
+  puts "inactive.value #{$1}"
+end
+
+if ARGV[0] == "config"
+  output_config
+else
+  output_values
+end
diff --git a/cookbooks/munin/files/default/plugins/passenger_queues b/cookbooks/munin/files/default/plugins/passenger_queues
new file mode 100755 (executable)
index 0000000..9a67faf
--- /dev/null
@@ -0,0 +1,28 @@
+#!/usr/bin/env ruby
+
+def output_config
+  puts <<-END
+graph_category passenger
+graph_title Passenger queues
+graph_vlabel count
+
+global.label global
+END
+  exit 0
+end
+
+def output_values
+  status = `/usr/sbin/passenger-status`
+  unless $?.success?
+    $stderr.puts "failed executing passenger-status"
+    exit 1
+  end
+  status =~ /Waiting on global queue:\s+(\d+)/
+  puts "global.value #{$1}"
+end
+
+if ARGV[0] == "config"
+  output_config
+else
+  output_values
+end
diff --git a/cookbooks/munin/files/default/plugins/passenger_requests b/cookbooks/munin/files/default/plugins/passenger_requests
new file mode 100755 (executable)
index 0000000..f783be9
--- /dev/null
@@ -0,0 +1,33 @@
+#!/usr/bin/env ruby
+
+def output_config
+  puts <<-END
+graph_args --base 1000
+graph_category passenger
+graph_title Passenger requests
+graph_vlabel requests / ${graph_period}
+
+requests.label requests
+requests.type DERIVE
+requests.max 1000000
+requests.min 0
+END
+  exit 0
+end
+
+def output_values
+  status = `/usr/sbin/passenger-status`
+  unless $?.success?
+    $stderr.puts "failed executing passenger-status"
+    exit 1
+  end
+  total_requests = 0
+  status.scan(/Processed: (\d+)/).flatten.each { |count| total_requests += count.to_i }
+  puts "requests.value #{total_requests}"
+end
+
+if ARGV[0] == "config"
+  output_config
+else
+  output_values
+end
diff --git a/cookbooks/munin/files/default/plugins/postgres_replication b/cookbooks/munin/files/default/plugins/postgres_replication
new file mode 100755 (executable)
index 0000000..a41af7d
--- /dev/null
@@ -0,0 +1,23 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Munin::Plugin::Pgsql;
+
+my $pg = Munin::Plugin::Pgsql->new(
+    title     => 'PostgreSQL replication delay',
+    info      => 'Replication delay',
+    vlabel    => 'Seconds',
+    basequery =>
+        "SELECT
+           CASE
+             WHEN pg_last_xlog_receive_location() = pg_last_xlog_replay_location() THEN 0::int
+             ELSE (extract(epoch FROM now()) - extract(epoch FROM pg_last_xact_replay_timestamp()))::int
+           END AS delay",
+    pivotquery => 1,
+    configquery =>
+        "VALUES ('delay','Replication delay')"
+);
+
+$pg->Process();
diff --git a/cookbooks/munin/files/default/plugins/renderd_processed b/cookbooks/munin/files/default/plugins/renderd_processed
new file mode 100755 (executable)
index 0000000..9cc953b
--- /dev/null
@@ -0,0 +1,60 @@
+#!/bin/sh
+#
+# Plugin to monitor the rendering throughput of Renderd
+#
+# Parameters: 
+#
+#      config   (required)
+#      autoconf (optional - used by munin-config)
+#
+
+if [ "$1" = "config" ]; then
+
+       echo 'graph_title Renderd throughput'
+       echo 'graph_args --base 1000 -l 0'
+       echo 'graph_vlabel Metatiles per ${graph_period}'
+       echo 'graph_category renderd'
+       echo 'graph_info Displays the number of metatiles being rendered by renderd per ${graph_period}'
+       echo 'req.label Request Queue'
+       echo 'req.type DERIVE'
+       echo 'req.min 0'
+       echo 'req.draw AREA'
+       echo 'req.info Throughput of Metatiles submitted for on the fly rendering'
+       echo 'reqPrio.label Priority request Queue'
+       echo 'reqPrio.type DERIVE'
+       echo 'reqPrio.min 0'
+       echo 'reqPrio.draw STACK'
+       echo 'reqPrio.info Throughput of Metatiles submitted high priority for on the fly rendering'
+       echo 'dirty.label Dirty Queue'
+       echo 'dirty.type DERIVE'
+       echo 'dirty.min 0'
+       echo 'dirty.draw STACK'
+       echo 'dirty.info Throughput of dirty Metatiles submitted for re-render'
+       echo 'reqBulk.label Bulk request Queue'
+       echo 'reqBulk.type DERIVE'
+       echo 'reqBulk.min 0'
+       echo 'reqBulk.draw STACK'
+       echo 'reqBulk.info Throughput of Metatiles submitted with background priority'
+       echo 'dropped.label Dropped (x20)'
+       echo 'dropped.type DERIVE'
+       echo 'dropped.min 0'
+       echo 'dropped.draw LINE2'
+       echo 'dropped.info Number of Tiles dropped due to queue overload (x20)'
+       echo 'dropped.cdef dropped,20,/'
+       exit 0
+fi
+
+reqprocessed=`sed -e '/^ReqRendered/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+reqprioprocessed=`sed -e '/^ReqPrioRendered/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+dirtprocessed=`sed -e '/^DirtyRendered/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+reqbulkprocessed=`sed -e '/^ReqBulkRendered/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+dropped=`sed -e '/^DropedRequest/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+
+echo "req.value " $reqprocessed
+echo "reqPrio.value " $reqprioprocessed
+echo "dirty.value " $dirtprocessed
+echo "reqBulk.value " $reqbulkprocessed
+echo "dropped.value " $dropped
+
+#  LocalWords:  reqprocessed ReqRendered dirtprocessed DirtyRendered req
+#  LocalWords:  DropedRequest
diff --git a/cookbooks/munin/files/default/plugins/renderd_queue b/cookbooks/munin/files/default/plugins/renderd_queue
new file mode 100755 (executable)
index 0000000..1bd79d1
--- /dev/null
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# Plugin to monitor queue length of tiles submited for rendering in renderd
+#
+# Parameters: 
+#
+#      config   (required)
+#      autoconf (optional - used by munin-config)
+#
+
+if [ "$1" = "config" ]; then
+
+       echo 'graph_title Renderd queue length'
+       echo 'graph_args --base 1000 -l 0'
+       echo 'graph_vlabel metatiles'
+       echo 'graph_category renderd'
+       echo 'req.label Request Queue'
+       echo 'req.type GAUGE'
+       echo 'req.max 100'
+       echo 'reqPrio.label Priority request Queue'
+       echo 'reqPrio.type GAUGE'
+       echo 'reqPrio.max 100'
+       echo 'dirty.label Dirty Queue'
+       echo 'dirty.type GAUGE'
+       echo 'dirty.max 1000'
+       echo 'reqBulk.label Bulk request Queue'
+       echo 'reqBulk.type GAUGE'
+       echo 'reqBulk.max 100'
+       exit 0
+fi
+
+reqlength=`sed -e '/^ReqQueueLength/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+reqpriolength=`sed -e '/^ReqPrioQueueLength/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+reqbulklength=`sed -e '/^ReqBulkQueueLength/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+dirtlength=`sed -e '/^DirtQueueLength/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+
+echo "req.value " $reqlength
+echo "reqPrio.value " $reqpriolength
+echo "dirty.value " $dirtlength
+echo "reqBulk.value " $reqbulklength
diff --git a/cookbooks/munin/files/default/plugins/renderd_zoom b/cookbooks/munin/files/default/plugins/renderd_zoom
new file mode 100755 (executable)
index 0000000..19cdd72
--- /dev/null
@@ -0,0 +1,72 @@
+#!/bin/sh
+#
+# Plugin to monitor the rendering throughput of Renderd
+#
+# Parameters: 
+#
+#      config   (required)
+#      autoconf (optional - used by munin-config)
+#
+
+if [ "$1" = "config" ]; then
+
+       echo 'graph_title Renderd throughput by zoom'
+       echo 'graph_args --base 1000 -l 0'
+       echo 'graph_vlabel Metatiles per ${graph_period}'
+       echo 'graph_category renderd'
+       echo 'graph_info Displays the number of metatiles being rendered by renderd per ${graph_period}'
+       echo 'lowest.label zoom z0 - z8'
+       echo 'lowest.type DERIVE'
+       echo 'lowest.min 0'
+       echo 'lowest.draw AREA'
+       echo 'lowest.info Throughput of Metatiles for z0 - z8'
+       echo 'low.label zoom z9 - z12'
+       echo 'low.type DERIVE'
+       echo 'low.min 0'
+       echo 'low.draw STACK'
+       echo 'low.info Throughput of Metatiles for z9 - z12'
+       echo 'medium.label zoom z13 - z14'
+       echo 'medium.type DERIVE'
+       echo 'medium.min 0'
+       echo 'medium.draw STACK'
+       echo 'medium.info Throughput of Metatiles for z13 - z14'
+       echo 'high.label zoom z15 - z16'
+       echo 'high.type DERIVE'
+       echo 'high.min 0'
+       echo 'high.draw STACK'
+       echo 'high.info Throughput of Metatiles for z15 - z16'
+       echo 'highest.label zoom z17 - z18'
+       echo 'highest.type DERIVE'
+       echo 'highest.min 0'
+       echo 'highest.draw STACK'
+       echo 'highest.info Throughput of Metatiles for z17 - z18'
+
+       exit 0
+fi
+
+req0=`sed -e '/^ZoomRendered00/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req1=`sed -e '/^ZoomRendered01/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req2=`sed -e '/^ZoomRendered02/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req3=`sed -e '/^ZoomRendered03/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req4=`sed -e '/^ZoomRendered04/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req5=`sed -e '/^ZoomRendered05/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req6=`sed -e '/^ZoomRendered06/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req7=`sed -e '/^ZoomRendered07/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req8=`sed -e '/^ZoomRendered08/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req9=`sed -e '/^ZoomRendered09/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req10=`sed -e '/^ZoomRendered10/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req11=`sed -e '/^ZoomRendered11/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req12=`sed -e '/^ZoomRendered12/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req13=`sed -e '/^ZoomRendered13/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req14=`sed -e '/^ZoomRendered14/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req15=`sed -e '/^ZoomRendered15/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req16=`sed -e '/^ZoomRendered16/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req17=`sed -e '/^ZoomRendered17/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req18=`sed -e '/^ZoomRendered18/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+
+
+echo "lowest.value " `expr $req0 + $req1 + + $req2 + $req3 + $req4 + $req5 + $req6 + $req7 + $req8`
+echo "low.value " `expr $req9 + $req10 + + $req11 + $req12`
+echo "medium.value " `expr $req13 + $req14`
+echo "high.value " `expr $req15 + $req16`
+echo "highest.value " `expr $req17 + $req18`
\ No newline at end of file
diff --git a/cookbooks/munin/files/default/plugins/renderd_zoom_time b/cookbooks/munin/files/default/plugins/renderd_zoom_time
new file mode 100755 (executable)
index 0000000..b2163e2
--- /dev/null
@@ -0,0 +1,76 @@
+#!/bin/sh
+#
+# Plugin to monitor the rendering throughput of Renderd
+#
+# Parameters: 
+#
+#      config   (required)
+#      autoconf (optional - used by munin-config)
+#
+
+if [ "$1" = "config" ]; then
+
+       echo 'graph_title Renderd time spent by zoom'
+       echo 'graph_args --base 1000 -l 0'
+       echo 'graph_vlabel time spent per ${graph_period}'
+       echo 'graph_category renderd'
+       echo 'graph_info Displays the amount of time renderd has spent rendering tiles of a given zoom per ${graph_period}'
+       echo 'zoomtime1.label zoom z0 - z8'
+       echo 'zoomtime1.type DERIVE'
+       echo 'zoomtime1.min 0'
+       echo 'zoomtime1.cdef zoomtime1,1000,/'
+       echo 'zoomtime1.draw AREA'
+       echo 'zoomtime1.info Time for Metatiles z0 - z8'
+       echo 'zoomtime2.label zoom z9 - z12'
+       echo 'zoomtime2.type DERIVE'
+       echo 'zoomtime2.min 0'
+       echo 'zoomtime2.cdef zoomtime2,1000,/'
+       echo 'zoomtime2.draw STACK'
+       echo 'zoomtime2.info Time for Metatiles for z9 - z12'
+       echo 'zoomtime3.label zoom z13 - z14'
+       echo 'zoomtime3.type DERIVE'
+       echo 'zoomtime3.min 0'
+       echo 'zoomtime3.cdef zoomtime3,1000,/'
+       echo 'zoomtime3.draw STACK'
+       echo 'zoomtime3.info Time for Metatiles for z13 - z14'
+       echo 'zoomtime4.label zoom z15 - z16'
+       echo 'zoomtime4.type DERIVE'
+       echo 'zoomtime4.min 0'
+       echo 'zoomtime4.cdef zoomtime4,1000,/'
+       echo 'zoomtime4.draw STACK'
+       echo 'zoomtime4.info Time for Metatiles for z15 - z16'
+       echo 'zoomtime5.label zoom z17 - z18'
+       echo 'zoomtime5.type DERIVE'
+       echo 'zoomtime5.min 0'
+       echo 'zoomtime5.cdef zoomtime5,1000,/'
+       echo 'zoomtime5.draw STACK'
+       echo 'zoomtime5.info Time for Metatiles for z17 - z18'
+
+       exit 0
+fi
+
+req0=`sed -e '/^TimeRenderedZoom00/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req1=`sed -e '/^TimeRenderedZoom01/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req2=`sed -e '/^TimeRenderedZoom02/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req3=`sed -e '/^TimeRenderedZoom03/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req4=`sed -e '/^TimeRenderedZoom04/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req5=`sed -e '/^TimeRenderedZoom05/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req6=`sed -e '/^TimeRenderedZoom06/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req7=`sed -e '/^TimeRenderedZoom07/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req8=`sed -e '/^TimeRenderedZoom08/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req9=`sed -e '/^TimeRenderedZoom09/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req10=`sed -e '/^TimeRenderedZoom10/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req11=`sed -e '/^TimeRenderedZoom11/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req12=`sed -e '/^TimeRenderedZoom12/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req13=`sed -e '/^TimeRenderedZoom13/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req14=`sed -e '/^TimeRenderedZoom14/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req15=`sed -e '/^TimeRenderedZoom15/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req16=`sed -e '/^TimeRenderedZoom16/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req17=`sed -e '/^TimeRenderedZoom17/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+req18=`sed -e '/^TimeRenderedZoom18/!d' -e 's/.*: //' -e q /var/run/renderd/renderd.stats`
+
+echo "zoomtime1.value " `expr $req0 + $req1 + + $req2 + $req3 + $req4 + $req5 + $req6 + $req7 + $req8`
+echo "zoomtime2.value " `expr $req9 + $req10 + + $req11 + $req12`
+echo "zoomtime3.value " `expr $req13 + $req14`
+echo "zoomtime4.value " `expr $req15 + $req16`
+echo "zoomtime5.value " `expr $req17 + $req18`
\ No newline at end of file
diff --git a/cookbooks/munin/files/default/plugins/replication_delay b/cookbooks/munin/files/default/plugins/replication_delay
new file mode 100755 (executable)
index 0000000..e88ae97
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/sh 
+# 
+# Plugin to monitor the age of the imported data in the rendering db 
+# 
+# Parameters:  
+# 
+#       config   (required) 
+#       autoconf (optional - used by munin-config) 
+# 
+if [ "$1" = "config" ]; then 
+        echo 'graph_title Data import lag' 
+        echo 'graph_args --base 1000 -l 0' 
+        echo 'graph_vlabel minutes' 
+        echo 'graph_category renderd' 
+        echo 'age.label DB import age' 
+        echo 'age.type GAUGE' 
+       echo 'age.cdef age,60,/'
+        exit 0 
+fi 
+tstamp=`sed -e '/^timestamp=/!d' -e 's/.*=//' -e 's/Z//' -e 's/T/Z/' -e 's/\\\\//' -e 's/\\\\//' -e q /home/jburgess/replicate/state.txt` 
+tstampsec=`date --date=$tstamp +%s` 
+nowsec=`date +%s` 
+echo "age.value " `expr $nowsec - $tstampsec`
\ No newline at end of file
diff --git a/cookbooks/munin/files/default/plugins/squid_delay_pools b/cookbooks/munin/files/default/plugins/squid_delay_pools
new file mode 100755 (executable)
index 0000000..35e5895
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/sh
+#
+# Plugin to monitor the number of IPs being slowed down by Squid delay pools
+#
+# Parameters: 
+#
+#      config   (required)
+#      autoconf (optional - used by munin-config)
+#
+
+if [ "$1" = "config" ]; then
+
+       echo 'graph_title IPs being delayed'
+       echo 'graph_args --base 1000 -l 0'
+       echo 'graph_vlabel IPs'
+       echo 'graph_category squid'
+       echo 'squid_delay1.label IPs'
+       echo 'squid_delay1.min 0'
+       echo 'squid_delay1.draw AREA'
+
+       exit 0
+fi
+
+req0=`squidclient -h 127.0.0.1 mgr:delay|fgrep Current|egrep --count '[0-9]{1,3}:-?[0-9]{1,3} '`
+
+echo "squid_delay1.value " `expr 0 + $req0`
+
diff --git a/cookbooks/munin/files/default/plugins/squid_times b/cookbooks/munin/files/default/plugins/squid_times
new file mode 100755 (executable)
index 0000000..c16612e
--- /dev/null
@@ -0,0 +1,61 @@
+#!/bin/sh
+#
+# Copyright (C) 2008 Olivier DELHOMME. All rights reserved.
+# License GPL V2 or higher
+#
+# Abstract
+# munin plugin that logs the cache mean services times 
+#
+# Authors
+#  . Olivier Delhomme <olivierdelhomme at gmail dot com>
+#  . Grant Slater
+#
+#%# family=auto
+#%# capabilities=autoconf
+
+if [ "$1" = "autoconf" ]; then
+       SQUID_STATS=$(squidclient -h 127.0.0.1 cache_object://localhost/info)
+       if [ -n "${SQUID_STATS}" ]; then
+               echo yes 
+               exit 0
+       else
+               echo "no (HTTP GET failed)"
+               exit 1
+       fi
+fi
+
+if [ "$1" = "config" ]; then
+       echo 'graph_title Squid Median Services Times'
+       echo 'graph_info This graph shows the proxy median services response times.'
+       echo 'graph_category squid'
+       echo 'graph_args --lower-limit 0'
+       echo 'graph_vlabel median reponse times (s)'
+
+       echo 'mean_http.label Http'
+       echo 'mean_cmis.label Cache misses'     
+       echo 'mean_chits.label Cache hits'
+       echo 'mean_nhits.label Near hits'
+       echo 'mean_nmr.label Not-modified replies'
+       echo 'mean_dnsl.label Dns lookups'
+       echo 'mean_icpq.label Icp queries'
+
+       exit 0
+fi 
+
+SQUID_TIME=$(squidclient -h 127.0.0.1 cache_object://localhost/info)
+
+SQUID_TIME_HTTP=$(echo "$SQUID_TIME" | grep "HTTP Requests (All)" | cut -d':' -f2 | sed -e "s/^\ *//" | cut -d' ' -f1)
+SQUID_TIME_CACHE_MISSES=$(echo "$SQUID_TIME" | grep "Cache Misses" | cut -d':' -f2 | sed -e "s/^\ *//" | cut -d' ' -f1)
+SQUID_TIME_CACHE_HITS=$(echo "$SQUID_TIME" | grep "Cache Hits" | cut -d':' -f2 | sed -e "s/^\ *//" | cut -d' ' -f1)
+SQUID_TIME_NEAR_HITS=$(echo "$SQUID_TIME" | grep "Near Hits" | cut -d':' -f2 | sed -e "s/^\ *//" | cut -d' ' -f1)
+SQUID_TIME_NM_REPLIES=$(echo "$SQUID_TIME" | grep "Not-Modified Replies" | cut -d':' -f2 | sed -e "s/^\ *//" | cut -d' ' -f1)
+SQUID_TIME_DNS_LOOKUPS=$(echo "$SQUID_TIME" | grep "DNS Lookups" | cut -d':' -f2 | sed -e "s/^\ *//" | cut -d' ' -f1)
+SQUID_TIME_ICP_QUERIES=$(echo "$SQUID_TIME" | grep "ICP Queries" | cut -d':' -f2 | sed -e "s/^\ *//" | cut -d' ' -f1)
+
+echo "mean_http.value $SQUID_TIME_HTTP"
+echo "mean_cmis.value $SQUID_TIME_CACHE_MISSES"
+echo "mean_chits.value $SQUID_TIME_CACHE_HITS" 
+echo "mean_nhits.value $SQUID_TIME_NEAR_HITS"
+echo "mean_nmr.value $SQUID_TIME_NM_REPLIES"
+echo "mean_dnsl.value $SQUID_TIME_DNS_LOOKUPS"
+echo "mean_icpq.value $SQUID_TIME_ICP_QUERIES"
diff --git a/cookbooks/munin/libraries/expand.rb b/cookbooks/munin/libraries/expand.rb
new file mode 100644 (file)
index 0000000..9269761
--- /dev/null
@@ -0,0 +1,13 @@
+class Chef
+  class Munin
+    def self.expand(template, nodes)
+      nodes.map do |node| 
+        if node.kind_of?(Hash)
+          template.gsub(/%%([^%]+)%%/) { node[$1.to_sym] }
+        else
+          template.gsub("%%", node)
+        end
+      end.join(" ")
+    end
+  end 
+end
diff --git a/cookbooks/munin/metadata.rb b/cookbooks/munin/metadata.rb
new file mode 100644 (file)
index 0000000..d132b5b
--- /dev/null
@@ -0,0 +1,7 @@
+maintainer        "OpenStreetMap Administrators"
+maintainer_email  "admins@openstreetmap.org"
+license           "Apache 2.0"
+description       "Installs and configures munin"
+long_description  IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
+version           "1.0.0"
+depends           "networking"
diff --git a/cookbooks/munin/recipes/default.rb b/cookbooks/munin/recipes/default.rb
new file mode 100644 (file)
index 0000000..775acc0
--- /dev/null
@@ -0,0 +1,241 @@
+#
+# Cookbook Name:: munin
+# Recipe:: default
+#
+# Copyright 2010, OpenStreetMap Foundation
+#
+# 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.
+#
+
+include_recipe "networking"
+
+package "munin-node"
+
+service "munin-node" do
+  action [ :enable, :start ]
+  supports :status => true, :restart => true, :reload => true
+end
+
+servers = search(:node, "recipes:munin\\:\\:server")
+
+servers.each do |server|
+  server.interfaces(:role => :external) do |interface|
+    if interface[:zone]
+      firewall_rule "accept-munin-#{server}" do
+        action :accept
+        family interface[:family]
+        source "#{interface[:zone]}:#{interface[:address]}"
+        dest "fw"
+        proto "tcp:syn"
+        dest_ports "munin"
+        source_ports "1024:"
+      end
+    end
+  end
+end
+
+template "/etc/munin/munin-node.conf" do
+  source "munin-node.conf.erb"
+  owner "root"
+  group "root"
+  mode 0644
+  variables :servers => servers
+  notifies :restart, resources(:service => "munin-node")
+end
+
+remote_directory "/usr/local/share/munin/plugins" do
+  source "plugins"
+  owner "root"
+  group "root"
+  mode 0755
+  files_owner "root"
+  files_group "root"
+  files_mode 0755
+  purge true
+end
+
+remote_directory "/etc/munin/plugin-conf.d" do
+  source "plugin-conf.d"
+  owner "root"
+  group "munin"
+  mode 0750
+  files_owner "root"
+  files_group "root"
+  files_mode 0644
+  purge false
+  notifies :restart, resources(:service => "munin-node")
+end
+
+if Dir.glob("/proc/acpi/thermal_zone/*/temperature").empty?
+  munin_plugin "acpi" do
+    action :delete
+  end
+else
+  munin_plugin "acpi"
+end
+
+# apcpdu_
+# api_
+munin_plugin "cpu"
+
+if File.exists?("/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state")
+  munin_plugin "cpuspeed"
+else
+  munin_plugin "cpuspeed" do
+    action :delete
+  end
+end
+
+munin_plugin "df"
+munin_plugin "df_inode"
+munin_plugin "diskstats"
+munin_plugin "entropy"
+munin_plugin "forks"
+
+if File.exists?("/proc/net/ip_conntrack") or File.exists?("/proc/net/nf_conntrack")
+  munin_plugin "fw_conntrack"
+  munin_plugin "fw_forwarded_local"
+else
+  munin_plugin "fw_conntrack" do
+    action :delete
+  end
+
+  munin_plugin "fw_forwarded_local" do
+    action :delete
+  end
+end
+
+if %x{sysctl -n net.ipv4.ip_forward}.chomp == "1"
+  munin_plugin "fw_packets"
+else
+  munin_plugin "fw_packets" do
+    action :delete
+  end
+end
+
+# hddtemp_smartctl
+
+if File.exists?("/sbin/hpasmcli")
+  munin_plugin "hpasmcli_temp"
+  munin_plugin "hpasmcli_fans"
+else
+  munin_plugin "hpasmcli_temp" do
+    action :delete
+  end
+
+  munin_plugin "hpasmcli_fans" do
+    action :delete
+  end
+end
+
+munin_plugin "http_loadtime" do
+  action :delete
+end
+
+node[:network][:interfaces].each do |ifname,ifattr|
+  if ifname =~ /^eth\d+$/
+    if ifattr[:flags] and ifattr[:flags].include?("UP")
+      munin_plugin "if_err_#{ifname}" do
+        target "if_err_"
+      end
+
+      munin_plugin "if_#{ifname}" do
+        target "if_"
+      end
+    else
+      munin_plugin "if_err_#{ifname}" do
+        action :delete
+      end
+
+      munin_plugin "if_#{ifname}" do
+        action :delete
+      end
+    end
+  end
+end
+
+munin_plugin "interrupts"
+munin_plugin "iostat"
+munin_plugin "iostat_ios"
+# ipmi_
+munin_plugin "irqstats"
+
+Dir.new("/sys/block").each do |device|
+  if device.match(/^sd/)
+    munin_plugin "linux_diskstat_iops_#{device}" do
+      target "linux_diskstat_"
+    end
+
+    munin_plugin "linux_diskstat_latency_#{device}" do
+      target "linux_diskstat_"
+    end
+
+    munin_plugin "linux_diskstat_throughput_#{device}" do
+      target "linux_diskstat_"
+    end
+  end
+end
+
+munin_plugin "load"
+munin_plugin "memory"
+# mod_tile_
+# mysql_
+munin_plugin "netstat"
+
+if File.exists?("/proc/net/rpc/nfs")
+  munin_plugin "nfs4_client"
+else
+  munin_plugin "nfs4_client" do
+    action :delete
+  end
+end
+
+if File.exists?("/proc/net/rpc/nfsd")
+  munin_plugin "nfsd"
+  munin_plugin "nfsd4"
+else
+  munin_plugin "nfsd" do
+    action :delete
+  end
+
+  munin_plugin "nfsd4" do
+    action :delete
+  end
+end
+
+# nominatim_
+munin_plugin "open_files"
+munin_plugin "open_inodes"
+# passenger_
+
+munin_plugin "postfix_mailqueue" do
+  action :delete
+end
+
+munin_plugin "postfix_mailvolume" do
+  action :delete
+end
+
+# postgres_
+munin_plugin "processes"
+munin_plugin "proc_pri"
+# renderd_
+# replication_delay
+# sensors_
+# smart_
+# squid_
+munin_plugin "swap"
+munin_plugin "threads"
+munin_plugin "uptime"
+munin_plugin "users"
+munin_plugin "vmstat"
diff --git a/cookbooks/munin/recipes/server.rb b/cookbooks/munin/recipes/server.rb
new file mode 100644 (file)
index 0000000..1e51b4c
--- /dev/null
@@ -0,0 +1,46 @@
+#
+# Cookbook Name:: munin
+# Recipe:: server
+#
+# Copyright 2010, OpenStreetMap Foundation
+#
+# 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.
+#
+
+include_recipe "apache"
+
+package "munin"
+
+expiry_time = 14 * 86400
+
+clients = search(:node, "recipes:munin").select { |n| n[:munin] }.sort_by { |n| n[:hostname] }
+frontends = search(:node, "recipes:web\\:\\:frontend").reject { |n| Time.now - Time.at(n[:ohai_time]) > expiry_time }.map { |n| n[:hostname] }.sort
+backends = search(:node, "recipes:web\\:\\:backend").reject { |n| Time.now - Time.at(n[:ohai_time]) > expiry_time }.map { |n| n[:hostname] }.sort
+tilecaches = search(:node, "roles:tilecache").reject { |n| Time.now - Time.at(n[:ohai_time]) > expiry_time }.sort_by { |n| n[:hostname] }.map do |n|
+  { :name => n[:hostname], :interface => n.interfaces(:role => :external).first[:interface] }
+end
+
+template "/etc/munin/munin.conf" do
+  source "munin.conf.erb"
+  owner "root"
+  group "root"
+  mode 0644
+  variables :expiry_time => expiry_time, :clients => clients, :frontends => frontends, :backends => backends, :tilecaches => tilecaches
+end
+
+apache_site "munin.openstreetmap.org" do
+  template "apache.erb"
+end
+
+munin_plugin "munin_stats"
+munin_plugin "munin_update"
diff --git a/cookbooks/munin/templates/default/apache.erb b/cookbooks/munin/templates/default/apache.erb
new file mode 100644 (file)
index 0000000..f3ce4e2
--- /dev/null
@@ -0,0 +1,16 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+<VirtualHost *:80>
+       ServerName munin.openstreetmap.org
+       ServerAlias munin.osm.org
+       ServerAdmin webmaster@openstreetmap.org
+
+       CustomLog /var/log/apache2/munin.openstreetmap.org-access.log combined
+       ErrorLog /var/log/apache2/munin.openstreetmap.org-error.log
+
+       DocumentRoot /var/cache/munin/www
+</VirtualHost>
+
+<Directory /var/cache/munin/www>
+       Allow from all
+</Directory>
diff --git a/cookbooks/munin/templates/default/munin-node.conf.erb b/cookbooks/munin/templates/default/munin-node.conf.erb
new file mode 100644 (file)
index 0000000..0ff07cb
--- /dev/null
@@ -0,0 +1,44 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+# Configure logging
+log_level 4
+log_file /var/log/munin/munin-node.log
+pid_file /var/run/munin/munin-node.pid
+
+# Run in the background
+background 1
+setsid 1
+
+# Run as root
+user root
+group root
+
+# Regexps for files to ignore
+ignore_file ~$
+ignore_file DEADJOE$ 
+ignore_file \.bak$
+ignore_file %$
+ignore_file \.dpkg-(tmp|new|old|dist)$
+ignore_file \.rpm(save|new)$
+ignore_file \.pod$
+
+# Set the hostname
+host_name <%= node[:hostname] -%>.openstreetmap.org
+
+# List on port 4949 on all interfaces
+host *
+port 4949
+
+# List the addresses that are allowed to connect
+allow ^127\.0\.0\.1$
+<% @servers.each do |server| -%>
+<% server.interfaces do |interface| -%>
+allow ^<%= Regexp.quote(interface[:address]) %>$
+<% end -%>
+<% if server[:openvpn] -%>
+allow ^<%= Regexp.quote(server[:openvpn][:address]) %>$
+<% end -%>
+<% end -%>
+<% node[:munin][:allow].each do |address| -%>
+allow ^<%= Regexp.quote(address) %>$
+<% end -%>
diff --git a/cookbooks/munin/templates/default/munin.conf.erb b/cookbooks/munin/templates/default/munin.conf.erb
new file mode 100644 (file)
index 0000000..16205df
--- /dev/null
@@ -0,0 +1,338 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+# Configure alert targets
+contact.admins.command mail -s "Munin Notification" admins@openstreetmap.org
+contact.null.command cat > /dev/null
+
+# Send alerts to the admins by default
+contacts admins
+
+# Ignore uncontactable hosts for twelve hours
+unknown_limit 144
+<% @clients.sort { |a,b| a[:hostname] <=> b[:hostname] }.each do |client| -%>
+
+# Configure monitoring for <%= client[:fqdn] %>
+[<%= client[:hostname] %>.openstreetmap]
+<% if Time.now - Time.at(client[:ohai_time]) > @expiry_time -%>
+    update no
+<% end -%>
+<% if client[:networking][:roles][:external][:zone] == "ucl" -%>
+    address <%= client.internal_ipaddress %>
+<% elsif client[:networking][:roles][:external][:zone] == "ic" -%>
+    address <%= client.internal_ipaddress || client.external_ipaddress %>
+<% else -%>
+    address <%= client.external_ipaddress %>
+<% end -%>
+    use_node_name yes
+<% if client[:munin][:plugins] -%>
+<% client[:munin][:plugins].keys.sort.each do |plugin| -%>
+<% client[:munin][:plugins][plugin].keys.sort.each do |value| -%>
+<% if client[:munin][:plugins][plugin][value].kind_of?(Hash) -%>
+<% if client[:munin][:plugins][plugin][value][:graph] -%>
+    <%= plugin %>.<%= value %>.graph <%= client[:munin][:plugins][plugin][value][:graph] %>
+<% end -%>
+<% if client[:munin][:plugins][plugin][value][:warning] -%>
+    <%= plugin %>.<%= value %>.warning <%= client[:munin][:plugins][plugin][value][:warning] %>
+<% end -%>
+<% if client[:munin][:plugins][plugin][value][:critical] -%>
+    <%= plugin %>.<%= value %>.critical <%= client[:munin][:plugins][plugin][value][:critical] %>
+<% end -%>
+<% else -%>
+    <%= plugin %>.<%= value %> <%= client[:munin][:plugins][plugin][value] %>
+<% end -%>
+<% end -%>
+<% end -%>
+<% end -%>
+<% if client[:munin][:graphs] -%>
+<% client[:munin][:graphs].keys.sort.each do |graph| -%>
+<% if client[:munin][:graphs][graph][:title] -%>
+    <%= graph %>.graph_title <%= client[:munin][:graphs][graph][:title] %>
+<% end -%>
+<% if client[:munin][:graphs][graph][:vlabel] -%>
+    <%= graph %>.graph_vlabel <%= client[:munin][:graphs][graph][:vlabel] %>
+<% end -%>
+<% if client[:munin][:graphs][graph][:category] -%>
+    <%= graph %>.graph_category <%= client[:munin][:graphs][graph][:category] %>
+<% end -%>
+<% client[:munin][:graphs][graph][:values].keys.sort.each do |value| -%>
+<% if client[:munin][:graphs][graph][:values][value][:sum] -%>
+    <%= graph %>.<%= value %>.sum <%= client[:munin][:graphs][graph][:values][value][:sum].join(" ") %>
+<% end -%>
+<% if client[:munin][:graphs][graph][:values][value][:label] -%>
+    <%= graph %>.<%= value %>.label <%= client[:munin][:graphs][graph][:values][value][:label] %>
+<% end -%>
+<% end -%>
+<% end -%>
+<% end -%>
+<% end -%>
+
+# Configure compound graphs for www.openstreetmap.org
+[www.openstreetmap]
+    update no
+    apache_accesses.graph_title Apache accesses
+    apache_accesses.graph_vlabel accesses / ${graph_period}
+    apache_accesses.graph_category apache
+    apache_accesses.accesses80.sum <%= Chef::Munin.expand "%%.openstreetmap:apache_accesses.accesses80", @frontends %>
+    apache_accesses.accesses80.label port 80
+    apache_volume.graph_title Apache volume
+    apache_volume.graph_vlabel bytes per ${graph_period}
+    apache_volume.graph_category apache
+    apache_volume.volume80.sum <%= Chef::Munin.expand "%%.openstreetmap:apache_volume.volume80", @frontends %>
+    apache_volume.volume80.label port 80
+    if_eth0.graph_title eth0 traffic
+    if_eth0.graph_vlabel bits in (-) / out (+) per ${graph_period}
+    if_eth0.graph_category network
+    if_eth0.down.sum <%= Chef::Munin.expand "%%.openstreetmap:if_eth0.down", @frontends %>
+    if_eth0.down.label received
+    if_eth0.down.cdef down,8,*
+    if_eth0.up.sum <%= Chef::Munin.expand "%%.openstreetmap:if_eth0.up", @frontends %>
+    if_eth0.up.label sent
+    if_eth0.up.cdef up,8,*
+    if_eth1.graph_title eth1 traffic
+    if_eth1.graph_vlabel bits in (-) / out (+) per ${graph_period}
+    if_eth1.graph_category network
+    if_eth1.down.sum <%= Chef::Munin.expand "%%.openstreetmap:if_eth1.down", @frontends %>
+    if_eth1.down.label received
+    if_eth1.down.cdef down,8,*
+    if_eth1.up.sum <%= Chef::Munin.expand "%%.openstreetmap:if_eth1.up", @frontends %>
+    if_eth1.up.label sent
+    if_eth1.up.cdef up,8,*
+    api_calls_www.graph_title Active requests
+    api_calls_www.graph_vlabel Number of requests
+    api_calls_www.graph_category api
+    api_calls_www.web.sum <%= Chef::Munin.expand "%%.openstreetmap:api_calls_%%.web", @frontends %>
+    api_calls_www.web.label Web site traffic
+    api_calls_www.upload.sum <%= Chef::Munin.expand "%%.openstreetmap:api_calls_%%.upload", @frontends %>
+    api_calls_www.upload.label Changeset diff uploads
+    api_calls_www.other.sum <%= Chef::Munin.expand "%%.openstreetmap:api_calls_%%.other", @frontends %>
+    api_calls_www.other.label Other API calls
+    api_calls_www.amf.sum <%= Chef::Munin.expand "%%.openstreetmap:api_calls_%%.amf", @frontends %>
+    api_calls_www.amf.label AMF API calls
+    api_calls_www.history.sum <%= Chef::Munin.expand "%%.openstreetmap:api_calls_%%.history", @frontends %>
+    api_calls_www.history.label Element history fetches
+    api_calls_www.full.sum <%= Chef::Munin.expand "%%.openstreetmap:api_calls_%%.full", @frontends %>
+    api_calls_www.full.label Full element fetches
+    api_calls_www.map.sum <%= Chef::Munin.expand "%%.openstreetmap:api_calls_%%.map", @frontends %>
+    api_calls_www.map.label Map API calls
+    api_calls_www.trkpts.sum <%= Chef::Munin.expand "%%.openstreetmap:api_calls_%%.trkpts", @frontends %>
+    api_calls_www.trkpts.label GPX trackpoints calls
+    api_calls_num.graph_title Requests processed
+    api_calls_num.graph_vlabel Number of requests per minute
+    api_calls_num.graph_category api
+    api_calls_num.web.sum <%= Chef::Munin.expand "%%.openstreetmap:api_calls_num.web", @frontends %>
+    api_calls_num.web.label Web site traffic
+    api_calls_num.upload.sum <%= Chef::Munin.expand "%%.openstreetmap:api_calls_num.upload", @frontends %>
+    api_calls_num.upload.label Changeset diff uploads
+    api_calls_num.other.sum <%= Chef::Munin.expand "%%.openstreetmap:api_calls_num.other", @frontends %>
+    api_calls_num.other.label Other API calls
+    api_calls_num.amf.sum <%= Chef::Munin.expand "%%.openstreetmap:api_calls_num.amf", @frontends %>
+    api_calls_num.amf.label AMF API calls
+    api_calls_num.history.sum <%= Chef::Munin.expand "%%.openstreetmap:api_calls_num.history", @frontends %>
+    api_calls_num.history.label Element history fetches
+    api_calls_num.full.sum <%= Chef::Munin.expand "%%.openstreetmap:api_calls_num.full", @frontends %>
+    api_calls_num.full.label Full element fetches
+    api_calls_num.map.sum <%= Chef::Munin.expand "%%.openstreetmap:api_calls_num.map", @frontends %>
+    api_calls_num.map.label Map API calls
+    api_calls_num.trkpts.sum <%= Chef::Munin.expand "%%.openstreetmap:api_calls_num.trkpts", @frontends %>
+    api_calls_num.trkpts.label GPX trackpoints calls
+    api_waits_www.graph_title Wait times for active requests
+    api_waits_www.graph_vlabel Average time of requests
+    api_waits_www.graph_category api
+    api_waits_www.web.sum <%= Chef::Munin.expand "%%.openstreetmap:api_waits_%%.web", @frontends %>
+    api_waits_www.web.label Web site traffic
+    api_waits_www.web.cdef web,2,/
+    api_waits_www.upload.sum <%= Chef::Munin.expand "%%.openstreetmap:api_waits_%%.upload", @frontends %>
+    api_waits_www.upload.label Changeset diff uploads
+    api_waits_www.upload.cdef upload,2,/
+    api_waits_www.other.sum <%= Chef::Munin.expand "%%.openstreetmap:api_waits_%%.other", @frontends %>
+    api_waits_www.other.label Other API calls
+    api_waits_www.other.cdef other,2,/
+    api_waits_www.amf.sum <%= Chef::Munin.expand "%%.openstreetmap:api_waits_%%.amf", @frontends %>
+    api_waits_www.amf.label AMF API calls
+    api_waits_www.amf.cdef amf,2,/
+    api_waits_www.history.sum <%= Chef::Munin.expand "%%.openstreetmap:api_waits_%%.history", @frontends %>
+    api_waits_www.history.label Element history fetches
+    api_waits_www.history.cdef history,2,/
+    api_waits_www.full.sum <%= Chef::Munin.expand "%%.openstreetmap:api_waits_%%.full", @frontends %>
+    api_waits_www.full.label Full element fetches
+    api_waits_www.full.cdef full,2,/
+    api_waits_www.map.sum <%= Chef::Munin.expand "%%.openstreetmap:api_waits_%%.map", @frontends %>
+    api_waits_www.map.label Map API calls
+    api_waits_www.map.cdef map,2,/
+    api_waits_www.trkpts.sum <%= Chef::Munin.expand "%%.openstreetmap:api_waits_%%.trkpts", @frontends %>
+    api_waits_www.trkpts.label GPX trackpoints calls
+    api_waits_www.trkpts.cdef trkpts,2,/
+    memcached_multi_bytes.graph_title Network Traffic
+    memcached_multi_bytes.graph_vlabel bits in (-) / out (+)
+    memcached_multi_bytes.graph_category memcached
+    memcached_multi_bytes.bytes_read.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_multi_bytes.bytes_read", @backends %>
+    memcached_multi_bytes.bytes_read.label Network Traffic coming in (-)
+    memcached_multi_bytes.bytes_read.cdef bytes_read,8,*
+    memcached_multi_bytes.bytes_written.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_multi_bytes.bytes_written", @backends %>
+    memcached_multi_bytes.bytes_written.label Traffic in (-) / out (+)
+    memcached_multi_bytes.bytes_written.cdef bytes_written,8,*
+    memcached_commands.graph_title Commands
+    memcached_commands.graph_vlabel Commands per ${graph_period}
+    memcached_commands.graph_category memcached
+    memcached_commands.cmd_get.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_commands.cmd_get", @backends %>
+    memcached_commands.cmd_get.label Gets
+    memcached_commands.cmd_set.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_commands.cmd_set", @backends %>
+    memcached_commands.cmd_set.label Sets
+    memcached_commands.get_hits.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_commands.get_hits", @backends %>
+    memcached_commands.get_hits.label Get Hits
+    memcached_commands.get_misses.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_commands.get_misses", @backends %>
+    memcached_commands.get_misses.label Get Misses
+    memcached_commands.delete_hits.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_commands.delete_hits", @backends %>
+    memcached_commands.delete_hits.label Delete Hits
+    memcached_commands.delete_misses.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_commands.delete_misses", @backends %>
+    memcached_commands.delete_misses.label Delete Misses
+    memcached_commands.incr_hits.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_commands.incr_hits", @backends %>
+    memcached_commands.incr_hits.label Increment Hits
+    memcached_commands.incr_misses.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_commands.incr_misses", @backends %>
+    memcached_commands.incr_misses.label Increment Misses
+    memcached_commands.decr_hits.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_commands.decr_hits", @backends %>
+    memcached_commands.decr_hits.label Decrement Hits
+    memcached_commands.decr_misses.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_commands.decr_misses", @backends %>
+    memcached_commands.decr_misses.label Decrement Misses
+    memcached_multi_conns.graph_title Connections
+    memcached_multi_conns.graph_vlabel Connections per ${graph_period}
+    memcached_multi_conns.graph_category memcached
+    memcached_multi_conns.curr_conns.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_multi_conns.curr_conns", @backends %>
+    memcached_multi_conns.curr_conns.label Current Connections
+    memcached_multi_conns.max_conns.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_multi_conns.max_conns", @backends %>
+    memcached_multi_conns.max_conns.label Max Connections
+    memcached_multi_conns.avg_conns.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_multi_conns.avg_conns", @backends %>
+    memcached_multi_conns.avg_conns.label Avg Connections
+    memcached_evictions.graph_title Evictions
+    memcached_evictions.graph_vlabel Evictions per ${graph_period}
+    memcached_evictions.graph_category memcached
+    memcached_evictions.evictions.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_evictions.evictions", @backends %>
+    memcached_evictions.evictions.label Evictions
+    memcached_evictions.evicted_nonzero.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_evictions.evicted_nonzero", @backends %>
+    memcached_evictions.evicted_nonzero.label Evictions prior to Expire
+    memcached_evictions.reclaimed.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_evictions.reclaimed", @backends %>
+    memcached_evictions.reclaimed.label Reclaimed Items
+    memcached_items.graph_title Items
+    memcached_items.graph_vlabel Items in Memcached
+    memcached_items.graph_category memcached
+    memcached_items.curr_items.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_items.curr_items", @backends %>
+    memcached_items.curr_items.label Current Items
+    memcached_items.total_items.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_items.total_items", @backends %>
+    memcached_items.total_items.label New Items
+    memcached_memory.graph_title Memory Usage
+    memcached_memory.graph_vlabel Bytes Used
+    memcached_memory.graph_category memcached
+    memcached_memory.limit_maxbytes.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_memory.limit_maxbytes", @backends %>
+    memcached_memory.limit_maxbytes.label Maximum Bytes Allocated
+    memcached_memory.bytes.sum <%= Chef::Munin.expand "%%.openstreetmap:memcached_memory.bytes", @backends %>
+    memcached_memory.bytes.label Current Bytes Used
+
+# Configure compound graphs for tile.openstreetmap.org
+[tile.openstreetmap]
+    update no
+    network_in.graph_title Inbound network traffic
+    network_in.graph_vlabel bits in per ${graph_period}
+    network_in.graph_category network
+    network_in.graph_order <%= Chef::Munin.expand "%%name%%=%%name%%.openstreetmap:if_%%interface%%.down", @tilecaches %>
+    network_in.graph_total total
+<% @tilecaches.each do |tc| -%>
+    network_in.<%= tc[:name] %>.label <%= tc[:name] %>
+    network_in.<%= tc[:name] %>.cdef <%= tc[:name] %>,8,*
+    network_in.<%= tc[:name] %>.draw AREASTACK
+<% end -%>
+    network_out.graph_title Outbound network traffic
+    network_out.graph_vlabel bits out per ${graph_period}
+    network_out.graph_category network
+    network_out.graph_order <%= Chef::Munin.expand "%%name%%=%%name%%.openstreetmap:if_%%interface%%.up", @tilecaches %>
+    network_out.graph_total total
+<% @tilecaches.each do |tc| -%>
+    network_out.<%= tc[:name] %>.label <%= tc[:name] %>
+    network_out.<%= tc[:name] %>.cdef <%= tc[:name] %>,8,*
+    network_out.<%= tc[:name] %>.draw AREASTACK
+<% end -%>
+    squid_delay_pools.graph_title IPs being delayed
+    squid_delay_pools.graph_args --base 1000 -l 0
+    squid_delay_pools.graph_vlabel IPs
+    squid_delay_pools.graph_order squid_delay1
+    squid_delay_pools.graph_category squid
+    squid_delay_pools.squid_delay1.sum <%= Chef::Munin.expand "%%name%%.openstreetmap:squid_delay_pools.squid_delay1", @tilecaches %>
+    squid_delay_pools.squid_delay1.label IPs
+    squid_delay_pools.squid_delay1.min 0
+    squid_delay_pools.squid_delay1.draw AREA
+    squid_requests.graph_title Squid client requests
+    squid_requests.graph_args --base 1000 -l 0
+    squid_requests.graph_vlabel requests / ${graph_period}
+    squid_requests.graph_order hits errors requests
+    squid_requests.graph_total total
+    squid_requests.graph_category squid
+    squid_requests.hits.sum <%= Chef::Munin.expand "%%name%%.openstreetmap:squid_requests.hits", @tilecaches %>
+    squid_requests.hits.label hits
+    squid_requests.hits.draw AREA
+    squid_requests.errors.sum <%= Chef::Munin.expand "%%name%%.openstreetmap:squid_requests.errors", @tilecaches %>
+    squid_requests.errors.label errors
+    squid_requests.errors.draw STACK
+    squid_requests.requests.sum <%= Chef::Munin.expand "%%name%%.openstreetmap:squid_requests.requests", @tilecaches %>
+    squid_requests.requests.label misses
+    squid_requests.requests.draw STACK
+    squid_traffic.graph_title Squid traffic status
+    squid_traffic.graph_args --base 1000
+    squid_traffic.graph_vlabel bits per ${graph_period}
+    squid_traffic.graph_order kbytes_in kbytes_out hit_kbytes_out
+    squid_traffic.graph_category squid
+    squid_traffic.kbytes_in.sum <%= Chef::Munin.expand "%%name%%.openstreetmap:squid_traffic.kbytes_in", @tilecaches %>
+    squid_traffic.kbytes_in.label received
+    squid_traffic.kbytes_in.cdef kbytes_in,8096,*
+    squid_traffic.kbytes_out.sum <%= Chef::Munin.expand "%%name%%.openstreetmap:squid_traffic.kbytes_out", @tilecaches %>
+    squid_traffic.kbytes_out.label sent
+    squid_traffic.kbytes_out.cdef kbytes_out,8096,*
+    squid_traffic.hit_kbytes_out.sum <%= Chef::Munin.expand "%%name%%.openstreetmap:squid_traffic.hit_kbytes_out", @tilecaches %>
+    squid_traffic.hit_kbytes_out.label from cache
+    squid_traffic.hit_kbytes_out.cdef hit_kbytes_out,8096,*
+    squid_times_http.graph_title Squid Http Service Times
+    squid_times_http.graph_category squid
+    squid_times_http.graph_args --lower-limit 0
+    squid_times_http.graph_vlabel median reponse times (s)
+    squid_times_http.graph_order <%= Chef::Munin.expand "%%name%%=%%name%%.openstreetmap:squid_times.mean_http", @tilecaches %>
+<% @tilecaches.each do |tc| -%>
+    squid_times_http.<%= tc[:name] %>.label <%= tc[:name] %>
+<% end -%>
+    squid_times_cmis.graph_title Squid Cache Miss Service Times
+    squid_times_cmis.graph_category squid
+    squid_times_cmis.graph_args --lower-limit 0
+    squid_times_cmis.graph_vlabel median reponse times (s)
+    squid_times_cmis.graph_order <%= Chef::Munin.expand "%%name%%=%%name%%.openstreetmap:squid_times.mean_cmis", @tilecaches %>
+<% @tilecaches.each do |tc| -%>
+    squid_times_cmis.<%= tc[:name] %>.label <%= tc[:name] %>
+<% end -%>
+    squid_times_chits.graph_title Squid Cache Hit Service Times
+    squid_times_chits.graph_category squid
+    squid_times_chits.graph_args --lower-limit 0
+    squid_times_chits.graph_vlabel median reponse times (s)
+    squid_times_chits.graph_order <%= Chef::Munin.expand "%%name%%=%%name%%.openstreetmap:squid_times.mean_chits", @tilecaches %>
+<% @tilecaches.each do |tc| -%>
+    squid_times_chits.<%= tc[:name] %>.label <%= tc[:name] %>
+<% end -%>
+    squid_times_nhits.graph_title Squid Cache Near Hit Service Times
+    squid_times_nhits.graph_category squid
+    squid_times_nhits.graph_args --lower-limit 0
+    squid_times_nhits.graph_vlabel median reponse times (s)
+    squid_times_nhits.graph_order <%= Chef::Munin.expand "%%name%%=%%name%%.openstreetmap:squid_times.mean_nhits", @tilecaches %>
+<% @tilecaches.each do |tc| -%>
+    squid_times_nhits.<%= tc[:name] %>.label <%= tc[:name] %>
+<% end -%>
+    squid_times_nmr.graph_title Squid Cache Not Modified Service Times
+    squid_times_nmr.graph_category squid
+    squid_times_nmr.graph_args --lower-limit 0
+    squid_times_nmr.graph_vlabel median reponse times (s)
+    squid_times_nmr.graph_order <%= Chef::Munin.expand "%%name%%=%%name%%.openstreetmap:squid_times.mean_nmr", @tilecaches %>
+<% @tilecaches.each do |tc| -%>
+    squid_times_nmr.<%= tc[:name] %>.label <%= tc[:name] %>
+<% end -%>
+    squid_times_dnsl.graph_title Squid Cache DNS Lookup Service Times
+    squid_times_dnsl.graph_category squid
+    squid_times_dnsl.graph_args --lower-limit 0
+    squid_times_dnsl.graph_vlabel median reponse times (s)
+    squid_times_dnsl.graph_order <%= Chef::Munin.expand "%%name%%=%%name%%.openstreetmap:squid_times.mean_dnsl", @tilecaches %>
+<% @tilecaches.each do |tc| -%>
+    squid_times_dnsl.<%= tc[:name] %>.label <%= tc[:name] %>
+<% end -%>
diff --git a/cookbooks/nodejs/README.rdoc b/cookbooks/nodejs/README.rdoc
new file mode 100644 (file)
index 0000000..3de2ec7
--- /dev/null
@@ -0,0 +1,8 @@
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
diff --git a/cookbooks/nodejs/metadata.rb b/cookbooks/nodejs/metadata.rb
new file mode 100644 (file)
index 0000000..b0924a7
--- /dev/null
@@ -0,0 +1,6 @@
+maintainer        "OpenStreetMap Administrators"
+maintainer_email  "admins@openstreetmap.org"
+license           "Apache 2.0"
+description       "Installs and configures Node.js"
+long_description  IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
+version           "1.0.0"
diff --git a/cookbooks/nodejs/providers/package.rb b/cookbooks/nodejs/providers/package.rb
new file mode 100644 (file)
index 0000000..f726df3
--- /dev/null
@@ -0,0 +1,67 @@
+#
+# Cookbook Name:: nodejs
+# Provider:: package
+#
+# Copyright 2013, OpenStreetMap Foundation
+#
+# 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.
+#
+
+require "chef/mixin/shell_out"
+require "json"
+
+include Chef::Mixin::ShellOut
+
+def load_current_resource
+  @packages = JSON.parse(shell_out("npm list --global --json").stdout)["dependencies"]
+
+  @current_resource = Chef::Resource::NodejsPackage.new(new_resource.name)
+  @current_resource.package_name(new_resource.package_name)
+  if package = @packages[@current_resource.package_name]
+    @current_resource.version(package["version"])
+  end
+  @current_resource
+end
+
+action :install do
+  if new_resource.version
+    package_name = "#{new_resource.package_name}@#{new_resource.version}"
+  else
+    package_name = new_resource.package_name
+  end
+
+  unless @packages.include?(new_resource.package_name)
+    shell_out!("npm install --global #{package_name}")
+    new_resource.updated_by_last_action(true)
+  else
+    if new_resource.version &&
+       new_resource.version != @current_resource.version
+      shell_out!("npm install --global #{package_name}")
+      new_resource.updated_by_last_action(true)
+    end
+  end
+end
+
+action :upgrade do
+  if @packages.include?(new_resource.package_name)
+    shell_out!("npm update --global #{new_resource.package_name}")
+    new_resource.updated_by_last_action(true)
+  end
+end
+
+action :remove do
+  if @packages.include?(new_resource.package_name)
+    shell_out!("npm remove --global #{new_resource.package_name}")
+    new_resource.updated_by_last_action(true)
+  end
+end
diff --git a/cookbooks/nodejs/recipes/default.rb b/cookbooks/nodejs/recipes/default.rb
new file mode 100644 (file)
index 0000000..673b8ac
--- /dev/null
@@ -0,0 +1,21 @@
+#
+# Cookbook Name:: nodejs
+# Recipe:: default
+#
+# Copyright 2013, OpenStreetMap Foundation
+#
+# 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.
+#
+
+package "nodejs"
+package "npm"
diff --git a/cookbooks/nodejs/resources/package.rb b/cookbooks/nodejs/resources/package.rb
new file mode 100644 (file)
index 0000000..2434112
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# Cookbook Name:: nodejs
+# Resource:: package
+#
+# Copyright 2013, OpenStreetMap Foundation
+#
+# 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.
+#
+
+actions :install, :upgrade, :remove
+
+attribute :package_name, :kind_of => String, :name_attribute => true
+attribute :version, :kind_of => String
+
+def initialize(*args)
+  super
+  @action = :install
+end
diff --git a/cookbooks/ntp/README.md b/cookbooks/ntp/README.md
new file mode 100644 (file)
index 0000000..227b395
--- /dev/null
@@ -0,0 +1,41 @@
+DESCRIPTION
+===========
+
+Installs and configures ntp, optionally set up a local NTP server.
+
+USAGE
+=====
+
+Set up the ntp attributes in a role. For example in a base.rb role applied to all nodes:
+
+    "ntp" => {
+      "servers" => "time.int.example.org"
+    }
+
+Then in an ntpserver.rb role that is applied to NTP servers:
+
+    "ntp" => {
+      "is_server" => "true",
+      "servers" => "0.us.pool.ntp.org"
+    }
+
+The time.int.example.org used in the base role is a CNAME for the NTP server.
+
+LICENSE AND AUTHOR
+==================
+
+Author:: Joshua Timberman (<joshua@opscode.com>)
+
+Copyright 2009, Opscode, Inc.
+
+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.
diff --git a/cookbooks/ntp/attributes/default.rb b/cookbooks/ntp/attributes/default.rb
new file mode 100644 (file)
index 0000000..81ef7aa
--- /dev/null
@@ -0,0 +1,11 @@
+case platform 
+when "ubuntu","debian"
+  default[:ntp][:service] = "ntp"
+when "redhat","centos","fedora"
+  default[:ntp][:service] = "ntpd"
+end
+
+default[:ntp][:is_server] = false
+default[:ntp][:servers]   = ["0.us.pool.ntp.org", "1.us.pool.ntp.org"]
+
+default[:tz] = "Etc/UTC"
diff --git a/cookbooks/ntp/metadata.rb b/cookbooks/ntp/metadata.rb
new file mode 100644 (file)
index 0000000..404666f
--- /dev/null
@@ -0,0 +1,34 @@
+maintainer        "Opscode, Inc."
+maintainer_email  "cookbooks@opscode.com"
+license           "Apache 2.0"
+description       "Installs and configures ntp as a client or server"
+long_description  IO.read(File.join(File.dirname(__FILE__), 'README.md'))
+version           "0.8.2"
+
+recipe "ntp", "Installs and configures ntp either as a server or client"
+
+%w{ ubuntu debian redhat centos fedora }.each do |os|
+  supports os
+end
+
+attribute "ntp",
+  :display_name => "NTP",
+  :description => "Hash of NTP attributes",
+  :type => "hash"
+
+attribute "ntp/service",
+  :display_name => "NTP Service",
+  :description => "Name of the NTP service",
+  :default => "ntp"
+
+attribute "ntp/is_server",
+  :display_name => "NTP Is Server?",
+  :description => "Set to true if this is an NTP server",
+  :default => "false"
+
+attribute "ntp/servers",
+  :display_name => "NTP Servers",
+  :description => "Array of servers we should talk to",
+  :type => "array",
+  :default => ["0.us.pool.ntp.org", "1.us.pool.ntp.org"]
+
diff --git a/cookbooks/ntp/recipes/default.rb b/cookbooks/ntp/recipes/default.rb
new file mode 100644 (file)
index 0000000..d568047
--- /dev/null
@@ -0,0 +1,87 @@
+#
+# Cookbook Name:: ntp
+# Recipe:: default
+#
+# Copyright 2010, OpenStreetMap Foundation.
+# Copyright 2009, Opscode, Inc
+#
+# 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.
+
+require "socket"
+
+package "ntp"
+package "ntpdate"
+package "tzdata"
+
+execute "dpkg-reconfigure-tzdata" do
+  action :nothing
+  command "/usr/sbin/dpkg-reconfigure -f noninteractive tzdata"
+  user "root"
+  group "root"
+end
+
+file "/etc/timezone" do
+  owner "root"
+  group "root"
+  mode 0644
+  content "#{node[:tz]}\n"
+  notifies :run, resources(:execute => "dpkg-reconfigure-tzdata"), :immediately
+end
+
+service "ntp" do
+  action [ :enable, :start ]
+  supports :status => true, :restart => true
+end
+
+template "/etc/ntp.conf" do
+  source "ntp.conf.erb"
+  owner "root"
+  group "root"
+  mode 0644
+  notifies :restart, resources(:service => "ntp")
+end
+
+munin_plugins = []
+
+if node[:lsb][:release].to_f <= 8.04
+  munin_plugins = [ "ntp_states" ]
+
+  node[:ntp][:servers].each do |name|
+    name = Socket.gethostbyname(name)[0].gsub!(/[.-]/, "_")
+
+    munin_plugin "ntp_#{name}" do
+      target "ntp_"
+    end
+
+    munin_plugins.push("ntp_#{name}")
+  end
+
+  munin_plugin "ntp_states"
+else
+  munin_plugins = [ "ntp_kernel_err", "ntp_kernel_pll_freq", "ntp_kernel_pll_off", "ntp_offset" ]
+
+  munin_plugin "ntp_kernel_err"
+  munin_plugin "ntp_kernel_pll_freq"
+  munin_plugin "ntp_kernel_pll_off"
+  munin_plugin "ntp_offset"
+end
+
+if File.directory?("/etc/munin/plugins")
+  Dir.new("/etc/munin/plugins").each do |plugin|
+    if plugin.match(/^ntp_/) and not munin_plugins.include?(plugin)
+      munin_plugin plugin do
+        action :delete
+      end
+    end
+  end
+end
diff --git a/cookbooks/ntp/templates/default/ntp.conf.erb b/cookbooks/ntp/templates/default/ntp.conf.erb
new file mode 100644 (file)
index 0000000..ffb263c
--- /dev/null
@@ -0,0 +1,16 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+# Exchange time with everybody, but don't allow configuration
+restrict default kod notrap nomodify nopeer noquery
+
+# Local users may interrogate the ntp server more closely
+restrict 127.0.0.1
+restrict ::1
+
+# Servers
+<% node[:ntp][:servers].each do |server| -%>
+server <%= server %> iburst
+<% end -%>
+
+# Drift file
+driftfile /var/lib/ntp/ntp.drift
diff --git a/cookbooks/openssh/metadata.rb b/cookbooks/openssh/metadata.rb
new file mode 100644 (file)
index 0000000..203061a
--- /dev/null
@@ -0,0 +1,8 @@
+maintainer        "OpenStreetMap Administrators"
+maintainer_email  "admins@openstreetmap.org"
+license           "Apache 2.0"
+description       "Installs and configures openssh"
+version           "1.0.0"
+recipe            "openssh", "Installs and configures openssh"
+supports          "ubuntu"
+depends           "networking"
diff --git a/cookbooks/openssh/recipes/default.rb b/cookbooks/openssh/recipes/default.rb
new file mode 100644 (file)
index 0000000..59c8fe7
--- /dev/null
@@ -0,0 +1,81 @@
+#
+# Cookbook Name:: openssh
+# Recipe:: default
+#
+# Copyright 2010, OpenStreetMap Foundation.
+# Copyright 2008-2009, Opscode, Inc.
+#
+# 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.
+#
+
+include_recipe "networking"
+
+package "openssh-client"
+package "openssh-server"
+
+service "ssh" do
+  action [ :enable, :start ]
+  if node[:lsb][:release].to_f >= 10.04
+    supports :status => true, :restart => true, :reload => true
+  else 
+    supports :restart => true, :reload => true
+  end
+end
+
+hosts = search(:node, "networking:interfaces").sort_by do |node|
+  node[:hostname]
+end.collect do |node|
+  names = [ node[:hostname] ]
+
+  node.interfaces(:role => :external).each do |interface|
+    names |= [ "#{node[:hostname]}.openstreetmap.org" ]
+    names |= [ "#{node[:hostname]}.#{interface[:zone]}.openstreetmap.org" ]
+  end
+
+  unless node.interfaces(:role => :internal).empty?
+    names |= [ "#{node[:hostname]}.#{node[:networking][:roles][:external][:zone]}.openstreetmap.org" ]
+  end
+
+  Hash[
+    :names => names.sort,
+    :addresses => node.ipaddresses.sort,
+    :rsa => node[:keys][:ssh][:host_rsa_public],
+    :dsa => node[:keys][:ssh][:host_dsa_public]
+  ]
+end
+
+template "/etc/ssh/ssh_config" do
+  source "ssh_config.erb"
+  mode 0644
+  owner "root"
+  group "root"
+end
+
+template "/etc/ssh/ssh_known_hosts" do
+  source "ssh_known_hosts.erb"
+  mode 0444
+  owner "root"
+  group "root"
+  backup false
+  variables(
+    :hosts => hosts
+  )
+end
+
+firewall_rule "accept-ssh" do
+  action :accept
+  source "net"
+  dest "fw"
+  proto "tcp:syn"
+  dest_ports "ssh"
+end
diff --git a/cookbooks/openssh/templates/default/ssh_config.erb b/cookbooks/openssh/templates/default/ssh_config.erb
new file mode 100644 (file)
index 0000000..d1e425e
--- /dev/null
@@ -0,0 +1,13 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+Host *
+    SendEnv LANG LC_*
+    HashKnownHosts yes
+    GSSAPIAuthentication yes
+    GSSAPIDelegateCredentials no
+
+Host *.oob
+    HostKeyAlgorithms ssh-rsa,ssh-dss
+
+Host *.oob.openstreetmap.org
+    HostKeyAlgorithms ssh-rsa,ssh-dss
diff --git a/cookbooks/openssh/templates/default/ssh_known_hosts.erb b/cookbooks/openssh/templates/default/ssh_known_hosts.erb
new file mode 100644 (file)
index 0000000..ee8848a
--- /dev/null
@@ -0,0 +1,52 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+<% @hosts.each do |host| -%>
+<%= host[:names].join(",") -%>,<%= host[:addresses].join(",") -%> ssh-rsa <%= host[:rsa] %>
+<%= host[:names].join(",") -%>,<%= host[:addresses].join(",") -%> ssh-dsa <%= host[:dsa] %>
+<% end -%>
+apc1,apc1.ucl.openstreetmap.org,10.0.0.49 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAYQDYDLYD52vwCagyebWxujdLw5/jnJ4Nln8g+pXFylT6OJU2R6t+U7mndZUKj1ClCt4AkS77/lEncs8Ie9YM3zzZlN0zsMEmhXzT62wO+0WJkr+hGSlTkMp1iL+dqC9Bk+U=
+apc2,apc2.ucl.openstreetmap.org,10.0.0.50 ssh-rsa AAAAB3NzaC1yc2EAAAACAQEAAAEBANYmUWIbP1bVQEcyeIoKZOvW/cyzmWytUA0u/057WGCMB70UKJrgmhRoArtxm3O4sFYS5b5xzhpcJ6YyYPjs3GMa67lkUBv/mOZEOIM20VeP7biRQf5DLrrSF5cS4A3p+ft7TyFPAuIgywxHQwpnRi7ZtBIPNj6MbRukUYivWrBVQML23O2hfWbwyLWQCTpedycgb1OFYbKC86r73PwW6ZP3Kzv0CDinDL2heEBT/hdeUkeXJCbop6tU3A4bA/obMTmKxsVoT2vEhto3v/bXFAFDQyYidBrOo+CBa3Nbbl+0wAZLBbrjkbQC7gz6TtU70ceLHo/cl8zmIQlHKa8c/Ec=
+apc3,apc3.ucl.openstreetmap.org,10.0.0.51 ssh-rsa AAAAB3NzaC1yc2EAAAACAQEAAAEBAM7kqwZuiMNnTQgI2/CpBwNna2vHC2W5kT0AVRFdd41f+Bet+NbXaHpa+/l1eGaMThtuEpXI8TuyyMP/Wna6xhaSBqcTyinbmc+1rqsSxqXTdNKFX+GSKJay/7jQpe/ZA94MAX/l+jHo50g9bjw5GhSv2sG5VeeabYM+eiTDwjSEwoqpsHYtRSbCCwNgM5hK0lTunPZ+wq31vY8tPbnYTZdi8ENxccXI1+wLPEIGg74FoWxy98lKTc8FIa/JaT37hDOwOC0uzDi1koXp5sCzCVAhRDNzHSSKkiIXx8rXp7/2ZPrKo2j++W/rl0b0xe1UO+/KWxhCC2YsCaDIgBXsG7E=
+#albi.oob,albi.oob.openstreetmap.org,10.0.1.2 ssh-rsa
+#albi.oob,albi.oob.openstreetmap.org,10.0.1.2 ssh-dss
+ridley.oob,ridley.oob.openstreetmap.org,10.0.1.3 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC6FtSZo3FZfOyWVdiUX1CSlWLIiB2iCWmtsfiqQ32i+AbNxiOfqBckp9CQazdaAmMp638TnLpCwSfJk9oJNui/J6yY5jq1RKb5U9YVGkhXvFmHH2dG/QpD9z786jWZ8RFdTwtdpHVfJzfm3vFDOORJcJwnvGr+Fe+fnY43aPzTZQ==
+ridley.oob,ridley.oob.openstreetmap.org,10.0.1.3 ssh-dss AAAAB3NzaC1kc3MAAACBAIc5G8Y5NSBvyNTK+JrawLWjhoY9Rv3QkaJyIYXTQEBOsF7oq1jt0/2i9nLKxnH/U2pdFNquwCWMETmPZpPN2ptLF7CAdxs8AzXq4K2qEflSvWYN0V44pCMNIqYooib3AweqhHncmpeOMFbPjh8SqUJ9I82vQBVrw2H5WaNNrDPfAAAAFQDATXZsaPwZo2hRkJbgHboED0lGGwAAAIAcyScviS3/VH+qaGn6CkMo+iXSIP1oYa7wPDnyiF2hYDn5ManBgpzfBewimGywYO9CB8b4f3M9Vy4ZoQgHIkIbygNU3lThe5acQGtCQqt7h6i2u6lbuUrmBGF1eWDwZWK7ASEMTCyitaQYAanW19qZtokONI2+phb8qw+OfOZ6ZQAAAIBwj3kucxst745TcWurZwKMQbhf4/iw65kgLlpXInMxpgkIHvp3S9GcsxarwjOGy7bi+4X4cFkI2GC9lslrZewpZXFD2i1DKOoL5cXVuyBczQUYBG5gDjW9LOgtNTtfF2waiUjRAtabBdLAsqK68iyumOttsNR6yjHcwKRqHJrVdA==
+idris.oob,idris.oob.openstreetmap.org,10.0.1.4 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDKG56AnuKGFcj5dv+IDAEOHY3U7pm6lwchKAHltwFP/pehf7QwYOAGn/m3hhjQP/hyZNaQ+Fp+GpkkEmIdnSt+a1QIj6tjSf6UEoIO4oPXyfBA1ju2B4v9tqcULTGJKO8TLGVQfdF59VfobkEZxtFbIu6g1Cwgf3bprZMcIWIzxQ==
+idris.oob,idris.oob.openstreetmap.org,10.0.1.4 ssh-dss AAAAB3NzaC1kc3MAAACBAIRoV7lQXd1/JpHMTvj/TUQMB60H5ZjBZnoZyxIZF0f9QsmxypBEkzO+I0ZcNgQYQYrdpwrCZu36MwQQIzSRPGyFN1CVr41fCKDwfYrnL+kLBzfJp3MDDuCVnnolkD1NzjyQIMNNWt1ITlVObDkauP4LZW9q3i+CUz67AFN3cHkxAAAAFQC3vDsSETUrw6gJcrFQD1dZZRYNPwAAAIAngRSO/4aoTc3y++FDSEYKX1FY1ZQ6TQxeAxSpeuPuD8mSPe5PR7UHLxNEPr0Eh0GiwxrvME4Gp2PWJFeI7W2S7M8CgEnwkV0jKv0/BR1RMIYP7UZZC9OJYT8z96IG8h7jy0HY7DXR/qVAvfEE8+wXP3LRCqe4G3xDGlyjIvHj6gAAAIA4Ryu3KIW1S8D3Nys5vBAV15Jn1lUbVp4KemlMl9VOG/MIk9ge9f9pT2AC2hBhLe9I0p1PdW+G17NF5f24jaM+DM/7dsxekrqvAfutoDIX5PmrXSMu5cvHUcSvH/DPXSchx4vNm2JXBtlLog9qbnkaFrTWz/9NgG6CaGXagGI0+w==
+#azure.oob,azure.oob.openstreetmap.org,10.0.1.5 ssh-rsa
+#azure.oob,azure.oob.openstreetmap.org,10.0.1.5 ssh-dss
+#urmel.oob,urmel.oob.openstreetmap.org,10.0.1.6 ssh-rsa
+#urmel.oob,urmel.oob.openstreetmap.org,10.0.1.6 ssh-dss
+faffy.oob,faffy.oob.openstreetmap.org,10.0.1.7 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDnQkrnLV6IEFpDX1gP3FLauDzZt9flMujBM0fx7p+8BnxbGIfyoCm49EKFn+Yw6U+k1FfHj6/JkEDQG8m4yvu0Uzo0vSlcwpuecBDl2Ky5x9m8lLilIEMv6PywWkaQ0CvTYmAdRpswFOlscHsRzsEN1mwuTsgcpQ1y4WVRwcq0uw==
+faffy.oob,faffy.oob.openstreetmap.org,10.0.1.7 ssh-dss AAAAB3NzaC1kc3MAAACBAOHI3ygTiRSx2xE29urtR6fym7zNm9tHHEjxKSpuYeA7Ka7cbvjtb1smXi7eZky48gS2vkrbT4PJeJrrc4utl4oBN/o5wX6hUwyjJcCwoALl2qaC9/hFo4mN6oHFal9bDbOmTwggghbEt5CPU3sX3BbgVF4rGN/gGhUeI3u4d77DAAAAFQD9cPRYV0zinxhnVABqI3OFWtwm5QAAAIB2zPz7jBHMpe9FuxtgqN6GaOUyVRxU1BlYB7rRQ11ZB4IWuCoRV083S2xz6aBN8xbQoSgB1rPQC76p4Og4Pc1ETVSpP1s0sREz/ZAvxyq1PHVfDMV3zWlntXrJLIxaOuBm2EZyPDI0anUM4vrKSY18EydEXZoIQzwUo7pBnL37eAAAAIEAhtJavzh0XIQHHdn7Jb5hOshIw2cPY8PldltqxoNK6HTzokzwna0K8LewUQf28mVaoizlDF9UvpX5qm44GJYdOJL23v9ATsjJ56YCp0DXhoHeeX0JnDEnOuVHgGktpBZp/e7Zbsz3AmQhM/wPI6sy/f40tLtaKFvTDkld/A44eeI=
+#zark.oob,zark.oob.openstreetmap.org,10.0.1.8 ssh-rsa
+#zark.oob,zark.oob.openstreetmap.org,10.0.1.8 ssh-dss
+eustace.oob,eustace.oob.openstreetmap.org,10.0.1.9 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAOlKh4CiefEXtWj8mXJB+Tn0RxLqU/ACMp9NfBNXnaYyOWkJJ4O0b5WX4pkPxi+n83e4ZXc/6180DPpafJ2faii0BDwdmZLNdeTVaae7BixjOImTt4HaDv30DUfvsGzPU5XAjId4v/iKrM6mplbn27C2CcHGwh73Oc3YxxGsWEw==
+eustace.oob,eustace.oob.openstreetmap.org,10.0.1.9 ssh-dss AAAAB3NzaC1kc3MAAACBAM9dCBACQykp7BM/HqbIdTPNSFaC0AAjA95WZP4AfHos+wkUt+zdNeKfO2xgnAj6WyBJFUvSOgcmAiKqCJk6+B1Zl2k+CyQIW9RnQbwBLH3M3AduqXMWB/EfD9SWt6HwyU/dumaiv/HqapGR/ly/84F+sIiNTXVSTZvtweUNuYFPAAAAFQCBQ4QjFUny6+XAL2ucyU9W8ya7rQAAAIAXSQrRSubw9Tli0PbBfWllf5AkR/ybB/rd6UQUUeMTVg5SHLVjc/HwyBYQbeRnSW+bpztauW1bx4cfpGQsqmEPHmJVfxuc36u5MyeYQn1HPLfXDGYILFcjT5aUwRoKqGCuOaCV2YIqBtgtS8nR9ihPJKQfbmtQ4gcAnKMSbMFnvQAAAIEAt4kLYCscN/DkSIxiCNjHVYTYxepsfP2IsZAYi3Cxs8GHWu3kdyP8AvT47t6pI6KxEFhFPozNCtU9w+0kxgCBApb0bALI/DcebNZYCYyk/S939KfLpRCBion53JdCXbFhPgWiYzI40IUQPwWo/cyXREB3Qw/AOLwp8vlKuq8RDtU=
+#puff.oob,puff.oob.openstreetmap.org,10.0.1.10 ssh-rsa
+#puff.oob,puff.oob.openstreetmap.org,10.0.1.10 ssh-dss
+errol.oob,errol.oob.openstreetmap.org,10.0.1.14 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA1riMj4gWqiovniYhlFNUxMm/AGmV/C2GjcMP+NcJ1ZyP4OdytGeGfhUm5GwVwraimkFQQlfEDcUWY7OX4EG115E8i15cUt6s6Ya2E6AXydigvBbrdp8MNnPOWBifVN3/5Cgi8nrAebmPs88ZZx2KM/Df5qIB2rHYpuHYyl+MpqE=
+errol.oob,errol.oob.openstreetmap.org,10.0.1.14 ssh-dss AAAAB3NzaC1kc3MAAACBAKcnhyMz3C4sku0e1/nFailjoPcMwLazXq4H/kUsdlt+f2By73F5KdUWffxoeRNL0UVT7+VCKG6IXmXGkKVfvpTipFjkP1N+b7I4SuJcQ/EUNPTCGAfC3l691K8jUBD6WSlQUqZtKGnpDS1zI/ZIYiNqrQnWu2RTYnP3QvY7JigDAAAAFQDI6aaH6mWx7vTVS9m3tyXQ4GQ08wAAAIAQjAM+q8Hfp1h45UjTeD2jIA74asQl0M+4q+4EcnNPnKXRbEBIg4rCWkHdd06uhayXZ91KzCDcj1b2LSb2zOE4U1MDEpdVnz22PuEl/f6/epKmLOqHoOGu9/9Lud6OoZQSveEPYmcpEEpt1RCN9ZvkVtFdLwtQ8+CSSGXg8yfCxgAAAIEAjQztmG1LN/e7pNRY0MtV148rJY3mR2knJegg0yBOEWHUGtKY91lgboWie1YTGR3RiXckJFFYkOGWAxqEVM//+rW0hatCxEp/mWEt/GWKPpV52fc4BUhJbi9hb8sg+dAvfoHwUL3CzHzqapaRNxxbfest8dfvascAjRDFP7yxU9w=
+yevaud.oob,yevaud.oob.openstreetmap.org,10.0.1.15 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAuWeUQd5ssUd5VFyTMXgC+U6c7s63mtuEj+cL6x8EU8PqNS12RGwLpeAI5VL8UzM0YLyPjPh/yzdQN2tl9ufK7KZF0apvoSZgp/uwyG+CgdFSf66nTrZN4NA/QP1ikH3kbqcM87LfNjCrMXnqMBJ/OCqz2z+An8t0KGDXS8haxlU=
+yevaud.oob,yevaud.oob.openstreetmap.org,10.0.1.15 ssh-dss AAAAB3NzaC1kc3MAAACBAL6RC7IMuQEtD4JIRmBJEownC0a7ZEvfCTw20PV5MjWb6twZlGBK3IA/0yV0oJ+75W6VWizn3cWSBS3y1zD8KktF4fh4+FVyin9WTyFuwME8cYmRPV+kuOa1lF1sLJxqvZJRjKMjweLeNTKnl1mb03049SL2YoGwMOTdVgVBjEyFAAAAFQC7rQIvnfLYbQdX87DwlzfMDALOoQAAAIEAmAu2kK8atEOR1Sc6maxYKSf68MYMHoTpm2MW9q2x5ls982kfEUMJ3h641cbRgOAuCmQU3gHnt73sl5LY3K3oLijIhSQm8+l+GkrXVhdwx7ScLXf+8TJZRWiP6Q98VWM4E3L4wmiJksLbTlxdoew3lv8gGhbpk0XuSyLWIBZIKJAAAACATogkqFXhPFzOMRJAR6G8J4bOqg9Ae2cGtf4aMZ9xdm/Hm7YLSu3kn5IhawwU+DL494VF+ky69T01iY3e4m/kQhYB4emlqsRHzVscblVH+GL6sVEkct0HMzfqzEFcfYWqqMdig9EwTzHwJzkAb4WqZdGnWG3Ln88x3liyDZTpGco=
+poldi.oob,poldi.oob.openstreetmap.org,10.0.1.16 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAuZiBE85lKbo03ctiEUNWK18n61akmCGLnKps2Sw8ZhIP42Ijzg9XyYsPWXbDZszGv45AtgFyCIVNzweZ2qRHimv5N5ZHxNVoCchnVWgTTSAQVVgjsITwl9VAxnyXXUQzp+NdyvzHDmz5S2HvB4f/i3K7SaEDbCcNbsXzgpdAu5U=
+spike-02.oob,spike-02.oob.openstreetmap.org,146.179.159.180 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDZR4RartuEvKPaJ+P1UZzDyFxYAEt+rPuy34aHk2OQNOdtR69G/SKsEfgSANMo7L+efFf4l9pBVcLTLbL5qXaVBb9y2LRiajySCFuTRNXokZ+0yd20728qmZsanCKIDKzSk9K3ij5rm/C6KuE3oswrWjfJnI5L4OILzNjSyPP7Ww==
+spike-02.oob,spike-02.oob.openstreetmap.org,146.179.159.180 ssh-dss AAAAB3NzaC1kc3MAAACBAIMptqip2uZDVeAHDSNPAK6nTwuw93MoloPOByX3xvUBiLOADC0WguonKIFF2d24DtkbjZEjD0b2mZU08vezfX+hDolzoZHaO7HuuULN89wRVB/yYAjmVHcv5QUouUkVgvRTd5mfFlWH95d9mDyzitv+jVfRo7NH2YacpAb0+VYTAAAAFQCHU+1IHN8NktVJzfl8Kma/R3pd8QAAAIBpR/8K11pa82YlSGRmzFPIk+j+HFIikD5J86oXTOahw2/K5qKq8BbkZ8lpES+9JXuHafTd4ljgb8Ldh+5wETKCNapRhAtBugOEAOtbCJ5I/8W4VqXQbUcPnrwVYMsIkGgBZvtzwuBxe0uoQno6befQhrwzRJbpK63cIsMSyhkKWQAAAIAhx6hTqrL2NJymjjXJJ+mpj2xejIX8cZRKKOliqeeL/ohLsxpD9JLMUou5Q16w0t1GPhjrfjBN+aQhaOjfYZ35yYIvqmuFbwof+ke2R81gMbvhnwa3cBBkjq4gZqPJ5px9fZW1+QuWd/uNHrZGB0EnhRi+Z4e+HHiKA5+yfXuz+w==
+ramoth.oob,ramoth.oob.openstreetmap.org,146.179.159.181 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgwDkRqR1VRgHOON8M7YCNnIG8k0zukAN/r4L5fPKTvWmdhe17UnxywPc+TySjXqNsXQ/jPLGvpO5uoSG3dgT2N7NUdAtdL4Enb87dX7yTbJTJzMMxTb9HSI1SL2/5iSefyAVVo1+R8DMmFqTWa2eFHoD9IoxFSNSTarTZQgmH1oZYoZX
+ramoth.oob,ramoth.oob.openstreetmap.org,146.179.159.181 ssh-dss AAAAB3NzaC1kc3MAAACBAJKKtKZBECA+wtvYtrEeMyTzkm3X/4IfC6E8NcnZouMCHYn3F964+pG7mRskZAi7P95VwJYx6TLkiK/MNKIh8mk8M4Xxu2USIXblkTPraPYHyVgTkfZit6F9qTR8cAOlHtoY+9GgKmWMLC+xeOgPtoERvUyuuprXsAztZ9C2BKWjAAAAFQDnPXN3n2g1xxsYZsaQpdPuijb1tQAAAIA7/IpFy3mSgpu/TmmBuYLccdRTCNt493U3wMLb/JdUBu4h1FM6J5DSozcQ70ATglpLLYa3Ru5ztv87Esu8c7CH/TAH+GZ5/3LJtS//HJDt+53yy4CgwO8pcKbYo0rfRy4/QdFXWeBUtM2XN4hHvbaBJ0fzP1gXI1GHvz3OQxWICgAAAIAvZVlk6GX+uGpqLdW4F1ctkuqUnkIGzRziJ9Gk46vOOFCPxU8bUXLGzvC7Zv3SOR04YH7/LDMUof2y68EOCbH9YT8mHNqLdZ9TxOWv8wUaDX5O9J8JXngLwl+U+ONitseg/PrEZKmP2/cR42pFwuTzb59+NSkEVAa0ZK6+2FkWog==
+sarel.oob,sarel.oob.openstreetmap.org,10.0.1.12 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCepzpzx1NqbX1uo10ePzF5lUnaHXtzxcgFR7LvXOuZrip+bSOY/4jBqCasZG3kofMcUL6TFh7Q2MrkZ+9Xj7B9AeNwzlZnohAjLNIdJJjHHyjJ5EHiJHnpVeElP+/W6NfLE2S4xq7JF+eOdeznb6X6JdkXnKhaJv5KQcz6JVp50Q==
+sarel.oob,sarel.oob.openstreetmap.org,10.0.1.12 ssh-dss AAAAB3NzaC1kc3MAAACBAKPIabHx0CCmG3tl36baYTalPout92RMZkX0RhfiRDOHXc+Mk5bAA/r8ep9BiMNbhB+qstay0yqpwemJLC0+0LxhQAyl4MDEDpHMLAlXmQO4HhEVyKB9hutfyFDMYNI4D1NwzBRO4yPRjhoai0NaEo5jBjI9SiIWMhPBDO2lLyGtAAAAFQCrlNl/cRw43H1BVzO3lhMG8+eTYwAAAIBbTcKalbfzeoWLOPuLSxL7AE57WqyqMB9/gdac6+c3YaO/g/WIsJRO2g5Im1/cCIvOH4nVF0wlQONh9CGZZKzSKdaIJIJ9y0A7kzRxLxEfGz5ZslH+xusdWeU4hx39yVzBinM2+qLiDpc6zgowd6klUiMR2Qv2bXo27gLSAHxLIAAAAIAC1gES35Xj85N+1VGR5rQbRf99ft6Cz5Ml4nq1c936z9OCzYTbCaWG0yrHsuKyC7kHO2drsDLb6kER9H/dx+ryULWIsNOv8JQtLaxr+TRnb8SDNE6pObruCkTpSgKJx9/fng1qAsuYTvZCkEu3vkS/ug+BfrE/1peIzVxTUz/DWA==
+smaug.oob,smaug.oob.openstreetmap.org,146.179.159.182 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgwChQ2pg1oUTM4AXFt62Axn7aax+Hv2qH0gD6CiTXBWPE9xLnWtGg4mqql2YS+5T/2kesL/KSeFwt87Qm/oRmH7VRJjBXmvjzNt4mN+/1bUtKbZW2WxG+3FyFfImWZPmjKvvyCUyAlNeywzwlrta7b1oW+65ybl7bfDeVvnYFm+s5Uzv
+smaug.oob,smaug.oob.openstreetmap.org,146.179.159.182 ssh-dss AAAAB3NzaC1kc3MAAACBAKFVZwvyU6Gk6MlAolXVnW78ptpQQC4SKhBtSUPL+7wIcXciBMJpDRvE8ZqoylrgHwfXtWC2/jtZubLNo6yIB8z2bVGUKmLErMMWeitQilx7arJXnyFy73hpbGaWIvKrcShqmpdjE/Hm2OplntoZsjPAEk/mYxhv1v9311glbkYzAAAAFQD1BOL1Y4g8igXgeGFFu3xSsMvRjwAAAIBffhnEbEO7yJzXpjJO6ihPaOY5xOXH9ITOlYyWy/asBlCqYHybs6arK48TpNF5EI2RET0VWTF/Wne+RoQ/a45+iYJWRA6hZ/nXaU29GeoVx8eXKWIcJbqYXQs9lV2nQrDj2+2JJjZGQ/7RgBXgML4kA0tAL5sqCZozzrQKmSc5ugAAAIAh8gC56sMFU0qBTCU+CQumu84hvJCKpu56wE6bPQCEfPFXm2dREagkTUxnK30BDMn0rNjqijPlJQQey85TsLwFOP7ORdudbeL826IxH5pr3JPVeJbUX+2ENh0sITDdKsVTZFlFIbio9kzW2mIMsnbFv/c61Cm8vb0xpBLGehHjTQ==
+thorn-03.oob,thorn-03.oob.openstreetmap.org,146.179.159.183 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC2lg+yVQkBhInrhTGBkgMfzHG+hERBPQ8xIdO2FuA3wMbUoK+3bjK27jh6yxZnD4pID6+Qt27GAV/AsF/jLbJBpLiNKSnKJt5/7o2a11umG8zv/uEmDg6GxY3e0Oktx/CUwcpbLclSFzK62wWJ/Op094XtLv8LxwPVJCmzDPDLLw==
+thorn-03.oob,thorn-03.oob.openstreetmap.org,146.179.159.183 ssh-dss AAAAB3NzaC1kc3MAAACBAKL04XsUooNz/5dsdnui8ey97WwM59gXHk8dwrqQzUBtwK6dDSF3+6vA/jo7wZci+DOrpgaoO0CyEyQDwIfdbisNUqERLhfEODMeglI7V83ZmNisQDE/+ngZqbXVHjJBEcB+oq/3q8vLb/eYCtoX3m09aGpuVrgIQNIuUJhMPoVNAAAAFQCYBSkaK6eeBVw2IGpipXRZu9WWWQAAAIEAlSpeTcVOlKgueOXKRBgF8sAIUypO7ndH5VPxVRY5OXdWoUN9PnpqU55D+shPxR52dJYeHkc+UZlt2upCa1d7uF+ooXLYS58YfsT8lbED2a5Pt9GMSY1jLNx0aCfarT5S78Q+qs/uo+ZKoVtr4AcNCJWZnseBtVp9hClXCWGlnoYAAACABcXDatWgNRLLqCVgY3vxMlgdIN+K3Mr3IvUmtmETcpkdnNC2sE77LIjAhIWs4N4L+cgVrjlTY/dlrWKmFgi+8vBRaEbswSkxQ29tyPewCaQPoA32Yyvj4rUbn/FKI76+N1Wmnu1ZMhkdN6D+mmkGhO1LniWyoZtM96EOKGa9Q0Q=
+thorn-02.oob,thorn-02.oob.openstreetmap.org,146.179.159.184 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDhuldwYpGJ3GQJJO2b6E1x+wQmy05xBzBhaVE+pKdMarPzKFcp+tN4b01TgR4rO3ZN+TDnbN3NMWmrzPaiLOR+bwfoYSLExwsbEsamx3jSMxdCa6oRYVWXqsgDH2jVKi41iln924Hh62sxFZ4ag3CIgWmG/KLwWtakGeJ6HPcLOw==
+thorn-02.oob,thorn-02.oob.openstreetmap.org,146.179.159.184 ssh-dss AAAAB3NzaC1kc3MAAACBALjtcG0KeRcyPQVMb5sDVkQZmGJ0vPXP2QGo7Z7wRI/ZHnUbRRQqnZIpB7TYfjolfmCrjwCLYVGRxGalpiiHDcvGS7tg//GC+NpIDj1CHhegsvuE4r5Qz9FvnZoDLpabivc1POc57raO+xvfseveS1e305Pq2WXNNccIZ/29rJCLAAAAFQCrTQOFI0EqgyKv/WDC5ZmHsxi8nwAAAH8Kg4SpT0XNn6kgmOIjlGnN+XZkdYkbEbC4UcZZn6TPw5/RIVnMK7eF89bKmXI78gMCPSzPdbOib5IeIiDCh1g139/pNqgtB4YWMxmLRHIUUK6QpGIquUHQRIpWPQloQ3RZhsK94rFHPevc0vqviW93YAJ/wxXeV2rGKhY833NSAAAAgE+bEOKEUvfybzvihoW2HEBKHqXbBl1YVz7elKHDTiAfHbkIVz6FWZocOWCuTtC/p17s4D6B41bijRLTaFFrm2uZy9/LmaXNvsVivstW+vRIs2fh48wMVzcO0+xQy7cmx9S0Y2wFhw6ktzU6qBm+U456Kb0Rnoip9IDekNKTo3gI
+thorn-01.oob,thorn-01.oob.openstreetmap.org,146.179.159.185 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCkC6PhhG/n2V0kV0aDo+562Q0gDi/AyzCAIsAFqaVHwhOw0BSPpliM1xxmGGCjais6IKl2yMokd7kZmYCyZAWkXez2IGmgfqEqD1tn2B3ZOZlj8xPSFRPE3NMBzSJblxnQBIpKGMC29GwIdIx8fb7VvVjVX4qV1nOFGrOggZ+p0w==
+thorn-01.oob,thorn-01.oob.openstreetmap.org,146.179.159.185 ssh-dss AAAAB3NzaC1kc3MAAACBAKK2zumEfJ11s3Usrz6TXI7j5jWNgxjtQR+RVJDDUwy/EHv0Sl/AeUKGDWVZUdr64Qsyx/Iytk3UnKd32S60dzicVZJREo80g/PdGh3U90gavwp3SDoOBcC0ZoK97n/74Ihzctp59KeYcG4G8oi+8wmagXcgsz78Wu03FAd4fR85AAAAFQCWQykZ8rhSIbua6NULV5+Gi89gpQAAAIAed3RYLlPJDiKZTTLBWHC6UTSLCuhBbAkZERAId1tVp7sf+o+cte7Dqn2Ks9qv2mOFxVaUkyU2u21qEKt/4BqwpZJ+os82lZj9ic8Z/a49hzxNgra9YWWIR7p9HNUvU4M4byhpZ8IwOpB3U0jSUC4etccq3OyyBoyyZY0W+wgrKwAAAIAU4FGogVGZH6VuGB8h1DlIKl87vhxGjtRIExFEnMD2xprESnMm+T2ONedrgMIsW2zmzH/6zvWqYB1cpJTni/2D8v5n+v9GJXxv7BNC8UnCxq0npumyF86aTuGnJ3Q6pSqkCmsHwkqFUfenhsv6fLtsNBbIXN6uaLsFnkVcJYHJgQ==
+#horntail.oob,horntail.oob.openstreetmap.org,146.179.159.186 ssh-rsa
+#horntail.oob,horntail.oob.openstreetmap.org,146.179.159.186 ssh-dss
+spike-03.oob,spike-03.oob.openstreetmap.org,146.179.159.187 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/M0SONamzIz6VBPFDqZQZpRghKbyE+hx3ZWmdh4OSFPVNZUxkJ//3nLDHAgX+aoKMDM95d9+ayNKJk734m7IB2wJJIVR3OzLwpUXQnjaIBph/qUoHfdvo7i9z0FqXLipqHhmNg1vXTNXEho91x9CqURxhOLDic/lZYL0Q7HHQXQ==
+spike-03.oob,spike-03.oob.openstreetmap.org,146.179.159.187 ssh-dss AAAAB3NzaC1kc3MAAACBAK5n0UmW9LIzYgc44TAgTruOmkq7Z8IH11nrcDJmtDzQLSPa7INr8KHWcr/vv9V4LaCN3fdynboALyccQm+nCyCM+CjN88v+J6e/Rw+NFyhDfEYV7lbeJE0y5Kr4UxBMfQAterStoamot9LYTgv/mT44Th21XgO01SJeCi/JxkLBAAAAFQD/VuUC44I5iAErPd40R9oJoQKjJwAAAIBdbOxKn9FcFIxlAAGQxSsknl1E2+plNemx45SS8JT1+pcfah7GLMxxOfmY+VCaHkpy1986ksxurnGbDbeHdQhIHRoRsLYekpSqwXAc7BLqjcO5kkbTGvc9UQB1fv6oEichXj4z0MML571y6IeLDTE7+pVAlxPwVLlx88gI1QV2DwAAAIBfM8sjf33slO17K+jxMYo+D9HEHs5tGn1Q6KbsgiwdTS55nelgBBXJXI2Aqlr0oW5dRGqbCxVA0SnbIqcwEx1NB5viI8WWkOn/n69wkPChk2QfGC/KjMCAdC6I72+WjpeF58V94OTL+0jjDyVvqmPt44G5xqywsdHkULreGo1T0w==
+spike-01.oob,spike-01.oob.openstreetmap.org,146.179.159.188 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDKqLGH1yu5FxWtzTsq0MvNvUowBJEzuBZscbIuzVidZV4zkz9pk7LUrmRGkCZ6xIsNZCEe8LUnOwLTdxz9ONmr8y4fCAZF7nKJhFW4Y37fom9byip8lrx3NbzCMNqLt34J8w4Pe/SFBJJqkPTkMeXKsb2N/IRRq7G8NJx9reHhLw==
+spike-01.oob,spike-01.oob.openstreetmap.org,146.179.159.188 ssh-dss AAAAB3NzaC1kc3MAAACBAKCyRz57Ky0tIwgFWnzn9b9Jb8gmdhnTlWKNxmjWrrVXOCzuFzGhxoslZFQI/1GMC+AlpuzZ4txwHjpRlBmoHQb0XVma7vbx44yAUDa0L9Y3UNmm9xIGPADWiEd8wXeBvfNw1060Fo/4rxKUJYP/1rPD/oGo85OPn9V0fWkTQhfNAAAAFQD0hnMolxEMPEkOf0SX/7ufWYQowwAAAIA4nWigIQmWCAAyL22L7lbVh042LIyiafPKyZBj4cXLvWwJT082oh50u7+RBwlNpTbw6hRQ8FUmqoBdTuSitXCX03LM4uLsgWQR0RYZEad7VVXSKWfChMvm63QNG8dB7VycwmApw9HaoHedW6KmZkrg2CEJaCnEH1sh5zSYQP2yUgAAAIAKD/05Kkq2IEQHR/6TtQX7yv30oz1MRG5nGxS+bWaz3e2i+k+1h64xPRK0EWZ3/U/2RmNYRe+oPXtzINTiodS4RovClxWSIKvt97N/0WQo5IX3k4gdfyjYO/33bOsrnPYyKWYt13E/4D2/hzSiAQCaB+1OJvJt+ScnpqC83qRJrg==
diff --git a/cookbooks/ssl/README.rdoc b/cookbooks/ssl/README.rdoc
new file mode 100644 (file)
index 0000000..3de2ec7
--- /dev/null
@@ -0,0 +1,8 @@
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
diff --git a/cookbooks/ssl/files/default/openstreetmap.pem b/cookbooks/ssl/files/default/openstreetmap.pem
new file mode 100644 (file)
index 0000000..e77c1b5
--- /dev/null
@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE-----
+MIIE7TCCA9WgAwIBAgIDBTEhMA0GCSqGSIb3DQEBBQUAMDwxCzAJBgNVBAYTAlVT
+MRcwFQYDVQQKEw5HZW9UcnVzdCwgSW5jLjEUMBIGA1UEAxMLUmFwaWRTU0wgQ0Ew
+HhcNMTIwMjEzMTU1MjUzWhcNMTYwMzE3MDUyMTU0WjCB7TEpMCcGA1UEBRMgRGl5
+enNGaXBZN3cvUFZpRnRkTTZnYmVzSi10Ri1PR3kxCzAJBgNVBAYTAkdCMRwwGgYD
+VQQKDBMqLm9wZW5zdHJlZXRtYXAub3JnMRMwEQYDVQQLEwpHVDMzMDQ0NTc4MTEw
+LwYDVQQLEyhTZWUgd3d3LnJhcGlkc3NsLmNvbS9yZXNvdXJjZXMvY3BzIChjKTEy
+MS8wLQYDVQQLEyZEb21haW4gQ29udHJvbCBWYWxpZGF0ZWQgLSBSYXBpZFNTTChS
+KTEcMBoGA1UEAwwTKi5vcGVuc3RyZWV0bWFwLm9yZzCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBANU6sWaRrWjggM2InAcwYh1HPKv6girYmCDM05WHh3av
+3wRLyG+kwGy5WMhdVX8Dq6dh0JicgKRFlgvtEdAfeoqFSVQmP6Fs9pyK3Zshu+zF
+KDAdHapeCvu/YCBRAubGwpENU/06hhaH7fw/QiCURWNrr8dziIlnvgw8E9Uzv8QX
+4k7qVGvgrNnvcrFtN/pS2cVZ6Cb5HVOguohWroLUlFrw0mTKaJeskmIadlfZtZgt
+cFzTbKXR+zVN5+PjGXv4vqRYBpTLs1C0ob1RDjbMHyo7mm/cIqswSsyMVCtVQ5b7
+T2xegsNSxMWO4IThnsg2agLZavegb+9YTcVXeWSeCckCAwEAAaOCAUQwggFAMB8G
+A1UdIwQYMBaAFGtpPWoYQkrdjwJlOf01JIZ4kRYwMA4GA1UdDwEB/wQEAwIFoDAd
+BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMQYDVR0RBCowKIITKi5vcGVu
+c3RyZWV0bWFwLm9yZ4IRb3BlbnN0cmVldG1hcC5vcmcwQwYDVR0fBDwwOjA4oDag
+NIYyaHR0cDovL3JhcGlkc3NsLWNybC5nZW90cnVzdC5jb20vY3Jscy9yYXBpZHNz
+bC5jcmwwHQYDVR0OBBYEFADUJB8wbdTqKniWijZ5R3Rvlu9PMAwGA1UdEwEB/wQC
+MAAwSQYIKwYBBQUHAQEEPTA7MDkGCCsGAQUFBzAChi1odHRwOi8vcmFwaWRzc2wt
+YWlhLmdlb3RydXN0LmNvbS9yYXBpZHNzbC5jcnQwDQYJKoZIhvcNAQEFBQADggEB
+ADX+eCfhwcP8yzyyDpFx6QFKU8XjUPiKT25XptcwA+FlTWH7C19+qLAY3lp41bZY
+hwVYJw05QSIot3VCbE0HbCuRiHSL5WTG2PwC18/wzHY6PnseibmqucldSDKnm7Cd
+/BzI5FcTvzVQ7EfoHexopwyUd1mr22bOlwc8Q4tw3V8dB+mIy+sOECVkiLHXWQkF
+4ylCgP4rIuOPl6vb+06hvq5//5kk55aXeGNY6IzG8V4/q8FOXbulsXbNck+uG+h2
+34rfKi1t0MPzbiX/kzIVCDNiH6RynswxxZbETx/IpzOqYv2vmhMX0MZcF5Hrq17E
+L/NPczD7d4S2DwJkonkOTX4=
+-----END CERTIFICATE-----
diff --git a/cookbooks/ssl/files/default/rapidssl.pem b/cookbooks/ssl/files/default/rapidssl.pem
new file mode 100644 (file)
index 0000000..b8232d2
--- /dev/null
@@ -0,0 +1,44 @@
+-----BEGIN CERTIFICATE-----
+MIID1TCCAr2gAwIBAgIDAjbRMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
+MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
+YWwgQ0EwHhcNMTAwMjE5MjI0NTA1WhcNMjAwMjE4MjI0NTA1WjA8MQswCQYDVQQG
+EwJVUzEXMBUGA1UEChMOR2VvVHJ1c3QsIEluYy4xFDASBgNVBAMTC1JhcGlkU1NM
+IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx3H4Vsce2cy1rfa0
+l6P7oeYLUF9QqjraD/w9KSRDxhApwfxVQHLuverfn7ZB9EhLyG7+T1cSi1v6kt1e
+6K3z8Buxe037z/3R5fjj3Of1c3/fAUnPjFbBvTfjW761T4uL8NpPx+PdVUdp3/Jb
+ewdPPeWsIcHIHXro5/YPoar1b96oZU8QiZwD84l6pV4BcjPtqelaHnnzh8jfyMX8
+N8iamte4dsywPuf95lTq319SQXhZV63xEtZ/vNWfcNMFbPqjfWdY3SZiHTGSDHl5
+HI7PynvBZq+odEj7joLCniyZXHstXZu8W1eefDp6E63yoxhbK1kPzVw662gzxigd
+gtFQiwIDAQABo4HZMIHWMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUa2k9ahhC
+St2PAmU5/TUkhniRFjAwHwYDVR0jBBgwFoAUwHqYaI2J+6sFZAwRfap9ZbjKzE4w
+EgYDVR0TAQH/BAgwBgEB/wIBADA6BgNVHR8EMzAxMC+gLaArhilodHRwOi8vY3Js
+Lmdlb3RydXN0LmNvbS9jcmxzL2d0Z2xvYmFsLmNybDA0BggrBgEFBQcBAQQoMCYw
+JAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmdlb3RydXN0LmNvbTANBgkqhkiG9w0B
+AQUFAAOCAQEAq7y8Cl0YlOPBscOoTFXWvrSY8e48HM3P8yQkXJYDJ1j8Nq6iL4/x
+/torAsMzvcjdSCIrYA+lAxD9d/jQ7ZZnT/3qRyBwVNypDFV+4ZYlitm12ldKvo2O
+SUNjpWxOJ4cl61tt/qJ/OCjgNqutOaWlYsS3XFgsql0BYKZiZ6PAx2Ij9OdsRu61
+04BqIhPSLT90T+qvjF+0OJzbrs6vhB6m9jRRWXnT43XcvNfzc9+S7NIgWW+c+5X4
+knYYCnwPLKbK3opie9jzzl9ovY8+wXS7FXI6FoOpC+ZNmZzYV+yoAVHHb1c0XqtK
+LEL2TxyJeN4mTvVvk0wVaydWTQBUbHq3tw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
+MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
+aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDIwNTIxMDQwMDAwWhcNMTgwODIxMDQwMDAw
+WjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE
+AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9m
+OSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIu
+T8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6c
+JmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmR
+Cw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5asz
+PeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo4HwMIHtMB8GA1UdIwQYMBaAFEjm
+aPkr0rKV10fYIyAQTzOYkJ/UMB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrM
+TjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA6BgNVHR8EMzAxMC+g
+LaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL3NlY3VyZWNhLmNybDBO
+BgNVHSAERzBFMEMGBFUdIAAwOzA5BggrBgEFBQcCARYtaHR0cHM6Ly93d3cuZ2Vv
+dHJ1c3QuY29tL3Jlc291cmNlcy9yZXBvc2l0b3J5MA0GCSqGSIb3DQEBBQUAA4GB
+AHbhEm5OSxYShjAGsoEIz/AIx8dxfmbuwu3UOx//8PDITtZDOLC5MH0Y0FWDomrL
+NhGc6Ehmo21/uBPUR/6LWlxz/K7ZGzIZOKuXNBSqltLroxwUCEm2u+WR74M26x1W
+b8ravHNjkOR/ez4iyz0H7V84dJzjA1BOoa+Y7mHyhD8S
+-----END CERTIFICATE-----
diff --git a/cookbooks/ssl/metadata.rb b/cookbooks/ssl/metadata.rb
new file mode 100644 (file)
index 0000000..ef83cb3
--- /dev/null
@@ -0,0 +1,6 @@
+maintainer        "OpenStreetMap Administrators"
+maintainer_email  "admins@openstreetmap.org"
+license           "Apache 2.0"
+description       "Installs and configures basic SSL support"
+long_description  IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
+version           "1.0.0"
diff --git a/cookbooks/ssl/recipes/default.rb b/cookbooks/ssl/recipes/default.rb
new file mode 100644 (file)
index 0000000..4bbcea4
--- /dev/null
@@ -0,0 +1,45 @@
+#
+# Cookbook Name:: ssl
+# Recipe:: default
+#
+# Copyright 2011, OpenStreetMap Foundation
+#
+# 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.
+#
+
+keys = data_bag_item("ssl", "keys")
+
+package "openssl"
+package "ssl-cert"
+
+cookbook_file "/etc/ssl/certs/rapidssl.pem" do
+  owner "root"
+  group "root"
+  mode 0444
+  backup false
+end
+
+cookbook_file "/etc/ssl/certs/openstreetmap.pem" do
+  owner "root"
+  group "root"
+  mode 0444
+  backup false
+end
+
+file "/etc/ssl/private/openstreetmap.key" do
+  owner "root"
+  group "ssl-cert"
+  mode 0440
+  content keys["openstreetmap"].join("\n")
+  backup false
+end
diff --git a/cookbooks/stateofthemap/README.rdoc b/cookbooks/stateofthemap/README.rdoc
new file mode 100644 (file)
index 0000000..3de2ec7
--- /dev/null
@@ -0,0 +1,8 @@
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
diff --git a/cookbooks/stateofthemap/metadata.rb b/cookbooks/stateofthemap/metadata.rb
new file mode 100644 (file)
index 0000000..68ef2ed
--- /dev/null
@@ -0,0 +1,7 @@
+maintainer        "OpenStreetMap Administrators"
+maintainer_email  "admins@openstreetmap.org"
+license           "Apache 2.0"
+description       "Installs and configures State of the Map services"
+long_description  IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
+version           "1.0.0"
+depends           "wordpress"
diff --git a/cookbooks/stateofthemap/recipes/default.rb b/cookbooks/stateofthemap/recipes/default.rb
new file mode 100644 (file)
index 0000000..49349a9
--- /dev/null
@@ -0,0 +1,230 @@
+#
+# Cookbook Name:: stateofthemap
+# Recipe:: default
+#
+# Copyright 2013, OpenStreetMap Foundation
+#
+# 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.
+#
+
+include_recipe "wordpress"
+
+passwords = data_bag_item("stateofthemap", "passwords")
+
+directory "/srv/2007.stateofthemap.org" do
+  owner "wordpress"
+  group "wordpress"
+  mode 0755
+end
+
+wordpress_site "2007.stateofthemap.org" do
+  aliases "2007.stateofthemap.com"
+  directory "/srv/2007.stateofthemap.org/wp"
+  database_name "sotm2007"
+  database_user "sotm2007"
+  database_password passwords["sotm2007"]
+  database_prefix "wp_sotm_"
+end
+
+wordpress_theme "refreshwp-11" do
+  site "2007.stateofthemap.org"
+  repository "git://git.openstreetmap.org/stateofthemap.git"
+  revision "theme-2007"
+end
+
+wordpress_plugin "geopress" do
+  site "2007.stateofthemap.org"
+end
+
+wordpress_plugin "sem-static-front" do
+  site "2007.stateofthemap.org"
+  source "plugins/sem-static-front"
+end
+
+directory "/srv/2008.stateofthemap.org" do
+  owner "wordpress"
+  group "wordpress"
+  mode 0755
+end
+
+wordpress_site "2008.stateofthemap.org" do
+  aliases "2008.stateofthemap.com"
+  directory "/srv/2008.stateofthemap.org/wp"
+  database_name "sotm2008"
+  database_user "sotm2008"
+  database_password passwords["sotm2008"]
+  database_prefix "wp_sotm08_"
+end
+
+wordpress_theme "refreshwp-11" do
+  site "2008.stateofthemap.org"
+  repository "git://git.openstreetmap.org/stateofthemap.git"
+  revision "theme-2008"
+end
+
+wordpress_plugin "geopress" do
+  site "2008.stateofthemap.org"
+end
+
+directory "/srv/2009.stateofthemap.org" do
+  owner "wordpress"
+  group "wordpress"
+  mode 0755
+end
+
+git "/srv/2009.stateofthemap.org" do
+  action :sync
+  repository "git://git.openstreetmap.org/stateofthemap.git"
+  revision "resources-2009"
+  user "wordpress"
+  group "wordpress"
+end
+
+wordpress_site "2009.stateofthemap.org" do
+  aliases "2009.stateofthemap.com"
+  directory "/srv/2009.stateofthemap.org/wp"
+  database_name "sotm2009"
+  database_user "sotm2009"
+  database_password passwords["sotm2009"]
+  urls "/register" => "/srv/2009.stateofthemap.org/register",
+       "/register-pro-user" => "/srv/2009.stateofthemap.org/register-pro-user",
+       "/podcasts" => "/srv/2009.stateofthemap.org/podcasts"
+end
+
+wordpress_theme "aerodrome" do
+  site "2009.stateofthemap.org"
+  repository "git://git.openstreetmap.org/stateofthemap.git"
+  revision "theme-2009"
+end
+
+wordpress_plugin "wp-sticky" do
+  site "2009.stateofthemap.org"
+end
+
+directory "/srv/2010.stateofthemap.org" do
+  owner "wordpress"
+  group "wordpress"
+  mode 0755
+end
+
+git "/srv/2010.stateofthemap.org" do
+  action :sync
+  repository "git://git.openstreetmap.org/stateofthemap.git"
+  revision "resources-2010"
+  user "wordpress"
+  group "wordpress"
+end
+
+wordpress_site "2010.stateofthemap.org" do
+  aliases "2010.stateofthemap.com"
+  directory "/srv/2010.stateofthemap.org/wp"
+  database_name "sotm2010"
+  database_user "sotm2010"
+  database_password passwords["sotm2010"]
+  urls "/register" => "/srv/2010.stateofthemap.org/register"
+end
+
+wordpress_theme "aerodrome" do
+  site "2010.stateofthemap.org"
+  repository "git://git.openstreetmap.org/stateofthemap.git"
+  revision "theme-2010"
+end
+
+wordpress_plugin "sitepress-multilingual-cms" do
+  site "2010.stateofthemap.org"
+  source "plugins/sitepress-multilingual-cms"
+end
+
+wordpress_plugin "wp-sticky" do
+  site "2010.stateofthemap.org"
+end
+
+directory "/srv/2011.stateofthemap.org" do
+  owner "wordpress"
+  group "wordpress"
+  mode 0755
+end
+
+git "/srv/2011.stateofthemap.org" do
+  action :sync
+  repository "git://git.openstreetmap.org/stateofthemap.git"
+  revision "resources-2011"
+  user "wordpress"
+  group "wordpress"
+end
+
+wordpress_site "2011.stateofthemap.org" do
+  aliases "2011.stateofthemap.com"
+  directory "/srv/2011.stateofthemap.org/wp"
+  database_name "sotm2011"
+  database_user "sotm2011"
+  database_password passwords["sotm2011"]
+  urls "/register" => "/srv/2011.stateofthemap.org/register"
+end
+
+wordpress_theme "aerodrome" do
+  site "2011.stateofthemap.org"
+  repository "git://git.openstreetmap.org/stateofthemap.git"
+  revision "theme-2011"
+end
+
+wordpress_plugin "sitepress-multilingual-cms" do
+  site "2011.stateofthemap.org"
+  source "plugins/sitepress-multilingual-cms"
+end
+
+wordpress_plugin "wp-sticky" do
+  site "2011.stateofthemap.org"
+end
+
+directory "/srv/2012.stateofthemap.org" do
+  owner "wordpress"
+  group "wordpress"
+  mode 0755
+end
+
+git "/srv/2012.stateofthemap.org" do
+  action :sync
+  repository "git://git.openstreetmap.org/stateofthemap.git"
+  revision "resources-2012"
+  user "wordpress"
+  group "wordpress"
+end
+
+wordpress_site "2012.stateofthemap.org" do
+  aliases "2012.stateofthemap.com"
+  directory "/srv/2012.stateofthemap.org/wp"
+  database_name "sotm2012"
+  database_user "sotm2012"
+  database_password passwords["sotm2012"]
+  urls "/register" => "/srv/2012.stateofthemap.org/register"
+end
+
+wordpress_theme "aerodrome" do
+  site "2012.stateofthemap.org"
+  repository "git://git.openstreetmap.org/stateofthemap.git"
+  revision "theme-2012"
+end
+
+wordpress_plugin "leaflet-maps-marker" do
+  site "2012.stateofthemap.org"
+end
+
+wordpress_plugin "sitepress-multilingual-cms" do
+  site "2012.stateofthemap.org"
+  source "plugins/sitepress-multilingual-cms"
+end
+
+wordpress_plugin "wp-sticky" do
+  site "2012.stateofthemap.org"
+end
diff --git a/cookbooks/sysctl/README.rdoc b/cookbooks/sysctl/README.rdoc
new file mode 100644 (file)
index 0000000..3de2ec7
--- /dev/null
@@ -0,0 +1,8 @@
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
diff --git a/cookbooks/sysctl/metadata.rb b/cookbooks/sysctl/metadata.rb
new file mode 100644 (file)
index 0000000..d1342a1
--- /dev/null
@@ -0,0 +1,15 @@
+maintainer       "Tom Hughes"
+maintainer_email "tom@compton.nu"
+license          "Apache 2.0"
+description      "Configures kernel parameters"
+long_description IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
+version          "0.1"
+%w{redhat centos debian ubuntu}.each do |os|
+  supports os
+end
+recipe           "sysctl", "Configure kernel parameters"
+
+attribute "sysctl",
+  :display_name => "Kernel Parameters",
+  :description => "Hash of kernel parameter groups",
+  :type => "hash"
diff --git a/cookbooks/sysctl/recipes/default.rb b/cookbooks/sysctl/recipes/default.rb
new file mode 100644 (file)
index 0000000..58e86f9
--- /dev/null
@@ -0,0 +1,60 @@
+#
+# Cookbook Name:: sysctl
+# Recipe:: default
+#
+# Copyright 2010, Tom Hughes
+#
+# 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.
+#
+
+package "procps" do
+  action :install
+end
+
+if node[:lsb][:release].to_f <= 8.04
+  sysctl_template = "sysctl.conf.erb"
+  sysctl_conf = "/etc/sysctl.conf"
+else
+  directory "/etc/sysctl.d" do
+    owner "root"
+    group "root"
+    mode 0755
+  end
+
+  sysctl_template = "chef.conf.erb"
+  sysctl_conf = "/etc/sysctl.d/60-chef.conf"
+end
+
+execute "sysctl" do
+  action :nothing
+  command "/sbin/sysctl -p #{sysctl_conf}"
+end
+
+template sysctl_conf do
+  source sysctl_template
+  owner "root"
+  group "root"
+  mode 0644
+  notifies :run, resources(:execute => "sysctl")
+end
+
+node[:sysctl].each_value do |group|
+  group[:parameters].each do |key,value|
+    sysctl_file = "/proc/sys/#{key.gsub('.', '/')}"
+
+    file sysctl_file do
+      content "#{value}\n"
+      only_if { File.exists?(sysctl_file) }
+    end
+  end
+end
diff --git a/cookbooks/sysctl/templates/default/chef.conf.erb b/cookbooks/sysctl/templates/default/chef.conf.erb
new file mode 100644 (file)
index 0000000..991664f
--- /dev/null
@@ -0,0 +1,8 @@
+# DO NOT EDIT - This file is being maintained by Chef
+<% node[:sysctl].each do |name,group| -%>
+
+# <%= group[:comment] %>
+<% group[:parameters].each do |key,value| -%>
+<%= key %> = <%= value %>
+<% end -%>
+<% end -%>
diff --git a/cookbooks/sysctl/templates/default/sysctl.conf.erb b/cookbooks/sysctl/templates/default/sysctl.conf.erb
new file mode 100644 (file)
index 0000000..0172a43
--- /dev/null
@@ -0,0 +1,30 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+# Stop low-level messages on console
+kernel.printk = 4 4 1 7
+
+# Enable /proc/$pid/maps privacy so that memory relocations are not
+# visible to other users.  (Added in kernel 2.6.22.)
+kernel.maps_protect = 1
+
+# Protect the zero page of memory from userspace mmap to prevent kernel
+# NULL-dereference attacks against potential future kernel security
+# vulnerabilities.  (Added in kernel 2.6.23.)
+#
+# While this default is built into the Ubuntu kernel, there is no way to
+# restore the kernel default if the value is changed during runtime; for
+# example via package removal (e.g. wine, dosemu).  Therefore, this value
+# is reset to the secure default each time the sysctl values are loaded.
+vm.mmap_min_addr = 65536
+
+# Turn on Source Address Verification in all interfaces to
+# prevent some spoofing attacks.
+net.ipv4.conf.default.rp_filter = 1
+net.ipv4.conf.all.rp_filter = 1
+<% node[:sysctl].each do |name,group| -%>
+
+# <%= group[:comment] %>
+<% group[:parameters].each do |key,value| -%>
+<%= key %> = <%= value %>
+<% end -%>
+<% end -%>
diff --git a/cookbooks/sysfs/README.rdoc b/cookbooks/sysfs/README.rdoc
new file mode 100644 (file)
index 0000000..3de2ec7
--- /dev/null
@@ -0,0 +1,8 @@
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
diff --git a/cookbooks/sysfs/attributes/default.rb b/cookbooks/sysfs/attributes/default.rb
new file mode 100644 (file)
index 0000000..000af72
--- /dev/null
@@ -0,0 +1 @@
+default[:sysfs] = {}
diff --git a/cookbooks/sysfs/metadata.rb b/cookbooks/sysfs/metadata.rb
new file mode 100644 (file)
index 0000000..a31243e
--- /dev/null
@@ -0,0 +1,6 @@
+maintainer       "Tom Hughes"
+maintainer_email "tom@compton.nu"
+license          "Apache 2.0"
+description      "Configures kernel parameters"
+long_description IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
+version          "1.0.0"
diff --git a/cookbooks/sysfs/recipes/default.rb b/cookbooks/sysfs/recipes/default.rb
new file mode 100644 (file)
index 0000000..c6eb15f
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# Cookbook Name:: sysfs
+# Recipe:: default
+#
+# Copyright 2013, Tom Hughes
+#
+# 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.
+#
+
+package "sysfsutils"
+
+service "sysfsutils" do
+  action :enable
+  supports :status => false, :restart => true, :reload => false
+end
+
+template "/etc/sysfs.conf" do
+  source "sysfs.conf.erb"
+  owner "root"
+  group "root"
+  mode 0644
+  notifies :restart, resources(:service => "sysfsutils")
+end
diff --git a/cookbooks/sysfs/templates/default/sysfs.conf.erb b/cookbooks/sysfs/templates/default/sysfs.conf.erb
new file mode 100644 (file)
index 0000000..95519e8
--- /dev/null
@@ -0,0 +1,8 @@
+# DO NOT EDIT - This file is being maintained by Chef
+<% node[:sysfs].each do |name,group| -%>
+
+# <%= group[:comment] %>
+<% group[:parameters].each do |key,value| -%>
+<%= key %> = <%= value %>
+<% end -%>
+<% end -%>
diff --git a/cookbooks/tools/README.rdoc b/cookbooks/tools/README.rdoc
new file mode 100644 (file)
index 0000000..3de2ec7
--- /dev/null
@@ -0,0 +1,8 @@
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
diff --git a/cookbooks/tools/libraries/content_from_file.rb b/cookbooks/tools/libraries/content_from_file.rb
new file mode 100644 (file)
index 0000000..d8d0fe7
--- /dev/null
@@ -0,0 +1,22 @@
+class Chef
+  class Resource
+    class File
+      def content_from_file(file, &block)
+        @content_file = file
+        @content_block = block
+      end
+
+      def content(text = nil)
+        if text
+          @content = text
+        elsif @content
+          @content
+        elsif @content_file
+          ::File.new(@content_file).collect do |line|
+            line = @content_block.call(line)
+          end.join("")
+        end
+      end
+    end
+  end
+end
diff --git a/cookbooks/tools/libraries/random_password.rb b/cookbooks/tools/libraries/random_password.rb
new file mode 100644 (file)
index 0000000..f8c6674
--- /dev/null
@@ -0,0 +1,9 @@
+class Chef
+  class Recipe
+    def random_password(length)
+      length.times.collect do
+        "!\#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~"[rand(91)].chr
+      end.join
+    end
+  end
+end
diff --git a/cookbooks/tools/metadata.rb b/cookbooks/tools/metadata.rb
new file mode 100644 (file)
index 0000000..49e3d87
--- /dev/null
@@ -0,0 +1,6 @@
+maintainer        "OpenStreetMap Administrators"
+maintainer_email  "admins@openstreetmap.org"
+license           "Apache 2.0"
+description       "Installs system administration tools"
+long_description  IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
+version           "1.0.0"
diff --git a/cookbooks/tools/recipes/default.rb b/cookbooks/tools/recipes/default.rb
new file mode 100644 (file)
index 0000000..432f0fd
--- /dev/null
@@ -0,0 +1,42 @@
+#
+# Cookbook Name:: tools
+# Recipe:: default
+#
+# Copyright 2011, OpenStreetMap Foundation
+#
+# 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.
+#
+
+package "bash-completion"
+package "dmidecode"
+package "ethtool"
+package "lsof"
+package "lsscsi"
+package "pciutils"
+package "screen"
+package "smartmontools"
+package "strace"
+package "sysstat"
+package "tcpdump"
+package "usbutils"
+package "numactl"
+package "xfsprogs"
+package "sysv-rc-conf"
+
+if node[:lsb][:release].to_f >= 10.04
+  package "iotop"
+end
+
+if node[:lsb][:release].to_f <= 11.04
+  package "lslk"
+end
diff --git a/cookbooks/trac/README.rdoc b/cookbooks/trac/README.rdoc
new file mode 100644 (file)
index 0000000..3de2ec7
--- /dev/null
@@ -0,0 +1,8 @@
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
diff --git a/cookbooks/trac/files/default/htdocs/osm.ico b/cookbooks/trac/files/default/htdocs/osm.ico
new file mode 100644 (file)
index 0000000..4448dd6
Binary files /dev/null and b/cookbooks/trac/files/default/htdocs/osm.ico differ
diff --git a/cookbooks/trac/files/default/htdocs/osm.png b/cookbooks/trac/files/default/htdocs/osm.png
new file mode 100644 (file)
index 0000000..abce19d
Binary files /dev/null and b/cookbooks/trac/files/default/htdocs/osm.png differ
diff --git a/cookbooks/trac/files/default/htdocs/robots.txt b/cookbooks/trac/files/default/htdocs/robots.txt
new file mode 100644 (file)
index 0000000..876457d
--- /dev/null
@@ -0,0 +1,5 @@
+#Trac really does not handle well being scraped.
+User-agent: *
+Disallow: /changeset
+Disallow: /changeset/
+Disallow: /wiki/
diff --git a/cookbooks/trac/files/default/templates/site.html b/cookbooks/trac/files/default/templates/site.html
new file mode 100644 (file)
index 0000000..6360c4a
--- /dev/null
@@ -0,0 +1,47 @@
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:py="http://genshi.edgewall.org/" py:strip="">
+
+  <form py:match="div[@id='content' and @class='ticket']/form" py:attrs="select('@*')">
+    <py:if test="req.environ['PATH_INFO'] == '/newticket' and (not 'preview' in req.args)">
+      <p>Before opening a new ticket, please:</p>
+      <ol>
+        <li>Check that you're in the right place. This is the bug-tracker for many OpenStreetMap related projects but not everything uses this site, so check the following list to make sure there isn't a better place to raise your issue:
+          <ul>
+            <li>Raise JOSM issues <a href="http://josm.openstreetmap.de/">here</a>.</li>
+            <li>Raise JXAPI issues <a href="https://github.com/iandees/xapi-servlet/issues">here</a>.</li>
+          </ul>
+        </li>
+        <li><a href="/report/1?sort=created&amp;asc=1">View the list of tickets</a> to make sure that your bug hasn't already been reported. You should also try <a href="/search">searching</a>.</li>
+        <li>Enter your bug descriptively. <i>Be sure you set the 'component' field (e.g. "website" or "potlatch (Flash editor)") so that it goes to the right person</i></li>
+      </ol>
+      <p>You can also use this to request enhancements.</p>
+      <h2>How to be a helpful bug reporter</h2>
+      <p>Where you can, always provide "steps to reproduce" - in other words, a series of instructions that the developers can follow to reproduce your bug. The more you can do to pinpoint the problem, the more likely it'll be fixed.</p>
+      <ol>
+        <li>Give any pertinent details of your system (operating system and version, browser and version, etc.).</li>
+        <li>If the problem is with a web page or web application, give its URL. If the problem is encountered with a particular set of data, say what (e.g. a location in <a class="wiki" href="/wiki/OpenStreetMap">OpenStreetMap</a>).</li>
+        <li>Explain what you are doing, click-by-click.</li>
+        <li>Explain what you expect to happen.</li>
+        <li>Explain what is happening instead.</li>
+      </ol>
+      <script type="text/javascript">
+        $(document).ready(function () {
+          var c = document.createElement("option");
+          $(c).attr("selected", "selected");
+          $("#field-component").prepend(c);
+
+          $("#propertyform").submit(function () {
+            if ($("#field-component").val() == "") {
+              alert("Please select a component!");
+              return false;
+            } else {
+              return true;
+            }
+          });
+        });
+      </script>
+    </py:if>
+    ${select('*')} 
+  </form>
+
+</html>
diff --git a/cookbooks/trac/files/default/trac-authenticate b/cookbooks/trac/files/default/trac-authenticate
new file mode 100755 (executable)
index 0000000..cfd33e7
--- /dev/null
@@ -0,0 +1,15 @@
+#!/usr/bin/ruby
+
+require "net/http"
+require "uri"
+
+user = gets.chop
+pass = gets.chop
+
+request = Net::HTTP::Get.new("/api/0.6/user/details")
+request.basic_auth user, pass
+
+response = Net::HTTP.new("api.openstreetmap.org").request(request)
+
+exit!(0) if response.kind_of?(Net::HTTPSuccess)
+exit!(1)
diff --git a/cookbooks/trac/metadata.rb b/cookbooks/trac/metadata.rb
new file mode 100644 (file)
index 0000000..cf417b9
--- /dev/null
@@ -0,0 +1,7 @@
+maintainer        "OpenStreetMap Administrators"
+maintainer_email  "admins@openstreetmap.org"
+license           "Apache 2.0"
+description       "Installs and configures trac servers"
+long_description  IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
+version           "1.0.0"
+depends           "apache"
diff --git a/cookbooks/trac/recipes/default.rb b/cookbooks/trac/recipes/default.rb
new file mode 100644 (file)
index 0000000..70213e8
--- /dev/null
@@ -0,0 +1,85 @@
+#
+# Cookbook Name:: trac
+# Recipe:: default
+#
+# Copyright 2012, OpenStreetMap Foundation
+#
+# 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.
+#
+
+include_recipe "apache::ssl"
+
+package "trac"
+package "trac-git"
+package "ruby"
+
+site_name = "trac.openstreetmap.org"
+site_directory = "/srv/#{site_name}"
+
+template "/var/lib/trac/conf/trac.ini" do
+  source "trac.ini.erb"
+  owner "trac"
+  group "www-data"
+  mode 0644
+  variables :name => site_name
+end
+
+remote_directory "/var/lib/trac/htdocs" do
+  source "htdocs"
+  owner "trac"
+  group "trac"
+  mode 0755
+  files_owner "trac"
+  files_group "trac"
+  files_mode 0644
+  purge true
+end
+
+remote_directory "/var/lib/trac/templates" do
+  source "templates"
+  owner "trac"
+  group "trac"
+  mode 0755
+  files_owner "trac"
+  files_group "trac"
+  files_mode 0644
+  purge true
+end
+
+execute "trac-deploy-#{site_name}" do
+  command "trac-admin /var/lib/trac deploy #{site_directory}"
+  user "root"
+  group "root"
+  not_if { File.exists?(site_directory) }
+end
+
+cookbook_file "/usr/local/bin/trac-authenticate" do
+  owner "root"
+  group "root"
+  mode 0755
+end
+
+apache_module "wsgi"
+
+apache_site site_name do
+  template "apache.erb"
+  directory site_directory
+  variables :user => "trac", :group => "trac"
+end
+
+template "/etc/sudoers.d/trac" do
+  source "sudoers.erb"
+  owner "root"
+  group "root"
+  mode 0440
+end
diff --git a/cookbooks/trac/templates/default/apache.erb b/cookbooks/trac/templates/default/apache.erb
new file mode 100644 (file)
index 0000000..eb53ae7
--- /dev/null
@@ -0,0 +1,39 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+WSGIDaemonProcess <%= @name %> user=<%= @user %> group=<%= @group %> maximum-requests=5000 threads=25 inactivity-timeout=180
+
+<VirtualHost *:80>
+        ServerName <%= @name %>
+        ServerAdmin webmaster@openstreetmap.org
+
+        CustomLog /var/log/apache2/<%= @name %>-access.log combined
+        ErrorLog /var/log/apache2/<%= @name %>-error.log
+
+        RedirectPermanent / https://<%= @name %>/
+</VirtualHost>
+
+<VirtualHost *:443>
+        ServerName <%= @name %>
+        ServerAdmin webmaster@openstreetmap.org
+
+        CustomLog /var/log/apache2/<%= @name %>-access.log combined
+        ErrorLog /var/log/apache2/<%= @name %>-error.log
+
+        DocumentRoot <%= @directory %>/htdocs
+       Alias /robots.txt <%= @directory %>/htdocs/site/robots.txt
+        WSGIScriptAlias / <%= @directory %>/cgi-bin/trac.wsgi
+
+        WSGIProcessGroup <%= @name %>
+
+       DefineExternalAuth osm pipe /usr/local/bin/trac-authenticate
+
+       <Location /login>
+               AuthType Basic
+               AuthName "OpenStreetMap Trac"
+               AuthBasicProvider external
+               AuthExternal osm
+               Require valid-user
+       </Location>
+
+        SSLEngine on
+</VirtualHost>
diff --git a/cookbooks/trac/templates/default/sudoers.erb b/cookbooks/trac/templates/default/sudoers.erb
new file mode 100644 (file)
index 0000000..85b74a6
--- /dev/null
@@ -0,0 +1,7 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+# Allow subversion to notify trac of commits
+www-data ALL=(trac) NOPASSWD: /usr/bin/trac-admin /var/lib/trac changeset *
+
+# Allow git to notify trac of commits
+%git ALL=(trac) NOPASSWD: /usr/bin/trac-admin /var/lib/trac changeset *
diff --git a/cookbooks/trac/templates/default/trac.ini.erb b/cookbooks/trac/templates/default/trac.ini.erb
new file mode 100644 (file)
index 0000000..08cd158
--- /dev/null
@@ -0,0 +1,207 @@
+# DO NOT EDIT - This file is being maintained by Chef
+
+[attachment]
+max_size = 262144
+render_unsafe_content = false
+
+[browser]
+color_scale = True
+downloadable_paths = /trunk, /branches/*, /tags/*
+hide_properties = svk:merge
+intermediate_color = 
+intermediate_point = 
+newest_color = (255, 136, 136)
+oldest_color = (136, 136, 255)
+oneliner_properties = trac:summary
+render_unsafe_content = false
+wiki_properties = trac:description
+
+[changeset]
+max_diff_files = 100
+wiki_format_messages = true
+
+[components]
+tracext.git.* = enabled
+
+[header_logo]
+alt = OpenStreetMap
+height = 80
+link = http://trac.openstreetmap.org/
+src = site/osm.png
+width = 228
+
+[inherit]
+plugins_dir = 
+templates_dir = 
+
+[intertrac]
+josm.compat = false
+josm.title = JOSM Trac
+josm.url = http://josm.openstreetmap.de
+
+[logging]
+log_file = trac.log
+log_level = INFO
+log_type = file
+
+[milestone]
+stats_provider = DefaultTicketGroupStatsProvider
+
+[mimeviewer]
+enscript_modes = text/x-dylan:dylan:4
+enscript_path = enscript
+max_preview_size = 102400
+mime_map = text/x-dylan:dylan,text/x-idl:ice,text/x-ada:ads:adb
+php_path = php
+pygments_default_style = trac
+pygments_modes = 
+tab_width = 8
+treat_as_binary = application/octet-stream,application/pdf,application/postscript,application/rtf
+
+[notification]
+admit_domains = 
+always_notify_owner = true
+always_notify_reporter = true
+always_notify_updater = true
+ignore_domains = 
+mime_encoding = qp
+smtp_always_bcc = 
+smtp_always_cc = 
+smtp_default_domain = 
+smtp_enabled = true
+smtp_from = trac@noreply.openstreetmap.org
+smtp_from_name = 
+smtp_password = 
+smtp_port = 25
+smtp_replyto = trac@noreply.openstreetmap.org
+smtp_server = localhost
+smtp_subject_prefix = __default__
+smtp_user = 
+ticket_subject_template = $prefix #$ticket.id: $summary
+use_public_cc = true
+use_short_addr = false
+use_tls = false
+
+[project]
+admin = 
+admin_trac_url = .
+descr = OpenStreetMap is a free editable map of the whole world
+footer = Visit the map at<br /><a href="http://www.openstreetmap.org/">http://www.openstreetmap.org/</a>
+icon = site/osm.ico
+name = OpenStreetMap
+url = http://www.openstreetmap.org/
+
+[query]
+default_anonymous_query = status!=closed&cc~=$USER
+default_query = status!=closed&owner=$USER
+items_per_page = 100
+
+[report]
+items_per_page = 100
+items_per_page_rss = 0
+
+[revisionlog]
+default_log_limit = 100
+
+[roadmap]
+stats_provider = DefaultTicketGroupStatsProvider
+
+[search]
+min_query_length = 3
+
+[svn]
+branches = trunk,branches/*
+tags = tags/*
+
+[ticket]
+default_cc = 
+default_component = 
+default_description = 
+default_keywords = 
+default_milestone = 
+default_owner = 
+default_priority = minor
+default_resolution = fixed
+default_severity = 
+default_summary = 
+default_type = defect
+default_version = 
+max_comment_size = 262144
+max_description_size = 262144
+preserve_newlines = default
+restrict_owner = false
+workflow = ConfigurableTicketWorkflow
+
+[ticket-workflow]
+accept = new,assigned,accepted,reopened -> accepted
+accept.operations = set_owner_to_self
+accept.permissions = TICKET_MODIFY
+leave = * -> *
+leave.default = 1
+leave.operations = leave_status
+reassign = new,assigned,accepted,reopened -> assigned
+reassign.operations = set_owner
+reassign.permissions = TICKET_MODIFY
+reopen = closed -> reopened
+reopen.operations = del_resolution
+reopen.permissions = TICKET_CREATE
+resolve = new,assigned,accepted,reopened -> closed
+resolve.operations = set_resolution
+resolve.permissions = TICKET_MODIFY
+
+[timeline]
+abbreviated_messages = True
+changeset_collapse_events = false
+changeset_long_messages = false
+changeset_show_files = 0
+default_daysback = 30
+max_daysback = 90
+newticket_formatter = oneliner
+ticket_show_details = false
+
+[trac]
+authz_file = 
+authz_module_name = 
+auto_reload = False
+backup_dir = db
+base_url = https://<%= @name %>/
+check_auth_ip = false
+database = sqlite:db/trac.db
+debug_sql = False
+default_charset = utf-8
+htdocs_location = 
+ignore_auth_case = false
+mainnav = wiki,timeline,roadmap,browser,tickets,newticket,search
+metanav = login,logout,prefs,help,about
+mysqldump_path = mysqldump
+never_obfuscate_mailto = false
+permission_policies = DefaultPermissionPolicy, LegacyAttachmentPolicy
+permission_store = DefaultPermissionStore
+pg_dump_path = pg_dump
+repository_sync_per_request = 
+secure_cookies = False
+show_email_addresses = false
+show_ip_addresses = false
+timeout = 20
+use_base_url_for_redirect = False
+
+[repositories]
+subversion.dir = /var/lib/subversion/repos/openstreetmap
+subversion.description = Legacy subversion repository
+subversion.type = svn
+subversion.url = http://svn.openstreetmap.org/
+subversion.hidden = true
+<% Dir.glob("/var/lib/git/*.git").each do |repository| -%>
+<%= File.basename(repository, ".git") %>.dir = <%= repository %>
+<%= File.basename(repository, ".git") %>.description = <%= IO.read("#{repository}/description").strip %>
+<%= File.basename(repository, ".git") %>.type = git
+<%= File.basename(repository, ".git") %>.url = git://git.openstreetmap.org/<%= File.basename(repository) %>
+<% end -%>
+.alias = subversion
+
+[wiki]
+ignore_missing_pages = false
+max_size = 262144
+render_unsafe_content = false
+split_page_names = false
+