Merge lp:~beuno/loggerhead/export-tarball into lp:loggerhead

Proposed by Martin Albisetti
Status: Rejected
Rejected by: Robert Collins
Proposed branch: lp:~beuno/loggerhead/export-tarball
Merge into: lp:loggerhead
Diff against target: 205 lines (+56/-6)
8 files modified
.bzrignore (+1/-0)
loggerhead/apps/branch.py (+9/-3)
loggerhead/config.py (+3/-0)
loggerhead/controllers/__init__.py (+3/-1)
loggerhead/controllers/download_ui.py (+27/-0)
loggerhead/controllers/revision_ui.py (+2/-1)
loggerhead/history.py (+7/-0)
loggerhead/templates/revision.pt (+4/-1)
To merge this branch: bzr merge lp:~beuno/loggerhead/export-tarball
Reviewer Review Type Date Requested Status
xaav (community) Needs Information
Robert Collins Needs Fixing
Review via email: mp+52797@code.launchpad.net

Description of the change

This adds some basic support for exporting tarballs of revisions.
It also allows excluding this feature by running BranchWSGIApp with allow_tarballs=False.

There are 2 more things I can think to add to this, but I've decided to defer that work after this lands:
- Allow specifying the cache dir
- Allow specifying zip or tarballs

To post a comment you must log in.
lp:~beuno/loggerhead/export-tarball updated
432. By Martin Albisetti

Allow conditionally exporting tarballs, now with 300% less cruft.

Revision history for this message
Robert Collins (lifeless) wrote :

Cache directory seems like a bad idea to me - will create stuff we have to clean up, and either the tarball is cheap enough to make that its ok to do it live (at all), or its too expensive and shouldn't be enabled on a given server.

review: Needs Fixing
Revision history for this message
xaav (xaav) wrote :

@beuno How is this coming along?

review: Needs Information
Revision history for this message
Martin Albisetti (beuno) wrote :

I need to re-work this patch. Proper support for this has landed in bzrlib, so now I need to make use of that, and also make sure we either have a fall-back for older versions (unlikely, lots of work and hackish) or only display the option if it's supported.
Hope to get back to this after the Natty release craze dies down.

Revision history for this message
xaav (xaav) wrote :

@beuno When (approximately) is this going to be ready?

Revision history for this message
xaav (xaav) wrote :
Revision history for this message
Robert Collins (lifeless) wrote :

I'd like us to stream it directly to the client.

Making the tarball even just in-memory, and then serving it adds the generation time to the overall delivery time: our load balancing software will timeout connections for non-trivial projects if we do it that way.

Revision history for this message
Martin Albisetti (beuno) wrote :
Revision history for this message
Robert Collins (lifeless) wrote :

I'm rejecting this branch - xaav's approach will work a lot better.

Revision history for this message
Robert Collins (lifeless) wrote :

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2010-04-22 08:52:59 +0000
3+++ .bzrignore 2011-03-10 03:57:10 +0000
4@@ -9,3 +9,4 @@
5 loggerhead-memprofile
6 ./docs/_build/
7 tags
8+loggerhead/static/downloads/*
9
10=== modified file 'loggerhead/apps/branch.py'
11--- loggerhead/apps/branch.py 2011-02-09 22:29:57 +0000
12+++ loggerhead/apps/branch.py 2011-03-10 03:57:10 +0000
13@@ -33,7 +33,7 @@
14 from loggerhead.controllers.atom_ui import AtomUI
15 from loggerhead.controllers.changelog_ui import ChangeLogUI
16 from loggerhead.controllers.diff_ui import DiffUI
17-from loggerhead.controllers.download_ui import DownloadUI
18+from loggerhead.controllers.download_ui import DownloadUI, DownloadTarballUI
19 from loggerhead.controllers.filediff_ui import FileDiffUI
20 from loggerhead.controllers.inventory_ui import InventoryUI
21 from loggerhead.controllers.revision_ui import RevisionUI
22@@ -49,7 +49,7 @@
23
24 def __init__(self, branch, friendly_name=None, config={},
25 graph_cache=None, branch_link=None, is_root=False,
26- served_url=_DEFAULT, use_cdn=False):
27+ served_url=_DEFAULT, use_cdn=False, export_tarballs=True):
28 self.branch = branch
29 self._config = config
30 self.friendly_name = friendly_name
31@@ -61,6 +61,7 @@
32 self.is_root = is_root
33 self.served_url = served_url
34 self.use_cdn = use_cdn
35+ self.export_tarballs = export_tarballs
36
37 def get_history(self):
38 file_cache = None
39@@ -126,6 +127,7 @@
40 'revision': RevisionUI,
41 'search': SearchUI,
42 'view': ViewUI,
43+ 'tarball': DownloadTarballUI,
44 }
45
46 def last_updated(self):
47@@ -171,10 +173,14 @@
48 try:
49 try:
50 c = cls(self, self.get_history)
51- return c(environ, start_response)
52+ to_ret = c(environ, start_response)
53 except:
54 environ['exc_info'] = sys.exc_info()
55 environ['branch'] = self
56 raise
57+ if type(to_ret) == type(httpexceptions.HTTPSeeOther('/')):
58+ raise to_ret
59+ else:
60+ return to_ret
61 finally:
62 self.branch.unlock()
63
64=== modified file 'loggerhead/config.py'
65--- loggerhead/config.py 2010-04-13 23:35:01 +0000
66+++ loggerhead/config.py 2011-03-10 03:57:10 +0000
67@@ -36,6 +36,7 @@
68 use_cdn=False,
69 sql_dir=None,
70 allow_writes=False,
71+ export_tarballs=True,
72 )
73 parser.add_option("--user-dirs", action="store_true",
74 help="Serve user directories as ~user.")
75@@ -69,6 +70,8 @@
76 help="The directory to place the SQL cache in")
77 parser.add_option("--allow-writes", action="store_true",
78 help="Allow writing to the Bazaar server.")
79+ parser.add_option("--export-tarballs", action="store_true",
80+ help="Allow exporting revisions to tarballs.")
81 return parser
82
83
84
85=== modified file 'loggerhead/controllers/__init__.py'
86--- loggerhead/controllers/__init__.py 2011-02-10 17:01:10 +0000
87+++ loggerhead/controllers/__init__.py 2011-03-10 03:57:10 +0000
88@@ -20,7 +20,7 @@
89 import bzrlib.errors
90 import time
91
92-from paste.httpexceptions import HTTPNotFound
93+from paste.httpexceptions import HTTPNotFound, HTTPSeeOther
94 from paste.request import path_info_pop, parse_querystring
95
96 from loggerhead import util
97@@ -93,6 +93,8 @@
98 headers = {}
99
100 vals.update(self.get_values(path, kwargs, headers))
101+ if 'download' in vals:
102+ return HTTPSeeOther(vals['download'])
103
104 self.log.info('Getting information for %s: %r secs' % (
105 self.__class__.__name__, time.time() - z))
106
107=== modified file 'loggerhead/controllers/download_ui.py'
108--- loggerhead/controllers/download_ui.py 2010-05-05 19:03:40 +0000
109+++ loggerhead/controllers/download_ui.py 2011-03-10 03:57:10 +0000
110@@ -19,6 +19,7 @@
111
112 import logging
113 import mimetypes
114+import os
115 import urllib
116
117 from paste import httpexceptions
118@@ -67,3 +68,29 @@
119 ]
120 start_response('200 OK', headers)
121 return [content]
122+
123+class DownloadTarballUI(TemplatedBranchView):
124+ """Download a revno as a tarball or zip file."""
125+ ext = 'tar.gz'
126+ dest = os.path.join(os.getcwd(), 'loggerhead/static/downloads/')
127+ download_dir = '/static/downloads/'
128+
129+ def get_values(self, path, kwargs, headers):
130+ """Return a URL to a tarball.
131+
132+ In the form of: /tarball/revno_or_revid."""
133+ history = self._history
134+ if len(self.args):
135+ revid = history.fix_revid(self.args[0])
136+ else:
137+ revid = self.get_revid()
138+ revno = history.get_revno(revid)
139+ filename = '%s_%s.%s' % (history._branch_nick, revno, self.ext)
140+ rpath = os.getcwd()+ '/loggerhead/static/downloads/' + filename
141+ if not os.path.exists(rpath):
142+ history.export(revid, rpath)
143+ if self._branch.export_tarballs:
144+ return {'download': '/static/downloads/' + filename}
145+ else:
146+ # redirect to the home page, the user is cheating :)
147+ return {'download': '/'}
148
149=== modified file 'loggerhead/controllers/revision_ui.py'
150--- loggerhead/controllers/revision_ui.py 2011-03-02 14:07:21 +0000
151+++ loggerhead/controllers/revision_ui.py 2011-03-10 03:57:10 +0000
152@@ -110,7 +110,7 @@
153 self._branch.friendly_name,
154 self._branch.is_root,
155 'changes'))
156-
157+ can_export = self._branch.export_tarballs
158 return {
159 'branch': self._branch,
160 'revid': revid,
161@@ -132,4 +132,5 @@
162 'compare_revid': compare_revid,
163 'url': self._branch.context_url,
164 'directory_breadcrumbs': directory_breadcrumbs,
165+ 'can_export': can_export,
166 }
167
168=== modified file 'loggerhead/history.py'
169--- loggerhead/history.py 2010-05-10 13:48:25 +0000
170+++ loggerhead/history.py 2011-03-10 03:57:10 +0000
171@@ -38,6 +38,7 @@
172 import bzrlib.branch
173 import bzrlib.delta
174 import bzrlib.errors
175+import bzrlib.export
176 import bzrlib.foreign
177 import bzrlib.revision
178
179@@ -760,3 +761,9 @@
180 removed=sorted(reporter.removed, key=lambda x: x.filename),
181 modified=sorted(reporter.modified, key=lambda x: x.filename),
182 text_changes=sorted(reporter.text_changes, key=lambda x: x.filename))
183+
184+ def export(self, revid, dest):
185+ """Export a tarball of a revision."""
186+ rev_tree = self._branch.repository.revision_tree(revid)
187+ bzrlib.export.export(rev_tree, dest)
188+ return dest
189
190=== added directory 'loggerhead/static/downloads'
191=== modified file 'loggerhead/templates/revision.pt'
192--- loggerhead/templates/revision.pt 2011-02-23 03:01:15 +0000
193+++ loggerhead/templates/revision.pt 2011-03-10 03:57:10 +0000
194@@ -84,7 +84,10 @@
195 tal:attributes="href python:url(['/diff', change.revno], clear=1)">download diff</a>
196 <a tal:condition="python:compare_revid is not None"
197 tal:attributes="href python:url(['/diff', change.revno, history.get_revno(compare_revid)], clear=1)">download diff</a>
198- </li>
199+ </li>
200+ <li tal:condition="python:can_export">
201+ <a tal:attributes="href python:url(['/tarball', change.revno])">download tarball</a>
202+ </li>
203 <li id="last"><a tal:attributes="href python:url(['/changes', change.revno]);
204 title string:view history from revision ${change/revno}"
205 tal:content="string:view history from revision ${change/revno}"></a></li>

Subscribers

People subscribed via source and target branches