PackagingDrafts/TGApps

= Hints on Packaging TurboGears Applications = !TurboGears applications are a bit complex to package well. These are some hints on how to do it well.

What is a TurboGears App?
!TurboGears applications are a hybrid of several different types of packages:


 * Python packages
 * Web applications
 * Daemons

Python Packages
!TurboGears is a python web framework. Thus TG apps are written in python. What's more, TG apps usually come with a setup.py that installs the main portions of the TG app as a python module in %{python_sitelib}. This is because tg-admin quickstart is the standard way to create a new TG app and that creates a setup.py that installs the programs in this manner.

Web Applications
The web application guidelines were written with php scripts in mind. Those place the data and program scripts in a subdirectory of %{_datadir}. The changeable data is placed in a subdirectory of /var/lib/. Configuration files belong in /etc. And so on. This is all according to the FHS.

Daemons
Unlike php web apps, TG apps are designed to run as a standalone server on their own port. Usually apache or another http server runs in front of the TG app, proxying requests on port 80 to the app. There should be a way to start the application just like any other daemon.

Decisions to Make

 * Where do files belong?
 * How do we invoke TG Apps?
 * How do we start them?
 * What level of rewriting of TG scripts are we willing to do?

Follow the FHS
Precedent is pretty clear in Fedora that we should follow the FHS in regards to placement of files. Thus, these files belong in a certain place:


 * Various config files
 * dev.cfg, sample-prod.cfg: One of these (probably prod.cfg) should be placed under /etc for the app to use. We could either include it as %{_sysconfdir}/APP.cfg or %{_sysconfdir}/APP/prod.cfg.  The other file could be placed in %doc as a sample of how to configure the app for another use.
 * app.cfg: This is for the application author to configure the way the TurboGears framework works with the app. We can leave this in APP/config/app.cfg.  There are some things in here that slightly straddle the boundaries of what should be user visible configs.  For instance, identity and visit providers.  However, there is enough app specific knowledge in that concept (identity providers contain knowledge directly from the identity provider.  If the app uses that specific knowledge it needs a specific identity provider.) that it is probably acceptable to consider it not a user visible config file.
 * start-APP.py: This, or another script like it belongs in %{_sbindir} to start the service.
 * Main body of the program: This can be placed in %{_datadir}/APP or %{python_sitelib}/APP. However, some of the app is clearly data (everything is under static) and some of it could be considered either data or program (templates).  Data should be placed under %{_datadir}.  This might mean it is easier for the main body of the app to go under %{_datadir} as well.  The main reason the app would go in %{_datadir} is because another program wants to import a piece of the app.  This might be true of the model.  It should probably not be true of the controller.  I think the right thing to do is to split up the pieces and propose the split to upstream.  Mirrormanager might be a place to try this out.

Starting the TG Apps

 * Init script. Even though TG apps are usually not started by init, there should be an init script since init is our default method for starting daemons in Fedora.
 * Including a supervisor config or similar can be done to help others who are likely to set them up that way as well as Apache configs for proxying to the TG app can be helpful and would probably be good to include.

start-APP Script

 * I think we will have to rewrite the start-APP.py scripts for most TG apps for these reasons:
 * we are moving the location of the configs to /etc. Thus the start script has to account for that.
 * if we end up placing the program's files in /usr/share then we need to set sys.path to find the program in the new location.
 * supervisor controlled TG apps have to use a wrapper script and not the start-APP.py directly. We might as well integrate this.
 * Upstream TG start-APP.py scripts can't handle multiple versions of installed eggs. We have to rewrite them to   or   instead of using
 * We might even consider making the start-APP script an entry point into the application managed by setuptools. This is how tg-admin is created.  It would be a more correct change (and less likely for a future setuptools to cause havoc) but is not going to be easy to implement as an "add-on" to the existing code.  It's probably better for this to be shown as a proof of concept and maybe make it into TG 2.0.

Here's an example start-pkgdb:: __requires__ = 'TurboGears[future] ' import pkg_resources
 * 1) !/usr/bin/python

CONFFILE=/etc/pkgdb.cfg PROGRAMDIR=/usr/share/pkgdb

from turbogears import config, update_config, start_server import cherrypy cherrypy.lowercase_api = True from os.path import * import sys

if len(sys.argv) > 1: update_config(configfile=sys.argv[1], modulename="pkgdb.config") elif exists(join(dirname(__file__), "setup.py")): update_config(configfile="dev.cfg",modulename="pkgdb.config") else: update_config(configfile=CONFFILE, modulename="pkgdb.config")

sys.path.append(PROGRAMDIR)

from pkgdb.controllers import Root

start_server(Root)

Both CONFFILE and PROGRAMDIR should be set from the spec file so that we can substitute distro-wide values for %{_datadir} and %{_sysconfdir}.