From 2c9fe2ad28b828c2e0f4809b5377171ad4325385 Mon Sep 17 00:00:00 2001 From: Christian Zagrodnick Date: Mon, 20 Oct 2008 12:24:02 +0000 Subject: [PATCH] - Added a way to change the owner of created directories. --- src/lovely/recipe/fs/README.txt | 47 +++++++++++++++++++++++++++++ src/lovely/recipe/fs/mkdir-root.txt | 37 +++++++++++++++++++++++ src/lovely/recipe/fs/mkdir.py | 23 ++++++++++++-- src/lovely/recipe/fs/tests.py | 8 ++++- 4 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 src/lovely/recipe/fs/mkdir-root.txt diff --git a/src/lovely/recipe/fs/README.txt b/src/lovely/recipe/fs/README.txt index eca6bad..ea5221d 100644 --- a/src/lovely/recipe/fs/README.txt +++ b/src/lovely/recipe/fs/README.txt @@ -107,6 +107,53 @@ But we need to activate this function explicitely. d subdir +We can change the owner of the created directory if run as root. This is tested +in mkdir-root.txt. + +If not run as root, setting the owner is an error: + + >>> write(sample_buildout, 'buildout.cfg', + ... """ + ... [buildout] + ... parts = data-dir + ... find-links = http://download.zope.org/distribution + ... + ... [data-dir] + ... recipe = lovely.recipe:mkdir + ... createpath = True + ... path = another/with/subdir + ... owner = nobody + ... """) + >>> print system(buildout), + While: + Installing. + Getting section data-dir. + Initializing part data-dir. + Error: Only root can change the owner to nobody. + + +It is an error when the user does not exist: + + >>> write(sample_buildout, 'buildout.cfg', + ... """ + ... [buildout] + ... parts = data-dir + ... find-links = http://download.zope.org/distribution + ... + ... [data-dir] + ... recipe = lovely.recipe:mkdir + ... createpath = True + ... path = another/with/subdir + ... owner = someuser + ... """) + >>> print system(buildout), + While: + Installing. + Getting section data-dir. + Initializing part data-dir. + Error: The user someuser does not exist. + + Creating Files ============== diff --git a/src/lovely/recipe/fs/mkdir-root.txt b/src/lovely/recipe/fs/mkdir-root.txt new file mode 100644 index 0000000..02c9ab4 --- /dev/null +++ b/src/lovely/recipe/fs/mkdir-root.txt @@ -0,0 +1,37 @@ +Creating Directories with owner change +====================================== + +We can change the owner of the created directory if run as root: + + >>> write(sample_buildout, 'buildout.cfg', + ... """ + ... [buildout] + ... parts = data-dir + ... find-links = http://download.zope.org/distribution + ... + ... [data-dir] + ... recipe = lovely.recipe:mkdir + ... createpath = True + ... path = with/subdir + ... owner = nobody + ... """) + >>> import os + >>> import pwd + >>> nobody_uid = pwd.getpwnam('nobody')[2] + >>> print system(buildout), + Installing data-dir. + data-dir: Creating parent directory .../_TEST_/sample-buildout/with + data-dir: Creating directory with/subdir + +The owner of the subdir is changed: + + >>> path = os.path.join(sample_buildout, 'with/subdir') + >>> os.stat(path).st_uid == nobody_uid + True + +But not the owner of the parent dir: + + >>> path = os.path.join(sample_buildout, 'with') + >>> os.stat(path).st_uid == nobody_uid + False + diff --git a/src/lovely/recipe/fs/mkdir.py b/src/lovely/recipe/fs/mkdir.py index fe43a4f..4ffbd11 100644 --- a/src/lovely/recipe/fs/mkdir.py +++ b/src/lovely/recipe/fs/mkdir.py @@ -1,5 +1,6 @@ -import os import logging +import os +import pwd import zc.buildout @@ -14,7 +15,21 @@ def __init__(self, buildout, name, options): buildout['buildout']['directory'], self.originalPath, ) - self.createPath = options.get('createpath', 'False').lower() in ['true', 'on', '1'] + owner = options.get('owner') + if owner: + try: + uid = pwd.getpwnam(owner)[2] + except KeyError: + raise zc.buildout.UserError( + 'The user %s does not exist.' % owner) + if os.getuid() != 0: + raise zc.buildout.UserError( + 'Only root can change the owner to %s.' % owner) + + options['owner-uid'] = str(uid) + + self.createPath = options.get('createpath', 'False').lower() in [ + 'true', 'on', '1'] def install(self): path = self.options['path'] @@ -35,6 +50,10 @@ def install(self): logging.getLogger(self.name).info( 'Creating directory %s', self.originalPath) os.mkdir(path) + uid = self.options.get('owner-uid') + if uid is not None: + uid = int(uid) + os.chown(path, uid, -1) return () def update(self): diff --git a/src/lovely/recipe/fs/tests.py b/src/lovely/recipe/fs/tests.py index cf1cab4..22df59b 100644 --- a/src/lovely/recipe/fs/tests.py +++ b/src/lovely/recipe/fs/tests.py @@ -16,6 +16,8 @@ """ __docformat__ = 'restructuredtext' +import os + from zc.buildout import testing import doctest, unittest from zope.testing import doctest, renormalizing @@ -25,9 +27,13 @@ def test_suite(): + test_file = 'README.txt' + if os.getuid() == 0: + test_file = 'mkdir-root.txt' + return unittest.TestSuite(( doctest.DocFileSuite( - 'README.txt', + test_file, setUp=setUpBuildout, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS, tearDown=testing.buildoutTearDown,