From owner-svn-ports-head@FreeBSD.ORG Sun Sep 14 03:58:17 2014 Return-Path: Delivered-To: svn-ports-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 82A7B417; Sun, 14 Sep 2014 03:58:17 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 6C782F2F; Sun, 14 Sep 2014 03:58:17 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s8E3wHdr045535; Sun, 14 Sep 2014 03:58:17 GMT (envelope-from swills@FreeBSD.org) Received: (from swills@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s8E3wFnP045521; Sun, 14 Sep 2014 03:58:15 GMT (envelope-from swills@FreeBSD.org) Message-Id: <201409140358.s8E3wFnP045521@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: swills set sender to swills@FreeBSD.org using -f From: Steve Wills Date: Sun, 14 Sep 2014 03:58:15 +0000 (UTC) To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r368157 - in head/www/py-graphite-web: . files X-SVN-Group: ports-head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-ports-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the ports tree for head List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 14 Sep 2014 03:58:17 -0000 Author: swills Date: Sun Sep 14 03:58:14 2014 New Revision: 368157 URL: http://svnweb.freebsd.org/changeset/ports/368157 QAT: https://qat.redports.org/buildarchive/r368157/ Log: www/py-graphite-web: add patches to make graphite work with django 1.7 While here, pet portlint and improve pkg-message a bit Reported by: brd Added: head/www/py-graphite-web/files/patch-webapp__graphite__browser__views.py (contents, props changed) head/www/py-graphite-web/files/patch-webapp__graphite__cli__views.py (contents, props changed) head/www/py-graphite-web/files/patch-webapp__graphite__dashboard__views.py (contents, props changed) head/www/py-graphite-web/files/patch-webapp__graphite__events__views.py (contents, props changed) head/www/py-graphite-web/files/patch-webapp__graphite__graphlot__views.py (contents, props changed) head/www/py-graphite-web/files/patch-webapp__graphite__metrics__views.py (contents, props changed) head/www/py-graphite-web/files/patch-webapp__graphite__render__views.py (contents, props changed) head/www/py-graphite-web/files/patch-webapp__graphite__whitelist__views.py (contents, props changed) Modified: head/www/py-graphite-web/Makefile head/www/py-graphite-web/files/patch-conf__graphite.wsgi.example head/www/py-graphite-web/files/pkg-message.in Modified: head/www/py-graphite-web/Makefile ============================================================================== --- head/www/py-graphite-web/Makefile Sun Sep 14 02:06:58 2014 (r368156) +++ head/www/py-graphite-web/Makefile Sun Sep 14 03:58:14 2014 (r368157) @@ -3,7 +3,7 @@ PORTNAME= graphite-web PORTVERSION= 0.9.12 -PORTREVISION= 1 +PORTREVISION= 2 CATEGORIES= www python MASTER_SITES= http://github.com/graphite-project/${PORTNAME}/archive/${PORTVERSION}.tar.gz?dummy=/ PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX} @@ -21,7 +21,7 @@ RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}cair FETCH_ARGS= -o ${DISTNAME}${EXTRACT_SUFX} USE_PYTHON= 2 -USE_PYDISTUTILS=yes +USE_PYTHON= distutils SUB_FILES= pkg-message SUB_LIST+= PYTHON_SITELIBDIR=${PYTHON_SITELIBDIR} WWWOWN=${WWWOWN} \ WWWGRP=${WWWGRP} DATADIR=${DATADIR} @@ -42,11 +42,11 @@ post-install: @(cd ${WRKSRC}/examples && ${COPYTREE_SHARE} . ${STAGEDIR}${DATADIR}/examples) @${MKDIR} ${STAGEDIR}${DATADIR}/content @(cd ${WRKSRC}/webapp/content && ${COPYTREE_SHARE} . ${STAGEDIR}${DATADIR}/content) - @${MKDIR} -p ${STAGEDIR}/var/log/graphite/webapp - @${MKDIR} -p ${STAGEDIR}/var/db/graphite + @${MKDIR} ${STAGEDIR}/var/log/graphite/webapp + @${MKDIR} ${STAGEDIR}/var/db/graphite @${CHOWN} ${WWWOWN} ${STAGEDIR}/var/log/graphite @${CHOWN} ${WWWOWN} ${STAGEDIR}/var/db/graphite @${CP} ${STAGEDIR}${PYTHON_SITELIBDIR}/graphite/local_settings.py.example ${STAGEDIR}${PREFIX}/etc/graphite/local_settings.py.example - @${LN} -s ${PREFIX}/etc/graphite/local_settings.py ${STAGEDIR}${PYTHON_SITELIBDIR}/graphite/local_settings.py + @${LN} -s ${PREFIX}/etc/graphite/local_settings.py ${STAGEDIR}${PYTHON_SITELIBDIR}/graphite/local_settings.py .include Modified: head/www/py-graphite-web/files/patch-conf__graphite.wsgi.example ============================================================================== --- head/www/py-graphite-web/files/patch-conf__graphite.wsgi.example Sun Sep 14 02:06:58 2014 (r368156) +++ head/www/py-graphite-web/files/patch-conf__graphite.wsgi.example Sun Sep 14 03:58:14 2014 (r368157) @@ -1,9 +1,14 @@ ---- ./conf/graphite.wsgi.example.orig 2013-08-21 17:11:04.000000000 +0000 -+++ ./conf/graphite.wsgi.example 2014-02-12 20:50:27.343398788 +0000 -@@ -1,5 +1,5 @@ +--- conf/graphite.wsgi.example.orig 2013-08-21 17:11:04.000000000 +0000 ++++ conf/graphite.wsgi.example 2014-09-14 03:30:45.456594225 +0000 +@@ -1,8 +1,10 @@ import os, sys -sys.path.append('/opt/graphite/webapp') +sys.path.append('%%PREFIX%%/graphite/webapp') os.environ['DJANGO_SETTINGS_MODULE'] = 'graphite.settings' ++import django import django.core.handlers.wsgi ++django.setup() + + application = django.core.handlers.wsgi.WSGIHandler() + Added: head/www/py-graphite-web/files/patch-webapp__graphite__browser__views.py ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/www/py-graphite-web/files/patch-webapp__graphite__browser__views.py Sun Sep 14 03:58:14 2014 (r368157) @@ -0,0 +1,23 @@ +--- webapp/graphite/browser/views.py.orig 2014-09-14 03:00:52 UTC ++++ webapp/graphite/browser/views.py +@@ -77,7 +77,7 @@ + + index_file.close() + result_string = ','.join(results) +- return HttpResponse(result_string, mimetype='text/plain') ++ return HttpResponse(result_string, content_type='text/plain') + + + def myGraphLookup(request): +@@ -254,9 +254,9 @@ + #json = str(nodes) #poor man's json encoder for simple types + json_data = json.dumps(nodes) + if jsonp: +- response = HttpResponse("%s(%s)" % (jsonp, json_data),mimetype="text/javascript") ++ response = HttpResponse("%s(%s)" % (jsonp, json_data),content_type="text/javascript") + else: +- response = HttpResponse(json_data,mimetype="application/json") ++ response = HttpResponse(json_data,content_type="application/json") + response['Pragma'] = 'no-cache' + response['Cache-Control'] = 'no-cache' + return response Added: head/www/py-graphite-web/files/patch-webapp__graphite__cli__views.py ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/www/py-graphite-web/files/patch-webapp__graphite__cli__views.py Sun Sep 14 03:58:14 2014 (r368157) @@ -0,0 +1,42 @@ +--- webapp/graphite/cli/views.py.orig 2014-09-14 03:00:52 UTC ++++ webapp/graphite/cli/views.py +@@ -40,7 +40,7 @@ + def evaluate(request): + if 'commandInput' not in request.GET: + output = commands.stderr("No commandInput parameter!") +- return HttpResponse(output, mimetype='text/plain') ++ return HttpResponse(output, content_type='text/plain') + + #Variable substitution + profile = getProfile(request) +@@ -59,7 +59,7 @@ + cmd = cmd[:i] + my_vars[var] + cmd[j:] + else: + output = commands.stderr("Unknown variable %s" % var) +- return HttpResponse(output, mimetype='text/plain') ++ return HttpResponse(output, content_type='text/plain') + + if cmd == '?': cmd = 'help' + +@@ -68,13 +68,13 @@ + + if not tokens.command: + output = commands.stderr("Invalid syntax") +- return HttpResponse(output, mimetype='text/plain') ++ return HttpResponse(output, content_type='text/plain') + + handler_name = '_' + tokens.command + handler = vars(commands).get(handler_name) + if handler is None: + output = commands.stderr("Unknown command") +- return HttpResponse(output, mimetype='text/plain') ++ return HttpResponse(output, content_type='text/plain') + + args = dict( tokens.items() ) + del args['command'] +@@ -89,4 +89,4 @@ + profile.history = '\n'.join(history) + profile.save() + +- return HttpResponse(output, mimetype='text/plain') ++ return HttpResponse(output, content_type='text/plain') Added: head/www/py-graphite-web/files/patch-webapp__graphite__dashboard__views.py ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/www/py-graphite-web/files/patch-webapp__graphite__dashboard__views.py Sun Sep 14 03:58:14 2014 (r368157) @@ -0,0 +1,8 @@ +--- webapp/graphite/dashboard/views.py.orig 2014-09-14 03:00:52 UTC ++++ webapp/graphite/dashboard/views.py +@@ -249,4 +249,4 @@ + + + def json_response(obj): +- return HttpResponse(mimetype='application/json', content=json.dumps(obj)) ++ return HttpResponse(content_type='application/json', content=json.dumps(obj)) Added: head/www/py-graphite-web/files/patch-webapp__graphite__events__views.py ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/www/py-graphite-web/files/patch-webapp__graphite__events__views.py Sun Sep 14 03:58:14 2014 (r368157) @@ -0,0 +1,16 @@ +--- webapp/graphite/events/views.py.orig 2014-09-14 03:00:52 UTC ++++ webapp/graphite/events/views.py +@@ -65,11 +65,11 @@ + response = HttpResponse( + "%s(%s)" % (request.REQUEST.get('jsonp'), + json.dumps(fetch(request), cls=EventEncoder)), +- mimetype='text/javascript') ++ content_type='text/javascript') + else: + response = HttpResponse( + json.dumps(fetch(request), cls=EventEncoder), +- mimetype="application/json") ++ content_type="application/json") + return response + + def fetch(request): Added: head/www/py-graphite-web/files/patch-webapp__graphite__graphlot__views.py ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/www/py-graphite-web/files/patch-webapp__graphite__graphlot__views.py Sun Sep 14 03:58:14 2014 (r368157) @@ -0,0 +1,46 @@ +--- webapp/graphite/graphlot/views.py.orig 2014-09-14 03:00:52 UTC ++++ webapp/graphite/graphlot/views.py +@@ -52,7 +52,7 @@ + ) for timeseries in seriesList ] + if not result: + raise Http404 +- return HttpResponse(json.dumps(result), mimetype="application/json") ++ return HttpResponse(json.dumps(result), content_type="application/json") + + + def find_metric(request): +@@ -61,11 +61,11 @@ + query = str( request.REQUEST['q'] ) + except: + return HttpResponseBadRequest( +- content="Missing required parameter 'q'", mimetype="text/plain") ++ content="Missing required parameter 'q'", content_type="text/plain") + + matches = list( STORE.find(query+"*") ) + content = "\n".join([node.metric_path for node in matches ]) +- response = HttpResponse(content, mimetype='text/plain') ++ response = HttpResponse(content, content_type='text/plain') + + return response + +@@ -118,7 +118,7 @@ + + index_file.close() + result_string = ','.join(results) +- return HttpResponse(result_string, mimetype='text/plain') ++ return HttpResponse(result_string, content_type='text/plain') + + + def myGraphLookup(request): +@@ -256,9 +256,9 @@ + jsonp = False + json_data = json.dumps(nodes) + if jsonp: +- response = HttpResponse("%s(%s)" % (jsonp, json_data),mimetype="text/javascript") ++ response = HttpResponse("%s(%s)" % (jsonp, json_data),content_type="text/javascript") + else: +- response = HttpResponse(json_data,mimetype="application/json") ++ response = HttpResponse(json_data,content_type="application/json") + response['Pragma'] = 'no-cache' + response['Cache-Control'] = 'no-cache' + return response Added: head/www/py-graphite-web/files/patch-webapp__graphite__metrics__views.py ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/www/py-graphite-web/files/patch-webapp__graphite__metrics__views.py Sun Sep 14 03:58:14 2014 (r368157) @@ -0,0 +1,126 @@ +--- webapp/graphite/metrics/views.py.orig 2014-09-14 03:00:52 UTC ++++ webapp/graphite/metrics/views.py +@@ -71,16 +71,16 @@ + for m in sorted(matches) + ] + if jsonp: +- return HttpResponse("%s(%s)" % (jsonp, json.dumps(matches)), mimetype='text/javascript') ++ return HttpResponse("%s(%s)" % (jsonp, json.dumps(matches)), content_type='text/javascript') + else: +- return HttpResponse(json.dumps(matches), mimetype='application/json') ++ return HttpResponse(json.dumps(matches), content_type='application/json') + + + def search_view(request): + try: + query = str( request.REQUEST['query'] ) + except: +- return HttpResponseBadRequest(content="Missing required parameter 'query'", mimetype="text/plain") ++ return HttpResponseBadRequest(content="Missing required parameter 'query'", content_type="text/plain") + search_request = { + 'query' : query, + 'max_results' : int( request.REQUEST.get('max_results', 25) ), +@@ -91,7 +91,7 @@ + + results = sorted(searcher.search(**search_request)) + result_data = json.dumps( dict(metrics=results) ) +- return HttpResponse(result_data, mimetype='application/json') ++ return HttpResponse(result_data, content_type='application/json') + + + def context_view(request): +@@ -99,7 +99,7 @@ + contexts = [] + + if not 'metric' not in request.GET: +- return HttpResponse('{ "error" : "missing required parameter \"metric\"" }', mimetype='application/json') ++ return HttpResponse('{ "error" : "missing required parameter \"metric\"" }', content_type='application/json') + + for metric in request.GET.getlist('metric'): + try: +@@ -110,19 +110,19 @@ + contexts.append({ 'metric' : metric, 'context' : context }) + + content = json.dumps( { 'contexts' : contexts } ) +- return HttpResponse(content, mimetype='application/json') ++ return HttpResponse(content, content_type='application/json') + + elif request.method == 'POST': + + if 'metric' not in request.POST: +- return HttpResponse('{ "error" : "missing required parameter \"metric\"" }', mimetype='application/json') ++ return HttpResponse('{ "error" : "missing required parameter \"metric\"" }', content_type='application/json') + + newContext = dict( item for item in request.POST.items() if item[0] != 'metric' ) + + for metric in request.POST.getlist('metric'): + STORE.get(metric).updateContext(newContext) + +- return HttpResponse('{ "success" : true }', mimetype='application/json') ++ return HttpResponse('{ "success" : true }', content_type='application/json') + + else: + return HttpResponseBadRequest("invalid method, must be GET or POST") +@@ -140,7 +140,7 @@ + try: + query = str( request.REQUEST['query'] ) + except: +- return HttpResponseBadRequest(content="Missing required parameter 'query'", mimetype="text/plain") ++ return HttpResponseBadRequest(content="Missing required parameter 'query'", content_type="text/plain") + + if '.' in query: + base_path = query.rsplit('.', 1)[0] + '.' +@@ -175,11 +175,11 @@ + + if format == 'treejson': + content = tree_json(matches, base_path, wildcards=profile.advancedUI or wildcards, contexts=contexts) +- response = HttpResponse(content, mimetype='application/json') ++ response = HttpResponse(content, content_type='application/json') + + elif format == 'pickle': + content = pickle_nodes(matches, contexts=contexts) +- response = HttpResponse(content, mimetype='application/pickle') ++ response = HttpResponse(content, content_type='application/pickle') + + elif format == 'completer': + #if len(matches) == 1 and (not matches[0].isLeaf()) and query == matches[0].metric_path + '*': # auto-complete children +@@ -196,10 +196,10 @@ + results.append(wildcardNode) + + content = json.dumps({ 'metrics' : results }) +- response = HttpResponse(content, mimetype='application/json') ++ response = HttpResponse(content, content_type='application/json') + + else: +- return HttpResponseBadRequest(content="Invalid value for 'format' parameter", mimetype="text/plain") ++ return HttpResponseBadRequest(content="Invalid value for 'format' parameter", content_type="text/plain") + + response['Pragma'] = 'no-cache' + response['Cache-Control'] = 'no-cache' +@@ -235,7 +235,7 @@ + 'results' : results + } + +- response = HttpResponse(json.dumps(result), mimetype='application/json') ++ response = HttpResponse(json.dumps(result), content_type='application/json') + response['Pragma'] = 'no-cache' + response['Cache-Control'] = 'no-cache' + return response +@@ -252,7 +252,7 @@ + log.exception() + results[metric] = dict(error="Unexpected error occurred in CarbonLink.get_metadata(%s, %s)" % (metric, key)) + +- return HttpResponse(json.dumps(results), mimetype='application/json') ++ return HttpResponse(json.dumps(results), content_type='application/json') + + + def set_metadata_view(request): +@@ -287,7 +287,7 @@ + else: + results = dict(error="Invalid request method") + +- return HttpResponse(json.dumps(results), mimetype='application/json') ++ return HttpResponse(json.dumps(results), content_type='application/json') + + + def tree_json(nodes, base_path, wildcards=False, contexts=False): Added: head/www/py-graphite-web/files/patch-webapp__graphite__render__views.py ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/www/py-graphite-web/files/patch-webapp__graphite__render__views.py Sun Sep 14 03:58:14 2014 (r368157) @@ -0,0 +1,58 @@ +--- webapp/graphite/render/views.py.orig 2013-08-21 17:11:04.000000000 +0000 ++++ webapp/graphite/render/views.py 2014-09-14 03:52:01.676505998 +0000 +@@ -116,7 +116,7 @@ + + format = requestOptions.get('format') + if format == 'csv': +- response = HttpResponse(mimetype='text/csv') ++ response = HttpResponse(content_type='text/csv') + writer = csv.writer(response, dialect='excel') + + for series in data: +@@ -136,16 +136,16 @@ + if 'jsonp' in requestOptions: + response = HttpResponse( + content="%s(%s)" % (requestOptions['jsonp'], json.dumps(series_data)), +- mimetype='text/javascript') ++ content_type='text/javascript') + else: +- response = HttpResponse(content=json.dumps(series_data), mimetype='application/json') ++ response = HttpResponse(content=json.dumps(series_data), content_type='application/json') + + response['Pragma'] = 'no-cache' + response['Cache-Control'] = 'no-cache' + return response + + if format == 'raw': +- response = HttpResponse(mimetype='text/plain') ++ response = HttpResponse(content_type='text/plain') + for series in data: + response.write( "%s,%d,%d,%d|" % (series.name, series.start, series.end, series.step) ) + response.write( ','.join(map(str,series)) ) +@@ -158,7 +158,7 @@ + graphOptions['outputFormat'] = 'svg' + + if format == 'pickle': +- response = HttpResponse(mimetype='application/pickle') ++ response = HttpResponse(content_type='application/pickle') + seriesInfo = [series.getInfo() for series in data] + pickle.dump(seriesInfo, response, protocol=-1) + +@@ -177,7 +177,7 @@ + if useSVG and 'jsonp' in requestOptions: + response = HttpResponse( + content="%s(%s)" % (requestOptions['jsonp'], json.dumps(image)), +- mimetype='text/javascript') ++ content_type='text/javascript') + else: + response = buildResponse(image, useSVG and 'image/svg+xml' or 'image/png') + +@@ -386,7 +386,7 @@ + + + def buildResponse(imageData, mimetype="image/png"): +- response = HttpResponse(imageData, mimetype=mimetype) ++ response = HttpResponse(imageData, content_type=mimetype) + response['Cache-Control'] = 'no-cache' + response['Pragma'] = 'no-cache' + return response Added: head/www/py-graphite-web/files/patch-webapp__graphite__whitelist__views.py ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/www/py-graphite-web/files/patch-webapp__graphite__whitelist__views.py Sun Sep 14 03:58:14 2014 (r368157) @@ -0,0 +1,25 @@ +--- webapp/graphite/whitelist/views.py.orig 2014-09-14 03:00:52 UTC ++++ webapp/graphite/whitelist/views.py +@@ -25,19 +25,19 @@ + whitelist = load_whitelist() + new_whitelist = whitelist | metrics + save_whitelist(new_whitelist) +- return HttpResponse(mimetype="text/plain", content="OK") ++ return HttpResponse(content_type="text/plain", content="OK") + + def remove(request): + metrics = set( request.POST['metrics'].split() ) + whitelist = load_whitelist() + new_whitelist = whitelist - metrics + save_whitelist(new_whitelist) +- return HttpResponse(mimetype="text/plain", content="OK") ++ return HttpResponse(content_type="text/plain", content="OK") + + def show(request): + whitelist = load_whitelist() + members = '\n'.join( sorted(whitelist) ) +- return HttpResponse(mimetype="text/plain", content=members) ++ return HttpResponse(content_type="text/plain", content=members) + + def load_whitelist(): + fh = open(settings.WHITELIST_FILE, 'rb') Modified: head/www/py-graphite-web/files/pkg-message.in ============================================================================== --- head/www/py-graphite-web/files/pkg-message.in Sun Sep 14 02:06:58 2014 (r368156) +++ head/www/py-graphite-web/files/pkg-message.in Sun Sep 14 03:58:14 2014 (r368157) @@ -1,7 +1,25 @@ -============================================================================== +======================================================================== + +Please note that this port/package overrides the default installation layout +for Graphite! To setup graphite, you will need to: + +* Set the SECRET_KEY in %%PREFIX%%/etc/graphite/local_settings.py + +* Initialize the sqlite user database and create the admin user: + + python2 %%PYTHON_SITELIBDIR%%/graphite/manage.py syncdb + +* Build the index: + + %%PREFIX%%/bin/build-index.sh + +* Change the ownership of the user database so the webapp can write to it: + + chown -R %%WWWOWN%%:%%WWWGRP%% /var/db/graphite/ /var/log/graphite/ -To run graphite, you will need to setup Apache by creating a vhost similar to -the following: +* Setup a web server: + +Setup Apache by creating a vhost similar to the following: ServerName graphite @@ -56,20 +74,6 @@ the following: -You should set the SECRET_KEY in %%PREFIX%%/etc/graphite/local_settings.py - -Then initialize the sqlite user database and create the admin user: - - python2 %%PYTHON_SITELIBDIR%%/graphite/manage.py syncdb - -Then build the index: - - %%PREFIX%%/bin/build-index.sh - -Change the ownership of the user database so the webapp can write to it: - - chown -R %%WWWOWN%%:%%WWWGRP%% /var/db/graphite/ /var/log/graphite/ - Now you should be able to access the graphite virtual host you created in the first step.