diff --git a/roles/varnish/files/proxy.vcl b/roles/varnish/files/proxy.vcl new file mode 100644 index 0000000000..9b0ca842b8 --- /dev/null +++ b/roles/varnish/files/proxy.vcl @@ -0,0 +1,228 @@ +#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. +# +sub vcl_error { + if (obj.status == 400 || obj.status == 413) { + return(deliver); + } +} + +backend wiki { + .host = "localhost"; + .port = "10001"; + .first_byte_timeout = 120s; +} + +backend mirrorlists { + .host = "localhost"; + .port = "10002"; +} + +backend pkgdb { + .host = "localhost"; + .port = "10003"; + .first_byte_timeout = 160s; +} + +backend fas { + .host = "localhost"; + .port = "10004"; +} + + +backend voting { + .host = "localhost"; + .port = "10007"; +} + +backend mirrormanager { + .host = "localhost"; + .port = "10008"; +} + +backend bodhi { + .host = "localhost"; + .port = "10009"; +} + +backend freemedia { + .host = "localhost"; + .port = "10011"; +} + +backend packages { + .host = "localhost"; + .port = "10016"; +} + +backend tagger { + .host = "localhost"; + .port = "10017"; +} + +backend askbot { + .host = "localhost"; + .port = "10021"; +} + +backend blockerbugs { + .host = "localhost"; + .port = "10022"; +} + +backend fedocal { + .host = "localhost"; + .port = "10023"; +} + +backend kerneltest { + .host = "localhost"; + .port = "10038"; +} + +backend paste { + .host = "localhost"; + .port = "10027"; +} + +acl purge { + "192.168.1.3"; + "192.168.1.4"; + "192.168.1.5"; + "192.168.1.6"; + "192.168.1.13"; + "192.168.1.24"; + "192.168.1.23"; + "192.168.1.41"; + "10.5.126.31"; + "10.5.126.32"; + "10.5.126.33"; + "10.5.126.34"; + "10.5.126.37"; + "10.5.126.38"; +} + +sub vcl_recv { + if (req.request == "PURGE") { + if (!client.ip ~ purge) { + error 405 "Not allowed."; + } + if (req.url ~ "^http://") { + set req.url = regsub(req.url, "http://localhost:6081",""); + } + purge_url(req.url); + } + + if (req.url ~ "^/wiki/") { + set req.backend = wiki; + } + if (req.url ~ "^/w/") { + set req.backend = wiki; + if (req.url ~ "^/w/skins/") { + unset req.http.cookie; + set req.url = regsub(req.url, "\?.*", ""); + } + } + if (req.url ~ "^/mirrorlist/") { + set req.backend = mirrorlists; + } + if (req.url ~ "^/pkgdb") { + set req.backend = pkgdb; + if ((req.url ~ "^/pkgdb/appicon/show/") || (req.url ~ "^/pkgdb/static/") || (req.url ~ "^/pkgdb/tg_js/")) { + unset req.http.cookie; + set req.url = regsub(req.url, "\?.*", ""); + } + } + if (req.url ~ "^/accounts/") { + set req.backend = fas; + } + if (req.url ~ "^/voting/") { + set req.backend = voting; + } + if (req.url ~ "^/mirrormanager/") { + set req.backend = mirrormanager; + } + if (req.url ~ "^/updates/") { + set req.backend = bodhi; + } + if (req.url ~ "^/freemedia/") { + set req.backend = freemedia; + } + if (req.url ~ "^/packages/") { + set req.backend = packages; + } + if (req.url ~ "^/tagger/") { + set req.backend = tagger; + } + if (req.url ~ "^/calendar") { + set req.backend = fedocal; + if (req.url ~ "^/calendar/static/") { + unset req.http.cookie; + set req.url = regsub(req.url, "\?.*", ""); + } + } + if (req.url ~ "^/kerneltest") { + set req.backend = kerneltest; + } + if (req.http.X-Forwarded-Server ~ "^paste.fedoraproject.org") { + set req.backend = paste; + if ((req.url ~ "^/skins/") || (req.url ~ "^/addons/") || (req.url ~ "^/admin/skins/")) { + unset req.http.cookie; + set req.url = regsub(req.url, "\?.*", ""); + } + } + if (req.http.X-Forwarded-Server ~ "^ask.fedoraproject.org") { + set req.backend = askbot; + if (req.url ~ "^/m/") { + unset req.http.cookie; + set req.url = regsub(req.url, "\?.*", ""); + } + } + if (req.http.X-Forwarded-Server ~ "^qa.fedoraproject.org") { + if (req.url ~ "^/blockerbugs") { + set req.backend = blockerbugs; + if (req.url ~ "^/blockerbugs/static/") { + unset req.http.cookie; + set req.url = regsub(req.url, "\?.*", ""); + } + + } + } + + # Pass any requests with the "If-None-Match" header directly. + if (req.http.If-None-Match) { + return (pass); + } + + # Force lookup if the request is a no-cache request from the client. + if (req.http.Cache-Control ~ "no-cache") { + purge_url(req.url); + } + if (req.http.Accept-Encoding) { + if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") { + # No point in compressing these + remove req.http.Accept-Encoding; + } elsif (req.http.Accept-Encoding ~ "gzip") { + # This is currently a bug with ipv6, so we need to nuke it. + remove req.http.Accept-Encoding; + } elsif (req.http.Accept-Encoding ~ "deflate") { + set req.http.Accept-Encoding = "deflate"; + } else { + # unknown algorithm + remove req.http.Accept-Encoding; + } + } +} + +# When requesting application icons, don't allow cherrypy to set cookies +sub vcl_fetch { + if ((req.url ~ "^/pkgdb/appicon/show/") || (req.url ~ "^/pkgdb/static/") || (req.url ~ "^/pkgdb/tg_js/") || (req.url ~ "^/blockerbugs/static/")) { + unset beresp.http.set-cookie; + } + if (beresp.status == 301) { + return (pass); + } +} diff --git a/roles/varnish/files/proxy.vcl.stg b/roles/varnish/files/proxy.vcl.stg new file mode 100644 index 0000000000..d51867992c --- /dev/null +++ b/roles/varnish/files/proxy.vcl.stg @@ -0,0 +1,245 @@ +#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. +# +sub vcl_error { + if (obj.status == 400 || obj.status == 413) { + return(deliver); + } +} + +backend wiki { + .host = "localhost"; + .port = "10001"; + .first_byte_timeout = 120s; +} + +backend mirrorlists { + .host = "localhost"; + .port = "10002"; +} + +backend pkgdb { + .host = "localhost"; + .port = "10003"; + .first_byte_timeout = 160s; +} + +backend fas01 { + .host = "fas01"; + .port = "http"; + .probe = { + .url = "/accounts/"; + .interval = 5s; + .timeout = 5s; + .window = 5; + .threshold = 5; + } +} + +backend fas02 { + .host = "fas02"; + .port = "http"; + .probe = { + .url = "/accounts/"; + .interval = 5s; + .timeout = 5s; + .window = 5; + .threshold = 5; + } +} + +backend fas03 { + .host = "fas03"; + .port = "http"; + .probe = { + .url = "/accounts/"; + .interval = 5s; + .timeout = 5s; + .window = 5; + .threshold = 5; + } +} + +director fas round-robin { + { .backend = fas01; } + { .backend = fas02; } + { .backend = fas03; } +} + +backend voting { + .host = "localhost"; + .port = "10007"; + .first_byte_timeout = 160s; +} + +backend mirrormanager { + .host = "localhost"; + .port = "10008"; +} + +backend bodhi { + .host = "localhost"; + .port = "10009"; +} + +backend freemedia { + .host = "localhost"; + .port = "10011"; +} + +backend packages { + .host = "localhost"; + .port = "10016"; +} + +backend tagger { + .host = "localhost"; + .port = "10017"; +} + +backend askbot { + .host = "localhost"; + .port = "10021"; +} + +backend blockerbugs { + .host = "localhost"; + .port = "10022"; +} + +backend fedocal { + .host = "localhost"; + .port = "10023"; +} + +backend kerneltest { + .host = "localhost"; + .port = "10038"; +} + +backend paste { + .host = "localhost"; + .port = "10027"; +} + +acl purge { + "192.168.1.3"; + "192.168.1.4"; + "192.168.1.5"; + "192.168.1.6"; + "192.168.1.13"; + "192.168.1.24"; + "192.168.1.23"; + "192.168.1.41"; + "10.5.126.31"; + "10.5.126.32"; + "10.5.126.33"; + "10.5.126.34"; + "10.5.126.37"; + "10.5.126.38"; +} + +sub vcl_recv { + if (req.request == "PURGE") { + if (!client.ip ~ purge) { + error 405 "Not allowed."; + } + if (req.url ~ "^http://") { + set req.url = regsub(req.url, "http://localhost:6081",""); + } + purge_url(req.url); + } + + if (req.url ~ "^/wiki/") { + set req.backend = wiki; + } + if (req.url ~ "^/w/") { + set req.backend = wiki; + } + if (req.url ~ "^/pkgdb/appicon/show/") { + set req.backend = pkgdb; + unset req.http.cookie; + } + if (req.url ~ "^/mirrorlist/") { + set req.backend = mirrorlists; + } + if (req.url ~ "^/pkgdb") { + set req.backend = pkgdb; + } + if (req.url ~ "^/accounts/") { + set req.backend = fas; + } + if (req.url ~ "^/voting/") { + set req.backend = voting; + } + if (req.url ~ "^/mirrormanager/") { + set req.backend = mirrormanager; + } + if (req.url ~ "^/updates/") { + set req.backend = bodhi; + } + if (req.url ~ "^/freemedia/") { + set req.backend = freemedia; + } + if (req.url ~ "^/packages/") { + set req.backend = packages; + } + if (req.url ~ "^/tagger/") { + set req.backend = tagger; + } + if (req.url ~ "^/calendar") { + set req.backend = fedocal; + } + if (req.url ~ "^/kerneltest") { + set req.backend = kerneltest; + } + if (req.http.X-Forwarded-Server ~ "^paste.fedoraproject.org") { + set req.backend = paste; + } + if (req.http.X-Forwarded-Server ~ "^ask.fedoraproject.org") { + set req.backend = askbot; + if (req.url ~ "^/m/") { + unset req.http.cookie; + set req.url = regsub(req.url, "\?.*", ""); + } + } + if (req.http.X-Forwarded-Server ~ "^qa.fedoraproject.org") { + if (req.url ~ "^/blockerbugs") { + set req.backend = blockerbugs; + } + } + + # Pass any requests with the "If-None-Match" header directly. + if (req.http.If-None-Match) { + return (pass); + } + + # Force lookup if the request is a no-cache request from the client. + if (req.http.Cache-Control ~ "no-cache") { + purge_url(req.url); + } + if (req.http.Accept-Encoding) { + if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") { + # No point in compressing these + remove req.http.Accept-Encoding; + } elsif (req.http.Accept-Encoding ~ "gzip") { + # This is currently a bug with ipv6, so we need to nuke it. + remove req.http.Accept-Encoding; + } elsif (req.http.Accept-Encoding ~ "deflate") { + set req.http.Accept-Encoding = "deflate"; + } else { + # unknown algorithm + remove req.http.Accept-Encoding; + } + } +} + +# When requesting application icons, don't allow cherrypy to set cookies +sub vcl_fetch { + if (req.url ~ "^/pkgdb/appicon/show/") { + unset beresp.http.set-cookie; + } +} diff --git a/roles/varnish/files/varnish b/roles/varnish/files/varnish new file mode 100644 index 0000000000..763e5fdbc3 --- /dev/null +++ b/roles/varnish/files/varnish @@ -0,0 +1,99 @@ +# Configuration file for varnish +# +# /etc/init.d/varnish expects the variable $DAEMON_OPTS to be set from this +# shell script fragment. +# + +# Maximum number of open files (for ulimit -n) +NFILES=131072 + +# Locked shared memory (for ulimit -l) +# Default log size is 82MB + header +MEMLOCK=82000 + +# Maximum size of corefile (for ulimit -c). Default in Fedora is 0 +# DAEMON_COREFILE_LIMIT="unlimited" + +# 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 fixed-size cache file. +# +#DAEMON_OPTS="-a :6081 \ +# -T localhost:6082 \ +# -b localhost:8080 \ +# -u varnish -g varnish \ +# -s file,/var/lib/varnish/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 +# fixed-size cache file. +# +DAEMON_OPTS="-a :6081 \ + -T localhost:6082 \ + -f /etc/varnish/default.vcl \ + -u varnish -g varnish \ + -s file,/var/lib/varnish/varnish_storage.bin,1G" + +VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1 +VARNISH_ADMIN_LISTEN_PORT=6082 + +## 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/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 +# +# # 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} \ +# -u varnish -g varnish \ +# -s ${VARNISH_STORAGE}" +# + + +## Alternative 4, Do It Yourself. See varnishd(1) for more information. +# +# DAEMON_OPTS="" diff --git a/roles/varnish/tasks/main.yml b/roles/varnish/tasks/main.yml new file mode 100644 index 0000000000..7376fdeaff --- /dev/null +++ b/roles/varnish/tasks/main.yml @@ -0,0 +1,29 @@ +--- +# Tasks to set up varnish + +- name: install needed packages + yum: pkg={{ item }} state=installed + with_items: + - varnish + tags: + - packages + +- name: install varnish /etc/sysconfig/varnish + copy: src={{ item.file }} dest={{ item.dest }} + owner=root group=root + with_items: + - { file: varnish, dest: /etc/sysconfig/varnish } + +- name: install /etc/varnish/default.vcl - stg + copy: src={{ item.file }} dest=/etc/varnish/default.vcl + owner=root group=root + with_items: + - proxy.vcl.stg + when: env == 'staging' + +- name: install /etc/varnish/default.vcl - prod + copy: src={{ item.file }} dest=/etc/varnish/default.vcl + owner=root group=root + with_items: + - proxy.vcl + when: env != 'staging'