OCSManager Installation Guide

Requirements

curl

sudo apt-get install curl

python-lxml

This package is used for processing XML payload on the server and clients

sudo apt-get install python-lxml

python-pycurl

This package is exclusively used on clients to connect to the ocsmanager service

sudo apt-get install python-pycurl

python-setuptools

This is required to use easy_install:

sudo apt-get install python-setuptools

virtualenv

Ubuntu Natty comes with python-virtualenv package, but on September 29th generating a virtualenv with go-pylons results in having an ImportError:

ImportError: No module named _weakrefset

We will instead install latest virtualenv package using easy_install:

sudo easy_install virtualenv

Installation

In this guide, we will install pylons 1.0 in an isolated python environment:

$ cd mapiproxy/services/
$ virtualenv mydevenv
$ curl http://pylonshq.com/download/1.0/go-pylons.py | python - mydevenv

Then run the following command to activate the isolated python environment and reconfigure the service:

$ source mydevenv/bin/activate
$ cd ocsmanager
$ python setup.py develop

The next step is to modify your configuration file.

Then the service can be run using:

$ paster serve --reload development.ini

Patchs

Signals, select and asynchronous notifications

In the paste module installed along pylons, the event loop in serve_forever is calling handle_request from python2.7/SocketServer.py which calls select.select() function.
However when a new notification is received, a signal is emitted and is also catched by select.select() causing it to raise a "Interrupted System Call" error. The following patch add an exception in paste serve_forever loop to avoid raising the exception when the system call is set to EINTR.

Edit mydevenv/local/lib/python2.7/site-packages/Paste-1.7.5.1-py2.7.egg/paste/httpserver.py file (assuming mydevenv is your virtualenv base dir)

  • At the top of the file, add the following import:
    import errno
    import select
    
  • Change the serve_forever function with the following code:
        def serve_forever(self):
            """ 
            Overrides `serve_forever` to shut the threadpool down cleanly.
            """ 
            try:
                while self.running:
                    try:
                        self.handle_request()
                    except socket.timeout:
                        # Timeout is expected, gives interrupts a chance to
                        # propogate, just keep handling
                        pass
                    except select.error, v:
                        if v[0] != errno.EINTR: raise
            finally:
                self.thread_pool.shutdown()