Merge lp:~gary/charms/precise/juju-gui/bug1218888 into lp:~juju-gui/charms/precise/juju-gui/trunk

Proposed by Gary Poster
Status: Merged
Merged at revision: 117
Proposed branch: lp:~gary/charms/precise/juju-gui/bug1218888
Merge into: lp:~juju-gui/charms/precise/juju-gui/trunk
Diff against target: 209 lines (+82/-37)
2 files modified
hooks/utils.py (+7/-3)
tests/test_utils.py (+75/-34)
To merge this branch: bzr merge lp:~gary/charms/precise/juju-gui/bug1218888
Reviewer Review Type Date Requested Status
charmers Pending
Review via email: mp+190971@code.launchpad.net

Description of the change

Add support for xz compression

An xz tarball reduces the size of the gui code by 30 to 40 percent. These changes let the charm use xz tarballs. A very simple change to the gui makefile will follow.

To qa, apply this diff to the gui trunk:

=== modified file 'Makefile'
--- Makefile 2013-10-12 01:30:26 +0000
+++ Makefile 2013-10-14 13:43:10 +0000
@@ -95,7 +95,7 @@
 LAUNCHPAD_API_ROOT=staging
 endif
 RELEASE_NAME=juju-gui-$(RELEASE_VERSION)
-RELEASE_FILE=releases/$(RELEASE_NAME).tgz
+RELEASE_FILE=releases/$(RELEASE_NAME).xz
 RELEASE_SIGNATURE=releases/$(RELEASE_NAME).asc
 NPM_CACHE_VERSION=$(BZR_REVNO)
 NPM_CACHE_FILE=$(CURDIR)/releases/npm-cache-$(NPM_CACHE_VERSION).tgz

Then run ``BRANCH_IS_GOOD=1 make distfile``. Copy over the new release to the charm's releases directory. If you compare the two file sizes in the charm's releases directory, the difference should be dramatic.

$ ls -l
-rw-r--r-- 1 gary gary 5076088 Oct 14 09:44 juju-gui-0.10.1+build.1133.xz
-rw-r--r-- 1 gary gary 44840221 Oct 12 20:15 juju-gui-0.10.1.tgz

You can remove the tgz, and then run juju bootstrap and make deploy in the charm root directory. Once it is deployed, you should be able to log in and see the gui as usual, and you should be able to verify the fact that you are using your custom release if you go to /juju-ui/version.js, where you will see something like "var jujuGuiVersionInfo=['unreleased', '1133'];".

Thank you!

https://codereview.appspot.com/14425057/

To post a comment you must log in.
Revision history for this message
Gary Poster (gary) wrote :

Reviewers: mp+190971_code.launchpad.net,

Message:
Please take a look.

Description:
Add support for xz compression

An xz tarball reduces the size of the gui code by 30 to 40 percent.
These changes let the charm use xz tarballs. A very simple change to
the gui makefile will follow.

To qa, apply this diff to the gui trunk:

=== modified file 'Makefile'
--- Makefile 2013-10-12 01:30:26 +0000
+++ Makefile 2013-10-14 13:43:10 +0000
@@ -95,7 +95,7 @@
  LAUNCHPAD_API_ROOT=staging
  endif
  RELEASE_NAME=juju-gui-$(RELEASE_VERSION)
-RELEASE_FILE=releases/$(RELEASE_NAME).tgz
+RELEASE_FILE=releases/$(RELEASE_NAME).xz
  RELEASE_SIGNATURE=releases/$(RELEASE_NAME).asc
  NPM_CACHE_VERSION=$(BZR_REVNO)
  NPM_CACHE_FILE=$(CURDIR)/releases/npm-cache-$(NPM_CACHE_VERSION).tgz

Then run ``BRANCH_IS_GOOD=1 make distfile``. Copy over the new release
to the charm's releases directory. If you compare the two file sizes in
the charm's releases directory, the difference should be dramatic.

$ ls -l
-rw-r--r-- 1 gary gary 5076088 Oct 14 09:44
juju-gui-0.10.1+build.1133.xz
-rw-r--r-- 1 gary gary 44840221 Oct 12 20:15 juju-gui-0.10.1.tgz

