OS: CentOS 5.1 Linux
Intro:
This document explains how to install ReviewBoard on CentOS 5.1. It guides you from the needed python modules, memcached server, Django framework and Apache 2 VirtualHost setup.
I hope this helps someone.
Assumptions:
I assume you have installed basic compiling software (gcc, gcc-c++), apache2, mysql, mysql-server, python, mod-python, subversion.
Apart from these, we also need some devel libraries of: mysql-devel, python-devel, subversion-devel.
I further assume You are placing all source tars in /usr/local/src, and that /var/www/html is the DocumentRoot of Apache web server.
Install:
First we need some additional modules for python: MySQLdb-python and pysvn.
MySQLdb-python
Even CentOS 5.1 has the modules as a package, it is broken, and we need to recompile new one from source. First get the source from official pages at http://sourceforge.net/projects/mysqldb-python (version 1.2.2). Untar it and enter new folder. Read README file. For the lazy ones build first and install as root:
$ python setup.py build
# python setup.py install
pysvn
This enables Python communication to Subversion. As CentOS 5.1 doesn’t have a package, we will compile this from source. Get the tar from http://pysvn.tigris.org. Additionaly, we need gcc-c++ and neon-devel packages, hence, if your system doesn’t have them user yum to add these.
Read INSTALL.html for installation instructions and referr to section “Building on unix and Mac OS X systems.”
We are finished with python modules for now. This is all I had to add on CentOS 5.1 to successifully run ReviewBoard.
The next software is not necessary but helps improve performance of our targer software ReviewBoard.
memcached
I need libevent-devel before compiling memcached:
# yum install libevent-devel
Next get the memcached tar:
$ wget http://www.danga.com/memcached/dist/memcached-1.2.4.tar.gz
$ tar xzvfp memcached*
Configure it and install:
$ ./configure –with-libevent=/usr/lib/
# make install
Now we add user memcached since we don’t need to run as root:
# adduser memcached
Next, start the server with the following line. This line is added to /etc/rc.local to start with every boot:
/usr/local/bin/memcached -u memcached -d -m 48 -l 192.168.0.200 -p 11211
Links:
[m] http://crazytoon.com/2008/01/20/memcached-how-do-you-install-memcached-centos-64-bit-linux-redhat-fedora/
Now we need to enable python to talk to memcached. We need libmemcache – C API for memcache, and cmemcache – python extension for libmemcache.
libmemcache
http://people.freebsd.org/~seanc/libmemcache/
There is not much to say here. Run the following commands, and it should get you down the road
$ wget http://people.freebsd.org/~seanc/libmemcache/libmemcache-1.4.0.rc2.tar.bz2
$ tar xjvf libmemcache*
$ cd libmemcache-1.4.0.rc2
$ ./configure
$ make
# make install
cmemcache
http://gijsbert.org/cmemcache/index.html
If you are interested, read the official pages for more information, but the following commands should get you cmemcached installed.
$ wget http://gijsbert.org/downloads/cmemcache/cmemcache-0.91.tar.bz2
$ tar xjvf cmemcache*
$ cd cmemcache-0.91
# python setup.py install
Now it’s time to install Django framework and finally ReviewBoard.
Django
http://www.djangoproject.com
We are using svn version of Django framework:
$ svn co http://code.djangoproject.com/svn/django/trunk django_src
$ cd django_src
# python setup.py install
That’s all to it.
ReviewBoard
http://code.google.com/reviewboard/wiki/GettingStarted
NOTE: I will put mine RB installation in /var/www/rb, but it shouldn’t matter if you put it to /opt/ or /usr/local/ or something else, just pay attention to paths for web server configuration.
Here we are using source version:
$ svn co http://reviewboard.googlecode.com/svn/trunk/ rb
After checkout enter the directory reviewboard, copy setting_local.py.tmpl to setting_local.py and edit. Here you add database settings (chose engine, connection parameters, cache backend, time-zone)
Now we create database:
$ ./manage.py syncdb
Run the test server:
$ ./manage.py runserver
or add another IP addres to listen on
$ ./manage.py runserver 192.168.0.200:8000
Test it with your browser. If that’ok, I assume you want to run it through Apache (or similar) web server, because this embedded server is relly slow for production use.
Now we set up VirtualHost in Apache. There is a copy of my /etc/httpd/conf.d/reviewboard.conf in this folder. Use this as a reference, and change according to your paths and needs.
NOTE: If this is the first VirtualHost you must uncomment line in /etc/httpd/conf/httpd.conf saying NameVirtualHost *:80 to enable named virtual hosting. If you are using DNS add this new domain to it’s base, or change your /etc/hosts file(s) on local machines.
If you are using SELinux (as CentOS is) you must change security context for this new folder so httpd user can access it:
# chown -R apache.apache /var/www/rb
# chcon -R -h -t http_sys_content_t /var/www/rb
ADDITIONAL SETTINGS:
file: /var/www/rb/reviewboard/settings_local.py
- Disable user registration. Only admin can register new users.
BUILTIN_AUTH = False
- Require log-in to view any part of ReviewBoard
REQUIRE_SITEWIDE_LOGIN = True


