Commit f8cde89a authored by Chris McDonough's avatar Chris McDonough

Import tempstorage from its new location instead of from TemporaryFolder.

Implement new "environment" section in config file which allows the
setting of environment variables within the configuration file.

Implement new "path" section in config file which allows insertions into
the Python module search path within the configuration file.

Fix bug where $INSTANCE/Products was not inserted into the products
path by default.

Note that most of these changes are for more comprehensive Windows service
support.  Windows can't run a batch file as a service, and sometimes it
is necessary to both munge the python module search path and environment
at startup time.  Instead of writing an executable application to do this,
we rely on the configuration machinery.
parent 9ca3435d
......@@ -126,6 +126,8 @@ def root_config(section):
swhome = os.path.dirname(os.path.dirname(here))
section.softwarehome = swhome
section.zopehome = os.path.dirname(os.path.dirname(swhome))
if section.environment is None:
section.environment = {}
if section.cgi_environment is None:
section.cgi_environment = {}
if section.clienthome is None:
......@@ -223,7 +225,7 @@ def getDefaultDatabaseFactories(context):
# and a temporary storage for session data
from ZODB.Connection import Connection
from ZODB.config import FileStorage
from Products.TemporaryFolder.config import TemporaryStorage
from tempstorage.config import TemporaryStorage
l = []
class dummy:
......@@ -248,7 +250,8 @@ def getDefaultDatabaseFactories(context):
l.append(main)
ts = dummy('temporary storage for sessioning')
temporary = ZopeDatabase(dummy('temporary', storage=TemporaryStorage(ts),
temporary = ZopeDatabase(dummy('temporary',
storage=TemporaryStorage(ts),
cache_size=5000, pool_size=7,
version_pool_size=3, version_cache_size=100,
mount_points=['/temp_folder'],
......
import os
import sys
# top-level key handlers
......@@ -126,9 +127,27 @@ def root_handler(config):
fixups of values that require knowledge about configuration
values outside of their context. """
# Set environment variables
for k,v in config.environment.items():
os.environ[k] = v
# Add directories to the pythonpath; always insert instancehome/lib/python
instancelib = os.path.join(config.instancehome, 'lib', 'python')
if instancelib not in config.path:
config.path.append(instancelib)
path = config.path[:]
path.reverse()
for dir in path:
sys.path.insert(0, dir)
# Add any product directories not already in Products.__path__.
# Directories are added in the order
if config.products:
# Directories are added in the order they are mentioned
# Always insert instancehome.Products
instanceprod = os.path.join(config.instancehome, 'Products')
if instanceprod not in config.products:
config.products.append(instanceprod)
import Products
L = []
for d in config.products + Products.__path__:
......
......@@ -54,7 +54,7 @@ class StartupTestCase(unittest.TestCase):
os.rmdir(TEMPPRODUCTS)
os.rmdir(TEMPNAME)
self.assertEqual(conf.instancehome, TEMPNAME)
return conf
return conf, handler
def test_load_config_template(self):
schema = self.schema
......@@ -66,7 +66,7 @@ class StartupTestCase(unittest.TestCase):
self.load_config_text(text)
def test_cgi_environment(self):
conf = self.load_config_text("""\
conf, handler = self.load_config_text("""\
# instancehome is here since it's required
instancehome <<INSTANCE_HOME>>
<cgi-environment>
......@@ -78,9 +78,32 @@ class StartupTestCase(unittest.TestCase):
items.sort()
self.assertEqual(items, [("ANOTHER", "value2"), ("HEADER", "value")])
def test_environment(self):
conf, handler = self.load_config_text("""\
# instancehome is here since it's required
instancehome <<INSTANCE_HOME>>
<environment>
FEARFACTORY rocks
NSYNC doesnt
</environment>
""")
items = conf.environment.items()
items.sort()
self.assertEqual(items, [("FEARFACTORY", "rocks"), ("NSYNC","doesnt")])
def test_path(self):
conf, handler = self.load_config_text("""\
# instancehome is here since it's required
instancehome <<INSTANCE_HOME>>
path /foo/bar
path /baz/bee
""")
items = conf.path
self.assertEqual(items, ['/foo/bar', '/baz/bee'])
def test_access_and_trace_logs(self):
fn = tempfile.mktemp()
conf = self.load_config_text("""
conf, handler = self.load_config_text("""
instancehome <<INSTANCE_HOME>>
<logger access>
<logfile>
......@@ -95,14 +118,14 @@ class StartupTestCase(unittest.TestCase):
def test_dns_resolver(self):
from ZServer.medusa import resolver
conf = self.load_config_text("""\
conf, handler = self.load_config_text("""\
instancehome <<INSTANCE_HOME>>
dns-server localhost
""")
self.assert_(isinstance(conf.dns_resolver, resolver.caching_resolver))
def test_zodb_db(self):
conf = self.load_config_text("""\
conf, handler = self.load_config_text("""\
instancehome <<INSTANCE_HOME>>
<zodb_db main>
<filestorage>
......
......@@ -7,7 +7,7 @@
<import package="zLOG"/>
<import package="ZODB"/>
<import package="ZServer"/>
<import package="Products.TemporaryFolder"/>
<import package="tempstorage"/>
<sectiontype name="logger" datatype=".LoggerFactory">
<description>
......@@ -34,6 +34,20 @@
</key>
</sectiontype>
<sectiontype name="environment"
datatype=".cgi_environment"
keytype="identifier">
<description>
A section which allows you to define simple key-value pairs which
will be used as environment variable settings during startup.
</description>
<key name="+" attribute="environ">
<description>
Use any key/value pair, e.g. 'MY_PRODUCT_ENVVAR foo_bar'
</description>
</key>
</sectiontype>
<sectiontype name="zoperunner">
<description>
This section describes the options for zopectl. These options
......@@ -184,6 +198,15 @@
<!-- schema begins -->
<section type="environment" attribute="environment" name="*">
<description>
A section which allows a user to define arbitrary key-value pairs for
use as environment variables during Zope's run cycle. It
is not recommended to set system-related environment variables such as
PYTHONPATH within this section.
</description>
</section>
<key name="instancehome" datatype="existing-directory"
required="yes">
<description>
......@@ -207,6 +230,28 @@
<metadefault>$instancehome/var</metadefault>
</key>
<multikey name="products" datatype="existing-directory">
<description>
This specifies additional product directories which are added to
Products.__path__. Directories are added in the order in which
they are specified.
</description>
<metadefault>$instancehome/Products</metadefault>
</multikey>
<multikey name="path" datatype="existing-directory">
<description>
This specifies additional paths directories which are inserted into
the beginning of Python's module search path. The set of directories
specified is inserted into the beginning of the module search path in
the order which they are specified here. Note that the processing of
this directive may happen too late under some circumstances; it is
recommended that you use the PYTHONPATH environment variable if
using this directive doesn't work for you.
</description>
<metadefault>$instancehome/lib/python</metadefault>
</multikey>
<key name="pid-filename" datatype="existing-dirpath">
<description>
The full path to which the Zope process will write its
......@@ -325,15 +370,6 @@
</description>
</key>
<multikey name="products" datatype="existing-directory">
<description>
This specifies additional product directories which are added to
Products.__path__. Directories are added in the order in which
they are specified.
</description>
<metadefault>$instancehome/Products</metadefault>
</multikey>
<key name="structured-text-header-level" datatype="integer" default="3"
handler="structured_text_header_level">
<description>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment