[Zope-Checkins] CVS: Zope/bin - .cvsignore:1.2 mkzeoinstance:1.2 mkzopeinstance:1.2 runzope.py:1.2 zopectl.py:1.2

Fred L. Drake, Jr. fred@zope.com
Tue, 18 Mar 2003 16:28:20 -0500


Update of /cvs-repository/Zope/bin
In directory cvs.zope.org:/tmp/cvs-serv25868/bin

Added Files:
	.cvsignore mkzeoinstance mkzopeinstance runzope.py zopectl.py 
Log Message:
Merge new scripts and configuration/installation support from the
new-install-branch.


=== Zope/bin/.cvsignore 1.1 => 1.2 ===
--- /dev/null	Tue Mar 18 16:28:20 2003
+++ Zope/bin/.cvsignore	Tue Mar 18 16:27:49 2003
@@ -0,0 +1,2 @@
+runzope
+zopectl


=== Zope/bin/mkzeoinstance 1.1 => 1.2 ===
--- /dev/null	Tue Mar 18 16:28:20 2003
+++ Zope/bin/mkzeoinstance	Tue Mar 18 16:27:49 2003
@@ -0,0 +1,37 @@
+#!python
+##############################################################################
+#
+# Copyright (c) 2001 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.
+#
+##############################################################################
+
+import os
+import sys
+
+mydir = os.path.dirname(os.path.abspath(sys.argv[0]))
+zopehome = os.path.dirname(mydir)
+softwarehome = os.path.join(zopehome, "lib", "python")
+
+if softwarehome not in sys.path:
+    sys.path.append(softwarehome)
+
+from ZEO.mkzeoinst import ZEOInstanceBuilder
+
+class InstanceBuilder(ZEOInstanceBuilder):
+    def get_params(self, *args, **kw):
+        params = ZEOInstanceBuilder.get_params(self, *args, **kw)
+        sw = os.path.join(softwarehome, "lib", "python")
+        params["server"] = os.path.join(sw, "ZEO", "runzeo.py")
+        params["zdrun"] = os.path.join(sw, "zdaemon", "zdrun.py")
+        params["zdctl"] = os.path.join(sw, "zdaemon", "zdctl.py")
+        return params
+
+if __name__ == "__main__":
+    InstanceBuilder().run()


=== Zope/bin/mkzopeinstance 1.1 => 1.2 ===
--- /dev/null	Tue Mar 18 16:28:20 2003
+++ Zope/bin/mkzopeinstance	Tue Mar 18 16:27:49 2003
@@ -0,0 +1,164 @@
+#! python
+##############################################################################
+#
+# Copyright (c) 2001 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
+#
+##############################################################################
+
+"""%(program)s:  Create a Zope instance home.
+
+usage:  %(program)s [options] directory
+
+Options:
+
+-h/--help -- print this help text
+-u/--user NAME:PASSWORD -- set the user name and password of the initial user
+"""
+
+import getopt
+import os
+import shutil
+import sys
+
+def main():
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "hu:", ["help", "user="])
+    except getopt.GetoptError, msg:
+        usage(sys.stderr, msg)
+        sys.exit(2)
+    user = None
+    password = None
+    for opt, arg in opts:
+        if opt in ("-h", "--help"):
+            usage(sys.stdout)
+            sys.exit()
+        if opt in ("-u", "--user"):
+            if not ":" in arg:
+                usage(sys.stderr, "user must be specified as name:password")
+                sys.exit(2)
+            user, password = arg.split(":", 1)
+    if len(args) != 1:
+        usage(sys.stderr, "mkzopeinstance requires exactly one argument")
+        sys.exit(2)
+    dirname = os.path.abspath(args[0])
+    inituser = os.path.join(dirname, "inituser")
+    if not (user or os.path.exists(inituser)):
+        user, password = get_inituser()
+    makeinstance(dirname, user, password, inituser)
+
+def usage(stream, msg=None):
+    if msg:
+        print >>stream, msg
+        print >>stream
+    program = os.path.basename(sys.argv[0])
+    print >>stream, __doc__ % {"program": program}
+
+def get_inituser():
+    import getpass
+    print 'Please choose a username and password for the initial user.'
+    print 'These will be the credentials you use to initially manage'
+    print 'your new Zope instance.'
+    print
+    user = raw_input("Username: ").strip()
+    if user == '':
+        return None, None
+    while 1:
+        passwd = getpass.getpass("Password: ")
+        verify = getpass.getpass("Verify password: ")
+        if verify == passwd:
+            break
+        else:
+            passwd = verify = ''
+            print "Password mismatch, please try again..."
+    return user, passwd
+
+def makeinstance(dirname, user, password, inituser):
+    script = os.path.abspath(sys.argv[0])
+    installation = os.path.dirname(os.path.dirname(script))
+    skel = os.path.join(installation, "skel")
+
+    # Create the top of the instance:
+    if not os.path.exists(dirname):
+        os.mkdir(dirname)
+
+    replacements = {
+        "PYTHON": sys.executable,
+        "INSTANCE_HOME": dirname,
+        "SOFTWARE_HOME": os.path.join(installation, "lib", "python"),
+        "ZOPE_HOME": installation,
+        }
+
+    # This is fairly ugly.  The chdir() makes path manipulation in the
+    # walk() callback a little easier (less magical), so we'll live
+    # with it.
+    pwd = os.getcwd()
+    os.chdir(skel)
+    try:
+        try:
+            os.path.walk(os.curdir, copyskel, (dirname, replacements))
+        finally:
+            os.chdir(pwd)
+    except (IOError, OSError), msg:
+        print >>sys.stderr, msg
+        sys.exit(1)
+
+    if user:
+        write_inituser(inituser, user, password)
+
+def write_inituser(fn, user, password):
+    import binascii
+    import sha
+    fp = open(fn, "w")
+    pw = binascii.b2a_base64(sha.new(password).digest())[:-1]
+    fp.write('%s:{SHA}%s\n' % (user, pw))
+    fp.close()
+    os.chmod(fn, 0644)
+
+CVS = os.path.normcase("CVS")
+
+def copyskel((basedir, replacements), dirname, names):
+    # Don't recurse into CVS directories:
+    for name in names[:]:
+        if os.path.normcase(name) == CVS:
+            names.remove(name)
+        elif os.path.isfile(os.path.join(dirname, name)):
+            # Copy the file:
+            sn, ext = os.path.splitext(name)
+            if os.path.normcase(ext) == ".in":
+                dst = os.path.join(basedir, dirname, sn)
+                if os.path.exists(dst):
+                    continue
+                copyin(os.path.join(dirname, name), dst, replacements)
+            else:
+                src = os.path.join(dirname, name)
+                dst = os.path.join(basedir, src)
+                if os.path.exists(dst):
+                    continue
+                shutil.copyfile(src, dst)
+        else:
+            # Directory:
+            dn = os.path.join(basedir, dirname, name)
+            if not os.path.exists(dn):
+                os.mkdir(dn)
+
+def copyin(src, dst, replacements):
+    ifp = open(src)
+    text = ifp.read()
+    ifp.close()
+    for k in replacements:
+        text = text.replace("<<%s>>" % k, replacements[k])
+    ofp = open(dst, "w")
+    ofp.write(text)
+    ofp.close()
+    shutil.copymode(src, dst)
+
+
+if __name__ == "__main__":
+    main()


=== Zope/bin/runzope.py 1.1 => 1.2 ===
--- /dev/null	Tue Mar 18 16:28:20 2003
+++ Zope/bin/runzope.py	Tue Mar 18 16:27:49 2003
@@ -0,0 +1,31 @@
+#!python
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Start Zope.  Now!"""
+
+import App.config
+
+from Zope.Startup import handlers, options, start_zope
+
+
+def main():
+    opts = options.ZopeOptions()
+    opts.realize()
+    handlers.handleConfig(opts.configroot, opts.confighandlers)
+    App.config.setConfiguration(opts.configroot)
+    start_zope(opts.configroot)
+
+
+if __name__ == "__main__":
+    main()


=== Zope/bin/zopectl.py 1.1 => 1.2 ===
--- /dev/null	Tue Mar 18 16:28:20 2003
+++ Zope/bin/zopectl.py	Tue Mar 18 16:27:49 2003
@@ -0,0 +1,141 @@
+#!python
+##############################################################################
+#
+# Copyright (c) 2001, 2002 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.
+#
+##############################################################################
+"""zopectl -- control Zope using zdaemon.
+
+Usage: zopectl [options] [action [arguments]]
+
+Options:
+-h/--help -- print usage message and exit
+-b/--backoff-limit SECONDS -- set backoff limit to SECONDS (default 10)
+-d/--daemon -- run as a proper daemon; fork a subprocess, close files etc.
+-f/--forever -- run forever (by default, exit when backoff limit is exceeded)
+-h/--help -- print this usage message and exit
+-i/--interactive -- start an interactive shell after executing commands
+-l/--logfile -- log file to be read by logtail command
+action [arguments] -- see below
+
+Actions are commands like "start", "stop" and "status".  If -i is
+specified or no action is specified on the command line, a "shell"
+interpreting actions typed interactively is started (unless the
+configuration option default_to_interactive is set to false).  Use the
+action "help" to find out about available actions.
+"""
+
+import os
+import sys
+
+import zdaemon
+import Zope.Startup
+
+from zdaemon.zdctl import ZDCmd
+from zdaemon.zdoptions import ZDOptions
+from zLOG.datatypes import FileHandlerFactory
+
+
+class ZopeCtlOptions(ZDOptions):
+    """Zope controller options.
+
+    After initialization, this should look very much like a
+    zdaemon.zdctl.ZDCtlOptions instance.  Many of the attributes are
+    initialized from different sources, however.
+    """
+
+    positional_args_allowed = 1
+    program = "zopectl"
+    schemadir = os.path.dirname(Zope.Startup.__file__)
+    schemafile = "zopeschema.xml"
+
+    # XXX Suppress using Zope's <eventlog> section to avoid using the
+    # same logging for zdctl as for the Zope appserver.  There still
+    # needs to be a way to set a logfile for zdctl.
+    logsectionname = None
+
+    def __init__(self):
+        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("forever", "runner.forever", "f", "forever",
+                 flag=1, default=0)
+        self.add("hang_around", "runner.hang_around", default=0)
+        self.add("interactive", None, "i", "interactive", flag=1)
+        self.add("default_to_interactive", "runner.default_to_interactive",
+                 default=1)
+        self.add("logfile", None, "l:", "logfile=")
+        self.add("prompt", "runner.prompt", default="zopectl>")
+
+    def realize(self, *args, **kw):
+        ZDOptions.realize(self, *args, **kw)
+        config = self.configroot
+        self.directory = config.instancehome
+        self.program = [os.path.join(self.directory, "bin", "runzope")]
+        self.sockname = os.path.join(config.clienthome, "zopectlsock")
+        self.user = None
+        self.python = sys.executable
+        self.zdrun = os.path.join(os.path.dirname(zdaemon.__file__),
+                                  "zdrun.py")
+        self.exitcodes = [0, 2]
+        if self.logfile is None and config.eventlog is not None:
+            for handler in config.eventlog.handler_factories:
+                if isinstance(handler, FileHandlerFactory):
+                    self.logfile = handler.section.path
+                    if self.logfile not in ("STDERR", "STDOUT"):
+                        break
+
+
+class ZopeCmd(ZDCmd):
+
+    def _get_override(self, opt, name, svalue=None, flag=0):
+        # Suppress the config file, and pass all configuration via the
+        # command line.  This avoids needing to specialize the zdrun
+        # script.
+        if name == "configfile":
+            return []
+        value = getattr(self.options, name)
+        if value is None:
+            return []
+        if flag:
+            if value:
+                args = [opt]
+            else:
+                args = []
+        else:
+            if svalue is None:
+                svalue = str(value)
+            args = [opt, svalue]
+        return args
+
+
+def main(args=None):
+    # This is exactly like zdctl.main(), but uses ZopeCtlOptions and
+    # ZopeCmd instead of ZDCtlOptions and ZDCmd, so the default values
+    # are handled properly for Zope.
+    options = ZopeCtlOptions()
+    options.realize(args)
+    c = ZopeCmd(options)
+    if options.args:
+        c.onecmd(" ".join(options.args))
+    if options.interactive:
+        try:
+            import readline
+        except ImportError:
+            pass
+        print "program:", " ".join(options.program)
+        c.do_status()
+        c.cmdloop()
+
+
+if __name__ == "__main__":
+    main()