Edgewall Software

Changes between Version 38 and Version 39 of TracModPython


Ignore:
Timestamp:
Sep 25, 2005, 3:26:28 PM (19 years ago)
Author:
Christopher Lenz
Comment:

House cleaning

Legend:

Unmodified
Added
Removed
Modified
  • TracModPython

    v38 v39  
    11= Trac and mod_python =
    22
    3 Trac 0.7.1 and later supports [http://www.modpython.org/ mod_python], which speeds up Trac's response times considerably and permits use of many Apache features not possible with tracd/mod_proxy.
     3Trac supports [http://www.modpython.org/ mod_python], which speeds up Trac's response times considerably and permits use of many Apache features not possible with [wiki:TracStandalone tracd]/mod_proxy.
    44
    5 Be sure to grab mod_python 3.1.3 and later for ''SetHandler'' ''mod_python'' directive to work.  Also, older versions may generate an internal error.  [http://projects.edgewall.com/trac/ticket/1090 #1090]
    6 
    7 == Trac Trunk Configuration ==
    8 
    9 The examples below are written for Trac 0.8.x.  If you are running Trac from the trunk source you will need to make a modification to the configuration.
    10 
    11 The mod_python handler class is changed in trunk revision [1287] and later, so you'll need to substitute the following line:
    12 
    13 {{{
    14    PythonHandler trac.ModPythonHandler
    15 }}}
    16 
    17 with this one:
    18 
    19 {{{
    20    PythonHandler trac.web.modpython_frontend
    21 }}}
     5Be sure to grab mod_python 3.1.3 and later for ''SetHandler'' ''mod_python'' directive to work.  Also, older versions may generate an internal error (see [http://projects.edgewall.com/trac/ticket/1090 #1090])
    226
    237== Simple configuration ==
    248
    25 If you just installed mod_python, you may have to add a line to load the module in the Apache conf:
    26 
     9If you just installed mod_python, you may have to add a line to load the module in the Apache configuration:
    2710{{{
    2811LoadModule python_module modules/mod_python.so
    2912}}}
    3013
    31 Here's a typical Trac CGI/Apache setup:
    32 
    33 {{{
    34 ScriptAlias /projects/myproject /path/to/python/share/trac/cgi-bin/trac.cgi
    35 <Location /projects/myproject>
    36    SetEnv TRAC_ENV /var/trac/myproject
    37 </Location>
    38 }}}
    39 
    40 The equivalent mod_python setup is:
    41 
     14A simple setup of Trac on mod_python looks like this:
    4215{{{
    4316<Location /projects/myproject>
    4417   SetHandler mod_python
    4518   PythonHandler trac.ModPythonHandler
    46    PythonOption TracUriRoot "/projects/myproject"
    4719   PythonOption TracEnv /var/trac/myproject
     20   PythonOption TracUriRoot /projects/myproject
    4821</Location>
    4922}}}
    5023
    51 Note that the option ''TracUriRoot'' may or may not be necessary in your setup. Try without first, and if the URLs produced by Trac look wrong or if Trac does not seem to recognize the URLs correctly, add the ''TracUriRoot'' option. When testing the setup I found that if a single directory (i.e. /myproject) is used the ''TracUriRoot'' line could be left out.  When multiple directories (i.e. /projects/myproject) were used the option was needed.
     24Note that the option `TracUriRoot` may or may not be necessary in your setup. Try without first, and if the URLs produced by Trac look wrong or if Trac does not seem to recognize the URLs correctly, add the `TracUriRoot` option.
    5225
    53 Authentication works the same as for CGI:
    54 
     26Configuring authentication works the same as for [wiki:TracCgi#AddingAuthentication CGI]:
    5527{{{
    5628<Location "/projects/myproject/login">
     
    6234}}}
    6335
    64 If your trac installation isn't installed in your Python path, you'll have to tell Apache where to find the {{{trac.ModPythonHandler}}} module by adding this line to the {{{<Location>}}} section:
    65 
     36If the Trac installation isn't installed in your Python path, you'll have to tell Apache where to find the Trac mod_python handler  using the `PythonPath` directive:
    6637{{{
    67 <Location "/projects/myproject">
    68   PythonPath "sys.path+['/path/to/trac']"
     38<Location /projects/myproject>
     39  ...
     40  PythonPath "sys.path + ['/path/to/trac']"
    6941  ...
    7042</Location>
    7143}}}
    7244
    73 == Setting up a project on the root of the webserver ==
    74 
    75 To install Trac on the root of the webserver (in a virtual host context for example) and make it available at the ''!http://some-hostname/'' URL, use the following:
    76 
    77 {{{
    78 <VirtualHost trac.example.org>
    79   ServerName trac.example.org
    80   Alias /trac /var/www/trac.example.org/htdocs/trac
    81   <Location />
    82     SetHandler mod_python
    83     PythonHandler trac.ModPythonHandler
    84 
    85 
    86     PythonOption TracUriRoot "/"
    87     PythonOption TracEnv /var/trac/myproject
    88   </Location>
    89   <Location /login>
    90     AuthType Basic
    91     AuthName "My Project"
    92     AuthUserFile /var/trac/myproject/.htaccess
    93     Require valid-user
    94   </Location>
    95   <Location /trac>
    96     SetHandler None
    97   </Location>
    98 </VirtualHost>
    99 }}}
    100 
    101 
    102 The path in the last {{{<Location>}}} block should match your {{{htdocs_location}}}. The directive "{{{SetHandler None}}}" allows us to escape mod_python and have Apache serve the static files (located at {{{/var/www/trac.example.org/htdocs/trac/}}} on the filesystem in this example). Any other URLs will be handled by mod_python.
    103 
    10445== Setting up multiple projects ==
    10546
    106 The Trac mod_python handler handler supports a configuration option similar to Subversion's {{{SvnParentPath}}}, called {{{TracEnvParentDir}}}:
    107 
     47The Trac mod_python handler handler supports a configuration option similar to Subversion's `SvnParentPath`, called `TracEnvParentDir`:
    10848{{{
    10949<Location /projects>
    11050  SetHandler mod_python
    11151  PythonHandler trac.ModPythonHandler
     52  PythonOption TracEnvParentDir /var/trac
    11253  PythonOption TracUriRoot /projects
    113   PythonOption TracEnvParentDir "/var/trac"
    11454</Location>
    11555}}}
    11656
    117 When you request the {{{/projects}}} URL, you will get a (currently very simple) listing of all subdirectories of the directory you set as {{{TracEnvParentDir}}}. Selecting any project in the list will bring you to the corresponding Trac instance. You should make sure that the configured directory only contains Trac environment directories that match the currently installed Trac version, because that is not checked prior to the generation of the project list.
     57When you request the `/projects` URL, you will get a listing of all subdirectories of the directory you set as `TracEnvParentDir`. Selecting any project in the list will bring you to the corresponding Trac environment.
    11858
    11959If you don't want to have the subdirectory listing as your projects home page you can use a
    120 
    12160{{{
    12261<LocationMatch "/.+/">
    12362}}}
    12463
    125 This will instruct Apache to use mod_python for all locations different from root while having the possibility of placing a custom home page for root in yuor !DocumentRoot folder.
     64This will instruct Apache to use mod_python for all locations different from root while having the possibility of placing a custom home page for root in your !DocumentRoot folder.
    12665
    127 
    128 === Use different locations for htdocs and mod_python ===
    129 The mod_python location must be different than the trac htdocs location. For example, if you map Trac's htdocs location to {{{/trac}}} and then map your mod_python handler to {{{/trac}}} as well, you will encounter strange problems.  Configuration for the location of the htdocs is in the environment's ini file.
    130 
    131 == Setting up multiple projects as the root URL ==
    132 
    133 Let's say you want something like http://projects.yourdomain.com which has a list of all of the projects hosted on it.  However, you don't want to do manual configuration every time a new project is added.  Or, you'd like to minimize it.  Here's a quick sample:
    134 
    135 {{{
    136 Alias /trac/ /usr/share/trac/htdocs/
    137 <Directory "/usr/share/trac/htdocs">
    138    Order allow,deny
    139    Allow from all
    140 </Directory>
    141 
    142 <Location />
    143    SetHandler mod_python
    144    PythonHandler trac.ModPythonHandler
    145    PythonOption TracEnvParentDir "/var/trac"
    146    PythonOption TracUriRoot /
    147 </Location>
    148 
    149 <Location /project1/login>
    150    AuthType Basic
    151    AuthName "Project1"
    152    AuthUserFile /var/www/projects.yourdomain.com/security/users
    153    AuthGroupFile /var/www/projects.yourdomain.com/security/groups
    154    Require group project1-users
    155 </Location>
    156 
    157 <Location /project2/login>
    158    AuthType Basic
    159    AuthName "Project2"
    160    AuthUserFile /var/www/projects.yourdomain.com/security/users
    161    AuthGroupFile /var/www/projects.yourdomain.com/security/groups
    162    Require group project2-users
    163 </Location>
    164 
    165 <Location /trac>
    166    SetHandler none
    167 </Location>
    168 }}}
    169 
    170 A few things to note about this example:  all of the users are stored in one file, {{{/var/www/projects.yourdomain.com/security/users}}}.  Groups for these users are defined in the groups file, {{{/var/www/projects.yourdomain.com/security/groups}}}.  The Trac projects are all stored under {{{/var/trac}}}.
    171 
    172 To add a new project, you'll have to create a new user in the user file.  Then, create a new group for the project in the group file.  Finally, create a new <Location> block with a new {{{Require group}}} directive.  That's about it.
    173 
    174 You can also use the same authentication realm for all of the projects using a {{{<LocationMatch>}}} directive:
    175 
     66You can also use the same authentication realm for all of the projects using a `<LocationMatch>` directive:
    17667{{{
    17768<LocationMatch "/[^/]+/login">
    178    ...
     69  AuthType Basic
     70  AuthName "Trac"
     71  AuthUserFile /var/trac/.htaccess
     72  Require valid-user
    17973</LocationMatch>
    18074}}}
    18175
    18276== Troubleshooting ==
    183 
    184 === Setting up plugin cache directory ===
    185 
    186 {{{
    187 SetEnv PYTHON_EGG_CACHE /path/to/dir
    188 }}}
    18977
    19078=== Form submission problems ===
     
    19482=== Using .htaccess ===
    19583
    196 Although it may seem trivial to rewrite the above configuration as a directory in your document root with a {{{.htaccess}}} file, this does not work. Apache will append a "/" to any Trac URLs, which interferes with its correct operation.
     84Although it may seem trivial to rewrite the above configuration as a directory in your document root with a `.htaccess` file, this does not work. Apache will append a "/" to any Trac URLs, which interferes with its correct operation.
    19785
    19886It may be possible to work around this with mod_rewrite, but I failed to get this working. In all, it is more hassle than it is worth. Stick to the provided instructions. :)
    199 
    200 === mod_python does caching: beware ===
    201 
    202 When using mod_python you have to reload apache before changes to a trac.ini of a project or a projects templates take effect!
    203 
    204  ''Note: This doesn't apply to the current development version (0.9pre), where the configuration is reloaded automatically if it has changed.''
    20587
    20688=== Win32 Issues ===
     
    21395=== OS X issues ===
    21496
    215 There is a mod_python issue on OSX: Look at the end of its README.
    216 You need to either define the environment variable DYLD_FORCE_FLAT_NAMESPACE before starting httpd
    217 or apply [http://www.dscpl.com.au/projects/vampire/PATCHES this patch] to mod_python.
     97When using mod_python on OS X you will not be able to restart Apache using `apachectl restart`. This is apparently fixed in mod_python 3.2, but there's also a patch available for earlier versions [http://www.dscpl.com.au/projects/vampire/patches.html here].
    21898
    219 Also note that there is an error in the module when you build it from source.  Basically an unpatched version will not respond correctly to the 'apachectl restart' command.  If you issue this command on an unpatched module your client will receive a 500 error from apache.  The patch needed to fix this problem is included below:
    220 
    221 {{{
    222 --- src/mod_python.c    Mon Feb 16 20:47:27 2004
    223 +++ /Usersjkp/mod_python.c      Wed Mar 16 21:15:49 2005
    224 @@ -31,6 +31,10 @@
    225   * (In a Python dictionary) */
    226  static PyObject * interpreters = NULL;
    227  
    228 +#ifdef WITH_THREAD
    229 +static apr_thread_mutex_t* interpreters_lock = 0;
    230 +#endif
    231 +
    232  apr_pool_t *child_init_pool = NULL;
    233  
    234  /**
    235 @@ -124,6 +128,8 @@
    236          name = MAIN_INTERPRETER;
    237  
    238  #ifdef WITH_THREAD
    239 +    apr_thread_mutex_lock(interpreters_lock);
    240 +
    241      PyEval_AcquireLock();
    242  #endif
    243  
    244 @@ -149,6 +155,8 @@
    245  
    246  #ifdef WITH_THREAD
    247      PyEval_ReleaseLock();
    248 +
    249 +    apr_thread_mutex_unlock(interpreters_lock);
    250  #endif
    251  
    252      if (! idata) {
    253 @@ -469,6 +477,9 @@
    254      const char *userdata_key = "python_init";
    255      apr_status_t rc;
    256  
    257 +    /* fudge for Mac OS X with Apache where Py_IsInitialized() broke */
    258 +    static int initialized = 0;
    259 +
    260      apr_pool_userdata_get(&data, userdata_key, s->process->pool);
    261      if (!data) {
    262          apr_pool_userdata_set((const void *)1, userdata_key,
    263 @@ -490,13 +501,16 @@
    264      }
    265  
    266      /* initialize global Python interpreter if necessary */
    267 -    if (! Py_IsInitialized())
    268 +    if (initialized == 0 || ! Py_IsInitialized())
    269      {
    270 +        initialized = 1;
    271  
    272          /* initialze the interpreter */
    273          Py_Initialize();
    274  
    275  #ifdef WITH_THREAD
    276 +        apr_thread_mutex_create(&interpreters_lock,APR_THREAD_MUTEX_UNNESTED,p);
    277 +
    278          /* create and acquire the interpreter lock */
    279          PyEval_InitThreads();
    280  #endif
    281 }}}
    282 
    283 
    284 ''Mar. 25/05''
    285 
    286 The patch listed above causes complaints when attempting to apply it; also, the URL for the OS X patch is broken. I found that patch as well as an additional one for mod_python for use with a multithreaded MPM [http://www.dscpl.com.au/projects/vampire/patches.html here] (same site; pages have been shuffled around).
    28799----
    288 See also TracGuide, TracInstall, TracMultipleProjects
     100See also TracGuide, TracInstall, TracCgi, TracFastCgi