Rev 6458: Merge 2.5 branch in http://bazaar.launchpad.net/~vila/bzr/integration/

Vincent Ladeuil v.ladeuil+lp at free.fr
Wed Feb 1 08:25:41 UTC 2012


At http://bazaar.launchpad.net/~vila/bzr/integration/

------------------------------------------------------------
revno: 6458 [merge]
revision-id: v.ladeuil+lp at free.fr-20120201082541-73d2i8rqcjrsx4ds
parent: pqm at pqm.ubuntu.com-20120131143924-l1u9chlhapdch9e2
parent: pqm at pqm.ubuntu.com-20120131182557-ywfu6m6vm89u525v
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: trunk
timestamp: Wed 2012-02-01 09:25:41 +0100
message:
  Merge 2.5 branch
modified:
  bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
  bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
  bzrlib/controldir.py           controldir.py-20100802102926-hvtvh0uae5epuibp-1
  bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
  bzrlib/tests/blackbox/test_rmbranch.py test_rmbranch.py-20100131150653-auenl06hu4y2d9tr-1
  bzrlib/tests/per_controldir/test_controldir.py test_bzrdir.py-20060131065642-0ebeca5e30e30866
  bzrlib/tests/test_https_urllib.py test_https_urllib.py-20111220105828-v3g3fknv8inj2jqv-1
  bzrlib/transport/http/_urllib2_wrappers.py _urllib2_wrappers.py-20060913231729-ha9ugi48ktx481ao-1
  doc/en/release-notes/bzr-2.5.txt bzr2.5.txt-20110708125756-587p0hpw7oke4h05-1
-------------- next part --------------
=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2012-01-28 17:58:09 +0000
+++ b/bzrlib/builtins.py	2012-02-01 08:25:41 +0000
@@ -6452,8 +6452,8 @@
     def run(self, location=None):
         if location is None:
             location = "."
-        branch = Branch.open_containing(location)[0]
-        branch.bzrdir.destroy_branch()
+        cdir = controldir.ControlDir.open_containing(location)[0]
+        cdir.destroy_branch()
 
 
 class cmd_shelve(Command):

=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py	2012-01-28 02:05:52 +0000
+++ b/bzrlib/bzrdir.py	2012-01-31 15:43:17 +0000
@@ -862,7 +862,7 @@
 
     def create_branch(self, name=None, repository=None,
             append_revisions_only=None):
-        """See BzrDir.create_branch."""
+        """See ControlDir.create_branch."""
         if name is None:
             name = self._get_selected_branch()
         return self._format.get_branch_format().initialize(self, name=name,
@@ -870,7 +870,7 @@
                 append_revisions_only=append_revisions_only)
 
     def destroy_branch(self, name=None):
-        """See BzrDir.create_branch."""
+        """See ControlDir.destroy_branch."""
         if name is None:
             name = self._get_selected_branch()
         path = self._get_branch_path(name)
@@ -885,7 +885,11 @@
                 self._write_branch_list(branches)
             finally:
                 self.control_files.unlock()
-        self.transport.delete_tree(path)
+        try:
+            self.transport.delete_tree(path)
+        except errors.NoSuchFile:
+            raise errors.NotBranchError(path=urlutils.join(self.transport.base,
+                path), bzrdir=self)
 
     def create_repository(self, shared=False):
         """See BzrDir.create_repository."""

=== modified file 'bzrlib/controldir.py'
--- a/bzrlib/controldir.py	2012-01-27 14:01:25 +0000
+++ b/bzrlib/controldir.py	2012-01-31 15:43:17 +0000
@@ -163,7 +163,7 @@
         """Create a branch in this ControlDir.
 
         :param name: Name of the colocated branch to create, None for
-            the default branch.
+            the user selected branch or "" for the active branch.
         :param append_revisions_only: Whether this branch should only allow
             appending new revisions to its history.
 
@@ -175,8 +175,9 @@
     def destroy_branch(self, name=None):
         """Destroy a branch in this ControlDir.
 
-        :param name: Name of the branch to destroy, None for the default 
-            branch.
+        :param name: Name of the branch to destroy, None for the 
+            user selected branch or "" for the active branch.
+        :raise NotBranchError: When the branch does not exist
         """
         raise NotImplementedError(self.destroy_branch)
 
@@ -302,7 +303,7 @@
     def _get_selected_branch(self):
         """Return the name of the branch selected by the user.
 
-        :return: Name of the branch selected by the user, or None.
+        :return: Name of the branch selected by the user, or "".
         """
         branch = self.root_transport.get_segment_parameters().get("branch")
         if branch is None:

=== modified file 'bzrlib/errors.py'
--- a/bzrlib/errors.py	2012-01-27 15:47:12 +0000
+++ b/bzrlib/errors.py	2012-01-31 18:25:57 +0000
@@ -1761,7 +1761,8 @@
 
 class ConfigOptionValueError(BzrError):
 
-    _fmt = """Bad value "%(value)s" for option "%(name)s"."""
+    _fmt = ('Bad value "%(value)s" for option "%(name)s".\n'
+            'See ``bzr help %(name)s``')
 
     def __init__(self, name, value):
         BzrError.__init__(self, name=name, value=value)

=== modified file 'bzrlib/tests/blackbox/test_rmbranch.py'
--- a/bzrlib/tests/blackbox/test_rmbranch.py	2011-12-14 20:21:52 +0000
+++ b/bzrlib/tests/blackbox/test_rmbranch.py	2012-01-25 17:31:04 +0000
@@ -83,6 +83,6 @@
         # being too low. If rpc_count increases, more network roundtrips have
         # become necessary for this use case. Please do not adjust this number
         # upwards without agreement from bzr's network support maintainers.
-        self.assertLength(5, self.hpss_calls)
+        self.assertLength(2, self.hpss_calls)
         self.assertLength(1, self.hpss_connections)
         self.assertThat(self.hpss_calls, ContainsNoVfsCalls)

=== modified file 'bzrlib/tests/per_controldir/test_controldir.py'
--- a/bzrlib/tests/per_controldir/test_controldir.py	2012-01-18 20:27:41 +0000
+++ b/bzrlib/tests/per_controldir/test_controldir.py	2012-01-25 17:31:04 +0000
@@ -159,6 +159,14 @@
         bzrdir.create_branch()
         bzrdir.open_branch()
 
+    def test_destroy_branch_no_branch(self):
+        branch = self.make_repository('branch')
+        bzrdir = branch.bzrdir
+        try:
+            self.assertRaises(errors.NotBranchError, bzrdir.destroy_branch)
+        except (errors.UnsupportedOperation, errors.TransportNotPossible):
+            raise TestNotApplicable('Format does not support destroying branch')
+
     def test_destroy_repository(self):
         repo = self.make_repository('repository')
         bzrdir = repo.bzrdir

=== modified file 'bzrlib/tests/test_https_urllib.py'
--- a/bzrlib/tests/test_https_urllib.py	2012-01-19 15:27:47 +0000
+++ b/bzrlib/tests/test_https_urllib.py	2012-01-31 16:36:53 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2011 Canonical Ltd
+# Copyright (C) 2011,2012 Canonical Ltd
 #
 # 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
@@ -41,18 +41,10 @@
     def get_stack(self, content):
         return config.MemoryStack(content.encode('utf-8'))
 
-    def test_default_raises_value_error(self):
-        stack = self.get_stack("")
-        self.overrideAttr(_urllib2_wrappers, "DEFAULT_CA_PATH",
-                "/i-do-not-exist")
-        self.assertRaises(ValueError, stack.get, 'ssl.ca_certs')
-
     def test_default_exists(self):
-        self.build_tree(['cacerts.pem'])
+        """Check that the default we provide exists for the tested platform."""
         stack = self.get_stack("")
-        path = os.path.join(self.test_dir, "cacerts.pem")
-        self.overrideAttr(_urllib2_wrappers, "DEFAULT_CA_PATH", path)
-        self.assertEquals(path, stack.get('ssl.ca_certs'))
+        self.assertPathExists(stack.get('ssl.ca_certs'))
 
     def test_specified(self):
         self.build_tree(['cacerts.pem'])
@@ -61,14 +53,15 @@
         self.assertEquals(path, stack.get('ssl.ca_certs'))
 
     def test_specified_doesnt_exist(self):
-        path = os.path.join(self.test_dir, "nonexisting.pem")
-        stack = self.get_stack("ssl.ca_certs = %s\n" % path)
+        stack = self.get_stack('')
+        # Disable the default value mechanism to force the behavior we want
+        self.overrideAttr(_urllib2_wrappers.opt_ssl_ca_certs, 'default',
+                          os.path.join(self.test_dir, u"nonexisting.pem"))
         self.warnings = []
         def warning(*args):
             self.warnings.append(args[0] % args[1:])
         self.overrideAttr(trace, 'warning', warning)
-        self.assertEquals(_urllib2_wrappers.DEFAULT_CA_PATH,
-                          stack.get('ssl.ca_certs'))
+        self.assertEquals(None, stack.get('ssl.ca_certs'))
         self.assertLength(1, self.warnings)
         self.assertContainsRe(self.warnings[0],
                               "is not valid for \"ssl.ca_certs\"")
@@ -83,8 +76,6 @@
     def test_from_string(self):
         stack = config.MemoryStack("ssl.cert_reqs = none\n")
         self.assertEquals(ssl.CERT_NONE, stack.get("ssl.cert_reqs"))
-        stack = config.MemoryStack("ssl.cert_reqs = optional\n")
-        self.assertEquals(ssl.CERT_OPTIONAL, stack.get("ssl.cert_reqs"))
         stack = config.MemoryStack("ssl.cert_reqs = required\n")
         self.assertEquals(ssl.CERT_REQUIRED, stack.get("ssl.cert_reqs"))
         stack = config.MemoryStack("ssl.cert_reqs = invalid\n")

=== modified file 'bzrlib/transport/http/_urllib2_wrappers.py'
--- a/bzrlib/transport/http/_urllib2_wrappers.py	2012-01-20 09:19:14 +0000
+++ b/bzrlib/transport/http/_urllib2_wrappers.py	2012-01-31 17:00:22 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2006-2011 Canonical Ltd
+# Copyright (C) 2006-2012 Canonical Ltd
 #
 # 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
@@ -74,14 +74,36 @@
 import ssl
 """)
 
-DEFAULT_CA_PATH = u"/etc/ssl/certs/ca-certificates.crt"
 
+# Note for packagers: if there is no package providing certs for your platform,
+# the curl project produces http://curl.haxx.se/ca/cacert.pem weekly.
+_ssl_ca_certs_known_locations = [
+    u'/etc/ssl/certs/ca-certificates.crt', # Ubuntu/debian/gentoo
+    u'/etc/pki/tls/certs/ca-bundle.crt', # Fedora/CentOS/RH
+    u'/etc/ssl/ca-bundle.pem', # OpenSuse
+    u'/etc/ssl/cert.pem', # OpenSuse
+    u"/usr/local/share/certs/ca-root-nss.crt", # FreeBSD
+    # XXX: Needs checking, can't trust the interweb ;) -- vila 2012-01-25
+    u'/etc/openssl/certs/ca-certificates.crt', # Solaris
+    ]
 
 def default_ca_certs():
-    if not os.path.exists(DEFAULT_CA_PATH):
-        raise ValueError("default ca certs path %s does not exist" %
-            DEFAULT_CA_PATH)
-    return DEFAULT_CA_PATH
+    if sys.platform == 'win32':
+        return os.path.join(os.path.dirname(sys.executable), u"ca_bundle.crt")
+    elif sys.platform == 'darwin':
+        # FIXME: Needs some default value for osx, waiting for osx installers
+        # guys feedback -- vila 2012-01-25
+        pass
+    else:
+        # Try known locations for friendly OSes providing the root certificates
+        # without making them hard to use for any https client.
+        for path in _ssl_ca_certs_known_locations:
+            if os.path.exists(path):
+                # First found wins
+                return path
+    # A default path that makes sense and will be mentioned in the error
+    # presented to the user, even if not correct for all platforms
+    return _ssl_ca_certs_known_locations[0]
 
 
 def ca_certs_from_store(path):
@@ -90,16 +112,11 @@
     return path
 
 
-def default_cert_reqs():
-    return u"required"
-
-
 def cert_reqs_from_store(unicode_str):
     import ssl
     try:
         return {
             "required": ssl.CERT_REQUIRED,
-            "optional": ssl.CERT_OPTIONAL,
             "none": ssl.CERT_NONE
             }[unicode_str]
     except KeyError:
@@ -112,10 +129,15 @@
         invalid='warning',
         help="""\
 Path to certification authority certificates to trust.
+
+This should be a valid path to a bundle containing all root Certificate
+Authorities used to verify an https server certificate.
+
+Use ssl.cert_reqs=none to disable certificate verification.
 """)
 
 opt_ssl_cert_reqs = config.Option('ssl.cert_reqs',
-        default=default_cert_reqs,
+        default=u"required",
         from_unicode=cert_reqs_from_store,
         invalid='error',
         help="""\
@@ -123,8 +145,7 @@
 
 Possible values:
  * none: Certificates ignored
- * optional: Certificates not required, but validated if provided
- * required: Certificates required, and validated
+ * required: Certificates required and validated
 """)
 
 checked_kerberos = False
@@ -448,34 +469,34 @@
     def connect_to_origin(self):
         # FIXME JRV 2011-12-18: Use location config here?
         config_stack = config.GlobalStack()
-        if self.ca_certs is None:
-            ca_certs = config_stack.get('ssl.ca_certs')
-        else:
-            ca_certs = self.ca_certs
         cert_reqs = config_stack.get('ssl.cert_reqs')
         if cert_reqs == ssl.CERT_NONE:
-            trace.warning("not checking SSL certificates for %s: %d",
+            trace.warning("Not checking SSL certificate for %s: %d",
                 self.host, self.port)
+            ca_certs = None
         else:
+            if self.ca_certs is None:
+                ca_certs = config_stack.get('ssl.ca_certs')
+            else:
+                ca_certs = self.ca_certs
             if ca_certs is None:
                 trace.warning(
-                    "no valid trusted SSL CA certificates file set. See "
+                    "No valid trusted SSL CA certificates file set. See "
                     "'bzr help ssl.ca_certs' for more information on setting "
-                    "trusted CA's.")
+                    "trusted CAs.")
         try:
             ssl_sock = ssl.wrap_socket(self.sock, self.key_file, self.cert_file,
                 cert_reqs=cert_reqs, ca_certs=ca_certs)
         except ssl.SSLError, e:
-            if e.errno != ssl.SSL_ERROR_SSL:
-                raise
             trace.note(
-                "To disable SSL certificate verification, use "
-                "-Ossl.cert_reqs=none. See ``bzr help ssl.ca_certs`` for "
-                "more information on specifying trusted CA certificates.")
+                "\n"
+                "See `bzr help ssl.ca_certs` for how to specify trusted CA"
+                "certificates.\n"
+                "Pass -Ossl.cert_reqs=none to disable certificate "
+                "verification entirely.\n")
             raise
-        peer_cert = ssl_sock.getpeercert()
-        if (cert_reqs == ssl.CERT_REQUIRED or
-            (cert_reqs == ssl.CERT_OPTIONAL and peer_cert)):
+        if cert_reqs == ssl.CERT_REQUIRED:
+            peer_cert = ssl_sock.getpeercert()
             match_hostname(peer_cert, self.host)
 
         # Wrap the ssl socket before anybody use it

=== modified file 'doc/en/release-notes/bzr-2.5.txt'
--- a/doc/en/release-notes/bzr-2.5.txt	2012-01-31 14:39:24 +0000
+++ b/doc/en/release-notes/bzr-2.5.txt	2012-02-01 08:25:41 +0000
@@ -60,6 +60,10 @@
 * ``bzr branch`` now fetches revisions when branching into an empty
   control directory. (Jelmer Vernooij, #905594)
 
+* A sane default is provided for ``ssl.ca_certs`` which should points to the
+  Certificate Authority bundle for supported platforms.
+  (Vincent Ladeuil, #920455)
+
 * ``bzr branch`` generates correct target branch locations again if not
   specified. (Jelmer Vernooij, #919218)
 
@@ -90,6 +94,9 @@
 * ``ControlDir`` now has a new method ``set_branch_reference`` which can
   be used for setting branch references. (Jelmer Vernooij)
 
+* ``ControlDir.destroy_branch`` now raises ``NotBranchError`` rather than
+  ``NoSuchFile`` if the branch didn't exist. (Jelmer Vernooij, #921693)
+
 * New convenience API method ``WorkingTree.get_config_stack``.
   (Jelmer Vernooij)
 



More information about the bazaar-commits mailing list