You can remove the tgz, and then run juju bootstrap and make deploy in
the charm root directory. Once it is deployed, you should be able to
log in and see the gui as usual, and you should be able to verify the
fact that you are using your custom release if you go to
/juju-ui/version.js, where you will see something like "var
jujuGuiVersionInfo=['unreleased', '1133'];".

Thank you!

https://code.launchpad.net/~gary/charms/precise/juju-gui/bug1218888/+merge/190971

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/14425057/

Affected files (+84, -37 lines):
   A [revision details]
   M hooks/utils.py
   M tests/test_utils.py

Revision history for this message
Brad Crittenden (bac) wrote :
Revision history for this message
Gary Poster (gary) wrote :

*** Submitted:

Add support for xz compression

An xz tarball reduces the size of the gui code by 30 to 40 percent.
These changes let the charm use xz tarballs. A very simple change to
the gui makefile will follow.

To qa, apply this diff to the gui trunk:

=== modified file 'Makefile'
--- Makefile 2013-10-12 01:30:26 +0000
+++ Makefile 2013-10-14 13:43:10 +0000
@@ -95,7 +95,7 @@
  LAUNCHPAD_API_ROOT=staging
  endif
  RELEASE_NAME=juju-gui-$(RELEASE_VERSION)
-RELEASE_FILE=releases/$(RELEASE_NAME).tgz
+RELEASE_FILE=releases/$(RELEASE_NAME).xz
  RELEASE_SIGNATURE=releases/$(RELEASE_NAME).asc
  NPM_CACHE_VERSION=$(BZR_REVNO)
  NPM_CACHE_FILE=$(CURDIR)/releases/npm-cache-$(NPM_CACHE_VERSION).tgz

Then run ``BRANCH_IS_GOOD=1 make distfile``. Copy over the new release
to the charm's releases directory. If you compare the two file sizes in
the charm's releases directory, the difference should be dramatic.

$ ls -l
-rw-r--r-- 1 gary gary 5076088 Oct 14 09:44
juju-gui-0.10.1+build.1133.xz
-rw-r--r-- 1 gary gary 44840221 Oct 12 20:15 juju-gui-0.10.1.tgz

You can remove the tgz, and then run juju bootstrap and make deploy in
the charm root directory. Once it is deployed, you should be able to
log in and see the gui as usual, and you should be able to verify the
fact that you are using your custom release if you go to
/juju-ui/version.js, where you will see something like "var
jujuGuiVersionInfo=['unreleased', '1133'];".

Thank you!

R=bac
CC=
https://codereview.appspot.com/14425057

https://codereview.appspot.com/14425057/

Revision history for this message
Gary Poster (gary) wrote :

Thank you very much, Brad.

https://codereview.appspot.com/14425057/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'hooks/utils.py'
2--- hooks/utils.py 2013-10-09 08:56:20 +0000
3+++ hooks/utils.py 2013-10-14 14:26:39 +0000
4@@ -163,7 +163,7 @@
5 \d+\.\d+\.\d+ # Major, minor, and patch version numbers.
6 (?:\+build\.\d+)? # Optional bzr revno for development releases.
7 )
8- \.tgz # File extension.
9+ \.(?:tgz|xz) # File extension.
10 """, re.VERBOSE)
11
12 results_log = None
13@@ -237,7 +237,7 @@
14 for release in releases:
15 for file_ in release.files:
16 file_url = str(file_)
17- if file_url.endswith('.tgz'):
18+ if file_url.endswith('.tgz') or file_url.endswith('.xz'):
19 filename = os.path.split(urlparse.urlsplit(file_url).path)[1]
20 return file_.file_link, filename
21 raise ValueError('%r: file not found' % release_version)
22@@ -706,7 +706,11 @@
23 """
24 log('Retrieving Juju GUI release.')
25 if origin == 'url':
26- return download_release(version, 'url-release.tgz')
27+ # "version" is a url.
28+ _, _, extension = version.rpartition('.')
29+ if extension not in ('tgz', 'xz'):
30+ extension = 'xz'
31+ return download_release(version, 'url-release.' + extension)
32 if origin == 'local':
33 path = get_release_file_path()
34 log('Using a local release: {}'.format(path))
35
36=== modified file 'tests/test_utils.py'
37--- tests/test_utils.py 2013-10-09 08:56:20 +0000
38+++ tests/test_utils.py 2013-10-14 14:26:39 +0000
39@@ -119,24 +119,26 @@
40 @mock.patch('utils.log', mock.Mock())
41 class TestFetchGuiRelease(unittest.TestCase):
42
43- release_path = '/my/release.tgz'
44+ sources = tuple(
45+ {'filename': 'release.' + extension,
46+ 'release_path': '/my/release.' + extension}
47+ for extension in ('tgz', 'xz'))
48
49 @contextmanager
50- def patch_launchpad(self, origin, version):
51+ def patch_launchpad(self, origin, version, source):
52 """Mock the functions used to download a release from Launchpad.
53
54 Ensure all the functions are called correctly.
55 """
56- url = 'http://launchpad.example.com/release.tgz/file'
57- filename = 'release.tgz'
58+ url = 'http://launchpad.example.com/' + source['filename'] + '/file'
59 patch_launchpad = mock.patch('utils.Launchpad')
60 patch_get_launchpad_release = mock.patch(
61 'utils.get_launchpad_release',
62- mock.Mock(return_value=(url, filename)),
63+ mock.Mock(return_value=(url, source['filename'])),
64 )
65 patch_download_release = mock.patch(
66 'utils.download_release',
67- mock.Mock(return_value=self.release_path),
68+ mock.Mock(return_value=source['release_path']),
69 )
70 with patch_launchpad as mock_launchpad:
71 with patch_get_launchpad_release as mock_get_launchpad_release:
72@@ -146,57 +148,68 @@
73 login.assert_called_once_with('Juju GUI charm', 'production')
74 mock_get_launchpad_release.assert_called_once_with(
75 login().projects['juju-gui'], origin, version)
76- mock_download_release.assert_called_once_with(url, filename)
77+ mock_download_release.assert_called_once_with(url, source['filename'])
78
79 @mock.patch('utils.download_release')
80 def test_url(self, mock_download_release):
81 # The release is retrieved from an URL.
82- mock_download_release.return_value = self.release_path
83- url = 'http://download.example.com/release.tgz'
84- path = fetch_gui_release('url', url)
85- self.assertEqual(self.release_path, path)
86- mock_download_release.assert_called_once_with(url, 'url-release.tgz')
87+ for source in self.sources:
88+ mock_download_release.return_value = source['release_path']
89+ url = 'http://download.example.com/' + source['filename']
90+ path = fetch_gui_release('url', url)
91+ self.assertEqual(source['release_path'], path)
92+ mock_download_release.assert_called_once_with(
93+ url, 'url-' + source['filename'])
94+ mock_download_release.reset_mock()
95
96 @mock.patch('utils.get_release_file_path')
97 def test_local(self, mock_get_release_file_path):
98 # The last local release is requested.
99- mock_get_release_file_path.return_value = self.release_path
100- path = fetch_gui_release('local', None)
101- self.assertEqual(self.release_path, path)
102- mock_get_release_file_path.assert_called_once_with()
103+ for source in self.sources:
104+ mock_get_release_file_path.return_value = source['release_path']
105+ path = fetch_gui_release('local', None)
106+ self.assertEqual(source['release_path'], path)
107+ mock_get_release_file_path.assert_called_once_with()
108+ mock_get_release_file_path.reset_mock()
109
110 @mock.patch('utils.get_release_file_path')
111 def test_version_found(self, mock_get_release_file_path):
112 # A release version is specified and found locally.
113- mock_get_release_file_path.return_value = self.release_path
114- path = fetch_gui_release('stable', '0.1.42')
115- self.assertEqual(self.release_path, path)
116- mock_get_release_file_path.assert_called_once_with('0.1.42')
117+ for source in self.sources:
118+ mock_get_release_file_path.return_value = source['release_path']
119+ path = fetch_gui_release('stable', '0.1.42')
120+ self.assertEqual(source['release_path'], path)
121+ mock_get_release_file_path.assert_called_once_with('0.1.42')
122+ mock_get_release_file_path.reset_mock()
123
124 @mock.patch('utils.get_release_file_path')
125 def test_version_not_found(self, mock_get_release_file_path):
126- # A release version is specified but not found locally.
127- mock_get_release_file_path.return_value = None
128- with self.patch_launchpad('stable', '0.1.42'):
129- path = fetch_gui_release('stable', '0.1.42')
130- self.assertEqual(self.release_path, path)
131- mock_get_release_file_path.assert_called_once_with('0.1.42')
132+ # A release version is specified but not found locally.
133+ for source in self.sources:
134+ mock_get_release_file_path.return_value = None
135+ with self.patch_launchpad('stable', '0.1.42', source):
136+ path = fetch_gui_release('stable', '0.1.42')
137+ self.assertEqual(source['release_path'], path)
138+ mock_get_release_file_path.assert_called_once_with('0.1.42')
139+ mock_get_release_file_path.reset_mock()
140
141 @mock.patch('utils.get_release_file_path')
142 def test_stable(self, mock_get_release_file_path):
143 # The last stable release is requested.
144- with self.patch_launchpad('stable', None):
145- path = fetch_gui_release('stable', None)
146- self.assertEqual(self.release_path, path)
147- self.assertFalse(mock_get_release_file_path.called)
148+ for source in self.sources:
149+ with self.patch_launchpad('stable', None, source):
150+ path = fetch_gui_release('stable', None)
151+ self.assertEqual(source['release_path'], path)
152+ self.assertFalse(mock_get_release_file_path.called)
153
154 @mock.patch('utils.get_release_file_path')
155 def test_trunk(self, mock_get_release_file_path):
156 # The last development release is requested.
157- with self.patch_launchpad('trunk', None):
158- path = fetch_gui_release('trunk', None)
159- self.assertEqual(self.release_path, path)
160- self.assertFalse(mock_get_release_file_path.called)
161+ for source in self.sources:
162+ with self.patch_launchpad('trunk', None, source):
163+ path = fetch_gui_release('trunk', None)
164+ self.assertEqual(source['release_path'], path)
165+ self.assertFalse(mock_get_release_file_path.called)
166
167
168 class TestFirstPathInDir(unittest.TestCase):
169@@ -330,6 +343,16 @@
170 path = get_release_file_path()
171 self.assert_path('juju-gui-2.0.1.tgz', path)
172
173+ def test_xz(self):
174+ # The last release is correctly retrieved for xz files too.
175+ self.add('juju-gui-0.12.1.tgz')
176+ self.add('juju-gui-1.2.3.tgz')
177+ self.add('juju-gui-2.0.0+build.42.tgz')
178+ self.add('juju-gui-2.0.1.xz')
179+ with self.mock_releases_dir():
180+ path = get_release_file_path()
181+ self.assert_path('juju-gui-2.0.1.xz', path)
182+
183 def test_ordering(self):
184 # Release versions are correctly ordered.
185 self.add('juju-gui-0.12.1.tgz')
186@@ -591,6 +614,24 @@
187 self.assertEqual('http://example.com/0.1.0.tgz', url)
188 self.assertEqual('0.1.0.tgz', name)
189
190+ def test_xz_files_are_found(self):
191+ project = AttrDict(
192+ series=[
193+ AttrDict(
194+ name='stable',
195+ releases=[
196+ AttrDict(
197+ version='0.1.0',
198+ files=[FileStub('http://example.com/0.1.0.xz')],
199+ ),
200+ ],
201+ ),
202+ ],
203+ )
204+ url, name = get_launchpad_release(project, 'stable', None)
205+ self.assertEqual('http://example.com/0.1.0.xz', url)
206+ self.assertEqual('0.1.0.xz', name)
207+
208
209 class TestGetZookeeperAddress(unittest.TestCase):
210

Subscribers

People subscribed via source and target branches

to all changes: