Rev 5107: (mbp, for parthm) inherit permissions on \~/.bazaar etc in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Wed Mar 24 07:27:47 GMT 2010


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 5107 [merge]
revision-id: pqm at pqm.ubuntu.com-20100324072744-2fod6mq1jqijs7c0
parent: pqm at pqm.ubuntu.com-20100322190243-u13kk6705w4k38i9
parent: mbp at canonical.com-20100324064908-xave4d44nx7ntws4
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2010-03-24 07:27:44 +0000
message:
  (mbp, for parthm) inherit permissions on \~/.bazaar etc
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/config.py               config.py-20051011043216-070c74f4e9e338e8
  bzrlib/osutils.py              osutils.py-20050309040759-eeaff12fbf77ac86
  bzrlib/tests/blackbox/test_upgrade.py test_upgrade.py-20060120060132-b41e5ed2f886ad28
  bzrlib/tests/features.py       features.py-20090820042958-jglgza3wrn03ha9e-1
  bzrlib/tests/test_osutils.py   test_osutils.py-20051201224856-e48ee24c12182989
  bzrlib/trace.py                trace.py-20050309040759-c8ed824bdcd4748a
  doc/developers/testing.txt     testing.txt-20080812140359-i70zzh6v2z7grqex-1
=== modified file 'NEWS'
--- a/NEWS	2010-03-22 13:59:33 +0000
+++ b/NEWS	2010-03-24 07:27:44 +0000
@@ -155,6 +155,11 @@
 * Tolerate patches with leading noise in ``bzr-handle-patch``.
   (Toshio Kuratomi, Martin Pool, #502076)
 
+* ``.bazaar``, ``.bazaar/bazaar.conf`` and ``.bzr.log`` inherit user and
+  group ownership from the containing directory. This allow bzr to work
+  better with sudo.
+  (Parth Malwankar, #376388)
+
 API Changes
 ***********
 

=== modified file 'bzrlib/config.py'
--- a/bzrlib/config.py	2010-02-23 07:43:11 +0000
+++ b/bzrlib/config.py	2010-03-06 05:28:17 +0000
@@ -510,7 +510,8 @@
         self._write_config_file()
 
     def _write_config_file(self):
-        f = open(self._get_filename(), 'wb')
+        path = self._get_filename()
+        f = osutils.open_with_ownership(path, 'wb')
         self._get_parser().write(f)
         f.close()
 
@@ -809,7 +810,7 @@
                 trace.mutter('creating config parent directory: %r', parent_dir)
             os.mkdir(parent_dir)
         trace.mutter('creating config directory: %r', path)
-        os.mkdir(path)
+        osutils.mkdir_with_ownership(path)
 
 
 def config_dir():

=== modified file 'bzrlib/osutils.py'
--- a/bzrlib/osutils.py	2010-03-11 04:33:41 +0000
+++ b/bzrlib/osutils.py	2010-03-11 06:35:52 +0000
@@ -51,7 +51,9 @@
     cache_utf8,
     errors,
     win32utils,
+    trace,
     )
+
 """)
 
 # sha and md5 modules are deprecated in python2.6 but hashlib is available as
@@ -1804,6 +1806,51 @@
             real_handlers[kind](abspath, relpath)
 
 
+def copy_ownership(dst, src=None):
+    """Copy usr/grp ownership from src file/dir to dst file/dir.
+
+    If src is None, the containing directory is used as source. If chown
+    fails, the error is ignored and a warning is printed.
+    """
+    has_chown = getattr(os, 'chown')
+    if has_chown is None: return
+
+    if src == None:
+        src = os.path.dirname(dst)
+        if src == '':
+            src = '.'
+
+    try:
+        s = os.stat(src)
+        os.chown(dst, s.st_uid, s.st_gid)
+    except OSError, e:
+        trace.warning("Unable to copy ownership from '%s' to '%s': IOError: %s." % (src, dst, e))
+
+
+def mkdir_with_ownership(path, ownership_src=None):
+    """Create the directory 'path' with specified ownership.
+
+    If ownership_src is given, copies (chown) usr/grp ownership
+    from 'ownership_src' to 'path'. If ownership_src is None, use the
+    containing dir ownership.
+    """
+    os.mkdir(path)
+    copy_ownership(path, ownership_src)
+
+
+def open_with_ownership(filename, mode='r', bufsize=-1, ownership_src=None):
+    """Open the file 'filename' with the specified ownership.
+
+    If ownership_src is specified, copy usr/grp ownership from ownership_src
+    to filename. If ownership_src is None, copy ownership from containing
+    directory.
+    Returns the opened file object.
+    """
+    f = open(filename, mode, bufsize)
+    copy_ownership(filename, ownership_src)
+    return f
+
+
 def path_prefix_key(path):
     """Generate a prefix-order path key for path.
 

=== modified file 'bzrlib/tests/blackbox/test_upgrade.py'
--- a/bzrlib/tests/blackbox/test_upgrade.py	2010-03-17 05:36:11 +0000
+++ b/bzrlib/tests/blackbox/test_upgrade.py	2010-03-24 06:49:08 +0000
@@ -151,7 +151,7 @@
 
     def test_upgrade_permission_check(self):
         """'backup.bzr' should retain permissions of .bzr. Bug #262450"""
-        self.requireFeature(features.PosixPermissionsFeature)
+        self.requireFeature(features.posix_permissions_feature)
         old_perms = stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR
         backup_dir = 'backup.bzr.~1~'
         self.run_bzr('init --format=1.6')

=== modified file 'bzrlib/tests/features.py'
--- a/bzrlib/tests/features.py	2010-03-03 14:55:44 +0000
+++ b/bzrlib/tests/features.py	2010-03-18 06:25:23 +0000
@@ -26,6 +26,7 @@
 pycurl = tests.ModuleAvailableFeature('pycurl')
 subunit = tests.ModuleAvailableFeature('subunit')
 
+
 class _PosixPermissionsFeature(tests.Feature):
 
     def _probe(self):
@@ -48,4 +49,15 @@
     def feature_name(self):
         return 'POSIX permissions support'
 
-PosixPermissionsFeature = _PosixPermissionsFeature()
+
+posix_permissions_feature = _PosixPermissionsFeature()
+
+
+class _ChownFeature(tests.Feature):
+    """os.chown is supported"""
+
+    def _probe(self):
+        return os.name == 'posix' and hasattr(os, 'chown')
+
+chown_feature = _ChownFeature()
+

=== modified file 'bzrlib/tests/test_osutils.py'
--- a/bzrlib/tests/test_osutils.py	2010-02-23 07:43:11 +0000
+++ b/bzrlib/tests/test_osutils.py	2010-03-11 06:24:00 +0000
@@ -33,6 +33,7 @@
     win32utils,
     )
 from bzrlib.tests import (
+    features,
     file_utils,
     test__walkdirs_win32,
     )
@@ -1975,3 +1976,43 @@
         del os.environ['COLUMNS']
         # Whatever the result is, if we don't raise an exception, it's ok.
         osutils.terminal_width()
+
+class TestCreationOps(tests.TestCaseInTempDir):
+    _test_needs_features = [features.chown_feature]
+
+    def setUp(self):
+        tests.TestCaseInTempDir.setUp(self)
+        self.overrideAttr(os, 'chown', self._dummy_chown)
+
+        # params set by call to _dummy_chown
+        self.path = self.uid = self.gid = None
+
+    def _dummy_chown(self, path, uid, gid):
+        self.path, self.uid, self.gid = path, uid, gid
+
+    def test_mkdir_with_ownership_chown(self):
+        """Ensure that osutils.mkdir_with_ownership chowns correctly with ownership_src.
+        """
+        ownsrc = '/'
+        osutils.mkdir_with_ownership('foo', ownsrc)
+
+        s = os.stat(ownsrc)
+        self.assertEquals(self.path, 'foo')
+        self.assertEquals(self.uid, s.st_uid)
+        self.assertEquals(self.gid, s.st_gid)
+
+    def test_open_with_ownership_chown(self):
+        """Ensure that osutils.open_with_ownership chowns correctly with ownership_src.
+        """
+        ownsrc = '/'
+        f = osutils.open_with_ownership('foo', 'w', ownership_src=ownsrc)
+
+        # do a test write and close
+        f.write('hello')
+        f.close()
+
+        s = os.stat(ownsrc)
+        self.assertEquals(self.path, 'foo')
+        self.assertEquals(self.uid, s.st_uid)
+        self.assertEquals(self.gid, s.st_gid)
+

=== modified file 'bzrlib/trace.py'
--- a/bzrlib/trace.py	2010-02-24 01:20:51 +0000
+++ b/bzrlib/trace.py	2010-03-06 05:28:17 +0000
@@ -241,14 +241,17 @@
     _bzr_log_filename = _get_bzr_log_filename()
     _rollover_trace_maybe(_bzr_log_filename)
     try:
-        bzr_log_file = open(_bzr_log_filename, 'at', buffering=0) # unbuffered
+        buffering = 0 # unbuffered
+        bzr_log_file = osutils.open_with_ownership(_bzr_log_filename, 'at', buffering)
         # bzr_log_file.tell() on windows always return 0 until some writing done
         bzr_log_file.write('\n')
         if bzr_log_file.tell() <= 2:
             bzr_log_file.write("this is a debug log for diagnosing/reporting problems in bzr\n")
             bzr_log_file.write("you can delete or truncate this file, or include sections in\n")
             bzr_log_file.write("bug reports to https://bugs.launchpad.net/bzr/+filebug\n\n")
+
         return bzr_log_file
+
     except IOError, e:
         # If we are failing to open the log, then most likely logging has not
         # been set up yet. So we just write to stderr rather than using

=== modified file 'doc/developers/testing.txt'
--- a/doc/developers/testing.txt	2010-03-09 01:15:37 +0000
+++ b/doc/developers/testing.txt	2010-03-18 06:25:23 +0000
@@ -599,6 +599,10 @@
  - UnicodeFilenameFeature
  - FTPServerFeature
  - CaseInsensitiveFilesystemFeature.
+ - chown_feature: The test can rely on OS being POSIX and python
+   supporting os.chown.
+ - posix_permissions_feature: The test can use POSIX-style
+   user/group/other permission bits.
 
 
 Defining a new feature that tests can require




More information about the bazaar-commits mailing list