[Checkins]
SVN: zc.recipe.deployment/trunk/src/zc/recipe/deployment/ Fixed bug:
Jim Fulton
jim at zope.com
Wed Feb 7 07:18:52 EST 2007
Log message for revision 72421:
Fixed bug:
Non-empty log and run directories were deleated in un- and
re-install.
Changed:
U zc.recipe.deployment/trunk/src/zc/recipe/deployment/README.txt
U zc.recipe.deployment/trunk/src/zc/recipe/deployment/__init__.py
A zc.recipe.deployment/trunk/src/zc/recipe/deployment/rtests.py
-=-
Modified: zc.recipe.deployment/trunk/src/zc/recipe/deployment/README.txt
===================================================================
--- zc.recipe.deployment/trunk/src/zc/recipe/deployment/README.txt 2007-02-07 12:10:39 UTC (rev 72420)
+++ zc.recipe.deployment/trunk/src/zc/recipe/deployment/README.txt 2007-02-07 12:18:51 UTC (rev 72421)
@@ -1,36 +1,142 @@
-Unix Deployment Support
-=======================
+Using the deplyment recipe is pretty simple. Simply specify a
+deployment name, specified via the part name, and a deployment user.
-The zc.recipe.deployment recipe provides support for deploying
-applications with multiple processes on Unix systems. It creates
-directories to hold application instance configuration, log and
-run-time files. It also sets or reads options that can be read by
-other programs to find out where to place files:
+Let's add a deployment to a sample buildout:
-cron-directory
- The name of the directory in which cron jobs should be placed.
- This is /etc/cron.d.
+ >>> write('buildout.cfg',
+ ... '''
+ ... [buildout]
+ ... parts = foo
+ ...
+ ... [foo]
+ ... recipe = zc.recipe.deployment
+ ... user = jim
+ ... ''')
-etc-directory
- The name of the directory where configuration files should be
- placed. This is /etc/NAME, where NAME is the deployment
- name.
+ >>> print system(join('bin', 'buildout')),
+ buildout: Installing foo
+ zc.recipe.deployment:
+ Creating '/etc/foo',
+ mode 755, user 'root', group 'root'
+ zc.recipe.deployment:
+ Creating '/var/log/foo',
+ mode 755, user 'jim', group 'jim'
+ zc.recipe.deployment:
+ Creating '/var/run/foo',
+ mode 750, user 'jim', group 'jim'
-log-directory
- The name of the directory where application instances should write
- their log files. This is /var/log/NAME, where NAME is
- the deployment name.
-run-directory
- The name of the directory where application instances should put
- their run-time files such as pid files and inter-process
- communication socket files. This is /var/run/NAME, where
- NAME is the deployment name.
+(Note that we have to be running as root and must have a user jim for
+this to work.)
-rc-directory
- The name of the directory where run-control scripts should be
- installed. This is /etc/init.d.
+Now we can see that directories named foo in /etc, /var/log and
+/var/run have been created:
-The etc, log, and run directories are created in such a way that the
-directories are owned by the user specified in the user option and are
-writable by the user and the user's group.
+ >>> print system('ls -ld /etc/foo'),
+ drwxr-xr-x 2 root root 4096 2007-02-06 09:50 /etc/foo
+
+ >>> print system('ls -ld /var/log/foo'),
+ drwxr-xr-x 2 jim jim 4096 2007-02-06 09:50 /var/log/foo
+
+ >>> print system('ls -ld /var/run/foo'),
+ drwxr-x--- 2 jim jim 40 2007-02-06 09:50 /var/run/foo
+
+By looking at .installed.cfg, we can see the options available for use
+by other recipes:
+
+ >>> cat('.installed.cfg')
+ ... # doctest: +ELLIPSIS
+ [buildout]
+ ...
+ [foo]
+ __buildout_installed__ =
+ ...
+ crontab-directory = /etc/cron.d
+ etc-directory = /etc/foo
+ log-directory = /var/log/foo
+ rc-directory = /etc/init.d
+ recipe = zc.recipe.deployment
+ run-directory = /var/run/foo
+ user = jim
+
+If we ininstall, then the directories are removed.
+
+ >>> print system(join('bin', 'buildout')+' buildout:parts='),
+ buildout: Uninstalling foo
+ buildout: Running uninstall recipe
+ zc.recipe.deployment: Removing '/etc/foo'
+ zc.recipe.deployment: Removing '/var/log/foo'.
+ zc.recipe.deployment: Removing '/var/run/foo'.
+
+ >>> import os
+ >>> os.path.exists('/etc/foo')
+ False
+ >>> os.path.exists('/var/log/foo')
+ False
+ >>> os.path.exists('/var/run/foo')
+ False
+
+The log and run directories are only removed if they are non-empty.
+To see that, we'll put a file in each of the directories created:
+
+ >>> print system(join('bin', 'buildout')), # doctest: +ELLIPSIS
+ buildout: Installing foo
+ ...
+
+ >>> write('/etc/foo/x', '')
+ >>> write('/var/log/foo/x', '')
+ >>> write('/var/run/foo/x', '')
+
+And then uninstall:
+
+ >>> print system(join('bin', 'buildout')+' buildout:parts='),
+ buildout: Uninstalling foo
+ buildout: Running uninstall recipe
+ zc.recipe.deployment: Removing '/etc/foo'
+ zc.recipe.deployment: Can't remove non-empty directory '/var/log/foo'.
+ zc.recipe.deployment: Can't remove non-empty directory '/var/run/foo'.
+
+ >>> os.path.exists('/etc/foo')
+ False
+
+ >>> print system('ls -ld /var/log/foo'),
+ drwxr-xr-x 2 jim jim 4096 2007-02-06 09:50 /var/log/foo
+
+ >>> print system('ls -ld /var/run/foo'),
+ drwxr-x--- 2 jim jim 40 2007-02-06 09:50 /var/run/foo
+
+Here we see that the var and run directories are kept. The etc
+directory is discarded because only buildout recipes should write to
+it and all of it's data are expendible.
+
+If we reinstall, remove the files, and uninstall, then the directories
+are removed:
+
+ >>> print system(join('bin', 'buildout')),
+ buildout: Installing foo
+ zc.recipe.deployment:
+ Creating '/etc/foo',
+ mode 755, user 'root', group 'root'
+ zc.recipe.deployment:
+ Updating '/var/log/foo',
+ mode 755, user 'jim', group 'jim'
+ zc.recipe.deployment:
+ Updating '/var/run/foo',
+ mode 750, user 'jim', group 'jim'
+
+ >>> os.remove('/var/log/foo/x')
+ >>> os.remove('/var/run/foo/x')
+
+ >>> print system(join('bin', 'buildout')+' buildout:parts='),
+ buildout: Uninstalling foo
+ buildout: Running uninstall recipe
+ zc.recipe.deployment: Removing '/etc/foo'
+ zc.recipe.deployment: Removing '/var/log/foo'.
+ zc.recipe.deployment: Removing '/var/run/foo'.
+
+ >>> os.path.exists('/etc/foo')
+ False
+ >>> os.path.exists('/var/log/foo')
+ False
+ >>> os.path.exists('/var/run/foo')
+ False
Modified: zc.recipe.deployment/trunk/src/zc/recipe/deployment/__init__.py
===================================================================
--- zc.recipe.deployment/trunk/src/zc/recipe/deployment/__init__.py 2007-02-07 12:10:39 UTC (rev 72420)
+++ zc.recipe.deployment/trunk/src/zc/recipe/deployment/__init__.py 2007-02-07 12:18:51 UTC (rev 72421)
@@ -16,10 +16,11 @@
$Id: deployment.py 14934 2006-11-10 23:57:33Z jim $
"""
-import os, pwd, shutil
+import grp, logging, os, pwd, shutil
+logger = logging.getLogger('zc.recipe.deployment')
-class Recipe:
+class Install:
def __init__(self, buildout, name, options):
self.name, self.options = name, options
@@ -31,7 +32,8 @@
name)
options['etc-directory'] = os.path.join(options.get('etc', '/etc'),
name)
- options['crontab-directory'] = options.get('crontab-directory', '/etc/cron.d')
+ options['crontab-directory'] = options.get('crontab-directory',
+ '/etc/cron.d')
options['rc-directory'] = options.get('rc-directory', '/etc/init.d')
def install(self):
@@ -43,7 +45,6 @@
make_dir(options['etc-directory'], 0, 0, 0755, created)
make_dir(options['log-directory'], uid, gid, 0755, created)
make_dir(options['run-directory'], uid, gid, 0750, created)
- return created
except Exception, e:
for d in created:
try:
@@ -53,11 +54,35 @@
pass
raise e
+ return ()
+
def update(self):
pass
+def uninstall(name, options):
+ path = options['etc-directory']
+ shutil.rmtree(path)
+ logger.info("Removing %r", path)
+ for d in 'log', 'run':
+ path = options[d+'-directory']
+ if os.listdir(path):
+ logger.warn("Can't remove non-empty directory %r.", path)
+ else:
+ os.rmdir(path)
+ logger.info("Removing %r.", path)
+
def make_dir(name, uid, gid, mode, created):
- os.mkdir(name, mode)
- created.append(name)
+ uname = pwd.getpwuid(uid)[0]
+ gname = grp.getgrgid(gid)[0]
+ if not os.path.isdir(name):
+ os.mkdir(name, mode)
+ created.append(name)
+ logger.info('\n Creating %r,\n mode %o, user %r, group %r',
+ name, mode, uname, gname)
+ else:
+ os.chmod(name, mode)
+ logger.info('\n Updating %r,\n mode %o, user %r, group %r',
+ name, mode, uname, gname)
+
os.chown(name, uid, gid)
Added: zc.recipe.deployment/trunk/src/zc/recipe/deployment/rtests.py
===================================================================
--- zc.recipe.deployment/trunk/src/zc/recipe/deployment/rtests.py 2007-02-07 12:10:39 UTC (rev 72420)
+++ zc.recipe.deployment/trunk/src/zc/recipe/deployment/rtests.py 2007-02-07 12:18:51 UTC (rev 72421)
@@ -0,0 +1,48 @@
+##############################################################################
+#
+# Copyright (c) 2006 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.
+#
+##############################################################################
+
+import re
+import zc.buildout.testing
+
+import unittest
+import zope.testing
+from zope.testing import doctest, renormalizing
+
+def setUp(test):
+ zc.buildout.testing.buildoutSetUp(test)
+ zc.buildout.testing.install_develop('zc.recipe.deployment', test)
+
+def test_suite():
+ return unittest.TestSuite((
+ #doctest.DocTestSuite(),
+ doctest.DocFileSuite(
+ 'README.txt',
+ setUp=setUp, tearDown=zc.buildout.testing.buildoutTearDown,
+ checker=renormalizing.RENormalizing([
+ (re.compile('\d+ \d\d\d\d-\d\d-\d\d \d\d:\d\d'), ''),
+## zc.buildout.testing.normalize_path,
+
+## zc.buildout.testing.normalize_script,
+## zc.buildout.testing.normalize_egg_py,
+## (re.compile('#!\S+python\S*'), '#!python'),
+## (re.compile('\d[.]\d+ seconds'), '0.001 seconds'),
+## (re.compile('zope.testing-[^-]+-'), 'zope.testing-X-'),
+## (re.compile('setuptools-[^-]+-'), 'setuptools-X-'),
+ ])
+ ),
+
+ ))
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Property changes on: zc.recipe.deployment/trunk/src/zc/recipe/deployment/rtests.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
More information about the Checkins
mailing list