[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

AGPL Licensing: Another "configuration" file example



This wsgi script also helps illustrate some of smooge's concerns about
what happens when configuration information is mixed into a script.  It
has two areas that differ between upstream's distribution and our own:

The first is bad application design but I've seen this done frequently
in PHP apps (and it sounds like Java frameworks like JBoss promote this
as well).  The fact that our apps are doing it shows it can occur in any
language although we should be able to change our apps to work around it
fairly easily:

The scripts that start up our web applications under mod_wsgi all seem
to have a bit of config tweaking.  Historically, this is because we
deployed with a start-app.py script that used the config file
exclusively and started as a standalone daemon.  The app.wsgi script
would load the standalone daemon config file and then make some config
changes in the wsgi script before starting the application server.  This
can be seen in the attached wsgi script in lines like this::


turbogears.update_config(configfile="/home/ricky/work/fedora/fas/fas.cfg",
modulename="fas.config")
  turbogears.config.update({'global': {'server.environment':
'development'}})

For our TurboGears apps it should be pretty easy for us to work around
that by moving all such lines into the config file instead of being in
the script.  But for third party PHP scripts licensed under AGPL and
single file cgi scripts that we write what is our responsibility?  I can
see several options:

1) We must patch every script/app/etc to put the config into its own
file.  Those changes fall unde the AGPL and we try to get them upstream.
 The config file falls outside of the AGPL either via explicit license
or some other way.

2) configuration, even embedded inside of an AGPL script is not subject
to the AGPL because it's not copyrightable data.


Second piece of code that varies between installations::
  import sys
  sys.path.append('/home/ricky/work/fedora/fas/fas/')

Setting the path at which to find the code must be done otherwise the
script won't be able to find the code related to the web application
itself.  On different installations (our servers, developers' test
machines, etc) this path will vary.  Are those changes that are covered
by the AGPL or are they non-copyrightable?  Is there a difference if
this is done manually by the system administrator vs automatically by
the Makefiles/build scripts provided by upstream?

This issue is harder to work around in code since finding the path to
files is a chicken and egg problem.  At some point, the executable has
to hardcode at least one path to be able to load the rest of its
information.

-Toshio
#!/usr/bin/python
import sys
sys.path.append('/home/ricky/work/fedora/fas/fas/')
sys.path.append('/home/ricky/work/fedora/fas/')
sys.path.append('/home/ricky/work/fedora/fas/plugins/fas-plugin-asterisk')
sys.stdout = sys.stderr

import pkg_resources
pkg_resources.require('CherryPy <= 3.0alpha')

import os
os.environ['PYTHON_EGG_CACHE'] = '/home/ricky/work/fedora/fas/fas.egg-info/'

import atexit
import cherrypy
import cherrypy._cpwsgi
import turbogears
import turbogears.startup
import fedora.tg.util

class MyNestedVariablesFilter(turbogears.startup.NestedVariablesFilter):
    def before_main(self):
        if hasattr(cherrypy.request, "params"):
            cherrypy.request.params_backup = cherrypy.request.params
        super(MyNestedVariablesFilter, self).before_main()

turbogears.startup.NestedVariablesFilter = MyNestedVariablesFilter

turbogears.update_config(configfile="/home/ricky/work/fedora/fas/fas.cfg", modulename="fas.config")
turbogears.config.update({'global': {'server.environment': 'development'}})
turbogears.config.update({'global': {'debug': 'on'}})
turbogears.config.update({'global': {'autoreload.on': False}})
turbogears.config.update({'global': {'server.throw_errors': True}})
turbogears.config.update({'global': {'server.log_to_screen': False}})
turbogears.config.update({'global': {'server.webpath': '/accounts'}})
turbogears.config.update({'global': {'base_url_filter.on': True}})
turbogears.config.update({'global': {'base_url_filter.base_url': 'http://alpha.rzhou.org'}})

turbogears.startup.call_on_startup.append(fedora.tg.util.enable_csrf)

import fas.controllers

cherrypy.root = fas.controllers.Root()

# Uncomment this (and the below section) to use weberror for development
#from weberror.evalexception import EvalException

if cherrypy.server.state == 0:
    atexit.register(cherrypy.server.stop)
    cherrypy.server.start(init_only=True, server_class=None)

from webob import Request

def application(environ, start_response):
    environ['SCRIPT_NAME'] = ''
    return cherrypy._cpwsgi.wsgiApp(environ, start_response)

def fake_call(self, environ, start_response):
    ## FIXME: print better error message (maybe fall back on
    ## normal middleware, plus an error message)
    assert not environ['wsgi.multiprocess'], (
        "The EvalException middleware is not usable in a "
        "multi-process environment")
    # XXX: Legacy support for Paste restorer
    environ['weberror.evalexception'] = environ['paste.evalexception'] = \
        self
    # UGH, this is hideous:
    environ['PATH_INFO_OLD'] = environ['PATH_INFO']
    environ['SCRIPT_NAME'] = '/accounts'
    environ['PATH_INFO'] = environ['PATH_INFO'].split('/', 2)[-1]
    req = Request(environ)
    if req.path_info_peek() == '_debug':
        return self.debug(req)(environ, start_response)
    else:
        environ['PATH_INFO'] = environ['PATH_INFO_OLD']
        return self.respond(environ, start_response)

# Uncomment these lines (and the above weberror import) to use weberror
# for testing.  This requires that python-weberror and its dependencies
# are installed.  debug must be set on above, and mod_wsgi must only use
# one process (don't specify processes= in the WSGIDaemonProcess directive.
# Due to a current WebError bug
# (http://bitbucket.org/bbangert/weberror/issue/2/reliance-on-side-effect-of-an-assert)
# WSGIPythonOptimize must be 0 for this to work properly.
#setattr(EvalException, '__call__', fake_call)
#application = EvalException(application, global_conf={'debug': True})

Attachment: signature.asc
Description: OpenPGP digital signature


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]