diff --git a/modules/undine/manifests/init.pp b/modules/undine/manifests/init.pp index ea303de..afb53b4 100644 --- a/modules/undine/manifests/init.pp +++ b/modules/undine/manifests/init.pp @@ -7,16 +7,16 @@ # === Examples # # The primary use of the Undine class is to encapuslate basic provisioning for -# the VM. It is intended to be declared in Puppet modules in the ./sites +# the VM. It is intended to be declared in Puppet modules in the ./sites # directory using the require syntax, typically followed by one or more # undine::drupal_instance resources. -# +# # require undine # undine::drupal_instance { "mysite": # ... # } # -class undine { +class undine { require undine_php require undine_git require undine_ssh @@ -26,6 +26,7 @@ class undine { require undine_drush require undine_xhprof require undine_xdebug + require undine_varnish require undine_sendmail file { "/etc/motd": diff --git a/modules/undine_varnish/files/default.vcl b/modules/undine_varnish/files/default.vcl new file mode 100644 index 0000000..8545903 --- /dev/null +++ b/modules/undine_varnish/files/default.vcl @@ -0,0 +1,158 @@ +# This is a basic VCL configuration file for varnish. See the vcl(7) +# man page for details on VCL syntax and semantics. + +# Default backend definition. Set this to point to your content +# server. +# +backend default { + .host = "127.0.0.1"; + .port = "1000"; +} + +# Respond to incoming requests. +sub vcl_recv { + # Use anonymous, cached pages if all backends are down. + if (!req.backend.healthy) { + unset req.http.Cookie; + } + + # Allow the backend to serve up stale content if it is responding slowly. + set req.grace = 6h; + + # Pipe these paths directly to Apache for streaming. + #if (req.url ~ "^/admin/content/backup_migrate/export") { + # return (pipe); + #} + + if (req.restarts == 0) { + if (req.http.x-forwarded-for) { + set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; + } + else { + set req.http.X-Forwarded-For = client.ip; + } + } + + # Do not cache these paths. + if (req.url ~ "^/status\.php$" || + req.url ~ "^/update\.php$" || + req.url ~ "^/admin$" || + req.url ~ "^/admin/.*$" || + req.url ~ "^/flag/.*$" || + req.url ~ "^.*/ajax/.*$" || + req.url ~ "^.*/ahah/.*$") { + return (pass); + } + + # Do not allow outside access to cron.php or install.php. + #if (req.url ~ "^/(cron|install)\.php$" && !client.ip ~ internal) { + # Have Varnish throw the error directly. + # error 404 "Page not found."; + # Use a custom error page that you've defined in Drupal at the path "404". + # set req.url = "/404"; + #} + + # Always cache the following file types for all users. This list of extensions + # appears twice, once here and again in vcl_fetch so make sure you edit both + # and keep them equal. + if (req.url ~ "(?i)\.(pdf|asc|dat|txt|doc|xls|ppt|tgz|csv|png|gif|jpeg|jpg|ico|swf|css|js)(\?.*)?$") { + unset req.http.Cookie; + } + + # Remove all cookies that Drupal doesn't need to know about. We explicitly + # list the ones that Drupal does need, the SESS and NO_CACHE. If, after + # running this code we find that either of these two cookies remains, we + # will pass as the page cannot be cached. + if (req.http.Cookie) { + # 1. Append a semi-colon to the front of the cookie string. + # 2. Remove all spaces that appear after semi-colons. + # 3. Match the cookies we want to keep, adding the space we removed + # previously back. (\1) is first matching group in the regsuball. + # 4. Remove all other cookies, identifying them by the fact that they have + # no space after the preceding semi-colon. + # 5. Remove all spaces and semi-colons from the beginning and end of the + # cookie string. + set req.http.Cookie = ";" + req.http.Cookie; + set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";"); + set req.http.Cookie = regsuball(req.http.Cookie, ";(SESS[a-z0-9]+|SSESS[a-z0-9]+|NO_CACHE)=", "; \1="); + set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", ""); + set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", ""); + + if (req.http.Cookie == "") { + # If there are no remaining cookies, remove the cookie header. If there + # aren't any cookie headers, Varnish's default behavior will be to cache + # the page. + unset req.http.Cookie; + } + else { + # If there is any cookies left (a session or NO_CACHE cookie), do not + # cache the page. Pass it on to Apache directly. + return (pass); + } + } +} + +# Set a header to track a cache HIT/MISS. +sub vcl_deliver { + if (obj.hits > 0) { + set resp.http.X-Varnish-Cache = "HIT"; + } + else { + set resp.http.X-Varnish-Cache = "MISS"; + } +} + +# Code determining what to do when serving items from the Apache servers. +# beresp == Back-end response from the web server. +sub vcl_fetch { + # We need this to cache 404s, 301s, 500s. Otherwise, depending on backend but + # definitely in Drupal's case these responses are not cacheable by default. + if (beresp.status == 404 || beresp.status == 301 || beresp.status == 500) { + set beresp.ttl = 10m; + } + + # Don't allow static files to set cookies. + # (?i) denotes case insensitive in PCRE (perl compatible regular expressions). + # This list of extensions appears twice, once here and again in vcl_recv so + # make sure you edit both and keep them equal. + if (req.url ~ "(?i)\.(pdf|asc|dat|txt|doc|xls|ppt|tgz|csv|png|gif|jpeg|jpg|ico|swf|css|js)(\?.*)?$") { + unset beresp.http.set-cookie; + } + + # Allow items to be stale if needed. + set beresp.grace = 6h; +} + +# In the event of an error, show friendlier messages. +sub vcl_error { + # Redirect to some other URL in the case of a homepage failure. + #if (req.url ~ "^/?$") { + # set obj.status = 302; + # set obj.http.Location = "http://backup.example.com/"; + #} + + # Otherwise redirect to the homepage, which will likely be in the cache. + set obj.http.Content-Type = "text/html; charset=utf-8"; + synthetic {" + + + Page Unavailable + + + +
+

Page Unavailable

+

The page you requested is temporarily unavailable.

+

We're redirecting you to the homepage in 5 seconds.

+
(Error "} + obj.status + " " + obj.response + {")
+
+ + +"}; + return (deliver); +} diff --git a/modules/undine_varnish/files/varnish b/modules/undine_varnish/files/varnish new file mode 100644 index 0000000..131c75f --- /dev/null +++ b/modules/undine_varnish/files/varnish @@ -0,0 +1,106 @@ +# Configuration file for varnish +# +# /etc/init.d/varnish expects the variables $DAEMON_OPTS, $NFILES and $MEMLOCK +# to be set from this shell script fragment. +# + +# Should we start varnishd at boot? Set to "no" to disable. +START=yes + +# Maximum number of open files (for ulimit -n) +NFILES=131072 + +# Maximum locked memory size (for ulimit -l) +# Used for locking the shared memory log in memory. If you increase log size, +# you need to increase this number as well +MEMLOCK=82000 + +# Default varnish instance name is the local nodename. Can be overridden with +# the -n switch, to have more instances on a single server. +# INSTANCE=$(uname -n) + +# This file contains 4 alternatives, please use only one. + +## Alternative 1, Minimal configuration, no VCL +# +# Listen on port 6081, administration on localhost:6082, and forward to +# content server on localhost:8080. Use a 1GB fixed-size cache file. +# +# DAEMON_OPTS="-a :6081 \ +# -T localhost:6082 \ +# -b localhost:8080 \ +# -u varnish -g varnish \ +# -S /etc/varnish/secret \ +# -s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G" + + +## Alternative 2, Configuration with VCL +# +# Listen on port 6081, administration on localhost:6082, and forward to +# one content server selected by the vcl file, based on the request. Use a 1GB +# fixed-size cache file. +# +DAEMON_OPTS="-a :80 \ + -T localhost:6082 \ + -f /etc/varnish/default.vcl \ + -S /etc/varnish/secret \ + -s malloc,256m" + + +## Alternative 3, Advanced configuration +# +# See varnishd(1) for more information. +# +# # Main configuration file. You probably want to change it :) +# VARNISH_VCL_CONF=/etc/varnish/default.vcl +# +# # Default address and port to bind to +# # Blank address means all IPv4 and IPv6 interfaces, otherwise specify +# # a host name, an IPv4 dotted quad, or an IPv6 address in brackets. +# VARNISH_LISTEN_ADDRESS= +# VARNISH_LISTEN_PORT=6081 +# +# # Telnet admin interface listen address and port +# VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1 +# VARNISH_ADMIN_LISTEN_PORT=6082 +# +# # The minimum number of worker threads to start +# VARNISH_MIN_THREADS=1 +# +# # The Maximum number of worker threads to start +# VARNISH_MAX_THREADS=1000 +# +# # Idle timeout for worker threads +# VARNISH_THREAD_TIMEOUT=120 +# +# # Cache file location +# VARNISH_STORAGE_FILE=/var/lib/varnish/$INSTANCE/varnish_storage.bin +# +# # Cache file size: in bytes, optionally using k / M / G / T suffix, +# # or in percentage of available disk space using the % suffix. +# VARNISH_STORAGE_SIZE=1G +# +# # File containing administration secret +# VARNISH_SECRET_FILE=/etc/varnish/secret +# +# # Backend storage specification +# VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}" +# +# # Default TTL used when the backend does not specify one +# VARNISH_TTL=120 +# +# # DAEMON_OPTS is used by the init script. If you add or remove options, make +# # sure you update this section, too. +# DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \ +# -f ${VARNISH_VCL_CONF} \ +# -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \ +# -t ${VARNISH_TTL} \ +# -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \ +# -S ${VARNISH_SECRET_FILE} \ +# -s ${VARNISH_STORAGE}" +# + + +## Alternative 4, Do It Yourself +# +# DAEMON_OPTS="" diff --git a/modules/undine_varnish/manifests/init.pp b/modules/undine_varnish/manifests/init.pp new file mode 100644 index 0000000..52fa4b7 --- /dev/null +++ b/modules/undine_varnish/manifests/init.pp @@ -0,0 +1,59 @@ +# == Class: undine_varnish +# +# The undine_varnish class is responsible for the installation of varnish in Undine. +# +# It should not be necessary to declare this class directly, as it will be +# declared automatically by the undine class, which all Undine sites should use. +# +class undine_varnish ( $version = '3.0' ) { + + # Installs the GPG key + exec { 'import-key': + path => '/bin:/usr/bin', + command => 'curl http://repo.varnish-cache.org/ubuntu/GPG-key.txt | apt-key add -', + unless => 'apt-key list | grep servergrove-ubuntu-precise', + require => Package['curl'], + } + + # Creates the source file for the ServerGrove repository + file { 'varnish.repo': + path => '/etc/apt/sources.list.d/varnish.list', + ensure => present, + content => "deb http://repo.varnish-cache.org/ubuntu/ precise varnish-${version}", + require => Exec['import-key'], + } + + exec { "varnish-update-sources-file": + command => '/usr/bin/apt-get update', + require => File['varnish.repo'], + } + + package { 'varnish': + ensure => installed, + require => Exec['varnish-update-sources-file'], + } + + file { '/etc/varnish/default.vcl': + owner => 'root', + group => 'root', + mode => '0444', + source => 'puppet:///modules/undine_varnish/default.vcl', + notify => Service['varnish'], + require => Package['varnish'], + } + + file { '/etc/default/varnish': + owner => 'root', + group => 'root', + mode => '0444', + source => 'puppet:///modules/undine_varnish/varnish', + notify => Service['varnish'], + require => Package['varnish'], + } + + service { 'varnish': + enable => true, + ensure => running, + require => Package['varnish'], + } +}