Instance Deployment

If your organization already has a Tendril deployment, you should skip this section and go directly to the User Installation section.

Instance deployment is the process you would have to go through to set up a Tendril instance for your organization, which will then provide the sandbox within which you can modify Tendril to suit your needs.

Creating an Instance

Instance Components

A tendril instance is a combination of atleast two elements:

  • The tendril core, containing the bulk of the business logic of tendril.
  • An instance folder, containing all of your propietary information, and (eventually) your process workflows.

In addition, various other resources will have to be setup, including:

  • An apache2 server with the following modules :

    • mpm_prefork (recommended)
    • modwsgi
    • modxsendfile
  • A postgresql database server. No other database is slated to be supported.

  • The following ‘filesystems’, each of which is currently expected to be a folder on the server running your central Tendril instance :

    • docstore to store numbered, generated documentation. Typically, things like reports, orders, and so on go here.
    • refdocs to store all Reference documentation.
    • wallet to store a small collection of standard company documents.
  • Your projects hierarchy, presently expected to be a tree of SVN checkouts.

Forking Tendril

While tendril is developed with the goal of having a process-agnostic core, it may well take some time to achieve the kind of separation that is desired. For the moment, every Tendril Deployment is expected to be a fork of tendril, not just a clone. This lets you make whatever changes you need to the core to get it to function exactly the way you need it to.

The primary tendril repository you should fork is at https://github.com/chintal/tendril . You should have an (empty) git repository into which you’re going to put the fork. Lets say you’re going to maintain this as a private repository on gitlab, under a group called <org>.

An additional repository, https://github.com/chintal/tendril-frontend-static , contains the static files used by the web frontend. This is used as a submodule inside the core tendril repository. If you want to customize the look and feel of the frontend, you will likely need to fork this repository as well. The documentation here does not explain how you would go about doing that. The eventual goal is to reintegrate the submodule after a package manager is used to remove the various javascript dependencies from the frontend repository, making it small enough to be contained within the main repository.

  1. Create a checkout of your empty repository.

    git clone git@gitlab.com:<org>/tendril.git
    
  2. Create a file and commit inside this checkout to create a master branch. (There is most definitely a cleaner way to do this, but I haven’t quite figured out how.)

    touch seed
    git add seed
    git commit -m "Initial seed commit"
    
  1. Add a new remote pointing to the upstream repository, fetch, and merge.

    git remote add upstream https://github.com/chintal/tendril.git
    git fetch upstream
    git checkout -b upstream-master upstream/master
    git checkout master
    git merge upstream-master master
    
  2. Clone the submodules as well.

    git submodule update --init
    
  3. Get rid of the seed file. (There is most definitely a cleaner way to do this as well.)

    git log
    git revert <ref for the seed commit>
    
  4. Push the repository up to gitlab.

    git push origin master
    

The fork thus created is what you you would use as the tendril core within your organization. You should then follow the instructions in the User Installation section to set up your central Tendril installation, configuring the instance folder while you do.

Setting up the Instance Folder

TODO

Generating the Documentation

You should build a copy of the documentation for local use. Your tendril instance’s frontend will serve this documentation to your users.

cd tendril/doc
make dirhtml

Setting up the ‘Filesystems’

Create the local folders to store your docstore, refdocs, and wallet. Each of these ‘filesystems’ is used by tendril via pyfilesystem (fs), and can in principle be remote filesystems. For your central instance, though, only using them as local folders is supported at present.

mkdir ~/fs
mkdir ~/fs/wallet
mkdir ~/fs/docstore
mkdir ~/fs/refdocs

See also

These folders can be wherever you want them to be. Just make sure to set the following configuration options in your local config overrides :

  • DOCUMENT_WALLET_ROOT
  • DOCSTORE_ROOT
  • REFDOC_ROOT

Your instance_config itself would benefit from having the reference to the XML-RPC endpoint for the filesystem, allowing your users to connect directly to it. See the next section for details.

Hint

Using a remote filesystem instead basically requires the serving of files by your webserver (through tendril.frontend.blueprints.expose via x-sendfile) to be changed to allow this. You could, in principle, mount the remote filesystems locally with fs.mountfs. However, expect a considerable performance hit. The ideal route would probably be to have tendril.frontend.blueprints.expose redirect you to the correct URL of the remote resource instead.

Exposing the Filesystems over http via XML-RPC

TODO

Setting up Apache

You can use apache or the webserver of your choice to serve Tendril. The basic requirements for the webserver are :

  • Support wsgi
  • (Recommended) Support x-sendfile

Hint

x-sendfile is enabled by default. If you want to disable it, set USE_X_SENDFILE to False in your instance_config.py.

You should edit the tendril.wsgi file in your instance root as well, and set the correct path to the virtualenv you have setup for tendril. If the tendril.wsgi file is missing, you should either copy tendril.wsgi.sample file, if there is one, or you can copy the example below.

Example tendril.wsgi:

activate_this = '/path/to/your/tendril-virtualenv/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))

from tendril.frontend.app import app as application
from tendril.frontend.app import db
from tendril.frontend.startup.init_app import init_app

init_app(application, db)


Your webserver should also be configured to serve files from within the exposed filesystems, and the wsgi script should be mounted.

Example configuration for apache:

<VirtualHost *:80>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.

        ServerName tendril.example.com
        ServerAdmin webmaster@localhost

        WSGIDaemonProcess tendril threads=5
        WSGIScriptAlias / /home/tendril/.tendril/tendril.wsgi process-group=tendril application-group=%{GLOBAL}

        <Directory /home/tendril/.tendril>
                WSGIProcessGroup tendril
                WSGIApplicationGroup %{GLOBAL}
                WSGIScriptReloading On
                Order deny,allow
                Allow from all
                Require all granted
        </Directory>

        <Directory /home/tendril/tendril/tendril>
                WSGIProcessGroup tendril
                WSGIApplicationGroup %{GLOBAL}
                WSGIScriptReloading On
                Order deny,allow
                Allow from all
                Require all granted
        </Directory>

        Alias /static   /home/tendril/tendril/tendril/frontend/static
        <Directory /home/tendril/tendril/tendril/frontend/static>
                Order allow,deny
                Allow from all
                Require all granted
        </Directory>

        Alias /doc      /home/tendril/tendril/doc/_build/dirhtml
        <Directory /home/tendril/tendril/doc/_build/dirhtml>
                Order allow,deny
                Allow from all
                Require all granted
        </Directory>

        XSendFile On
        XSendFilePath   /home/tendril/fs/docstore
        XSendFilePath   /home/tendril/fs/wallet
        XSendFilePath   /home/tendril/fs/refdocs
        XSendFilePath   /home/tendril/fs/instance/folder/cache/gsymlib
        XSendFilePath   /home/tendril/fs/instance/folder/_static
        XSendFilePath   /home/tendril/tendril/tendril/frontend/static
        XSendFilePath   /home/tendril/tendril/doc/_build/dirhtml

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf
</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

Your webserver should also have the necessary permissions to read/write all required files (Draft)

(rw) ~/fs
(r ) ~/tendril
(r ) ~/.tendril
(rw) ~/.tendril/cache

This is probably most easily achieved by letting wsgi run tendril as the tendril user.

Setting up Postgresql

TODO

Maintaining the Instance

TODO

Updating the Core

The core would only be updated from upstream by an instance administrator. Updating the core, especially in the present nascent state of the code (and consequently the API), is very liable to break things.

The update should be run in a clone of your instance core. Assuming you’re using the same clone as you did to create the fork to begin with, you already have the upstream remote setup and the upstream-master tracking branch.

  1. Fetch updates from upstream and merge into your remote tracking branch :

    git checkout upstream-master
    git pull
    
  2. Merge upstream-master into your master. If you have customizations in place, you should probably merge first into a temporary branch of your master and make sure nothing breaks.

    git checkout master
    git merge upstream-master
    

    Hint

    This is a good place to run a full test suite and make sure nothing broke.

  3. Push the updates to your central core repository.

    git push
    

Contributing to Upstream

TODO