[Checkins] SVN: z3c.recipe.mkdir/trunk/ Support `user`, `group` and `mode` option. First draft.
Ulrich Fouquet
cvs-admin at zope.org
Sat Jun 23 04:11:47 UTC 2012
Log message for revision 127052:
Support `user`, `group` and `mode` option. First draft.
Changed:
U z3c.recipe.mkdir/trunk/CHANGES.txt
U z3c.recipe.mkdir/trunk/z3c/recipe/mkdir/README.txt
U z3c.recipe.mkdir/trunk/z3c/recipe/mkdir/__init__.py
U z3c.recipe.mkdir/trunk/z3c/recipe/mkdir/tests.py
-=-
Modified: z3c.recipe.mkdir/trunk/CHANGES.txt
===================================================================
--- z3c.recipe.mkdir/trunk/CHANGES.txt 2012-06-23 01:03:50 UTC (rev 127051)
+++ z3c.recipe.mkdir/trunk/CHANGES.txt 2012-06-23 04:11:43 UTC (rev 127052)
@@ -4,6 +4,8 @@
0.4 (unreleased)
================
+* Added support for ``mode``, ``user``, and ``group`` options.
+
* Fixed (unnoticed?) bug when using the deprecated ``path`` option. In
that case the default path (``parts/<sectionname>``) was created
instead of the given one.
Modified: z3c.recipe.mkdir/trunk/z3c/recipe/mkdir/README.txt
===================================================================
--- z3c.recipe.mkdir/trunk/z3c/recipe/mkdir/README.txt 2012-06-23 01:03:50 UTC (rev 127051)
+++ z3c.recipe.mkdir/trunk/z3c/recipe/mkdir/README.txt 2012-06-23 04:11:43 UTC (rev 127052)
@@ -163,7 +163,51 @@
Note, that the created directory will be removed on next modification
of `buildout.cfg`.
+Setting user, group, and permissions
+====================================
+You can optionally set ``user``, ``group``, or ``mode`` option for the
+dirs to be created.
+
+While ``user`` and ``group`` give the user/group that should own the
+created directory, ``mode`` is expected to be an octal number to
+represent the directory permissions in Unix style.
+
+Of course, setting all these permissions and ownerships only works if
+the system supports it and the running user has the permissions to do
+so.
+
+ >>> write('buildout.cfg',
+ ... '''
+ ... [buildout]
+ ... parts = mydir
+ ... offline = true
+ ...
+ ... [mydir]
+ ... recipe = z3c.recipe.mkdir
+ ... paths = my/newdir
+ ... remove-on-update = true
+ ... mode = 700
+ ... user = %s
+ ... group = %s
+ ... ''' % (user, group))
+
+ >>> print system(join('bin', 'buildout')),
+ Uninstalling mydir.
+ Installing mydir.
+ mydir: created path: /sample-buildout/my
+ mydir: mode 0700, user 'USER', group 'GROUP'
+ mydir: created path: /sample-buildout/my/newdir
+ mydir: mode 0700, user 'USER', group 'GROUP'
+
+ >>> lls('my')
+ drwx------ USER GROUP my/newdir
+
+
+These options are optional, so you can leave any of them out and the system
+defaults will be used instead.
+
+
Creating relative paths
=======================
Modified: z3c.recipe.mkdir/trunk/z3c/recipe/mkdir/__init__.py
===================================================================
--- z3c.recipe.mkdir/trunk/z3c/recipe/mkdir/__init__.py 2012-06-23 01:03:50 UTC (rev 127051)
+++ z3c.recipe.mkdir/trunk/z3c/recipe/mkdir/__init__.py 2012-06-23 04:11:43 UTC (rev 127052)
@@ -21,15 +21,50 @@
self.paths = [os.path.normpath(os.path.abspath(
x.strip())) for x in paths.split('\n')]
+ self.mode = options.get('mode', None)
+ if self.mode is not None:
+ try:
+ self.mode = int(self.mode, 8)
+ except ValueError:
+ raise zc.buildout.UserError(
+ "'mode' must be an octal number: " % self.mode)
+
+ # determine user id
+ self.user = options.get('user', None)
+ self.uid = -1
+ if self.user:
+ try:
+ import pwd
+ self.uid = pwd.getpwnam(options['user'])[2]
+ except ImportError:
+ self.logger.warn(
+ "System does not support `pwd`. Using default user")
+
+ # determine group id
+ self.group = options.get('group', None)
+ self.gid = -1
+ if self.group:
+ try:
+ import grp
+ self.gid = grp.getgrnam(options['group'])[2]
+ except ImportError:
+ self.logger.warn(
+ "System does not support `grp`. Using default group")
+
# Update options to be referencable...
options['path'] = options['paths'] = '\n'.join(self.paths)
+ if self.mode:
+ options['mode'] = oct(self.mode)
+ if self.user:
+ options['user'] = self.user
+ if self.group:
+ options['group'] = self.group
def install(self):
for path in self.paths:
self.createIntermediatePaths(path)
return self.options.created()
-
def update(self):
return self.install()
@@ -38,14 +73,30 @@
if os.path.exists(path) and not os.path.isdir(path):
raise zc.buildout.UserError(
"Cannot create directory: %s. It's a file." % path)
- if os.path.exists(path) or parent == path:
+ if parent == path or os.path.exists(path):
return
self.createIntermediatePaths(parent)
os.mkdir(path)
self.logger.info('created path: %s' % path)
+ self.setPermissions(path)
if self.remove_on_update:
self.options.created(path)
+ def setPermissions(self, path):
+ additional_msgs = []
+ if self.mode is not None:
+ os.chmod(path, self.mode)
+ additional_msgs.append('mode 0%o' % self.mode)
+ if self.uid != -1 or self.gid != -1:
+ os.chown(path, self.uid, self.gid)
+ if self.uid != -1:
+ additional_msgs.append("user %r" % self.user)
+ if self.gid != -1:
+ additional_msgs.append("group %r" % self.group)
+ if additional_msgs:
+ self.logger.info(' ' + ', '.join(additional_msgs))
+
+
def string_to_bool(value):
if value is True or value is False:
return value
Modified: z3c.recipe.mkdir/trunk/z3c/recipe/mkdir/tests.py
===================================================================
--- z3c.recipe.mkdir/trunk/z3c/recipe/mkdir/tests.py 2012-06-23 01:03:50 UTC (rev 127051)
+++ z3c.recipe.mkdir/trunk/z3c/recipe/mkdir/tests.py 2012-06-23 04:11:43 UTC (rev 127052)
@@ -11,18 +11,47 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-
+import grp
+import os
+import pwd
import re
+import stat
import unittest
import doctest
import zc.buildout.testing
from zope.testing import renormalizing
+user = pwd.getpwuid(os.geteuid()).pw_name
+group = grp.getgrgid(os.getegid()).gr_name
+def dir_entry(path):
+ # create a dir entry for file/dir in path.
+ def perm(mode):
+ # turn file stat mode into rwx...-string
+ result = ''
+ for grp in oct(mode)[-3:]:
+ perms = int(grp)
+ for num, sign in ((04, 'r'), (02, 'w'), (01, 'x')):
+ result += perms & num and sign or '-'
+ return result
+ st = os.stat(path)
+ type_flag = stat.S_ISDIR(st.st_mode) and 'd' or '-'
+ permissions = type_flag + perm(st.st_mode)
+ return '%s %s %s %s' % (permissions, user, group, path)
+
+def lls(path):
+ # list files and directories in `path` with permissions and type.
+ for name in sorted(os.listdir(path)):
+ print dir_entry(os.path.join(path, name))
+
+
def setUp(test):
zc.buildout.testing.buildoutSetUp(test)
zc.buildout.testing.install_develop('z3c.recipe.mkdir', test)
+ test.globs['lls'] = lls
+ test.globs['user'] = user
+ test.globs['group'] = group
checker = renormalizing.RENormalizing([
@@ -38,6 +67,10 @@
(re.compile('-\S+-py\d[.]\d(-\S+)?.egg'),
'-pyN.N.egg',
),
+ (re.compile("user '%s'" % user), "user 'USER'"),
+ (re.compile("group '%s'" % group), "group 'GROUP'"),
+ (re.compile("%s %s" % (user, group)), "USER GROUP"),
+ (re.compile(user), "USER"),
])
More information about the checkins
mailing list