+++++++++++++++++++++++++++
Railroad Installation Guide
+++++++++++++++++++++++++++

:Author: Guido Goldstein
:Email: gst@infrae.com
:License: BSD, see LICENSE.txt

=============
 Requirements
=============

Railroad requires the following components:

* Python 2.3.3 or higher.

* Apache 2.0. Railroad will not work with previous versions of Apache.

* Apache's DAV support.

* mod_python for Apache.

* libxml2 including the Python bindings.

* pydavclient, a Python package.

If you plan to use railroad with authorization support or the search
feature, the following additional software is needed:

* PostgreSQL database.

* The psycopg module for Python to access the database.

============
Installation
============

Basic Apache configuration
==========================

To activate Railroad, Apache first has to be configured for WebDAV
access and Python support.

Make sure the following modules are enabled and configured in Apache:

1. mod_dav
2. mod_davfs
3. mod_python

How to do this is not described in this document; please refer to the
Apache 2 documentation. Look for ``a2enmod`` and ``a2dismod``.

pydavclient installation
========================

PyDAVClient needs to be installed for the Python version that Apache
is going to use. The simplest way to do that is to go to the pydavclient
directory and typing::

  python2.3 setup.py install

as root. This will install the pydavclient libraries in the right
directory. Note: this is will only work if the libxml2 python bindings
have also been installed for that Python, as the pydavclient depends
on them.


Railroad Apache configuration
=============================

Next, the particular railroad functionality needs to be configured.

We have supplied a script that can generate the Apache configuration
for you, called ``mk_config.py``. This script will ask questions and
emit the needed config snippets to the standard output. The next
section provides a sample session. To start the script type::

  python mk_config.py

For now the only option known by ``mk_config.py`` is::

  -o <output file>

which will induce the script to write the Apache2 config to the given
file instead of stdout.

Once the script has generated the snippets you can paste them to a
configuration file that gets loaded by Apache.

Optionally you need to set up a database; this is only necessary is
you plan to use the **Authorization** feature of Railroad. See the
section **Using authorization**.

``mk_config.py`` sample session
-------------------------------

Lets have a look at the following ``mk_config.py`` session. You start the
script by going to the ``railroad`` directory and typing the following::

  python2.3 mk_config.py

The script will then start asking you questions. The first set of
questions are about the repository. Default answers if available will
be given in square brackets behind the questions. Just press enter if
you want to accept the default.

The questions have been numbered in the output of ``mk_config.py``, so
we can refer to them.

::

 <00> Installation directory of the RR scripts [/home/gst/prog/svn/railroad]: 
 <01> Name of the repository [railroad_data]: 
 <02> The prefix is the part before `over` the repository.
 Prefix to path to the top of the repository [/rrr/]: 
 <03> The RR server needs to access the local file system to perform some of its duties.
 Absolute path to the parent dir of the repository on the file system (must exist!): /home/gst/prog/rrr
 <04> Name of the Python interpreter [rrpy]: 
 <05> Host/port the repository is running on [localhost]: nova.infrae:82
 <06> Use authorization (needs the DB!) [on]: off
 <07> Use property search (needs the DB!) [on]: off


As you can see, for the first two questions (<00>, <01>) the suggested
default values have been accepted.

Question <00> always uses the current directory as default. So you
don't need to install the Railroad programs into a special location.

Question <02> asks for the path portion of the URL one level **above**
the repository. The repositroy iteself will have the path
`prefix`/repo and the services will be reachable under
`prefix`/service.

Question <03> is similar to Question <02>, but asks for the top
directory on the **local** filesystem of the Railroad server. This
directory is mapped to the above path by Apache (via an ``Alias``
directive). It has to be writable by the Apache2 server running this
repository because here the actual files and DAV properties will be
stored.

Question <04>: You only need to change this value if you plan to have
more then one repository running in the same Apache setup. If this
isn't the case, you can safely use the default.

Question <05> is about the hostname of the machine the repository is
running on. You should enter the full official name of the machine the
repository is running on here. As usual, the port can be attached to
this name separated by a colon.

Question <06>: Here you have to decide if you want to use the
authorization or not. In the given session this option was turned off.

