--- /dev/null
+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.
--- /dev/null
+default[:bind] = { }
--- /dev/null
+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"
--- /dev/null
+#
+# 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
--- /dev/null
+; 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.
--- /dev/null
+# DO NOT EDIT - This file is being maintained by Chef
+
+zone "10.in-addr.arpa" {
+ type master;
+ file "/etc/bind/db.10";
+};
--- /dev/null
+# 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; };
+};
+
--- /dev/null
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
--- /dev/null
+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"
--- /dev/null
+#
+# 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
--- /dev/null
+# 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>
--- /dev/null
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
--- /dev/null
+# 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] = []
--- /dev/null
+#
+# 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
--- /dev/null
+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'
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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"
--- /dev/null
+#
+# 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
--- /dev/null
+#
+# 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
--- /dev/null
+#
+# 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
--- /dev/null
+#
+# 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
--- /dev/null
+# 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>
--- /dev/null
+# 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
--- /dev/null
+# 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"
--- /dev/null
+# 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
+}
--- /dev/null
+#!/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
--- /dev/null
+# 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
--- /dev/null
+# 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"
--- /dev/null
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
--- /dev/null
+default[:devices] = {}
--- /dev/null
+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"
--- /dev/null
+#
+# 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
--- /dev/null
+# 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 -%>
--- /dev/null
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
--- /dev/null
+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"
--- /dev/null
+#
+# 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
--- /dev/null
+#!/bin/sh
+
+rsync -zt rsync://countries-ns.mdc.dk/zone/zz.countries.nerd.dk.rbldnsd /etc/powerdns/countries.conf
+pdns_control rediscover >/dev/null
--- /dev/null
+# 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
--- /dev/null
+# 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
--- /dev/null
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
--- /dev/null
+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"
--- /dev/null
+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"
--- /dev/null
+#
+# 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
--- /dev/null
+# 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] %>
--- /dev/null
+# 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] %>
--- /dev/null
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
--- /dev/null
+default[:munin][:allow] = []
+default[:munin][:graphs] = {}
+default[:munin][:plugins] = {}
--- /dev/null
+#
+# 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
--- /dev/null
+#
+# 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
--- /dev/null
+[api_calls_num]
+user root
--- /dev/null
+[hpasmcli_*]
+user root
--- /dev/null
+[passenger_*]
+user root
--- /dev/null
+#!/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};
+ }
+}
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+#!/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
+
--- /dev/null
+#! /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);
+
--- /dev/null
+#! /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);
+
+
+
--- /dev/null
+#!/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/;
+ }
+}
--- /dev/null
+#!/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;
+}
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+#!/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;
+
--- /dev/null
+#!/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;
+
--- /dev/null
+#!/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;
+
--- /dev/null
+#!/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
+
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+#!/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();
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+#!/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`
+
--- /dev/null
+#!/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"
--- /dev/null
+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
--- /dev/null
+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"
--- /dev/null
+#
+# 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"
--- /dev/null
+#
+# 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"
--- /dev/null
+# 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>
--- /dev/null
+# 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 -%>
--- /dev/null
+# 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 -%>
--- /dev/null
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
--- /dev/null
+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"
--- /dev/null
+#
+# 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
--- /dev/null
+#
+# 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"
--- /dev/null
+#
+# 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
--- /dev/null
+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.
--- /dev/null
+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"
--- /dev/null
+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"]
+
--- /dev/null
+#
+# 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
--- /dev/null
+# 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
--- /dev/null
+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"
--- /dev/null
+#
+# 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
--- /dev/null
+# 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
--- /dev/null
+# 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==
--- /dev/null
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
--- /dev/null
+-----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-----
--- /dev/null
+-----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-----
--- /dev/null
+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"
--- /dev/null
+#
+# 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
--- /dev/null
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
--- /dev/null
+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"
--- /dev/null
+#
+# 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
--- /dev/null
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
--- /dev/null
+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"
--- /dev/null
+#
+# 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
--- /dev/null
+# 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 -%>
--- /dev/null
+# 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 -%>
--- /dev/null
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
--- /dev/null
+default[:sysfs] = {}
--- /dev/null
+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"
--- /dev/null
+#
+# 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
--- /dev/null
+# 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 -%>
--- /dev/null
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
--- /dev/null
+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
--- /dev/null
+class Chef
+ class Recipe
+ def random_password(length)
+ length.times.collect do
+ "!\#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~"[rand(91)].chr
+ end.join
+ end
+ end
+end
--- /dev/null
+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"
--- /dev/null
+#
+# 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
--- /dev/null
+= DESCRIPTION:
+
+= REQUIREMENTS:
+
+= ATTRIBUTES:
+
+= USAGE:
+
--- /dev/null
+#Trac really does not handle well being scraped.
+User-agent: *
+Disallow: /changeset
+Disallow: /changeset/
+Disallow: /wiki/
--- /dev/null
+<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&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>
--- /dev/null
+#!/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)
--- /dev/null
+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"
--- /dev/null
+#
+# 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
--- /dev/null
+# 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>
--- /dev/null
+# 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 *
--- /dev/null
+# 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
+