Commit 2987b932 authored by Chris Withers's avatar Chris Withers

Merge of my recent changes from the 2.12 branch:

- Ignore pyd's when they're built in place.
- add sphinx section to buildout and make.bat for Windows user
- de-cruft of tree
- revamp of docs
- rework of Windows service stuff to make zopeservice.py in instances unnecessary
- make zopectl work properly on Windows
parents 1b53d8d0 ea03022f
Place files containing code for External Method objects in this
directory.
......@@ -7,6 +7,7 @@ parts =
alltests
allpy
dependencies
docs
extends = versions.cfg
unzip = true
......@@ -28,7 +29,6 @@ eggs = Zope2
interpreter = zopepy
scripts = zopepy
[alltests]
recipe = zc.recipe.testrunner
eggs =
......@@ -122,3 +122,7 @@ exclude =
ClientForm
docutils
mechanize
[docs]
recipe = zc.recipe.egg
eggs = sphinx
Credits
=======
The Zope software receives contributions from far and wide. Here's
the Zope Hall of Fame:
- Stephen Purcell allows us to distribute his PyUnit unit testing
framework with Zope.
- Jeff Bauer is Zope Dude Number One. Jeff took over PCGI and
kept pushing it forward through the years.
- Sam Rushing worked with us at Digital Creations to make Medusa
the publishing platform for ZServer and the concurrency of Zope2.
- A subset of windows guru Mark Hammond's win32 extensions are
bundled with win32 binary distributions of Zope.
- Martijn Pieters and Brian Hooper contributed the #in reverse
attribute.
- Phillip Eby contributed the DTML 'let' tag and many
other useful ideas, including the inspiration for the DTML
'call', 'with' and 'return'
tags.
- The DateTime module was based on work from Ted Horst.
- Jordan Baker contributed the 'try' tag, something we've wanted
for a long, long time.
- Martijn Pieters chipped in with a safe range function.
- Michael Hauser came up with the name "Zope".
- Eric Kidd from Userland contributed to ZPublisher's support for
XML-RPC.
- Andrew M. Kuchling wrote the initial version of mod_pcgi, making
him extremely cool in our book.
- Oleg Broytmann has taken up the standard of mod_pcgi and moving
it to be a really amazing thing, and ready for prime time.
- Jephte CLAIN made some patches to European ZopeTime.
- Thanks to Gregor Hoffleit for his work in getting Zope into the
Debian distribution.
- All the other Zopistas far and wide that stuck with us during
the Bobo/Principia days and politely push us to make the best damn
app server on this or any other planet.
- Of course the list of credits would be quite incomplete without
mentioning Guido van Rossum, benevolent dictator of Python and
long-time friend of Digital Creations. Zope Power is Python
Power.
- Special thanks to Richard Stallman and the Free Software
Foundation for their assistance and feedback on the
GPL-compatible 2.0 version of the Zope Public License.
This diff is collapsed.
Setting the initial user name and password
==========================================
Filesytem Permissions
=====================
Because Zope is managed through the web, user names and passwords must be
used to assure that only authorized people can make changes to a Zope
installation.
Some user name and password is needed to "bootstrap" the creation of
normal managers of your Zope site. This is accomplished through the
use of the file 'inituser'. The first time Zope starts, it will detect
that no users have been defined in the root user folder. It will search
for the 'inituser' file and, if it exists, will add the user defined
in the file to the root user folder.
Normally, 'inituser' is created by the Zope install scripts. Either
the installer prompts for the password or a randomly generated
password is created and displayed at the end of the build script.
You can use the 'zpasswd.py' script to create 'inituser' yourself.
Execute 'zpasswd.py' like this::
python zpasswd.py inituser
The script will prompt you for the name, password, and allowed
domains. The default is to encode the password with SHA, so please
remember this password as there is no way to recover it (although
'zpasswd.py' lets you reset it.)
In some situations you may need to bypass normal security controls
because you have lost your password or because the security settings
have been mixed up. Zope provides a facility called an "emergency
user" so that you can reset passwords and correct security
settings.
The emergency user password must be defined outside the application
user interface. It is defined in the 'access' file located
in the Zope directory. It should be readable only by the user
as which your web server runs.
To create the emergency user, use 'zpasswd.py' to create the
'access' file like this::
python zpasswd.py access
In order to provide a somewhat higher level of security, various
encoding schemes are supported which provide access to either SHA-1
encryption or the standard UNIX crypt facility if it has been compiled
into Python. Unless you have some special requirements (see below),
you should use the SHA-1 facility, which is the default.
Format of 'inituser' and 'access'
---------------------------------
A password file should consist of a single line of the form::
name:password
Note that you may also add an optional third component to the line in the
access file to restrict access by domain. For example, the line::
mario:nintendoRules:*.mydomain.com
in your 'access' file will only allow permit emergency user access
from `*.mydomain.com` machines. Attempts to access the system from
other domains will fail, even if the correct emergency user name
and password are used.
Please note that if you use the ZServer monitor capability, you will
need to run with a clear text password.
Setting permissions on the var directory
----------------------------------------
You need to set permissions on the Zope var directory.
Zope needs to read and write data from its var directory. Before
You need to set permissions on the directory Zope uses to store its
data. This will normally be the `var` directory in the instance home.
Zope needs to read and write data to this directory. Before
running Zope you should ensure that you give adequate permissions
to the Zope var directory for the userid Zope will run under.
to this directory for the userid Zope will run under.
Depending on how you choose to run Zope you will need to give
different permissions to the var directory. If you use Zope with an
different permissions to the directory. If you use Zope with an
existing web server, it will probably run Zope as 'nobody'. In this
case 'nobody' needs read and write permissions to the var directory.
If you change the way you run Zope you may need to modify the permissions
of the var directory and the files in it to allow Zope to read and write
If you change the way you run Zope, you may need to modify the permissions
of the directory and the files in it to allow Zope to read and write
under its changed userid.
......@@ -2,9 +2,9 @@ Zope effective user support
===========================
.. note::
It is best practice running Zope behind a reverse proxy like
Apache, Squid or Varnish. In this case you do not need to run
or install Zope with root privileges since the reverse proxy
It is best practice to run Zope behind a reverse proxy like
Apache, Squid or Varnish. In this case, you do not need to run
or install Zope with root privileges, since the reverse proxy
will bind to port 80 and proxy back all request to Zope running
on an unpriviledged port.
......
Special Users
=============
Because Zope is managed through the web, user names and passwords must be
used to assure that only authorized people can make changes to a Zope
installation.
Adding Managers
---------------
If you need to add a Manager to an existing Zope instance, you can do
this using `zopectl` as follows::
zopectl adduser `name` `password`
The Initial User
----------------
An initial username and password is needed to "bootstrap" the creation of
normal managers of your Zope site. This is accomplished through the
use of the 'inituser' file in the directory specified as the instance
home.
The first time Zope starts, it will detect
that no users have been defined in the root user folder. It will search
for the 'inituser' file and, if it exists, will add the user defined
in the file to the root user folder.
Normally, 'inituser' is created by the Zope install scripts. Either
the installer prompts for the password or a randomly generated
password is created and displayed at the end of the build script.
You can use the 'zpasswd.py' script to create 'inituser' yourself.
Execute 'zpasswd.py' like this::
python zpasswd.py inituser
The script will prompt you for the name, password, and allowed
domains. The default is to encode the password with SHA, so please
remember this password as there is no way to recover it (although
'zpasswd.py' lets you reset it.)
The Emergency User
------------------
In some situations you may need to bypass normal security controls
because you have lost your password or because the security settings
have been mixed up. Zope provides a facility called an "emergency
user" so that you can reset passwords and correct security
settings.
The emergency user password must be defined outside the application
user interface. It is defined in the 'access' file located
in the Zope directory. It should be readable only by the user
as which your web server runs.
To create the emergency user, use 'zpasswd.py' to create the
'access' file like this::
python zpasswd.py access
In order to provide a somewhat higher level of security, various
encoding schemes are supported which provide access to either SHA-1
encryption or the standard UNIX crypt facility if it has been compiled
into Python. Unless you have some special requirements (see below),
you should use the SHA-1 facility, which is the default.
Format of 'inituser' and 'access'
---------------------------------
A password file should consist of a single line of the form::
name:password
Note that you may also add an optional third component to the line in the
access file to restrict access by domain. For example, the line::
mario:nintendoRules:*.mydomain.com
in your 'access' file will only allow permit emergency user access
from `*.mydomain.com` machines. Attempts to access the system from
other domains will fail, even if the correct emergency user name
and password are used.
Please note that if you use the ZServer monitor capability, you will
need to run with a clear text password.
How to build and install Zope from source code on Windows.
----------------------------------------------------------
* Ensure you have the correct MSVC version installed for the
version of Python you will be using.
* Install (or build from sources) Python
http://www.python.org
* Install (or build from sources) the Python for Windows extensions
http://sourceforge.net/projects/pywin32/
* Unpack the Zope source distribution. Change to that directory.
* Execute:
% python.exe inst\configure.py
It should say something like:
>
> - Zope top-level binary directory will be c:\Zope-2.13.
> - Makefile written.
>
> Next, run the Visual C++ batch file "VCVARS32.bat" and then "nmake".
(run 'configure.py --help' to see how to change things)
* 'makefile' will have ben created. As instructed, execute 'nmake'.
If the build succeeds, the last message printed should be:
> Zope built. Next, do 'nmake install'.
* As instructed, execute 'nmake install'. A few warnings will be generated,
but they can be ignored. The last message in the build process should be:
> Zope binaries installed successfully.
* Zope itself has now been installed. We need to create an instance. Run:
% python.exe {install_path}\bin\mkzopeinstance.py
We will be prompted, via the console, for the instance directory and
username/password for the admin user.
* We are now ready to start zope. Run:
% {zope_instance}\bin\runzope.bat
Zope should start with nice log messages being printed to
stdout. When Zope is ready, you should see:
> ------
> 2004-10-13T12:27:58 INFO(0) Zope Ready to handle requests
Press Ctrl+C to stop this instance of the server.
* Optionally, install as a Windows service. Execute:
% python {zope_instance}\bin\zopeservice.py
to see the valid options. You may want something like:
% python {zope_instance}\bin\zopeservice.py --startup=auto install
Once installed, it can be started any number of ways:
- % {zope_instance}\bin\zopectl.bat start
- % python {zope_instance}\bin\zopeservice.py start
- Control Panel
- % net start service_short_name (eg, `net start Zope_-1227678699`)
......@@ -8,12 +8,11 @@ Contents:
:maxdepth: 2
WHATSNEW.rst
CHANGES.rst
INSTALL.rst
USERS.rst
SECURITY.rst
ZOPE3.rst
SETUID.rst
SIGNALS.rst
DEBUGGING.rst
CREDITS.rst
CHANGES.rst
@ECHO OFF
REM Command file for Sphinx documentation
set SPHINXBUILD=..\bin\sphinx-build
set ALLSPHINXOPTS=-d .build/doctrees %SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. changes to make an overview over all changed/added/deprecated items
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (.build\*) do rmdir /q /s %%i
del /q /s .build\*
goto end
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% .build/html
echo.
echo.Build finished. The HTML pages are in .build/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% .build/dirhtml
echo.
echo.Build finished. The HTML pages are in .build/dirhtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% .build/pickle
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% .build/json
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% .build/htmlhelp
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in .build/htmlhelp.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% .build/latex
echo.
echo.Build finished; the LaTeX files are in .build/latex.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% .build/changes
echo.
echo.The overview file is in .build/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% .build/linkcheck
echo.
echo.Link check complete; look for any errors in the above output ^
or in .build/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% .build/doctest
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in .build/doctest/output.txt.
goto end
)
:end
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
"""
Compatibility stub (Zope 2.7's up to b1 used to keep all nt service-related
files here; they've since moved to ntservice_utils)
"""
from nt_svcutils import service
import win32serviceutil
# this is a class which instance services subclass
ZopeService = service.Service
if __name__=='__main__':
win32serviceutil.HandleCommandLine(ZopeService)
""" Placeholder module file """
......@@ -51,10 +51,56 @@ from ZConfig.datatypes import existing_dirpath
WIN = False
if sys.platform[:3].lower() == "win":
WIN = True
import win32serviceutil
from nt_svcutils import service
def do_windows(command):
def inner(self,arg):
INSTANCE_HOME = self.options.directory
name = 'Zope'+str(hash(INSTANCE_HOME.lower()))
display_name = 'Zope instance at '+INSTANCE_HOME
# This class exists only so we can take advantage of
# win32serviceutil.HandleCommandLine, it is never
# instantiated.
class InstanceService(service.Service):
_svc_name_ = name
_svc_display_name_ = display_name
_svc_description_ = "A Zope application instance running as a service"
# getopt sucks :-(
argv = [sys.argv[0]]
argv.extend(arg.split())
argv.append(command)
# we need to supply this manually as HandleCommandLine guesses wrong
serviceClassName = os.path.splitext(service.__file__)[0]+'.Service'
err = win32serviceutil.HandleCommandLine(
InstanceService,
serviceClassName,
argv=argv,
)
return err,InstanceService
return inner
def string_list(arg):
return arg.split()
def quote_command(command):
print " ".join(command)
# Quote the program name, so it works even if it contains spaces
command = " ".join(['"%s"' % x for x in command])
if WIN:
# odd, but true: the windows cmd processor can't handle more than
# one quoted item per string unless you add quotes around the
# whole line.
command = '"%s"' % command
return command
class ZopeCtlOptions(ZDOptions):
# Zope controller options.
#
......@@ -132,11 +178,6 @@ class ZopeCtlOptions(ZDOptions):
self.python = os.environ.get('PYTHON', config.python) or sys.executable
self.zdrun = os.path.join(os.path.dirname(zdaemon.__file__),
"zdrun.py")
if WIN:
# Add the path to the zopeservice.py script, which is needed for
# some of the Windows specific commands
servicescript = os.path.join(self.directory, 'bin', 'zopeservice.py')
self.servicescript = '"%s" %s' % (self.python, servicescript)
self.exitcodes = [0, 2]
if self.logfile is None and config.eventlog is not None:
......@@ -171,6 +212,13 @@ class ZopeCmd(ZDCmd):
args = [opt, svalue]
return args
def do_start(self, arg):
# signal to Zope that it is being managed
# (to indicate it's web-restartable)
os.putenv('ZMANAGED', '1')
## START OF WINDOWS ONLY STUFF
if WIN:
def get_status(self):
# get_status from zdaemon relies on *nix specific socket handling.
......@@ -182,52 +230,48 @@ class ZopeCmd(ZDCmd):
self.zd_status = None
return
def do_stop(self, arg):
# Stop the Windows service
program = "%s stop" % self.options.servicescript
print program
os.system(program)
def do_restart(self, arg):
# Restart the Windows service
program = "%s restart" % self.options.servicescript
print program
os.system(program)
do_start = do_windows('start')
do_stop = do_windows('stop')
do_restart = do_windows('restart')
# Add extra commands to install and remove the Windows service
def do_install(self, arg):
program = "%s install" % self.options.servicescript
print program
os.system(program)
def do_install(self,arg):
err,InstanceClass = do_windows('install')(self,arg)
if not err:
# If we installed successfully, put info in registry for the
# real Service class to use:
command = '"%s" -C "%s"' % (
# This gives us the instance script for buildout instances
# and the install script for classic instances.
os.path.join(os.path.split(sys.argv[0])[0],'runzope'),
self.options.configfile
)
InstanceClass.setReg('command',command)
# This is unfortunately needed because runzope.exe is a setuptools
# generated .exe that spawns off a sub process, so pid would give us
# the wrong event name.
InstanceClass.setReg('pid_filename',self.options.configroot.pid_filename)
def help_install(self):
print "install -- Installs Zope as a Windows service."
def do_remove(self, arg):
program = "%s remove" % self.options.servicescript
print program
os.system(program)
do_remove = do_windows('remove')
def help_remove(self):
print "remove -- Removes the Zope Windows service."
def do_start(self, arg):
# signal to Zope that it is being managed
# (to indicate it's web-restartable)
os.putenv('ZMANAGED', '1')
if WIN:
# On Windows start the service, this fails with a reasonable
# error message as long as the service is not installed
program = "%s start" % self.options.servicescript
print program
os.system(program)
else:
ZDCmd.do_start(self, arg)
do_windebug = do_windows('debug')
def help_windebug(self):
print "windebug -- Runs the Zope Windows service in the foreground, in debug mode."
## END OF WINDOWS ONLY STUFF
def get_startup_cmd(self, python, more):
cmdline = ( '%s -c "from Zope2 import configure;'
'configure(\'%s\');' %
'configure(%r);' %
(python, self.options.configfile)
)
return cmdline + more + '\"'
......@@ -240,18 +284,19 @@ class ZopeCmd(ZDCmd):
os.system(cmdline)
def do_foreground(self, arg):
if WIN:
# Adding arguments to the program is not supported on Windows
# and the runzope script doesn't put you in debug-mode either
ZDCmd.do_foreground(self, arg)
else:
self.options.program[1:1] = ["-X", "debug-mode=on"]
try:
ZDCmd.do_foreground(self, arg)
finally:
self.options.program.remove("-X")
self.options.program.remove("debug-mode=on")
program = self.options.program
local_additions = []
if not program.count('-X'):
local_additions += ['-X']
if not program.count('debug-mode=on'):
local_additions += ['debug-mode=on']
program[1:1] = local_additions
command = quote_command(program)
try:
return os.system(command)
finally:
for addition in local_additions: program.remove(addition)
def help_debug(self):
print "debug -- run the Zope debugger to inspect your database"
print " manually using a Python interactive shell"
......
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
"""
A Zope Windows NT service frontend.
Usage:
Installation
The Zope service should be installed by the Zope Windows
installer. You can manually install, uninstall the service from
the commandline.
ntservice.py [options] install|update|remove|start [...]
|stop|restart [...]|debug [...]
Options for 'install' and 'update' commands only:
--username domain\username : The Username the service is to run
under
--password password : The password for the username
--startup [manual|auto|disabled] : How the service starts,
default = manual
Commands
install : Installs the service
update : Updates the service. Use this if you change any
configuration settings and need the service to be
re-registered.
remove : Removes the service
start : Starts the service, this can also be done from the
services control panel
stop : Stops the service, this can also be done from the
services control panel
restart : Restarts the service
debug : Runs the service in debug mode
You can view the usage options by running this module without any
arguments.
Starting Zope
Start Zope by clicking the 'start' button in the services control
panel. You can set Zope to automatically start at boot time by
choosing 'Auto' startup by clicking the 'statup' button.
Stopping Zope
Stop Zope by clicking the 'stop' button in the services control
panel. You can also stop Zope through the web by going to the
Zope control panel and by clicking 'Shutdown'.
Event logging
Service related events (such as startup, shutdown, or errors executing
the Zope process) are logged to the NT application event log. Use the
event viewer to see these events.
Zope Events are still written to the Zope event logs.
"""
import sys, os
# these are replacements from mkzopeinstance
INSTANCE_HOME = r'<<INSTANCE_HOME>>'
ZOPE_SCRIPTS = r'<<ZOPE_SCRIPTS>>'
ZOPE2PATH = r'<<ZOPE2PATH>>'
ZOPE_RUN = os.path.join(ZOPE_SCRIPTS, 'runzope')
CONFIG_FILE = os.path.join(INSTANCE_HOME, 'etc', 'zope.conf')
PYTHONSERVICE_EXE = os.path.join(ZOPE_SCRIPTS, 'PythonService.exe')
os.environ["INSTANCE_HOME"] = INSTANCE_HOME
# XXX: we need to find nt_svcutils.service
sys.path[0:0] = [ZOPE2PATH]
from nt_svcutils.service import Service
servicename = 'Zope_%s' % str(hash(INSTANCE_HOME.lower()))
class InstanceService(Service):
_svc_name_ = servicename
_svc_display_name_ = 'Zope instance at %s' % INSTANCE_HOME
# _svc_description_ can also be set (but what to say isn't clear!)
# If the exe we expect is not there, let the service framework search
# for it. This will be true for people running from source builds and
# relying on pre-installed pythonservice.exe.
# Note this is only used at install time, not runtime.
if os.path.isfile(PYTHONSERVICE_EXE):
_exe_name_ = PYTHONSERVICE_EXE
process_runner = ZOPE_RUN
process_args = '-C "%s"' % CONFIG_FILE
if __name__ == '__main__':
import win32serviceutil
win32serviceutil.HandleCommandLine(InstanceService)
This diff is collapsed.
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