Question <07>: Here you have to decide if you want to use the
search feature or not. In the given session this option was turned off.

Below you can see the resulting config snippets.

::

    # WebDAV repository
    Alias "/rrr/repo/" "/home/gst/prog/rrr/"
    <Location "/rrr/repo/" >
        DAV On
        Options -MultiViews -Indexes
        AddHandler mod_python .py
        PythonDebug On
        PythonAutoReload On
        PythonPath "['/home/gst/prog/svn/railroad']+sys.path"
        PythonInterpreter "rrpy"
        PythonHeaderParserHandler rr_main::inithandler
        PythonAuthenHandler rr_main
        PythonAuthzHandler rr_main
        PythonOption repository "railroad_data"
        PythonOption authorize "off"
        PythonOption search "off"
        <Limit GET POST OPTIONS PROPFIND PUT DELETE PATCH PROPPATCH MKCOL COPY MOVE LOCK UNLOCK >
            Order Deny,Allow
            Allow from all
         </Limit>
        PythonOption repo_host "nova.infrae:82"
        PythonOption repo_path "/rrr/repo/"
        PythonOption repo_dir "/home/gst/prog/rrr/"
     </Location>

    # services url
    <Location "/rrr/service/" >
        SetHandler python-program
        PythonDebug On
        PythonAutoReload On
        PythonPath "['/home/gst/prog/svn/railroad']+sys.path"
        PythonInterpreter "rrpy"
        PythonHeaderParserHandler rr_main::inithandler
        PythonAuthenHandler rr_main
        PythonAuthzHandler rr_main
        PythonHandler rr_service
        PythonOption repository "railroad_data"
        PythonOption authorize "off"
        PythonOption search "off"
        PythonOption repo_host "nova.infrae:82"
        PythonOption repo_path "/rrr/repo/"
        PythonOption repo_dir "/home/gst/prog/rrr/"
     </Location>


These snippets should be pasted into the Apache configuration, inside
the (virtual) host you want to use it in. You have to make sure that
the directories exist and have the right access permisions
(owner/group). Which in detail means that Apache has to have write
permission on the repository directory.

The installation directory of the server code (see question <00>) does
not necessarily need to be writable by the Apache server.

A browser can verify whether the repository is functioning. To do a little
bit more testing, a WebDAV tool like ``cadaver`` can be used to verify
whether it can make a WebDAV connection.

If you don't have a WebDAV client, you might use the test.py from the
pydavclient source distribution. Run the test

  python test.py <full URL to your repositor>



===================
Using authorization
===================

In this section the proper configuration for authorization will be
described.

Configuartion using the database
================================

Sample configuration session
----------------------------

In this chapter I will refer to data given in the followin example
session of ``mk_config.py``::

 <00> Installation directory of the RR scripts [/home/gst/prog/svn/railroad]: 
 <01> Name of the repository [railroad_data]: 
 <02> The prefix is the part before `over` the repository.
 Prefix to path to the top of the repository [/rrr/]: 
 <03> The RR server needs to access the local file system to perform some of its duties.
 Absolute path to the parent dir of the repository on the file system (must exist!): /home/gst/prog/rrr
 <04> Name of the Python interpreter [rrpy]: 
 <05> Host/port the repository is running on [localhost]: nova.infrae:82
 <06> Use authorization (needs the DB!) [on]: 
 <07> Use property search (needs the DB!) [on]: 
 <08> Authorization domain [Railroad]: Zope
 <09> DB module to use [db_pg]: 
 <10> Name of database to use: dav
 <11> User to use for db-connection: gst
 <12> Password to use []: 
 <13> Host the db is running on []: nova.infrae

As you can see, there're additional questions after you've activcated the authorization.

Question <08> asks for the realm or domain the Railroad server should
use for authorization. The server uses the `Basic Authorization`
protocol of HTTP. For more on this topic see
http://www.w3.org/Protocols/rfc2616/rfc2616.html and
http://www.ietf.org/rfc/rfc2617.txt.

Question <09> asks for name of a python module which acts as interface
to the database. For now only the PostgeSQL database is supported. So
you should better accept the default value here.

In question <10> you supply the name of the database to use. For the
setup of the database see below.

