[Zope-Checkins] CVS: Zope/lib/python/Zope/Startup - __init__.py:1.7.2.1 datatypes.py:1.6.2.2 handlers.py:1.6.2.1 run.py:1.1.2.1 zopectl.py:1.3.2.2 zopeschema.xml:1.7.2.2

Chris McDonough chrism@zope.com
Mon, 21 Jul 2003 12:38:56 -0400


Update of /cvs-repository/Zope/lib/python/Zope/Startup
In directory cvs.zope.org:/tmp/cvs-serv17213/lib/python/Zope/Startup

Modified Files:
      Tag: Zope-2_7-branch
	__init__.py datatypes.py handlers.py run.py zopectl.py 
	zopeschema.xml 
Log Message:
Merge changes from HEAD since the release of Zope 2.7a1 into the Zope-2_7-branch in preparation for release of Zope 2.7b1.


=== Zope/lib/python/Zope/Startup/__init__.py 1.7 => 1.7.2.1 ===
--- Zope/lib/python/Zope/Startup/__init__.py:1.7	Wed Jun 18 03:57:11 2003
+++ Zope/lib/python/Zope/Startup/__init__.py	Mon Jul 21 12:37:47 2003
@@ -21,35 +21,11 @@
 
 import ZConfig
 
-from cmdline import getOptions, getOptionDescriptions # exported
-
-# global to hold config structures
-_schema = None
-_configuration = None
-
-def getConfiguration():
-    return _configuration
-
-def getSchema():
-    global _schema
-    if _schema is None:
-        here = os.path.dirname(__file__)
-        path = os.path.join(here, 'zopeschema.xml')
-        _schema = ZConfig.loadSchema(path)
-    return _schema
-
-def configure(config_location, options):
-    global _configuration
-    import handlers
-    schema = getSchema()
-    _configuration, handler = ZConfig.loadConfig(schema, config_location)
-    handlers.handleConfig(_configuration, handler, options)
-    return _configuration
-
 def start_zope(cfg):
     # set up our initial logging environment (log everything to stderr
     # if we're not in debug mode).
     import zLOG
+    import logging
 
     # don't initialize the event logger from the environment
     zLOG._call_initialize = 0
@@ -76,6 +52,9 @@
     # set up our event logger temporarily with a startup handler
     event_logger = zLOG.EventLogger.EventLogger.logger
     event_logger.addHandler(startup_handler)
+    # set the initial logging level to INFO (this will be changed by the
+    # zconfig settings later)
+    event_logger.level = logging.INFO
 
     # set a locale if one has been specified in the config
     if cfg.locale:
@@ -104,7 +83,7 @@
                                              % (server.servertype(),e[1]))
     cfg.servers = servers
 
-    # do stuff that only applies to posix platforms (setuid, daemonizing)
+    # do stuff that only applies to posix platforms (setuid mainly)
     if os.name == 'posix':
         do_posix_stuff(cfg)
 
@@ -112,9 +91,18 @@
     import Zope
     Zope.startup()
 
+    # this is a bit of a white lie, since we haven't actually successfully
+    # started yet, but we're pretty close and we want this output to
+    # go to the startup logger in order to prevent the kinds of email messages 
+    # to the Zope maillist in which people claim that Zope has "frozen"
+    # after it has emitted ZServer messages ;-)
+    zLOG.LOG('Zope', zLOG.INFO, 'Ready to handle requests')
+
     if not cfg.zserver_read_only_mode:
-        # lock_file is used for the benefit of zctl, so it can tell whether
-        # Zope is already running before attempting to fire it off again.
+        # lock_file is used for the benefit of zctl-like systems, so they
+        # can tell whether Zope is already running before attempting to fire
+        # it off again.
+        #
         # We aren't concerned about locking the file to protect against
         # other Zope instances running from our CLIENT_HOME, we just
         # try to lock the file to signal that zctl should not try to
@@ -129,9 +117,22 @@
                 os.unlink(lock_filename)
             LOCK_FILE = open(lock_filename, 'w')
             lock_file(LOCK_FILE)
+            LOCK_FILE.write(str(os.getpid()))
+            LOCK_FILE.flush()
         except IOError:
             pass
 
+        # write the pid into the pidfile if possible
+        pid_filename = cfg.pid_filename
+        try:
+            if os.path.exists(pid_filename):
+                os.unlink(pid_filename)
+            f = open(pid_filename, 'w')
+            f.write(str(os.getpid()))
+            f.close()
+        except IOError:
+            pass
+        
         # Now that we've successfully setuid'd, we can log to
         # somewhere other than stderr.  Activate the configured logs:
         if cfg.access is not None:
@@ -145,8 +146,6 @@
             logger = cfg.eventlog()
             startup_handler.flushBufferTo(logger)
 
-    zLOG.LOG('Zope', zLOG.INFO, 'Ready to handle requests')
-
     # Start Medusa, Ye Hass!
     try:
         import Lifetime
@@ -155,7 +154,7 @@
     finally:
         if not cfg.zserver_read_only_mode:
             try:
-                os.unlink(cfg.pid_filename)
+                os.unlink(pid_filename)
             except OSError:
                 pass
             try:


=== Zope/lib/python/Zope/Startup/datatypes.py 1.6.2.1 => 1.6.2.2 ===
--- Zope/lib/python/Zope/Startup/datatypes.py:1.6.2.1	Tue Jul  8 01:28:47 2003
+++ Zope/lib/python/Zope/Startup/datatypes.py	Mon Jul 21 12:37:47 2003
@@ -16,7 +16,6 @@
 
 import os
 from ZODB.config import ZODBDatabase
-from ZODB.config import FileStorage
 
 # generic datatypes
 
@@ -25,7 +24,16 @@
     ok = ('PYTHON', 'C')
     if value not in ok:
         raise ValueError, (
-            "security_policy_implementation must be one of %s" % ok
+            "security-policy-implementation must be one of %s" % repr(ok)
+            )
+    return value
+
+def datetime_format(value):
+    value = value.lower()
+    ok = ('us', 'international')
+    if value not in ok:
+        raise ValueError, (
+            "datetime-format must be one of %r" % repr(ok)
             )
     return value
 
@@ -103,7 +111,7 @@
 
 # Datatype for the root configuration object
 # (adds the softwarehome and zopehome fields; default values for some
-#  computed paths)
+#  computed paths, configures dbtab)
 
 def root_config(section):
     from ZConfig import ConfigurationError
@@ -123,58 +131,120 @@
         section.lock_filename = os.path.join(section.clienthome, 'Z2.lock')
 
     if not section.databases:
-        section.databases = [getDefaultDatabaseFactory(section)]
+        section.databases = getDefaultDatabaseFactories(section)
 
-    section.db_mount_tab = db_mount_tab = {}
-    section.db_name_tab =  db_name_tab = {}
+    mount_factories = {} # { name -> factory}
+    mount_points = {} # { virtual path -> name }
     dup_err = ('Invalid configuration: ZODB databases named "%s" and "%s" are '
                'both configured to use the same mount point, named "%s"')
 
     for database in section.databases:
-        mount_points = database.config.mount_points
+        points = database.getVirtualMountPaths()
         name = database.config.getSectionName()
-        db_name_tab[name] = database
-        for point in mount_points:
-            if db_mount_tab.has_key(point):
-                raise ConfigurationError(dup_err % (db_mount_tab[point], name,
-                                         point))
-            db_mount_tab[point] = name
+        mount_factories[name] = database
+        for point in points:
+            if mount_points.has_key(point):
+                raise ConfigurationError(dup_err % (mount_points[point],
+                                                    name, point))
+            mount_points[point] = name
+    from DBTab.DBTab import DBTab
+    section.dbtab = DBTab(mount_factories, mount_points)
 
     return section
 
 class ZopeDatabase(ZODBDatabase):
     """ A ZODB database datatype that can handle an extended set of
-    attributes """
+    attributes for use by DBTab """
+
+    container_class = 'OFS.Folder.Folder'
+
     def open(self):
         DB = ZODBDatabase.open(self)
         # set the connection class
         DB.klass = self.config.connection_class
+        if self.config.class_factory is not None:
+            DB.setClassFactory(self.config.class_factory)
+        from ZODB.ActivityMonitor import ActivityMonitor
+        DB.setActivityMonitor(ActivityMonitor())
         return DB
+
+    def getName(self):
+        return self.name
+
+    def getOpenAtStartup(self):
+        # XXX implement
+        return 0
+
+    def computeMountPaths(self):
+        mps = []
+        for part in self.config.mount_points:
+            real_root = None
+            if ':' in part:
+                # 'virtual_path:real_path'
+                virtual_path, real_path = part.split(':', 1)
+                if real_path.startswith('~'):
+                    # Use a special root.
+                    # 'virtual_path:~real_root/real_path'
+                    real_root, real_path = real_path[1:].split('/', 1)
+            else:
+                # Virtual path is the same as the real path.
+                virtual_path = real_path = part
+            mps.append((virtual_path, real_root, real_path))
+        return mps
+
+    def getVirtualMountPaths(self):
+        return [item[0] for item in self.computeMountPaths()]
+
+    def getMountParams(self, mount_path):
+        """Returns (real_root, real_path, container_class) for a virtual
+        mount path.
+        """
+        for (virtual_path, real_root, real_path) in self.computeMountPaths():
+            if virtual_path == mount_path:
+                return (real_root, real_path, self.container_class)
+        raise LookupError('Nothing known about mount path %s' % mount_path)
     
-def getDefaultDatabaseFactory(context):
+def getDefaultDatabaseFactories(context):
     # default to a filestorage named 'Data.fs' in clienthome
+    # and a temporary storage for session data
+    from ZODB.Connection import Connection
+    from ZODB.config import FileStorage
+    from Products.TemporaryFolder.config import TemporaryStorage
+
+    l = []
     class dummy:
-        def __init__(self, name):
+        def __init__(self, name, **kw):
             self.name = name
+            for k, v in kw.items():
+                setattr(self, k, v)
+
         def getSectionName(self):
             return self.name
 
-    from ZODB.Connection import Connection
-
     path = os.path.join(context.clienthome, 'Data.fs')
-    fs_ns = dummy('default filestorage at %s' % path)
-    fs_ns.path = path
-    fs_ns.create = None
-    fs_ns.read_only = None
-    fs_ns.quota = None
-    storage = FileStorage(fs_ns)
-    db_ns = dummy('default zodb database using filestorage at %s' % path)
-    db_ns.storage = storage
-    db_ns.cache_size = 5000
-    db_ns.pool_size = 7
-    db_ns.version_pool_size=3
-    db_ns.version_cache_size = 100
-    db_ns.mount_points = ['/']
-    db_ns.connection_class = Connection
-    return ZopeDatabase(db_ns)
+
+    fs = dummy('default filestorage at %s' % path, path=path,
+                  create=None, read_only=None, quota=None)
+    main = ZopeDatabase(dummy('main', storage=FileStorage(fs), cache_size=5000,
+                              pool_size=7, version_pool_size=3,
+                              version_cache_size=100, mount_points=['/'],
+                              connection_class=Connection,
+                              class_factory=None))
+
+    l.append(main)
+
+    ts = dummy('temporary storage for sessioning')
+    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'],
+                                   connection_class=Connection,
+                                   class_factory=None))
+
+    temporary.container_class = ('Products.TemporaryFolder.TemporaryFolder.'
+                                 'SimpleTemporaryContainer')
+    l.append(temporary)
+
+    return l
+    
 


=== Zope/lib/python/Zope/Startup/handlers.py 1.6 => 1.6.2.1 ===
--- Zope/lib/python/Zope/Startup/handlers.py:1.6	Wed Apr 23 15:27:38 2003
+++ Zope/lib/python/Zope/Startup/handlers.py	Mon Jul 21 12:37:47 2003
@@ -28,6 +28,10 @@
     locale.setlocale(locale.LC_ALL, value)
     return value
 
+def datetime_format(value):
+    value and _setenv('DATETIME_FORMAT', value)
+    return value
+
 def zserver_read_only_mode(value):
     value and _setenv('ZOPE_READ_ONLY', '1')
     return value
@@ -86,6 +90,14 @@
     value is not None and _setenv('STX_DEFAULT_LEVEL', value)
     return value
 
+def rest_input_encoding(value):
+    value and _setenv('REST_INPUT_ENCODING' , value)
+    return value
+
+def rest_output_encoding(value):
+    value and _setenv('REST_OUTPUT_ENCODING' , value)
+    return value
+
 def maximum_security_manager_stack_size(value):
     value is not None and _setenv('Z_MAX_STACK_SIZE', value)
     return value
@@ -101,6 +113,10 @@
 def security_policy_implementation(value):
     value not in ('C', None) and _setenv('ZOPE_SECURITY_POLICY', value)
 
+def max_listen_sockets(value):
+    import ZServer
+    ZServer.CONNECTION_LIMIT = value
+
 # server handlers
 
 def root_handler(config):
@@ -134,6 +150,10 @@
                         config.cgi_environment,
                         config.port_base)
 
+    # set up trusted proxies
+    if config.trusted_proxies:
+        import ZPublisher.HTTPRequest
+        ZPublisher.HTTPRequest.trusted_proxies = tuple(config.trusted_proxies)
 
 class _DummyServerConfig:
     class _Thing:


=== Zope/lib/python/Zope/Startup/run.py 1.1 => 1.1.2.1 ===
--- Zope/lib/python/Zope/Startup/run.py:1.1	Mon Apr  7 20:48:45 2003
+++ Zope/lib/python/Zope/Startup/run.py	Mon Jul 21 12:37:47 2003
@@ -1,3 +1,16 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
 
 # this function will actually start up a Zope instance
 def run():
@@ -5,7 +18,7 @@
     from Zope.Startup import handlers, options, start_zope
 
     opts = options.ZopeOptions()
-    opts.realize()
+    opts.realize(doc="Sorry, no option docs yet.")
     handlers.handleConfig(opts.configroot, opts.confighandlers)
     App.config.setConfiguration(opts.configroot)
     start_zope(opts.configroot)


=== Zope/lib/python/Zope/Startup/zopectl.py 1.3.2.1 => 1.3.2.2 ===
--- Zope/lib/python/Zope/Startup/zopectl.py:1.3.2.1	Mon Jul  7 00:20:18 2003
+++ Zope/lib/python/Zope/Startup/zopectl.py	Mon Jul 21 12:37:47 2003
@@ -35,6 +35,7 @@
 
 import os
 import sys
+import signal
 
 import zdaemon
 import Zope.Startup
@@ -66,7 +67,7 @@
         ZDOptions.__init__(self)
         self.add("backofflimit", "runner.backoff_limit",
                  "b:", "backoff-limit=", int, default=10)
-        self.add("daemon", "runner.daemon", "d", "daemon", flag=1, default=0)
+        self.add("daemon", "runner.daemon", "d", "daemon", flag=1, default=1)
         self.add("forever", "runner.forever", "f", "forever",
                  flag=1, default=0)
         self.add("hang_around", "runner.hang_around", default=0)
@@ -179,6 +180,9 @@
         c.do_status()
         c.cmdloop()
 
-
 if __name__ == "__main__":
+    # we don't care to be notified of our childrens' exit statuses.
+    # this prevents zombie processes from cluttering up the process
+    # table when zopectl start/stop is used interactively.
+    signal.signal(signal.SIGCHLD, signal.SIG_IGN)
     main()


=== Zope/lib/python/Zope/Startup/zopeschema.xml 1.7.2.1 => 1.7.2.2 ===
--- Zope/lib/python/Zope/Startup/zopeschema.xml:1.7.2.1	Tue Jul  8 01:28:47 2003
+++ Zope/lib/python/Zope/Startup/zopeschema.xml	Mon Jul 21 12:37:47 2003
@@ -7,6 +7,7 @@
   <import package="zLOG"/>
   <import package="ZODB"/>
   <import package="ZServer"/>
+  <import package="Products.TemporaryFolder"/>
 
   <sectiontype name="logger" datatype=".LoggerFactory">
     <description>
@@ -22,7 +23,15 @@
   <sectiontype name="cgi-environment"
                datatype=".cgi_environment"
                keytype="identifier">
-    <key name="+" attribute="environ"/>
+    <description>
+     A section which allows you to define simple key-value pairs which
+     will extend the CGI environment variables exposed by ZServer.
+    </description>
+    <key name="+" attribute="environ">
+      <description>
+        Use any key/value pair, e.g. 'HTTPS_PORT 443'
+      </description>
+    </key>
   </sectiontype>
 
   <sectiontype name="zoperunner">
@@ -131,16 +140,29 @@
       so this is a multikey.
     </description>
     <multikey name="mount-point" required="yes" attribute="mount_points"
-              datatype=".mount_point"/>
+              datatype=".mount_point">
+      <description>
+       The mount point is the slash-separated path to which this database
+       will be mounted within the Zope application server.
+      </description>
+    </multikey>
 
-    <description>
-     We want to allow people to be able to change the connection
-     class a database uses on a per-database basis to support
-     different connection policies.
-    </description>
     <key name="connection-class" datatype=".importable_name"
-              default="ZODB.Connection.Connection"/>
+              default="ZODB.Connection.Connection">
+      <description>
+       Change the connection class a database uses on a per-database basis to
+       support different connection policies.  Use a Python dotted-path
+       name to specify the connection class.
+      </description>
+    </key>
 
+   <key name="class-factory" datatype=".importable_name">
+      <description>
+       Change the class factory function a database uses on a
+       per-database basis to support different class factory policy.
+       Use a Python dotted-path name to specify the class factory function.
+      </description>
+    </key>
   </sectiontype>
 
   <!-- end of type definitions -->
@@ -150,35 +172,122 @@
   <key name="instancehome" datatype="existing-directory"
        required="yes">
     <description>
-      The top-level directory which contains the "instance" of the
-      application server.
+      The top-level directory which contains the "instance" data for the
+      application server.  Typically this is a directory which
+      may contain a "Products" subdirectory (which holds instance-local
+      Zope Products), an "Extensions" subdirectory (which holds instance-local
+      external methods), and an "import" directory (which holds instance-local
+      importable ZODB exports).  It may also contain "etc", "bin", "log",
+      and "var" directories depending on how you'ce configured your Zope
+      instance.
     </description>
   </key>
 
   <key name="clienthome" datatype="existing-directory">
     <description>
-      The directory used to store the file-storage used to back the
-      ZODB database by default, as well as other files used by the
-      Zope application server to control the run-time behavior.
+      The directory used to store the default filestorage file used to
+      back the ZODB database, as well as other files used by the
+      Zope applications server during runtime.
     </description>
-    <metadefault>$INSTANCE_HOME/var</metadefault>
+    <metadefault>$instancehome/var</metadefault>
   </key>
 
-  <key name="pid-filename" datatype="existing-dirpath"/>
+  <key name="pid-filename" datatype="existing-dirpath">
+    <description>
+      The full path to which the Zope process will write its
+      OS process id at startup.
+    </description>
+    <metadefault>$clienthome/Z2.pid</metadefault>
+  </key>
 
-  <key name="lock-filename" datatype="existing-dirpath"/>
+  <key name="lock-filename" datatype="existing-dirpath">
+    <description>
+      The full path to a file which the Zope process will attempt to lock
+      at startup (used to signal to other processes that this Zope instance is
+      currently running).
+    </description>
+    <metadefault>$clienthome/Z2.lock</metadefault>
+  </key>
 
   <key name="debug-mode" datatype="boolean" default="on"
-       handler="debug_mode"/>
+       handler="debug_mode">
+    <description>
+    A switch which controls several aspects of Zope operation useful for
+    developing under Zope.  When debug mode is on:
+
+     - The process will not detach from the controlling terminal
+
+     - Errors in product initialization will cause startup to fail
+       (instead of writing error messages to the event log file).
 
-  <key name="effective-user"/>
+     - Filesystem-based scripts such as skins, PageTemplateFiles, and
+       DTMLFiles can be edited while the server is running and the server
+       will detect these changes in real time.  When this switch is
+       off, you must restart the server to see the changes.
+
+     Setting this to 'off' when Zope is in a
+     production environment is encouraged, as it speeds execution (sometimes
+     dramatically).
+    </description>
+    <metadefault>on</metadefault>
+  </key>
+
+  <key name="effective-user">
+    <description>
+     If you intend to run Zope as the "root" user, you must supply this
+     directive with an effective username or userid number to which Zope
+     will 'suid' after the server ports are bound. This directive only
+     has effect under UNIX and if Zope is started as the root user.
+    </description>
+    <metadefault>unset</metadefault>
+  </key>
 
   <key name="enable-product-installation" datatype="boolean" default="on"
-       handler="enable_product_installation"/>
+       handler="enable_product_installation">
+    <description>
+     If this directive is turned on, Zope performs 'product installation'
+     (the registration of Python modules in various Products directories)
+     at startup. Turning this off can speed Zope startup time, but it can
+     also cause your Control_Panel Product list to become desynchronized
+     with the contents of your Products directories. If the
+     'zeo_client_name' directive is set, and this directive is unset, this
+     directive will be implicitly turned off.
+    </description>
+    <metadefault>on</metadefault>
+  </key>
+
+  <key name="locale" datatype="locale" handler="locale">
+    <description>
+     Enable locale (internationalization) support by supplying a locale
+     name to be used. See your operating system documentation for locale
+     information specific to your system. If your Python module does not
+     support the locale module, or if the requested locale is not
+     supported by your system, an error will be raised and Zope will not
+     start.
+    </description>
+    <metadefault>unset</metadefault>
+  </key>
 
-  <key name="locale" datatype="locale" handler="locale"/>
+  <key name="datetime-format" datatype=".datetime_format"
+       handler="datetime_format" default="us">
+    <description>
+     Set this variable either to "us" or "international" to force the
+     DateTime module to parse date strings either with
+     month-before-days-before-year ("us") or
+     days-before-month-before-year ("international").  The default
+     behaviour of DateTime (when this setting is left unset) is to
+     parse dates as US dates.
+    </description>
+    <metadefault>us</metadefault>
+  </key>
 
-  <key name="zserver-threads" datatype="integer" default="4"/>
+  <key name="zserver-threads" datatype="integer" default="4">
+     <description>
+     Specify the number of threads that Zope's ZServer web server will use
+     to service requests. The default is 4.
+    </description>
+    <metadefault>4 threads</metadefault>
+  </key>
 
   <key name="python-check-interval" datatype="integer" default="500">
     <description>
@@ -207,63 +316,244 @@
       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"/>
+       handler="structured_text_header_level">
+    <description>
+     Set the default starting HTML header level for structured text
+     documents. The default is 3, which implies that top-level headers
+     will be created with an H3 HTML tag.
+    </description>
+    <metadefault>3</metadefault>
+  </key>
+
+  <key name="rest-input-encoding" handler="rest_input_encoding">
+    <description>
+    Specifies the input encoding of re-StructuredText documents
+    (e.g. 'utf-8', 'iso-8859' or any other valid encoding recognized
+    by Python).  The default is your Python's default encoding.
+    </description>
+    <metadefault>unset</metadefault>
+  </key>
+
+  <key name="rest-output-encoding" handler="rest_output_encoding">
+    <description>
+    Specifies the output encoding of re-StructuredText documents
+    (e.g. 'utf-8', 'iso-8859' or any other valid encoding recognized
+    by Python).  The default is your Python's default encoding.
+    </description>
+    <metadefault>unset</metadefault>
+  </key>
 
   <key name="maximum-security-manager-stack-size" datatype="integer"
-       default="100" handler="maximum_security_manager_stack_size"/>
+       default="100" handler="maximum_security_manager_stack_size">
+     <description>
+     This variable allows you to customize the size of the Zope
+     SecurityManager stack. You shouldn't change this unless you know what
+     it means.
+     </description>
+     <metadefault>100</metadefault>
+  </key>
 
-  <key name="publisher-profile-file" handler="publisher_profile_file"/>
+  <key name="publisher-profile-file" handler="publisher_profile_file">
+    <description>
+     Causing this directive to point to a file on the filesystem will
+     cause Zope's profiling capabilities to be enabled. For more
+     information, see the Debug/Profiling tab of Zope's Control_Panel.
+    </description>
+    <metadefault>unset</metadefault>
+  </key>
 
-  <section type="cgi-environment" attribute="cgi_environment" name="*"/>
+  <section type="cgi-environment" attribute="cgi_environment" name="*">
+    <description>
+     A section which allows a user to define arbitrary key-value pairs for
+     use as the initial CGI environment variables. This setting is useful
+     when you want to proxy requests from another web server to Zserver,
+     and would like Zserver's CGI environment to reflect the CGI
+     environment of the other web server.
+    </description>
+  </section>
 
-  <key name="dns-server" datatype=".dns_resolver" attribute="dns_resolver"/>
+  <key name="dns-server" datatype=".dns_resolver" attribute="dns_resolver">
+    <description>
+     Specify the ip address of your DNS server in order to cause resolved
+     hostnames to be written to Zope's access log. By default, Zope will
+     not resolve hostnames unless this is set.
+    </description>
+  </key>
 
-  <key name="ip-address" datatype="ipaddr-or-hostname"/>
+  <key name="ip-address" datatype="ipaddr-or-hostname">
+    <description>
+     The default IP address on which Zope's various server protocol
+     implementations will listen for requests. If this is unset, Zope
+     will listen on all IP addresses supported by the machine.
+    </description>
+  </key>
 
-  <key name="http-realm" default="Zope" handler="http_realm"/>
+  <key name="http-realm" default="Zope" handler="http_realm">
+    <description>
+     The HTTP "Realm" header value sent by this Zope instance. This value
+     often shows up in basic authentication dialogs.
+    </description>
+    <metadefault>Zope</metadefault>
+  </key>
 
   <key name="automatically-quote-dtml-request-data" datatype="boolean"
-       default="on" handler="automatically_quote_dtml_request_data"/>
+       default="on" handler="automatically_quote_dtml_request_data">
+     <description>
+     Set this directive to 'off' in order to disable the autoquoting of
+     implicitly retrieved REQUEST data by DTML code which contains a '&lt;'
+     when used in &lt;dtml-var&gt; construction. When this directive is 'on',
+     all data implicitly retrieved from the REQUEST in DTML (as opposed to
+     addressing REQUEST.somevarname directly) that contains a '&lt;' will be
+     HTML-quoted when interpolated via a &lt;dtml-var&gt; or &amp;dtml-
+     construct. This mitigates the possibility that DTML programmers will
+     leave their sites open to a "client-side trojan" attack.
+     </description>
+     <metadefault>on</metadefault>
+  </key>
+
+  <multikey name="trusted-proxy" datatype="ipaddr-or-hostname"
+       attribute="trusted_proxies">
+     <description>
+     Define one or more 'trusted-proxies' keys, each of which is a
+     hostname or an IP address.  The set of definitions comprises a list
+     of front-end proxies that are trusted to supply an accurate
+     X_FORWARDED_FOR header to Zope (security-related).
+     </description>
+     <metadefault>unset</metadefault>
+  </multikey>
 
   <key name="security-policy-implementation"
        datatype=".security_policy_implementation"
-       default="C" handler="security_policy_implementation"/>
+       default="C" handler="security_policy_implementation">
+     <description>
+     The default Zope "security policy" implementation is written in C.
+     Set this key to "PYTHON" to use the Python implementation
+     (useful for debugging purposes); set it to "C" to use the C
+     implementation.
+     </description>
+     <metadefault>C</metadefault>
+  </key>
 
   <key name="skip-authentication-checking" datatype="boolean"
-       default="off" handler="skip_authentication_checking"/>
+       default="off" handler="skip_authentication_checking">
+     <description>
+     Set this directive to 'on' to cause Zope to prevent Zope from
+     attempting to authenticate users during normal operation.
+     Potentially dangerous from a security perspective.  Only works if
+     security-policy-implementation is set to 'C'.
+     </description>
+     <metadefault>off</metadefault>
+  </key>
 
   <key name="skip-ownership-checking" datatype="boolean"
-       default="off" handler="skip_ownership_checking"/>
+       default="off" handler="skip_ownership_checking">
+     <description>
+     Set this directive to 'on' to cause Zope to ignore ownership checking
+     when attempting to execute "through the web" code. By default, this
+     directive is off in order to prevent 'trojan horse' security problems
+     whereby a user with less privilege can cause a user with more
+     privilege to execute code which the less privileged user has written.
+     </description>
+     <metadefault>off</metadefault>
+  </key>
 
   <key name="maximum-number-of-session-objects" datatype="integer"
-       default="1000" handler="maximum_number_of_session_objects"/>
+       default="1000" handler="maximum_number_of_session_objects">
+     <description>
+     An integer value representing the number of items to use as a
+     "maximum number of subobjects" value of the
+     '/temp_folder/session_data' transient object container within
+     Zope's object database.
+     </description>
+     <metadefault>1000</metadefault>
+  </key>
 
   <key name="session-add-notify-script-path"
-       handler="session_add_notify_script_path"/>
+       handler="session_add_notify_script_path">
+     <description>
+     An optional full Zope path name of a callable object to be set as the
+     "script to call on object addition" of the session_data transient
+     object container created in the '/temp_folder' folder at startup.
+     </description>
+     <metadefault>unset</metadefault>
+  </key>
 
   <key name="session-delete-notify-script-path"
-       handler="session_add_notify_script_path"/>
+       handler="session_add_notify_script_path">
+     <description>
+     An optional full Zope path name of a callable object to be set as the
+     "script to call on object deletion" of the sessioN_data transient
+     object container created in the /temp_folder folder at startup.
+     </description>
+     <metadefault>unset</metadefault>
+  </key>
 
   <key name="session-timeout-minutes" datatype="integer"
-       default="20" handler="session_timeout_minutes"/>
+       default="20" handler="session_timeout_minutes">
+     <description>
+     An integer value representing the number of minutes to be used as the
+     "data object timeout" of the '/temp_folder/session_data' transient
+     object container in Zope's object database.
+     </description>
+     <metadefault>20</metadefault>
+  </key>
 
   <key name="suppress-all-access-rules" datatype="boolean"
-       default="off" handler="suppress_all_access_rules"/>
+       default="off" handler="suppress_all_access_rules">
+     <description>
+     If this directive is set to on, no access rules in your Zope site
+     will be executed. This is useful if you "lock yourself out" of a
+     particular part of your site by setting an improper access rule.
+     </description>
+     <metadefault>off</metadefault>
+  </key>
+
 
   <key name="suppress-all-site-roots" datatype="boolean"
-       default="off" handler="suppress_all_site_roots"/>
+       default="off" handler="suppress_all_site_roots">
+     <description>
+     If this directive is set to on, no site roots in your Zope site will
+     be effective. This is useful if you "lock yourself out" of a
+     particular part of your site by setting an improper site root.
+     </description>
+     <metadefault>off</metadefault>
+  </key>
+
 
   <key name="database-quota-size" datatype="byte-size"
-       handler="database_quota_size"/>
+       handler="database_quota_size">
+     <description>
+     Set this directive to an integer in bytes in order to place a hard
+     limit on the size which the default FileStorage-backed Zope database
+     can grow. Additions to the database will not be permitted once this
+     filesize is exceeded.
+     </description>
+     <metadefault>unset</metadefault>
+  </key>
 
   <key name="read-only-database" datatype="boolean"
-       handler="read_only_database"/>
+       handler="read_only_database">
+     <description>
+     If this directive is set to "on", the main Zope
+     FileStorage-backed ZODB database will be opened in read-only
+     mode.
+     </description>
+     <metadefault>off</metadefault>
+  </key>
 
-  <key name="zeo-client-name"
-       handler="zeo_client_name"/>
+  <key name="zeo-client-name" handler="zeo_client_name">
+    <description>
+     Provide a string value to uniquely identify the local cache files
+     created if this Zope is a ZEO client. Setting this directive implies
+     setting 'enable-product-installation' to 'off' if
+     'enable-product-installation' is left unset.
+     </description>
+     <metadefault>unset</metadefault>
+  </key>
 
   <section type="eventlog" name="*" attribute="eventlog">
     <description>
@@ -271,9 +561,32 @@
     </description>
   </section>
 
-  <section type="logger" name="access"/>
+  <section type="logger" name="access">
+     <description>
+      Describes the logging performed to capture the 'access' log,
+      which typically captures per-request data in common or combined
+      log format.
+    </description>
+  </section>
+
+  <section type="logger" name="trace">
+     <description>
+      Describes the logging performed to capture the 'trace log,
+      which typically captures detailed per-request data useful for
+      Zope debugging.
+    </description>
+  </section>
+
+  <!-- max-listen-sockets should really go into the ZServer package, but
+       I can't quite figure out how to put it there -->
 
-  <section type="logger" name="trace"/>
+  <key name="max-listen-sockets" datatype="integer"
+       handler="max_listen_sockets" default="1000">
+     <description>
+       The maximum number of sockets that ZServer will attempt to open
+       in order to service incoming connections.
+     </description>
+  </key>
 
   <multisection type="ZServer.server" name="*" attribute="servers"/>
   <key name="port-base" datatype="integer" default="0">
@@ -296,5 +609,6 @@
   </multisection>
 
   <section type="zoperunner" name="*" attribute="runner"/>
+
 
 </schema>