~bzr-pqm/bzr/bzr.dev

2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
1
# Copyright (C) 2006 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
"""Server-side bzrdir related request implmentations."""
18
19
20
from bzrlib import errors
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
21
from bzrlib.bzrdir import BzrDir, BzrDirFormat
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
22
from bzrlib.smart.request import (
23
    FailedSmartServerResponse,
24
    SmartServerRequest,
25
    SuccessfulSmartServerResponse,
26
    )
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
27
28
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
29
class SmartServerRequestOpenBzrDir(SmartServerRequest):
30
31
    def do(self, path):
32
        from bzrlib.bzrdir import BzrDirFormat
33
        try:
2692.1.11 by Andrew Bennetts
Improve test coverage by making SmartTCPServer_for_testing by default create a server that does not serve the backing transport's root at its own root. This mirrors the way most HTTP smart servers are configured.
34
            t = self.transport_from_client_path(path)
35
        except errors.PathNotChild:
36
            # The client is trying to ask about a path that they have no access
37
            # to.
38
            # Ideally we'd return a FailedSmartServerResponse here rather than
39
            # a "successful" negative, but we want to be compatibile with
40
            # clients that don't anticipate errors from this method.
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
41
            answer = 'no'
42
        else:
2692.1.11 by Andrew Bennetts
Improve test coverage by making SmartTCPServer_for_testing by default create a server that does not serve the backing transport's root at its own root. This mirrors the way most HTTP smart servers are configured.
43
            default_format = BzrDirFormat.get_default_format()
44
            real_bzrdir = default_format.open(t, _found=True)
45
            try:
46
                real_bzrdir._format.probe_transport(t)
47
            except (errors.NotBranchError, errors.UnknownFormatError):
48
                answer = 'no'
49
            else:
50
                answer = 'yes'
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
51
        return SuccessfulSmartServerResponse((answer,))
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
52
53
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
54
class SmartServerRequestFindRepository(SmartServerRequest):
55
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
56
    def _boolean_to_yes_no(self, a_boolean):
57
        if a_boolean:
58
            return 'yes'
59
        else:
60
            return 'no'
61
62
    def _find(self, path):
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
63
        """try to find a repository from path upwards
64
        
65
        This operates precisely like 'bzrdir.find_repository'.
66
        
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
67
        :return: (relpath, rich_root, tree_ref, external_lookup) flags. All are
68
            strings, relpath is a / prefixed path, and the other three are
69
            either 'yes' or 'no'.
70
        :raises errors.NoRepositoryPresent: When there is no repository
71
            present.
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
72
        """
2692.1.6 by Andrew Bennetts
Fix some >80 columns violations.
73
        bzrdir = BzrDir.open_from_transport(
74
            self.transport_from_client_path(path))
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
75
        repository = bzrdir.find_repository()
76
        # the relpath of the bzrdir in the found repository gives us the 
77
        # path segments to pop-out.
2692.1.24 by Andrew Bennetts
Merge from bzr.dev.
78
        relpath = repository.bzrdir.root_transport.relpath(
79
            bzrdir.root_transport.base)
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
80
        if len(relpath):
81
            segments = ['..'] * len(relpath.split('/'))
82
        else:
83
            segments = []
84
        rich_root = self._boolean_to_yes_no(repository.supports_rich_root())
85
        tree_ref = self._boolean_to_yes_no(
86
            repository._format.supports_tree_reference)
87
        external_lookup = self._boolean_to_yes_no(
88
            repository._format.supports_external_lookups)
89
        return '/'.join(segments), rich_root, tree_ref, external_lookup
90
91
92
class SmartServerRequestFindRepositoryV1(SmartServerRequestFindRepository):
93
94
    def do(self, path):
95
        """try to find a repository from path upwards
96
        
97
        This operates precisely like 'bzrdir.find_repository'.
98
        
99
        If a bzrdir is not present, an exception is propogated
100
        rather than 'no branch' because these are different conditions.
101
102
        This is the initial version of this method introduced with the smart
103
        server. Modern clients will try the V2 method that adds support for the
104
        supports_external_lookups attribute.
105
106
        :return: norepository or ok, relpath.
107
        """
108
        try:
109
            path, rich_root, tree_ref, external_lookup = self._find(path)
110
            return SuccessfulSmartServerResponse(('ok', path, rich_root, tree_ref))
111
        except errors.NoRepositoryPresent:
112
            return FailedSmartServerResponse(('norepository', ))
113
114
115
class SmartServerRequestFindRepositoryV2(SmartServerRequestFindRepository):
116
117
    def do(self, path):
118
        """try to find a repository from path upwards
119
        
120
        This operates precisely like 'bzrdir.find_repository'.
121
        
122
        If a bzrdir is not present, an exception is propogated
123
        rather than 'no branch' because these are different conditions.
124
3221.3.3 by Robert Collins
* Hook up the new remote method ``RemoteBzrDir.find_repositoryV2`` so
125
        This is the second edition of this method introduced in bzr 1.3, which
3221.3.2 by Robert Collins
* New remote method ``RemoteBzrDir.find_repositoryV2`` adding support for
126
        returns information about the supports_external_lookups format
127
        attribute too.
128
129
        :return: norepository or ok, relpath.
130
        """
131
        try:
132
            path, rich_root, tree_ref, external_lookup = self._find(path)
133
            return SuccessfulSmartServerResponse(
134
                ('ok', path, rich_root, tree_ref, external_lookup))
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
135
        except errors.NoRepositoryPresent:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
136
            return FailedSmartServerResponse(('norepository', ))
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
137
138
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
139
class SmartServerRequestInitializeBzrDir(SmartServerRequest):
140
141
    def do(self, path):
142
        """Initialize a bzrdir at path.
143
144
        The default format of the server is used.
145
        :return: SmartServerResponse(('ok', ))
146
        """
2692.1.1 by Andrew Bennetts
Add translate_client_path method to SmartServerRequest.
147
        target_transport = self.transport_from_client_path(path)
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
148
        BzrDirFormat.get_default_format().initialize_on_transport(target_transport)
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
149
        return SuccessfulSmartServerResponse(('ok', ))
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
150
151
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
152
class SmartServerRequestOpenBranch(SmartServerRequest):
153
154
    def do(self, path):
155
        """try to open a branch at path and return ok/nobranch.
156
        
157
        If a bzrdir is not present, an exception is propogated
158
        rather than 'no branch' because these are different conditions.
159
        """
2692.1.6 by Andrew Bennetts
Fix some >80 columns violations.
160
        bzrdir = BzrDir.open_from_transport(
161
            self.transport_from_client_path(path))
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
162
        try:
163
            reference_url = bzrdir.get_branch_reference()
164
            if reference_url is None:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
165
                return SuccessfulSmartServerResponse(('ok', ''))
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
166
            else:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
167
                return SuccessfulSmartServerResponse(('ok', reference_url))
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
168
        except errors.NotBranchError:
2432.4.5 by Robert Collins
Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic.
169
            return FailedSmartServerResponse(('nobranch', ))