Question <11> is very important because here you need to specify the
user name under which the Railroad server will access the database. 
This is further complicated by the fact that the Railroad server runs
inside Apache, which is normally configured to run as a special user. 
You have to give the correct user (user of the Apache server) or tell
the database to not do any identity checks of users that wish to
connect.

In question <12> you may supply the password that's needed to get
access to the database. In this example no password is needed.

Question <13> makes sure on which machine the database is running. This
implies that there's no need to have the Railroad repository server
(the Apache part) and the database on the same machine.

After the last questions is answered, ``mk_conf.py`` creates the
Apache config and in addition a python module called ``admconf.py``. 
This module is used by the admin tools to get access to the database,
which means that the tools will use the user/password combination
given above.


Setting up the database
=======================

The easiest way to get authorization  up and running is to create a new
database for exclusive use by Railroad. Of course, if you know your
PostgreSQL you can use an existing database but for this guide we
assume a fresh one.

After the creation of the database run the ``db_pg.sql`` script which
will create the tables and indices needed by Railroad. If you don't
want the Apache to connect to the database as a DBA -- and the default
for PUBLIC doesn't suite you --, you have to ``REVOKE``/``GRANT`` the
``SELECT``, ``UPDATE`` and ``INSERT`` rights to the user the
web-server is connecting as. But first step first.

In this guide we assume the database name is ``dav`` and the db is
already created albeit empty. We also assume that the current user has
DBA rights. By running::

  psql dav <db_pg.sql

the tables and indices will be created.

To get the rights done right, have a look at the ``db_pg.sql`` script. 
You can resuse the ``GRANT`` and ``REVOKE`` statements and fill in the
desired user name.


Initialising a repository
-------------------------

Before the database can be used by clients, some data has to be
entered.

There're two scripts which ease the initialization a little bit. 
There're far from easy to use but better than doing the SQL by hand.

The repository data
___________________

First step is to enter the data for the repository itself. The table
``repositories`` is ment to hold the information for the repositories
connected to this database.

First try the ``repoadm.py`` script. Just type::

  python repoadm.py

You'll see a short usage message. To add a new repository you need to
use the ``add`` command and provide the script with all data on the
command line.

If you type::

  python repoadm.py show

it will already show a repository defined with the name of ``unknown``
and an id of 0. This repository exists for administrative reasons only
and can **not** be used as a real repository!

You can use a statement like the following to add a new repository::

  python repoadm.py add name master_user master_pw host[:port] path upload_path fs_top_dir


The used parameters in detail:

**1. name**
   The name of the repository. Used to find the right repository.

**2. master_user**
   The name of a user which is allowed to connect to the repository
   and to perform all actions w/o restrictions.

**3. master_pw**
   The password for the former.

**4. host[:port]**
   The full name of the host including the port, like ``xxx.aaa.com:8080``.

**5. path**
   The absolute path to the top of the repository (for the given host).

**6. upload_path**
   The absolute path to where the form based uploads go.

**7. fs_top_dir**
   The location of the top of the repository on the local file system.

You can verify your entry by using::

  python repoadm.py show


The client data
_______________

The second step is to register the client CMS with the database.

To register a CMS with the database the following statement can be used::

   python clientadm.py add name auth_url auth_domain

The used parameters in detail:

**1. name**
   The name assigned to the client CMS. Used to find the right client record.

**2. auth_url**
   The URL to request for authorization. See the cms_integration document for details.

**3. auth_domain**
   The authorization domain to use for the Basic Auth headers for the auth_url.

Test your entry with::

  python clientadm.py show

To allow a relation between clients and the repositories they can use,
the table ``repoclient`` builds a mapping between them.

To activate a client-repository relationship, the following command can be used::

  python clientadm.py activate client_name repo_name

The used parameters in detail:

**1. client_name**
   The name of the client as assigned via ``add``.

**2. repo_name**
   The name of the repository you want the client to attach to.

A ``show`` should now show a status of `A` for active.

The database is ready for use.


..
   Local Variables:
   mode: rst
   indent-tabs-mode: nil
   sentence-end-double-space: nil
   fill-column: 70
   End:
