diff --git a/pgweb/core/views.py b/pgweb/core/views.py index dc6db30e..daaa86c2 100644 --- a/pgweb/core/views.py +++ b/pgweb/core/views.py @@ -21,7 +21,7 @@ from pgweb.util.decorators import cache, nocache from pgweb.util.contexts import render_pgweb, get_nav_menu, PGWebContextProcessor from pgweb.util.helpers import simple_form, PgXmlHelper, HttpServerError from pgweb.util.moderation import get_all_pending_moderations -from pgweb.util.misc import get_client_ip, varnish_purge +from pgweb.util.misc import get_client_ip, varnish_purge, varnish_purge_expr, varnish_purge_xkey from pgweb.util.sitestruct import get_all_pages_struct # models needed for the pieces on the frontpage @@ -277,10 +277,24 @@ def admin_pending(request): def admin_purge(request): if request.method == 'POST': url = request.POST['url'] - if url == '': + expr = request.POST['expr'] + xkey = request.POST['xkey'] + l = len(filter(None, [url, expr, xkey])) + if l == 0: + # Nothing specified return HttpResponseRedirect('.') - varnish_purge(url) - messages.info(request, "Purge completed: '^%s'" % url) + elif l > 1: + messages.error(request, "Can only specify one of url, expression and xkey!") + return HttpResponseRedirect('.') + + if url: + varnish_purge(url) + elif expr: + varnish_purge_expr(expr) + else: + varnish_purge_xkey(xkey) + + messages.info(request, "Purge added.") return HttpResponseRedirect('.') # Fetch list of latest purges diff --git a/pgweb/util/misc.py b/pgweb/util/misc.py index 364af5f4..20bf822e 100644 --- a/pgweb/util/misc.py +++ b/pgweb/util/misc.py @@ -34,6 +34,12 @@ def get_client_ip(request): return request.META['REMOTE_ADDR'] +def varnish_purge_xkey(xkey): + """ + Purge the specified xkey from Varnish. + """ + connection.cursor().execute("SELECT varnish_purge_xkey(%s)", (xkey, )) + def varnish_purge(url): """ Purge the specified URL from Varnish. Will add initial anchor to the URL, @@ -42,6 +48,13 @@ def varnish_purge(url): url = '^%s' % url connection.cursor().execute("SELECT varnish_purge(%s)", (url, )) +def varnish_purge_expr(expr): + """ + Purge the specified expression from Varnish. Does not modify the expression + at all, so be very careful! + """ + connection.cursor().execute("SELECT varnish_purge_expr(%s)", (expr, )) + def version_sort(l): """ map a directory name to a format that will show up sensibly in an ascii sort diff --git a/sql/varnish.sql b/sql/varnish.sql index 10792088..d78138fd 100644 --- a/sql/varnish.sql +++ b/sql/varnish.sql @@ -26,4 +26,12 @@ AS $$ INSERT INTO varnishqueue.queue (mode, consumerid, expr) SELECT 'X', consumerid, $1 FROM varnishqueue.consumers; NOTIFY varnishqueue; $$ LANGUAGE 'sql'; + +DROP FUNCTION IF EXISTS varnish_purge_xkey(key text); +CREATE OR REPLACE FUNCTION varnish_purge_xkey(key text) +RETURNS void +AS $$ + INSERT INTO varnishqueue.queue (mode, consumerid, expr) SELECT 'K', consumerid, $1 FROM varnishqueue.consumers; + NOTIFY varnishqueue; +$$ LANGUAGE 'sql'; COMMIT; diff --git a/sql/varnish_local.sql b/sql/varnish_local.sql index 30fe7360..926eb142 100644 --- a/sql/varnish_local.sql +++ b/sql/varnish_local.sql @@ -16,4 +16,9 @@ RETURNS void AS $$ $$ LANGUAGE 'sql'; -COMMIT; \ No newline at end of file +CREATE OR REPLACE FUNCTION varnish_purge_xkey(key text) +RETURNS void +AS $$ +$$ LANGUAGE 'sql'; + +COMMIT; diff --git a/tools/varnishqueue/varnish_queue.py b/tools/varnishqueue/varnish_queue.py index afbe7679..1e66ea57 100755 --- a/tools/varnishqueue/varnish_queue.py +++ b/tools/varnishqueue/varnish_queue.py @@ -63,6 +63,11 @@ def worker(consumerid, consumername, dsn): if not do_purge(consumername, {'X-Purge-Expr': r[2]}): failed = True continue + elif r[1] == 'K': + logging.info("Purging xkey %s on %s" % (r[2], consumername)) + if not do_purge(consumername, {'X-Purge-Xkey': r[2]}): + failed = True + continue else: logging.warning("Unknown purge type %s on %s, ignoring." % (r[1], consumername))