r447 - in zope-common/trunk: . debian
Fabio Tranchitella
kobold at alioth.debian.org
Sun Nov 5 08:46:03 CET 2006
Author: kobold
Date: 2006-11-05 08:46:03 +0100 (Sun, 05 Nov 2006)
New Revision: 447
Modified:
zope-common/trunk/debian/README.Debian
zope-common/trunk/debian/changelog
zope-common/trunk/debian/postinst
zope-common/trunk/debian/postrm
zope-common/trunk/dzhandle
Log:
Changes for dzhandle: allow user and system local products.
Modified: zope-common/trunk/debian/README.Debian
===================================================================
--- zope-common/trunk/debian/README.Debian 2006-11-02 22:43:46 UTC (rev 446)
+++ zope-common/trunk/debian/README.Debian 2006-11-05 07:46:03 UTC (rev 447)
@@ -64,7 +64,7 @@
You (or a package) can create a zope instance using:
- dzhandle -z 2.9 make-instance <instance> --addon-mode [all|manual]
+ dzhandle -z 2.9 make-instance <instance> --addon-mode [manual|all]
The script uses the `mkzopeinstance.py' script to create the instance
and creates a file /etc/zope2.9/<instance>/debian_policy, which has
@@ -125,6 +125,24 @@
the instances.
+Local third-party zope products
+-------------------------------
+
+The system administrator can install third-party custom products in
+/usr/local/share/zope/Products, and they will be read before the
+system-installed ones.
+
+To enable dzhandle usage for a manually installed product, the system
+administrator has to create a .dzproduct file inside the product with
+a content like:
+
+ Name: ProductName
+ Package: local
+ Version: 0.1
+
+At this point, dzhandle list-products will include the custom product.
+
+
Using dzhandle with non-root users
----------------------------------
@@ -134,8 +152,8 @@
The default paths for personal zope and zeo instances are:
- $HOME/zope-instances
- $HOME/zeo-instances
+ $HOME/zope/instance
+ $HOME/zope/zeo
These paths can be overridden creating a file ~/.dzhandle.conf within the
home directory of the user with the following syntax:
@@ -143,9 +161,10 @@
# this is a comment
instances: /home/user1/zope/instances
zeoinstances: /home/user1/zope/zeo
+ products: /home/user1/zope/products
dzhandle detects when it is used with a non-root user and reads the
-configuration file in the home directory (or use the defaults). This
+configuration file in the home directory (or uses the default). This
is an example usage of this feature:
$ whoami
@@ -158,3 +177,7 @@
this instance will be created in:
/home/user1/zope-instances/zope2.9/testing
+
+Users can enable dzhandle usage for custom products putting them under
+~/zope/products (or where specified by the configuration file) and following
+the instructions from the "Local third-party zope products" paragraph.
Modified: zope-common/trunk/debian/changelog
===================================================================
--- zope-common/trunk/debian/changelog 2006-11-02 22:43:46 UTC (rev 446)
+++ zope-common/trunk/debian/changelog 2006-11-05 07:46:03 UTC (rev 447)
@@ -1,20 +1,20 @@
-zope-common (0.5.26) unstable; urgency=low
+zope-common (0.5.26) unstable; urgency=medium
* debian/README.Debian: updated to use zope2.9 instead of zope2.10
in the examples, because that's the version we'll ship in etch.
* debian/templates: fixed two typos. (Closes: #385882)
- * debian/control: sb-release and po-debconf should be in Build-Depends.
+ * debian/control: lsb-release and po-debconf should be in Build-Depends.
(Closes: #392653)
* debian/po/cs.po: updated. (Closes: #396759)
* dzhandle: restart only running instances on upgrades.
(Closes: #388253, #378364)
- * dzhandle: use the atechnique from instance if not specified on the
+ * dzhandle: use atechnique from the instance if not specified on the
command-line. (Closes: #382773)
- * dzhandle: implemented basic normal-user personal instances handling.
+ * dzhandle: implemented basic non-root usage for personal instances.
(Closes: #359256)
* debian/rules: mv dzhandle from /usr/sbin to /usr/bin. (Closes: #379169)
- -- Fabio Tranchitella <kobold at debian.org> Thu, 2 Nov 2006 23:10:54 +0100
+ -- Fabio Tranchitella <kobold at debian.org> Fri, 3 Nov 2006 20:35:19 +0100
zope-common (0.5.25) unstable; urgency=low
Modified: zope-common/trunk/debian/postinst
===================================================================
--- zope-common/trunk/debian/postinst 2006-11-02 22:43:46 UTC (rev 446)
+++ zope-common/trunk/debian/postinst 2006-11-05 07:46:03 UTC (rev 447)
@@ -21,6 +21,16 @@
mkdir -p /var/lib/zope/dzhandle
chown $zopeuse:$zopegroup /var/lib/zope/dzhandle
fi
+
+ LOCALDIR=/usr/local/share/zope
+ if [ ! -d $LOCALDIR ]; then
+ if mkdir $LOCALDIR 2>/dev/null ; then
+ mkdir $LOCALDIR/Products
+ chmod 2775 $LOCALDIR -R
+ chown root:$zopegroup $LOCALDIR -R
+ fi
+ fi
+
;;
abort-upgrade|abort-remove|abort-deconfigure)
Modified: zope-common/trunk/debian/postrm
===================================================================
--- zope-common/trunk/debian/postrm 2006-11-02 22:43:46 UTC (rev 446)
+++ zope-common/trunk/debian/postrm 2006-11-05 07:46:03 UTC (rev 447)
@@ -35,7 +35,11 @@
# # PCGI resuource file should have already been removed.
#fi
- rm -rf /var/lib/zope/dzhandle
+ rm -rf /var/lib/zope/dzhandle
+
+ LOCALDIR=/usr/local/share/zope
+ rmdir --ignore-fail-on-non-empty $LOCALDIR/Products || true
+ rmdir --ignore-fail-on-non-empty $LOCALDIR || true
;;
remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
Modified: zope-common/trunk/dzhandle
===================================================================
--- zope-common/trunk/dzhandle 2006-11-02 22:43:46 UTC (rev 446)
+++ zope-common/trunk/dzhandle 2006-11-05 07:46:03 UTC (rev 447)
@@ -1,6 +1,29 @@
#! /usr/bin/python2.4
-import fnmatch, glob, os, re, sys, shutil
+# Copyright (C) 2005-2006 Matthias Klose <doko at ubuntu.com>
+# Fabio Tranchitella <kobold at debian.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+import os
+import sys
+import re
+import glob
+import fnmatch
+import shutil
import pwd, grp
import logging
import subprocess
@@ -76,18 +99,16 @@
def addon_technique_code(name):
return addon_options.index(name)
-personal_conf = {}
-def is_root():
- return os.getuid() == 0
-
known_actions = {}
def register_action(action_class):
known_actions[action_class.name] = action_class
+personal_conf = {}
+
# --------------------------------------------------------------------------- #
-class DZError(Exception):
- pass
+def is_root():
+ return os.getuid() == 0
def strlist(sequence):
return ', '.join(["`%s'" % s for s in sequence])
@@ -95,10 +116,8 @@
def available_zope_versions():
return [z['version'] for z in zope_packages if os.path.isdir(z['prefix'])]
-def filter_zope_version(**kw):
- key = kw.keys()[0]
- value = kw[key]
- return [z for z in zope_packages if z[key] == value][0]
+def filter_zope_version(version):
+ return [z for z in zope_packages if z['version'] == version][0]
def read_config_file(fn, required=None):
attrs = {}
@@ -201,6 +220,7 @@
self.depends = None
self.recommends = None
self.suggests = None
+ self.is_global = False
self.zopeversions = " ".join([z['version'] for z in zope_packages])
else:
self.read_dzfile()
@@ -229,6 +249,7 @@
self.suggests = attrs.get('Suggests', None)
self.zopeversions = attrs.get('ZopeVersions', \
" ".join([z['version'] for z in zope_packages]))
+ self.is_global = (attrs.get('Global', None) == 'yes')
def write_dzfile(self, fn=None):
fn = fn or os.path.join(self.path, self.dzname)
@@ -252,6 +273,10 @@
"""checks if the addon is available in the instance
"""
+ if self.is_global:
+ ipath = os.path.join(instance.home, self.subdir, self.name + '.installed')
+ return os.path.exists(ipath)
+
ipath = os.path.join(instance.home, self.subdir, self.name)
return os.path.isdir(ipath)
@@ -259,6 +284,10 @@
"""If the addon is available in the instance, return it, else return None.
"""
+ if self.is_global:
+ ipath = os.path.join(instance.home, self.subdir, self.name + '.installed')
+ return os.path.exists(ipath) and self or None
+
ipath = os.path.join(instance.home, self.subdir, self.name)
if not os.path.isdir(ipath):
return None
@@ -276,9 +305,7 @@
iaddons = []
for instance in instances:
iaddon = self.installed_in_instance(instance)
- if iaddon \
- and not iaddon.type in exclude \
- and iaddon.installed_by(self):
+ if iaddon and not iaddon.type in exclude and iaddon.installed_by(self):
iaddons.append(iaddon)
return iaddons
@@ -303,12 +330,14 @@
def installed_by(self, master):
"""checks if the installed addon was installed by the `master' addon
"""
- assert self.type != ADDON_MASTER and master.type == ADDON_MASTER
+ assert self.type != ADDON_MASTER and master.type == ADDON_MASTER or self.is_global
- if self.name != master.name or self.package != master.package:
+ if self.is_global:
+ return True
+ elif self.name != master.name or self.package != master.package:
# other addon, or same addon installed by other package
return False
- if self.type == ADDON_COPIED:
+ elif self.type == ADDON_COPIED:
# copied from master to instance, version may mismatch
return True
@@ -327,7 +356,8 @@
return True
def printit(self, stream=sys.stdout):
- print >>stream, self.kind, self.name, self.directory, self.package, self.version, self.path, self.depends
+ print >>stream, self.kind, self.name, self.directory, \
+ self.package, self.version, self.path, self.depends
class ProductAttributes:
kind = 'product'
@@ -348,6 +378,8 @@
ProductAttributes.addonClass = Product
ExtensionAttributes.addonClass = Extension
+# --------------------------------------------------------------------------- #
+
class DZAction:
_option_parser = None
name = None
@@ -706,7 +738,7 @@
class DZPrermProduct(ProductAttributes, DZPrerm):
name = 'prerm-%s' % ProductAttributes.kind
- help = 'handle prerm of a packaged %s' % ExtensionAttributes.kind
+ help = 'handle prerm of a packaged %s' % ProductAttributes.kind
class DZPrermExtension(ExtensionAttributes, DZPrerm):
name = 'prerm-%s' % ExtensionAttributes.kind
@@ -744,7 +776,7 @@
class DZPostrmProduct(ProductAttributes, DZPostrm):
name = 'postrm-%s' % ProductAttributes.kind
- help = 'handle postrm of a packaged %s' % ExtensionAttributes.kind
+ help = 'handle postrm of a packaged %s' % ProductAttributes.kind
class DZPostrmExtension(ExtensionAttributes, DZPostrm):
name = 'postrm-%s' % ExtensionAttributes.kind
@@ -1054,7 +1086,12 @@
else:
addon_base, addon_suffix = arg, ''
ipath = os.path.join(self.instance.home, self.subdir, addon_base)
- if not os.path.isdir(ipath):
+ if os.path.exists(ipath + '.installed'):
+ path = open(ipath + '.installed', 'r').read()
+ addon = self.addonClass(path, dzfile_required=False)
+ addons.append((addon, addon))
+ continue
+ elif not os.path.isdir(ipath):
if not self.options.lazy:
self.error("%s `%s' not found in instance `%s' (%s)"
% (self.kind, addon_base, self.instance.name, self.instance.version),
@@ -1819,12 +1856,24 @@
return
addon_technique = addon_technique or self.addon_technique
+ if addon_technique == ADDON_MANUAL:
+ return
+ assert addon_technique in (ADDON_LINKED, ADDON_TREELINKED, ADDON_COPIED)
- if addon_technique == ADDON_MANUAL: return
- assert addon_technique in (ADDON_LINKED, ADDON_TREELINKED, ADDON_COPIED)
-
+ if self.version.startswith("3"):
+ files = []
+ files.extend(glob.glob(os.path.join(addon.path, '*-configure.zcml')))
+ files.extend(glob.glob(os.path.join(addon.path, '*-meta.zcml')))
+ files.extend(glob.glob(os.path.join(addon.path, '*-ftesting.zcml')))
+ for f in files:
+ filename = os.path.split(f)[1]
+ os.symlink(f, os.path.join(self.home, "etc/package-includes/", filename))
+
target_path = os.path.join(self.home, addon.subdir, addon.name)
- if addon_technique == ADDON_LINKED:
+ if addon.is_global:
+ open(target_path + '.installed', 'w').write(addon.path)
+ target_path = addon.path
+ elif addon_technique == ADDON_LINKED:
os.symlink(addon.path, target_path)
if global_options.verbose:
print "linked: %s -> %s" % (target_path, addon.path)
@@ -1839,10 +1888,6 @@
if global_options.verbose:
print "copied: %s -> %s" % (addon.path, target_path)
- if self.version.startswith("3") and os.path.isfile(os.path.join(addon.path, ".dzconfigure")):
- os.symlink(os.path.join(addon.path, ".dzconfigure"), \
- os.path.join(self.home, "etc/package-includes/", addon.name + "-configure.zcml"))
-
added_addon = addon.addonClass(target_path, False)
self._installed_addons.append(added_addon)
logging.info("added %s `%s'", added_addon.kind, added_addon.path)
@@ -1851,11 +1896,24 @@
installed = [a for a in self.installed_addons() if getattr(addon, 'name', None) == a.name]
if len(installed) != 1:
raise DZError, "%s `%s' not installed in instance `%s'" \
- % (a.kind, a.name, self.name)
+ % (addon.kind, addon.name, self.name)
installed = installed[0]
assert addon.name == installed.name
- if installed.type == ADDON_LINKED:
+ if self.version.startswith("3"):
+ files = []
+ files.extend(glob.glob(os.path.join(addon.path, '*-configure.zcml')))
+ files.extend(glob.glob(os.path.join(addon.path, '*-meta.zcml')))
+ files.extend(glob.glob(os.path.join(addon.path, '*-ftesting.zcml')))
+ for f in files:
+ filename = os.path.split(f)[1]
+ target = os.path.join(self.home, "etc/package-includes/", filename)
+ if os.path.exists(target):
+ os.unlink(target)
+
+ if addon.is_global:
+ os.unlink(os.path.join(self.home, addon.subdir, addon.name) + '.installed')
+ elif installed.type == ADDON_LINKED:
os.unlink(installed.path)
elif installed.type in (ADDON_MANUAL, ADDON_COPIED) and not global_options.force:
raise DZError, "not removing copied or manually installed %s `%s'" \
@@ -1876,11 +1934,6 @@
else:
return
- if self.version.startswith("3"):
- try:
- os.unlink(os.path.join(self.home, "etc/package-includes/", addon.name + "-configure.zcml"))
- except OSError: pass
-
self._installed_addons.remove(installed)
logging.info("removed %s `%s'", installed.kind, installed.path)
@@ -2108,21 +2161,27 @@
elif arch == 'any':
prefixes = ['/usr/lib/zope']
elif arch == 'all':
- prefixes = ['/usr/share/zope']
+ prefixes = ['/usr/share/zope', '/usr/local/share/zope']
else:
- prefixes = ['/usr/share/zope', '/usr/lib/zope']
+ prefixes = ['/usr/share/zope', '/usr/lib/zope', '/usr/local/share/zope']
if addonClass == Product:
subdirs = [Product.subdir]
elif addonClass == Extension:
subdirs = [Extension.subdir]
else:
subdirs = [Product.subdir, Extension.subdir]
+ locals = []
+ if not instance and not is_root():
+ locals.append(personal_conf['products'])
addons = []
- for d in [os.path.join(pf, sd) for pf in prefixes for sd in subdirs]:
+ for d in locals + [os.path.join(pf, sd) for pf in prefixes for sd in subdirs]:
for path in glob.glob(os.path.join(d, '*')):
- if not os.path.isdir(path):
+ if os.path.isfile(path) and path.endswith('.installed'):
+ path = open(path, 'r').read()
+ addonClass = Product
+ elif not os.path.isdir(path):
continue
- if not addonClass:
+ elif not addonClass:
if os.path.basename(os.path.dirname(path)) == Product.subdir:
addonClass = Product
else:
@@ -2302,11 +2361,13 @@
if not is_root():
home_dir = pwd.getpwuid(uid)[5]
conf = os.path.join(home_dir, '.dzhandle.conf')
+ personal_conf['instances'] = os.path.join(home_dir, 'zope/instance')
+ personal_conf['products'] = os.path.join(home_dir, 'zope/products')
+ personal_conf['zeoinstances'] = os.path.join(home_dir, 'zope/zeo')
if os.path.exists(conf):
personal_conf.update(read_config_file(conf))
else:
- personal_conf['instances'] = os.path.join(home_dir, 'zope-instances')
- personal_conf['zeoinstances'] = os.path.join(home_dir, 'zeo-instances')
+ write_config_file(conf, personal_conf)
# setup logging stuff
setup_logging(config.get('logfile', None),
More information about the pkg-zope-commits
mailing list