15 Responses
Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.
Nice document. But I can’t seem to get your /etc/httpd/conf.d/reviewboard.conf. Can you post it here? Thanks,
Oh, I will upload it here soon
Did you manage to upload the /etc/httpd/conf.d/reviewboard.conf? I’m kind of stuck in my reviewboard installation with directory dependencies…
Here’s the conf file:
http://pletisan.rs.ba/reviewboard.conf
Hope it helps You!
please support for me create a structure SVN, and how to use it with reviewboard.
thanks you so much!
I am not sure I’ve understood You very well…
We are using ’standard’ SVN structure (tag/branch/trunk) and reviewboard is pointed to trunk part.
Or I missed the question…
the apache conf can’t be access, can you post it in your blog?
Here it will be: http://pastebin.com/f3ae9da5f
Igor,
I might be missing something big time. When I issued “./manage.py syncdb”, I got the following error message:
[root@nss reviewboard]# ./manage.py syncdb
[WARN@1231752776.612255] mcm_server_add3():2082: unable to lookup/resolve host: Servname not supported for ai_socktype
Traceback (most recent call last):
File “./manage.py”, line 134, in ?
execute_manager(settings)
File “/usr/lib/python2.4/site-packages/django/core/management/__init__.py”, line 340, in execute_manager
utility.execute()
File “/usr/lib/python2.4/site-packages/django/core/management/__init__.py”, line 295, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File “/usr/lib/python2.4/site-packages/django/core/management/base.py”, line 195, in run_from_argv
self.execute(*args, **options.__dict__)
File “/usr/lib/python2.4/site-packages/django/core/management/base.py”, line 221, in execute
self.validate()
File “/usr/lib/python2.4/site-packages/django/core/management/base.py”, line 249, in validate
num_errors = get_validation_errors(s, app)
File “/usr/lib/python2.4/site-packages/django/core/management/validation.py”, line 28, in get_validation_errors
for (app_name, error) in get_app_errors().items():
File “/usr/lib/python2.4/site-packages/django/db/models/loading.py”, line 128, in get_app_errors
self._populate()
File “/usr/lib/python2.4/site-packages/django/db/models/loading.py”, line 57, in _populate
self.load_app(app_name, True)
File “/usr/lib/python2.4/site-packages/django/db/models/loading.py”, line 72, in load_app
mod = __import__(app_name, {}, {}, ['models'])
File “/usr/local/rb/reviewboard/accounts/models.py”, line 9, in ?
from reviewboard.reviews.models import Group, ReviewRequest
File “/usr/local/rb/reviewboard/reviews/models.py”, line 17, in ?
from djblets.util.templatetags.djblets_images import crop_image, thumbnail
File “/usr/local/rb/reviewboard/djblets/util/templatetags/djblets_images.py”, line 32, in ?
import Image
ImportError: No module named Image
[root@nss reviewboard]#
Able to provide some help? Thanks.
when I try to do make on the pysvn/Source after I do the configure, I get lots of these:
/usr/include/subversion-1/svn_string.h:235: error: ‘apr_size_t’ has not been declared
/usr/include/subversion-1/svn_string.h:263: error: ‘apr_size_t’ does not name a type
/usr/include/subversion-1/svn_string.h:271: error: ‘apr_size_t’ does not name a type
make: *** [generate_svn_error_codes/generate_svn_error_codes] Error 1
Any suggestion on why I get these errors?
Thanks
You need to install apr-devel
To the guy that said this:
“when I try to do make on the pysvn/Source after I do the configure, I get lots of these:
/usr/include/subversion-1/svn_string.h:235: error: ‘apr_size_t’ has not been declared
/usr/include/subversion-1/svn_string.h:263: error: ‘apr_size_t’ does not name a type
/usr/include/subversion-1/svn_string.h:271: error: ‘apr_size_t’ does not name a type
make: *** [generate_svn_error_codes/generate_svn_error_codes] Error 1″
hi,
iam trying to install on centos5.3 and mysql Ver 14.12 Distrib 5.0.45, svn 1.5.6, python2.4, pysvn 1.7.0 also tried with 1.6.3.
i don't understand test in the pysvn is giving errors.
i followed exactly what ever given in review board admin guide.
but test in pysvn giving error (make)
can you help me how to solve it
thanks a lot
Can You post what errors it gives?
[root@localhost Tests]# make
rm -rf testroot-01
PATH=/usr/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/home/phaneendra.gb/bin PYTHON=/usr/bin/python ./test-01.sh (lessthansym)test-01.unix.new.log 2lessthansym)&1
/usr/bin/python benchmark_diff.py test-01.unix.known_good-1.5.log test-01.unix.new.log
Info: Comparing test-01.unix.known_good-1.5.log
Info: Against test-01.unix.new.log
Error: Test failed – test-01.unix.new.log
Error: ——————————————————————————–
Error: Result(642) insert A workdir/Tests/testroot-01/wc3/test-branch/file-merge-3.txt
Error: Result(643) insert U workdir/Tests/testroot-01/wc3/test-branch
Error: Result(644) insert U workdir/Tests/testroot-01/wc3/test-branch/file-merge-2.txt
Error: Result(645) insert merge_begin workdir/Tests/testroot-01/wc3/test-branch/file-merge-3.txt
Error: Result(646) insert skip workdir/Tests/testroot-01/wc3/test-branch/file-merge-1.txt
Error: ——————————————————————————–
Error: Benchmark(644) delete M workdir/Tests/testroot-01/wc3/test-branch
Error: ——————————————————————————–
Error: Benchmark(646) replace MM workdir/Tests/testroot-01/wc3/test-branch/file-merge-2.txt
Error: Result(650) replace M workdir/Tests/testroot-01/wc3/test-branch/file-merge-2.txt
Error: ——————————————————————————–
Error: Benchmark(648) delete M workdir/Tests/testroot-01/wc3/test-branch/file1.txt
Error: Benchmark(649) delete M workdir/Tests/testroot-01/wc3/test-branch/file1b.txt
Error: Benchmark(650) delete M workdir/Tests/testroot-01/wc3/test-branch/file2b.txt
Error: Benchmark(651) delete M workdir/Tests/testroot-01/wc3/test-branch/file3b.txt
Error: Benchmark(652) delete M workdir/Tests/testroot-01/wc3/test-branch/file4.txt
Error: Benchmark(653) delete M workdir/Tests/testroot-01/wc3/test-branch/file5.txt
Error: ——————————————————————————–
Error: Benchmark(656) delete
Error: Benchmark(657) delete Property changes on: workdir/Tests/testroot-01/wc3/test-branch
.
.
.
Error: Benchmark(721) delete Merged /trunk/test/file1.txt:r17
Error: Benchmark(722) delete
Error: ——————————————————————————–
make: *** [test-01.unix.new.log] Error 1
i went through test-01.unix.new.log file there is some diffs present but not much information present.
like
Index: /home/phaneendra.gb/Desktop/pysvn-1.6.3/Tests/testroot-01/wc2/test/file1b.txt
===================================================================
— /home/phaneendra.gb/Desktop/pysvn-1.6.3/Tests/testroot-01/wc2/test/file1b.txt (revision 9)
+++ /home/phaneendra.gb/Desktop/pysvn-1.6.3/Tests/testroot-01/wc2/test/file1b.txt (working copy)
@@ -1,2 +1,3 @@
test add file 1
line 2
+new line
i am very new to this and ???? how to solve it
Hi,Igor
Thanks for your guide, however, I encountered a problem when visit my RB. Following is the error message:
Traceback (most recent call last):
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/core/handlers/base.py”, line 92, in get_response
response = callback(request, *callback_args, **callback_kwargs)
File “/usr/lib/python2.4/site-packages/Djblets-0.5.9-py2.4.egg/djblets/auth/views.py”, line 85, in login
return render_to_response(template_name, context)
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/shortcuts/__init__.py”, line 20, in render_to_response
return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/template/loader.py”, line 108, in render_to_string
return t.render(context_instance)
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/template/__init__.py”, line 178, in render
return self.nodelist.render(context)
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/template/__init__.py”, line 779, in render
bits.append(self.render_node(node, context))
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/template/__init__.py”, line 792, in render_node
return node.render(context)
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/template/loader_tags.py”, line 97, in render
return compiled_parent.render(context)
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/template/__init__.py”, line 178, in render
return self.nodelist.render(context)
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/template/__init__.py”, line 779, in render
bits.append(self.render_node(node, context))
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/template/__init__.py”, line 792, in render_node
return node.render(context)
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/template/loader_tags.py”, line 24, in render
result = self.nodelist.render(context)
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/template/__init__.py”, line 779, in render
bits.append(self.render_node(node, context))
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/template/__init__.py”, line 792, in render_node
return node.render(context)
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/template/defaulttags.py”, line 244, in render
return self.nodelist_false.render(context)
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/template/__init__.py”, line 779, in render
bits.append(self.render_node(node, context))
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/template/__init__.py”, line 792, in render_node
return node.render(context)
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/template/defaulttags.py”, line 370, in render
url = reverse(self.view_name, args=args, kwargs=kwargs, current_app=context.current_app)
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/core/urlresolvers.py”, line 349, in reverse
return iri_to_uri(u’%s%s’ % (prefix, resolver.reverse(view,
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/core/urlresolvers.py”, line 275, in reverse
possibilities = self.reverse_dict.getlist(lookup_view)
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/core/urlresolvers.py”, line 195, in _get_reverse_dict
self._populate()
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/core/urlresolvers.py”, line 175, in _populate
for name in pattern.reverse_dict:
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/core/urlresolvers.py”, line 195, in _get_reverse_dict
self._populate()
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/core/urlresolvers.py”, line 175, in _populate
for name in pattern.reverse_dict:
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/core/urlresolvers.py”, line 195, in _get_reverse_dict
self._populate()
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/core/urlresolvers.py”, line 164, in _populate
for pattern in reversed(self.url_patterns):
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/core/urlresolvers.py”, line 245, in _get_url_patterns
patterns = getattr(self.urlconf_module, “urlpatterns”, self.urlconf_module)
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/core/urlresolvers.py”, line 240, in _get_urlconf_module
self._urlconf_module = import_module(self.urlconf_name)
File “/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg/django/utils/importlib.py”, line 35, in import_module
__import__(name)
File “/usr/lib/python2.4/site-packages/ReviewBoard-1.0.6-py2.4.egg/reviewboard/admin/urls.py”, line 4, in ?
from reviewboard.admin import forms
File “/usr/lib/python2.4/site-packages/ReviewBoard-1.0.6-py2.4.egg/reviewboard/admin/forms.py”, line 1, in ?
import pytz
ImportError: No module named pytz
<ModPythonRequest
path:/review/account/login/,
GET:,
POST:,
COOKIES:{‘rbsessionid’: ‘a982f9053583aef9a5ee5e731c1cd3ba’},
META:{‘AUTH_TYPE’: None,
‘CONTENT_LENGTH’: 0,
‘CONTENT_TYPE’: None,
‘GATEWAY_INTERFACE’: ‘CGI/1.1′,
‘HTTP_ACCEPT’: ‘text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8′,
‘HTTP_ACCEPT_CHARSET’: ‘ISO-8859-1,utf-8;q=0.7,*;q=0.7′,
‘HTTP_ACCEPT_ENCODING’: ‘gzip,deflate’,
‘HTTP_ACCEPT_LANGUAGE’: ‘en,en-us;q=0.7,ar;q=0.3′,
‘HTTP_CONNECTION’: ‘keep-alive’,
‘HTTP_COOKIE’: ‘rbsessionid=a982f9053583aef9a5ee5e731c1cd3ba’,
‘HTTP_HOST’: ‘147.128.104.190′,
‘HTTP_KEEP_ALIVE’: ‘300′,
‘HTTP_USER_AGENT’: ‘Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8′,
‘PATH_INFO’: u’/review/account/login/’,
‘PATH_TRANSLATED’: None,
‘QUERY_STRING’: ‘next_page=/review/dashboard/’,
‘REMOTE_ADDR’: ‘147.128.104.64′,
‘REMOTE_HOST’: None,
‘REMOTE_IDENT’: None,
‘REMOTE_USER’: None,
‘REQUEST_METHOD’: ‘GET’,
‘SCRIPT_NAME’: ”,
‘SERVER_NAME’: ‘147.128.104.190′,
‘SERVER_PORT’: 80,
‘SERVER_PROTOCOL’: ‘HTTP/1.1′,
‘SERVER_SOFTWARE’: ‘mod_python’}>
Seems that can not find pytz module. However, when I use python directly, i can import this module, like following:
[root@tieguanying site-packages]# python
Python 2.4.3 (#1, Sep 3 2009, 15:37:37)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.
>>> import pytz
>>>
>>> import sys
>>> sys.path
['/usr/lib/python2.4/site-packages/ReviewBoard-1.0.6-py2.4.egg', '/usr/lib/python2.4/site-packages/pytz-2010g-py2.4.egg', '/usr/lib/python2.4/site-packages/flup-1.0.3.dev_20100221-py2.4.egg', '/usr/lib/python2.4/site-packages/Pygments-1.3.1-py2.4.egg', '/usr/lib/python2.4/site-packages/Djblets-0.5.9-py2.4.egg', '/usr/lib/python2.4/site-packages/django_evolution-0.0.0-py2.4.egg', '/usr/lib/python2.4/site-packages/Django-1.1.1-py2.4.egg', '/usr/lib/python2.4/site-packages/PIL-1.1.6-py2.4-linux-x86_64.egg', '', '/usr/lib/python2.4/site-packages/setuptools-0.6c11-py2.4.egg', '/usr/lib64/python24.zip', '/usr/lib64/python2.4', '/usr/lib64/python2.4/plat-linux2', '/usr/lib64/python2.4/lib-tk', '/usr/lib64/python2.4/lib-dynload', '/usr/lib64/python2.4/site-packages', '/usr/lib64/python2.4/site-packages/Numeric', '/usr/lib64/python2.4/site-packages/gtk-2.0']
>>>
Do you have any idea about this? Thanks