17
17
"""Server-side repository related request implmentations."""
20
23
from bzrlib import errors
21
24
from bzrlib.bzrdir import BzrDir
22
25
from bzrlib.smart.request import SmartServerRequest, SmartServerResponse
26
from bzrlib.transport.local import LocalTransport
25
29
class SmartServerRepositoryRequest(SmartServerRequest):
173
177
repository.unlock()
174
178
return SmartServerResponse(('ok',))
181
class SmartServerRepositoryTarball(SmartServerRepositoryRequest):
182
"""Get the raw repository files as a tarball.
184
The returned tarball contains a .bzr control directory which in turn
185
contains a repository.
187
This takes one parameter, compression, which currently must be
190
This is used to implement the Repository.copy_content_into operation.
193
def do_repository_request(self, repository, compression):
194
from bzrlib import osutils
195
repo_transport = repository.control_files._transport
196
tmp_dirname, tmp_repo = self._copy_to_tempdir(repository)
198
controldir_name = tmp_dirname + '/.bzr'
199
return self._tarfile_response(controldir_name, compression)
201
osutils.rmtree(tmp_dirname)
203
def _copy_to_tempdir(self, from_repo):
204
tmp_dirname = tempfile.mkdtemp(prefix='tmpbzrclone')
205
tmp_bzrdir = from_repo.bzrdir._format.initialize(tmp_dirname)
206
tmp_repo = from_repo._format.initialize(tmp_bzrdir)
207
from_repo.copy_content_into(tmp_repo)
208
return tmp_dirname, tmp_repo
210
def _tarfile_response(self, tmp_dirname, compression):
211
temp = tempfile.NamedTemporaryFile()
213
self._tarball_of_dir(tmp_dirname, compression, temp.name)
214
# all finished; write the tempfile out to the network
216
return SmartServerResponse(('ok',), temp.read())
217
# FIXME: Don't read the whole thing into memory here; rather stream it
218
# out from the file onto the network. mbp 20070411
222
def _tarball_of_dir(self, dirname, compression, tarfile_name):
223
tarball = tarfile.open(tarfile_name, mode='w:' + compression)
225
# The tarball module only accepts ascii names, and (i guess)
226
# packs them with their 8bit names. We know all the files
227
# within the repository have ASCII names so the should be safe
229
dirname = dirname.encode(sys.getfilesystemencoding())
230
# python's tarball module includes the whole path by default so
232
assert dirname.endswith('.bzr')
233
tarball.add(dirname, '.bzr') # recursive by default