Wednesday, October 7, 2009

SVN and Trac - Ubuntu 9.04 Server

Machine Info:
root@mydomain:/projects/trac# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=9.04
DISTRIB_CODENAME=jaunty
DISTRIB_DESCRIPTION="Ubuntu 9.04"

My server has following directories created on it.
root@mydomain:~# mkdir /projects
root@mydomain:~# mkdir /projects/svn
root@mydomain:~# mkdir /projects/trac
root@mydomain:~# mkdir /projects/files

Enable dav_fs as follows:
root@mydomain:~# a2enmod dav_fs

First we will tell Apache that any and all requests for the (virtual) folder projects should be handled by Trac.

root@mydomain:~# aptitude install subversion libapache2-svn
Reading package lists... Done
Building dependency tree
Reading state information... Done
Reading extended state information
Initializing package states... Done

Installed TRAC as follows:
root@mydomain:/home/wiz# aptitude install libapache2-svn python-setuptools python-subversion
root@mydomain:/home/wiz# aptitude install python-mysqldb
root@mydomain:/projects/trac# wget http://ftp.edgewall.com/pub/trac/Trac-0.11.5.tar.gz
root@mydomain:/projects/trac# tar -xzf Trac-0.11.5.tar.gz
root@mydomain:/projects/trac# cd Trac-0.11.5
root@mydomain:/projects/trac/Trac-0.11.5# python setup.py install

Made changes in /etc/apache2/sites-available/default as follows:
#
# >>> Added for Mgmt of software with Trac/svn
# >>> 09/25/2009 ... @mj@d <<<
#
ScriptAlias /projects /usr/share/trac/cgi-bin/trac.cgi
SetEnv TRAC_ENV_PARENT_DIR "/projects/trac"
#
AuthType Basic
AuthName "Trac Environment"
AuthUserFile /projects/projects.passwd
Require valid-user
#
DAV svn
SVNParentPath /projects/svn
AuthType Basic
AuthName "Subversion Repositories"
AuthUserFile /projects/projects.passwd
Require valid-user
#
Alias /files "/projects/files"
DAV On
AuthType Basic
AuthName "Files"
AuthUserFile /projects/projects.passwd
Require valid-user
#
Require valid-user


Installed Berkeley DB as follows:
root@mydomain:/projects/bdb/db-4.8.24# cd build_unix/
root@mydomain:/projects/bdb/db-4.8.24/build_unix# ../dist/configure --bindir=/usr/local/bin
root@mydomain:/projects/bdb/db-4.8.24/build_unix# make prefix=/usr/contrib/bdb install

./libtool --mode=execute true db_verify


Created Project as follows:
root@mydomain:/projects# svnadmin create svn/sandbox --fs-type=fsfs
root@mydomain:/projects# mkdir -p files/sandbox/public files/sandbox/private files/sandbox/images

Creating Trac Environment:
root@mydomain:/projects# trac-admin trac/sandbox initenv

/var/lib/python-support/python2.6/MySQLdb/__init__.py:34:
DeprecationWarning: the sets module is deprecated from sets import ImmutableSet

Creating a new Trac environment at /projects/trac/sandbox Trac will first ask a few questions about your environment in order to initialize and prepare the project database.

Please enter the name of your project. This name will be used in page titles and descriptions.

Project Name [My Project]> sandbox

Please specify the connection string for the database to use.

By default, a local SQLite database is created in the environment directory. It is also possible to use an already existing

PostgreSQL database (check the Trac documentation for the exact connection string syntax).

Database connection string [sqlite:db/trac.db]>

Please specify the type of version control system, By default, it will be svn.

If you don't want to use Trac with version control integration, choose the default here and don't specify a repository directory in the next question.

Repository type [svn]>

Please specify the absolute path to the version control repository, or leave it blank to use Trac without a repository. You can also set the repository location later.

Path to repository [/path/to/repos]> /projects/svn/sandbox


http://localhost:8000/sandbox

Giving error while I started project/sandbox as follows:


# tracd --port 8000 /projects/trac/sandbox
Server starting in PID 24970.
Serving on 0.0.0.0:8000 view at http://127.0.0.1:8000/


Following commands is used to start server…
root@mydomain:/projects# tracd -p 8000 -b 192.168.1.105 /projects/trac/sandbox

Server starting in PID 27409.
Serving on http://192.168.1.105:8000/


Pointed browser to http://192.168.1.105:8000/sandbox
It shows the page successfully:


Security
At the moment our server is configured to allow access to certain actions—like writing to our subversion repository—only to authenticated users. Now we need to actually allow our users to perform these actions by storing their authentication details. These are stored in a text file that Apache understands— the projects.passwd file referred to in the earlier excerpts.

Managing Users
Creating this file is quite simple using the htpasswd tool provided by Apache, which should be accessible simply by its name on Linux. We need to explicitly tell it to create a new file the first time, and which file to use for subsequent user additions.

Initially dav_svn was setup as follows:

root@mydomain:~# htpasswd -cm /etc/apache2/dav_svn.passwd adminsvn
New password:
Re-type new password:

Adding password for user adminsvn
Note: we replaced dav_svn.passwd with new projects.passwd. For a first run, we use the following:

$ htpasswd -c /projects/projects.passwd wiz
We will be prompted to specify and then confirm the password for our user wiz.

root@mydomain:/projects# htpasswd -c /projects/projects.passwd wiz
New password:
Re-type new password:

Adding password for user wiz
Alternatively we can specify the password as part of the command if we use the -b parameter, although we should be aware that this is not safe since the password will be stored in the command history of our Operating System.

For subsequent users we simply drop the -c:

root@mydomain:/projects# htpasswd /projects/projects.passwd mike
New password:
Re-type new password:

Adding password for user mike

Again we will have to specify and confirm mike's password. Now we have two users who can access our server.

Create an administrator user right now. Make sure you add a user who’s already in your /etc/apache2/dav_svn.passwd file.

root@mydomain:/projects# trac-admin trac/sandbox permission add mike TRAC_ADMIN

The changes we have made in file /etc/apache2/sites-available/default should look as follows:
#
# >>> Added for Mgmt of software with Trac/svn
# >>> 09/25/2009 <<<
#
ScriptAlias /projects /usr/share/trac/cgi-bin/trac.cgi
SetEnv TRAC_ENV_PARENT_DIR "/projects/trac"
SetHandler mod_python
PythonHandler trac.web.modpython_frontend
PythonOption TracEnvParentDir /projects/trac
PythonOption TracUriRoot /projects
#
AuthType Basic
AuthName "Trac Authentication"
AuthUserFile /projects/projects.passwd
# AuthUserFile /etc/apache2/dav_svn.passwd
Require valid-user
#
DAV svn
SVNParentPath /projects/svn
AuthType Basic
AuthName "Subversion Repositories"
AuthUserFile /projects/projects.passwd
Require valid-user
#
Alias /files "/projects/files"
DAV On
AuthType Basic
AuthName "Files"
AuthUserFile /projects/projects.passwd
Require valid-user
#
Require valid-user

Notice here, again that we use TracEnvParentDir to show we host multiple instances of Trac. You may change the TracUriRoot to something different.

File Permissions
Since everything is running through Apache, we need to ensure it can write to the files it needs. Since we have put everything under the projects folder, we can set our permissions there and let them cascade down through the rest.

Linux
Linux file permissions are split into user, group, and other. We will change the group to the same one used by Apache, allow the group to write to our projects folder and then make sure the permissions are inherited by anything inside the folder.

Again, make sure to chown your Trac installation to www-data:

The general format for using authentication is:
root@mydomain:/projects# chgrp -R www-data /projects
root@mydomain:/projects# chmod -R g+w /projects
root@mydomain:/projects# chmod -R g+s /projects
root@mydomain:/projects# chown -R www-data.www-data /projects/trac

Trac Permissions:
Trac maintains it own set of permissions for each environment we create. The permissions we are going to create here cover the behavior described in the following chapters.

The default permissions in Trac allow unauthenticated (or rather anonymous) users to do anything. We are going to prevent them from editing the wiki—they can still view it though—and accessing the source code browser. Then we are going to let authenticated users do both of these as well as access milestones.

1. Type cd /projects and press Enter.
2. Type trac-admin followed by trac/sandbox and press Enter.
3. Type permission remove anonymous WIKI_CREATE WIKI_MODIFY BROWSER_VIEW and press Enter.
4. Type permission add authenticated WIKI_ADMIN BROWSER_VIEW MILESTONE_ADMIN and press Enter.
5. Type quit and press Enter to leave trac-admin.

Remember, we will need to do this for each Trac environment that we create.

root@mydomain:/projects# trac-admin trac/sandbox
Welcome to trac-admin 0.11.5

Interactive Trac administration console.
Copyright (c) 2003-2009 Edgewall Software

Type: '?' or 'help' for help on commands.

Trac [/projects/trac/sandbox]> permission remove anonymous WIKI_CREATE WIKI_MODIFY BROWSER_VIEW
/var/lib/python-support/python2.6/MySQLdb/__init__.py:34: *DeprecationWarning: the sets module is deprecated from sets import ImmutableSet
Trac [/projects/trac/sandbox]> permission add authenticated WIKI_ADMIN BROWSER_VIEW MILESTONE_ADMIN
Trac [/projects/trac/sandbox]> quit


*See troubleshooting section.

$ tracd -p port --auth=base_project_dir,password_file_path,realm project_path
where:
* base_project_dir is the base directory of the project; note: this doesn't refer to the project name, and it is case-sensitive even for windows environments
* password_file_path path of the password file
* realm realm
* project_path path of the project

Example:
$ tracd -p 8080 \
--auth=project1,/path/to/users.htdigest,mycompany.com /path/to/project1

Now start standalone server using tracd as follows:
root@mydomain:~# tracd -p 8000 -b 192.168.1.105 --basic-auth=/projects/trac,/projects/projects.passwd,mydomain.com /projects/trac/sandbox
Server starting in PID 20268.
Serving on http://192.168.1.105:8000/

Now, access your trac over the web: http://mydomain.com/projects for a complete listing of hosted projects or http://mydomain.com/projects/sandbox for the sandbox project.
You may also login now! As you can see, we use the projects.passwd file here so everyone with subversion access also has access to trac.

With a minor configuration change, Trac is capable of sending emails when tickets are raised/updated. To make the most of this it is recommended that we use email addresses for our htpasswd usernames, then we need to do nothing besides enabling email.

See the Notification section of http://trac.edgewall.org/wiki/TracIni to see how to enable this.
Editing or deleting users is simply a matter of modifying the password file. If we want to change their password we need to re-run the htpasswd command.

Troubleshooting the warnings for user:
When server is started using following commands it spit out warnings as follows:
root@mydomain:~# tracd -p 8000 -a *,/projects/projects.passwd,mydomain.com /projects/trac/sandbox
Warning: invalid digest line in /projects/projects.passwd: wiz:N8pehMMzM0reI
Warning: invalid digest line in /projects/projects.passwd: mike:Qt4TvmrlBvF0I
Warning: found no users in realm: mydomain.com
Server starting in PID 30586.
Serving on 0.0.0.0:8000 view at http://127.0.0.1:8000/

made changes in /etc/group file as follows:
root@mydomain:~# nano /etc/group
...
trac:x:1003:mydomain.com+wiz,mydomain.com+mike

Also changed the stand alone startup command "tracd" to start the server as follows:

root@mydomain:~# tracd -p 8000 --basic-auth=*,/projects/projects.passwd,mydomain.com /projects/trac/sandbox

Server starting in PID 604.
Serving on 0.0.0.0:8000 view at http://127.0.0.1:8000/

Open up browser and typed the http://mydomain.com:8000/ in address bar...
Trac now allows authentication and works with above defined users...