Merge lp:~rharding/charms/precise/juju-gui/git-ify into lp:~juju-gui/charms/precise/juju-gui/trunk
- Precise Pangolin (12.04)
- git-ify
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 149 |
Proposed branch: | lp:~rharding/charms/precise/juju-gui/git-ify |
Merge into: | lp:~juju-gui/charms/precise/juju-gui/trunk |
Diff against target: |
704 lines (+151/-265) 13 files modified
Makefile (+1/-1) README.md (+4/-13) config.yaml (+17/-18) hooks/backend.py (+11/-1) hooks/install (+4/-2) hooks/utils.py (+80/-40) server/guiserver/auth.py (+2/-62) server/guiserver/tests/helpers.py (+0/-38) server/guiserver/tests/test_auth.py (+0/-35) tests/20-functional.test (+3/-2) tests/deploy.py (+5/-2) tests/test_deploy.py (+0/-4) tests/test_utils.py (+24/-47) |
To merge this branch: | bzr merge lp:~rharding/charms/precise/juju-gui/git-ify |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Marco Ceppi (community) | Abstain | ||
Juju GUI Hackers | Pending | ||
Review via email: mp+201442@code.launchpad.net |
Commit message
Description of the change
Change juju-gui-source to be git-enabled.
- Allow pulling from various repo urls
- Support checking out a branch name
- Support checkout out a direct sha
- Remove support for the trunk releases.
The list of what you can check out is simplified a bit. You can easily use the
git access, url, or a local file in the releases directory to enable loading
the gui with any combination of code you would like to use.
Drive by removing some left over bits of the PyJuju branch previously.
QA:
juju boostrap
make deploy
# make sure the gui is running off the latest release. You can check the
# local equivelent of https:/
Run the follow config changes and after each make sure that the version is
correct for what you've requested. You can get the sha values from looking in
Github.
https:/
# The develop support
juju set juju-gui juju-gui-
# Supports the HEAD of a branch specified.
juju set juju-gui juju-gui-source="https:/
# Supports an older commit in the main develop line.
juju set juju-gui juju-gui-source="https:/
Richard Harding (rharding) wrote : | # |
Richard Harding (rharding) wrote : | # |
Added reviewer comments
https:/
File README.md (left):
https:/
README.md:127: 3. Retry as described in the step 3 above (`juju resolved
--retry juju-gui/0`).
missed pyjuju cleanup.
https:/
File README.md (right):
https:/
README.md:92: to build the source used by the charm.
this is just to reduce the duplication of what's supported. It
generalizes it a bit to read nicer.
https:/
File config.yaml (left):
https:/
config.yaml:24: - 'trunk': The latest release from the "trunk" series
will be deployed.
this was proven to not be used and there's so many other ways to load a
specific release now it's deemed redundant.
https:/
config.yaml:39: - a "url:" prefixed url: The release found at the given
URL
file:// is gone for the same reason. You can stick that file at a url,
you can put it in the releases folder, you can just point at the branch
for that file.
https:/
File hooks/backend.py (right):
https:/
hooks/backend.
develop is just a shortcut for the branch so it's moved up here.
https:/
hooks/backend.
revision))
added some logging helpers to make sure things were doing the right
thing in QA.
https:/
File hooks/install (right):
https:/
hooks/install:32: 'libapt-pkg-dev', 'python-apt', 'python-
'python-tempita',
I hit this dep on trusty to build.
https:/
File hooks/utils.py (right):
https:/
hooks/utils.py:124: git_checkout = command('git', 'clone', '--depth',
'1')
this is the equivelent shallow clone. Note, to do a revision checkout we
'undo' this later on.
https:/
hooks/utils.py:276: log('Source is defaulting to stable release.')
since this is a 'all else fails' log it to note it got hit.
https:/
hooks/utils.py:568: cmd_log(
to do anything else we have to have a checkout. So we always checkout
the develop branch and then move on from there if a different branch or
commit was specified.
https:/
hooks/utils.py:572: git_dir = juju_gui_source_dir + "/.git"
our cwd isn't the source dir so we have to prefix the git commands with
--git-dir and --wor...
Marco Ceppi (marcoceppi) wrote : | # |
Deferring to ~juju-gui
- 155. By Richard Harding
-
Update functional tests to test a git branch
- 156. By Richard Harding
-
Update deploy to ignore .git as well
Richard Harding (rharding) wrote : | # |
Please take a look.
Brad Crittenden (bac) wrote : | # |
LGTM mit changes.
QA-A-OK
https:/
File config.yaml (right):
https:/
config.yaml:3: # Copyright (C) 2012-2013 Canonical Ltd.
update for all files you touch.</pita>
https:/
File hooks/install (right):
https:/
hooks/install:32: 'libapt-pkg-dev', 'python-apt', 'python-
'python-tempita',
thanks for being out front. i should upgrade to trusty soon.
https:/
File hooks/utils.py (right):
https:/
hooks/utils.py:123: # Bazaar checkout command.
s/Bazaar c/C/
https:/
hooks/utils.py:124: git_checkout = command('git', 'clone', '--depth',
'1')
I'd promote this review comment to a code comment. Would be useful.
https:/
File tests/test_utils.py (right):
https:/
tests/test_
If you aren't going to use the mock, and there may be more, I find using
*args to be appropriate.
https:/
tests/test_
including revision.
s/Bazaar/git/
You may want to grep the whole tree for Bazaar and bzr.
Richard Harding (rharding) wrote : | # |
Thanks for the review. Updated and re-running one final full functional
test run before landing.
- 157. By Richard Harding
-
update per review
- 158. By Richard Harding
-
Remove the master bit
- 159. By Richard Harding
-
Update test runs to take a bit to check out master
Preview Diff
1 | === modified file 'Makefile' |
2 | --- Makefile 2014-01-15 14:49:19 +0000 |
3 | +++ Makefile 2014-01-16 20:33:25 +0000 |
4 | @@ -14,7 +14,7 @@ |
5 | # You should have received a copy of the GNU Affero General Public License |
6 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
7 | |
8 | -JUJUTEST = yes | juju-test --timeout=40m -v -e "$(JUJU_ENV)" |
9 | +JUJUTEST = yes | juju-test --timeout=60m -v -e "$(JUJU_ENV)" |
10 | VENV = tests/.venv |
11 | SYSDEPS = build-essential bzr libapt-pkg-dev libpython-dev python-virtualenv \ |
12 | rsync xvfb |
13 | |
14 | === modified file 'README.md' |
15 | --- README.md 2014-01-14 23:57:37 +0000 |
16 | +++ README.md 2014-01-16 20:33:25 +0000 |
17 | @@ -85,16 +85,11 @@ |
18 | juju deploy juju-gui |
19 | |
20 | There are situations and customizations in which the charm needs to connect to |
21 | -Launchpad: |
22 | +the Internet: |
23 | |
24 | -- juju-gui-source is set to "stable" or "trunk": in this cases the charm pulls |
25 | - the latest stable or development release from Launchpad; |
26 | -- juju-gui-source is set to a branch (e.g. "lp:juju-gui"): in this case the |
27 | - charm retrieves a checkout of the specified branch from Launchpad, and adds |
28 | - an external Launchpad PPA to install build dependencies; |
29 | -- juju-gui-source is set to a specific version number not available in the |
30 | - local store (i.e. in the releases directory of the deployed charm): in this |
31 | - case the release is downloaded from Launchpad; |
32 | +- juju-gui-source is set to a configuration that requires accessing an |
33 | + external source in order to fetch a release tarball or a Git checkout in order |
34 | + to build the source used by the charm. |
35 | - builtin-server is set to false: in this case the charm adds an external |
36 | Launchpad PPA to install the legacy server dependencies. |
37 | |
38 | @@ -122,10 +117,6 @@ |
39 | |
40 | `juju resolved --retry juju-gui/0` |
41 | |
42 | -These steps are sufficient for Juju Core. |
43 | - |
44 | -3. Retry as described in the step 3 above (`juju resolved --retry juju-gui/0`). |
45 | - |
46 | ### Upgrading the charm behind a firewall ### |
47 | |
48 | When a new version of Juju GUI is released, the charm is updated to include the |
49 | |
50 | === modified file 'config.yaml' |
51 | --- config.yaml 2014-01-13 19:26:48 +0000 |
52 | +++ config.yaml 2014-01-16 20:33:25 +0000 |
53 | @@ -1,6 +1,6 @@ |
54 | # This file is part of the Juju GUI, which lets users view and manage Juju |
55 | # environments within a graphical interface (https://launchpad.net/juju-gui). |
56 | -# Copyright (C) 2012-2013 Canonical Ltd. |
57 | +# Copyright (C) 2012-2014 Canonical Ltd. |
58 | # |
59 | # This program is free software: you can redistribute it and/or modify it under |
60 | # the terms of the GNU Affero General Public License version 3, as published by |
61 | @@ -21,23 +21,22 @@ |
62 | - 'local' (default): The latest local release will be deployed. Releases |
63 | are stored in the releases directory of this charm. |
64 | - 'stable': The latest release from the "stable" series will be deployed. |
65 | - - 'trunk': The latest release from the "trunk" series will be deployed. |
66 | - Please note that this is not a build of the current Juju GUI trunk. |
67 | - For that functionality, use "lp:juju-gui", as described below. |
68 | - - a stable version (e.g '0.1.0'): The specified stable version will be |
69 | - deployed. A suitable release is looked up in the local releases |
70 | - repository (see the "local" choice above). If not found locally, the |
71 | - release will be downloaded from Launchpad. |
72 | - - a trunk version (e.g '0.1.0+build.1'): The specified trunk version |
73 | - will be deployed. A suitable release is looked up in the local releases |
74 | - repository (see the "local" choice above). If not found locally, the |
75 | - release will be downloaded from Launchpad. |
76 | - - a Bazaar branch (e.g. 'lp:juju-gui'): A release will be created and |
77 | - deployed from the specified Bazaar branch. "http://"" prefixed branches |
78 | - work as well. It is also possible to include the specific branch |
79 | - revision, e.g. "lp:juju-gui:42" will checkout revno 42. |
80 | - - a "url:" prefixed url: The release found at the given URL |
81 | - (ex: url:http://... or url:file://...) will be deployed. |
82 | + - 'develop': The latest, in development, version from the Git repository. |
83 | + - a specific release version (e.g '0.1.0' or '0.1.0+build.1'): The |
84 | + specified stable version will be deployed. A suitable release is |
85 | + looked up in the local releases repository (see the "local" choice |
86 | + above). If not found locally, the release will be downloaded from |
87 | + Launchpad. |
88 | + - a Git branch (e.g. 'https://github.com/juju/juju-gui.git' or |
89 | + 'https://github.com/mitechie/juju-gui.git updated-test-runner'): A |
90 | + release will be created and deployed from the specified Git |
91 | + repository. You can include a branch name or a specific commit SHA |
92 | + after the url to the Git repository to deploy that specific commit |
93 | + point. You may instead specify a commit SHA: (e.g. |
94 | + 'https://github.com/mitechie/juju-gui.git @de5e61bf9fa') which will |
95 | + clone the git repository and then check out the specified commit |
96 | + before building the release. |
97 | + - a URL: The release found at the given URL (ex: http://...) will be deployed. |
98 | type: string |
99 | default: local |
100 | juju-gui-debug: |
101 | |
102 | === modified file 'hooks/backend.py' |
103 | --- hooks/backend.py 2014-01-13 19:26:48 +0000 |
104 | +++ hooks/backend.py 2014-01-16 20:33:25 +0000 |
105 | @@ -91,7 +91,14 @@ |
106 | # Get a tarball somehow. |
107 | origin, version_or_branch = utils.parse_source( |
108 | backend.config['juju-gui-source']) |
109 | - if origin == 'branch': |
110 | + if origin in ('branch', 'develop'): |
111 | + # Develop is the latest passing build from Git. |
112 | + if origin == 'develop': |
113 | + version_or_branch = ( |
114 | + 'https://github.com/juju/juju-gui.git', |
115 | + None |
116 | + ) |
117 | + |
118 | logpath = backend.config['command-log-file'] |
119 | # Make sure we have the required build dependencies. |
120 | # Note that we also need to add the juju-gui repository |
121 | @@ -100,7 +107,10 @@ |
122 | utils.install_missing_packages( |
123 | utils.DEB_BUILD_DEPENDENCIES, |
124 | repository=backend.config['repository-location']) |
125 | + |
126 | branch_url, revision = version_or_branch |
127 | + log('Using source {}: {}'.format(branch_url, revision)) |
128 | + |
129 | release_tarball_path = utils.fetch_gui_from_branch( |
130 | branch_url, revision, logpath) |
131 | else: |
132 | |
133 | === modified file 'hooks/install' |
134 | --- hooks/install 2013-11-13 18:37:07 +0000 |
135 | +++ hooks/install 2014-01-16 20:33:25 +0000 |
136 | @@ -3,7 +3,7 @@ |
137 | |
138 | # This file is part of the Juju GUI, which lets users view and manage Juju |
139 | # environments within a graphical interface (https://launchpad.net/juju-gui). |
140 | -# Copyright (C) 2012-2013 Canonical Ltd. |
141 | +# Copyright (C) 2012-2014 Canonical Ltd. |
142 | # |
143 | # This program is free software: you can redistribute it and/or modify it under |
144 | # the terms of the GNU Affero General Public License version 3, as published by |
145 | @@ -29,7 +29,9 @@ |
146 | # Python dependencies must be installed here so that the charm can import and |
147 | # use required libraries. |
148 | PYTHON_DEPENDENCIES = ( |
149 | - 'python-apt', 'python-launchpadlib', 'python-tempita', 'python-yaml') |
150 | + 'libapt-pkg-dev', 'python-apt', 'python-launchpadlib', 'python-tempita', |
151 | + 'python-yaml' |
152 | +) |
153 | |
154 | run('juju-log', '--', 'Installing base Python dependencies: {}.'.format( |
155 | ', '.join(PYTHON_DEPENDENCIES))) |
156 | |
157 | === modified file 'hooks/utils.py' |
158 | --- hooks/utils.py 2014-01-15 12:03:24 +0000 |
159 | +++ hooks/utils.py 2014-01-16 20:33:25 +0000 |
160 | @@ -1,6 +1,6 @@ |
161 | # This file is part of the Juju GUI, which lets users view and manage Juju |
162 | # environments within a graphical interface (https://launchpad.net/juju-gui). |
163 | -# Copyright (C) 2012-2013 Canonical Ltd. |
164 | +# Copyright (C) 2012-2014 Canonical Ltd. |
165 | # |
166 | # This program is free software: you can redistribute it and/or modify it under |
167 | # the terms of the GNU Affero General Public License version 3, as published by |
168 | @@ -81,7 +81,6 @@ |
169 | from shelltoolbox import ( |
170 | apt_get_install, |
171 | command, |
172 | - environ, |
173 | install_extra_repositories, |
174 | run, |
175 | script_name, |
176 | @@ -115,21 +114,17 @@ |
177 | |
178 | JUJU_PEM = 'juju.includes-private-key.pem' |
179 | DEB_BUILD_DEPENDENCIES = ( |
180 | - 'bzr', 'g++', 'imagemagick', 'make', 'nodejs', 'npm', |
181 | + 'bzr', 'g++', 'git', 'imagemagick', 'make', 'nodejs', 'npm', |
182 | ) |
183 | |
184 | |
185 | # Store the configuration from on invocation to the next. |
186 | config_json = Serializer(os.path.join(os.path.sep, 'tmp', 'config.json')) |
187 | -# Bazaar checkout command. |
188 | -bzr_checkout = command('bzr', 'co', '--lightweight') |
189 | +# Git checkout command. |
190 | +# This is the equivalent shallow clone. Note, to do a revision checkout we |
191 | +# 'undo' this later on. |
192 | +git_checkout = command('git', 'clone', '--depth', '1') |
193 | |
194 | -bzr_url_expression = re.compile(r""" |
195 | - ^ # Beginning of line. |
196 | - ((?:lp:|http:\/\/)[^:]+) # Branch URL (scheme + domain/path). |
197 | - (?::(\d+))? # Optional branch revision. |
198 | - $ # End of line. |
199 | -""", re.VERBOSE) |
200 | release_expression = re.compile(r""" |
201 | juju-gui- # Juju GUI prefix. |
202 | ( |
203 | @@ -240,29 +235,47 @@ |
204 | Examples: |
205 | - ('local', None): latest local release; |
206 | - ('stable', None): latest stable release; |
207 | - - ('stable', '0.1.0'): stable release v0.1.0; |
208 | - - ('trunk', None): latest trunk release; |
209 | - - ('trunk', '0.1.0+build.1'): trunk release v0.1.0 bzr revision 1; |
210 | - - ('branch', ('lp:juju-gui', 42): release is made from a branch - |
211 | - in this case the second element includes the branch URL and revision; |
212 | - - ('branch', ('lp:juju-gui', None): no revision is specified; |
213 | - - ('url', 'http://example.com/gui'): release from a downloaded file. |
214 | + - ('develop', None): latest build from git trunk; |
215 | + - ('release', '0.1.0'): release v0.1.0; |
216 | + - ('branch', ('https://github.com/juju/juju-gui.git', 'add-feature'): |
217 | + release is made from a branch - |
218 | + in this case the second element includes the branch or SHA; |
219 | + - ('branch', ('https://github.com/juju/juju-gui.git', None): no |
220 | + revision is specified; |
221 | + - ('url', 'http://example.com/gui.tar.gz'): release from a downloaded |
222 | + file. |
223 | """ |
224 | - if source.startswith('url:'): |
225 | - source = source[4:] |
226 | - # Support file paths, including relative paths. |
227 | - if urlparse.urlparse(source).scheme == '': |
228 | - if not source.startswith('/'): |
229 | - source = os.path.join(os.path.abspath(CURRENT_DIR), source) |
230 | - source = "file://%s" % source |
231 | + |
232 | + def is_url(url_check): |
233 | + if ' ' in url_check: |
234 | + url_check, _ = url_check.split(' ') |
235 | + |
236 | + if url_check.startswith('http') and not url_check.endswith('.git'): |
237 | + return True |
238 | + else: |
239 | + return False |
240 | + |
241 | + def is_branch(check_branch): |
242 | + target = None |
243 | + if ' ' in check_branch: |
244 | + check_branch, target = check_branch.split(' ') |
245 | + |
246 | + if check_branch.startswith('http') and check_branch.endswith('.git'): |
247 | + return (check_branch, target) |
248 | + else: |
249 | + return False |
250 | + |
251 | + if is_url(source): |
252 | return 'url', source |
253 | - if source in ('local', 'stable', 'trunk'): |
254 | + |
255 | + if source in ('local', 'stable', 'develop'): |
256 | return source, None |
257 | - match = bzr_url_expression.match(source) |
258 | - if match is not None: |
259 | - return 'branch', match.groups() |
260 | - if 'build' in source: |
261 | - return 'trunk', source |
262 | + |
263 | + check_branch = is_branch(source) |
264 | + if (check_branch): |
265 | + return ('branch', check_branch) |
266 | + |
267 | + log('Source is defaulting to stable release.') |
268 | return 'stable', source |
269 | |
270 | |
271 | @@ -545,22 +558,49 @@ |
272 | """Retrieve the Juju GUI from a branch and build a release archive.""" |
273 | # Inject NPM packages into the cache for faster building. |
274 | prime_npm_cache(get_npm_cache_archive_url()) |
275 | + |
276 | # Create a release starting from a branch. |
277 | juju_gui_source_dir = os.path.join(CURRENT_DIR, 'juju-gui-source') |
278 | - checkout_args, revno = ([], 'latest revno') if revision is None else ( |
279 | - ['--revision', revision], 'revno {}'.format(revision)) |
280 | + |
281 | log('Retrieving Juju GUI source checkout from {} ({}).'.format( |
282 | - branch_url, revno)) |
283 | + branch_url, revision)) |
284 | + |
285 | cmd_log(run('rm', '-rf', juju_gui_source_dir)) |
286 | - checkout_args.extend([branch_url, juju_gui_source_dir]) |
287 | - cmd_log(bzr_checkout(*checkout_args)) |
288 | + checkout_args = [branch_url, juju_gui_source_dir] |
289 | + cmd_log(git_checkout(*checkout_args)) |
290 | + |
291 | + # If there's a revision attempt to checkout that revision. |
292 | + if revision: |
293 | + git_dir = juju_gui_source_dir + "/.git" |
294 | + if revision.startswith('@'): |
295 | + revision = revision[1:] |
296 | + # We have to unshallow the checkout in order to be able to 'see' |
297 | + # older commit hashes to check them out. |
298 | + cmd_log(run( |
299 | + 'git', '--git-dir', git_dir, '--work-tree', |
300 | + juju_gui_source_dir, 'fetch', '--depth', '20000')) |
301 | + |
302 | + cmd_log(run( |
303 | + 'git', '--git-dir', git_dir, '--work-tree', |
304 | + juju_gui_source_dir, 'checkout', revision)) |
305 | + else: |
306 | + cmd_log(run( |
307 | + 'git', '--git-dir', git_dir, '--work-tree', |
308 | + juju_gui_source_dir, 'fetch', 'origin')) |
309 | + cmd_log(run( |
310 | + 'git', '--git-dir', git_dir, '--work-tree', |
311 | + juju_gui_source_dir, 'checkout', '-b', revision, |
312 | + 'origin/' + revision)) |
313 | + |
314 | log('Preparing a Juju GUI release.') |
315 | logdir = os.path.dirname(logpath) |
316 | + |
317 | fd, name = tempfile.mkstemp(prefix='make-distfile-', dir=logdir) |
318 | log('Output from "make distfile" sent to %s' % name) |
319 | - with environ(NO_BZR='1'): |
320 | - run('make', '-C', juju_gui_source_dir, 'distfile', |
321 | - stdout=fd, stderr=fd) |
322 | + |
323 | + run('make', '-C', juju_gui_source_dir, 'distfile', 'BRANCH_IS_GOOD=true', |
324 | + stdout=fd, stderr=fd) |
325 | + |
326 | return first_path_in_dir( |
327 | os.path.join(juju_gui_source_dir, 'releases')) |
328 | |
329 | @@ -623,7 +663,7 @@ |
330 | path = get_release_file_path() |
331 | log('Using a local release: {}'.format(path)) |
332 | return path |
333 | - # Handle "stable" and "trunk" origins. |
334 | + # Handle "stable" |
335 | if version is not None: |
336 | # If the user specified a version, before attempting to download the |
337 | # requested release from Launchpad, check if that version is already |
338 | |
339 | === modified file 'server/guiserver/auth.py' |
340 | --- server/guiserver/auth.py 2013-11-25 14:02:15 +0000 |
341 | +++ server/guiserver/auth.py 2014-01-16 20:33:25 +0000 |
342 | @@ -20,7 +20,7 @@ |
343 | |
344 | - User: this is a simple data structure representing a logged in or |
345 | anonymous user. |
346 | - - Authentication backends (GoBackend and PythonBackend): the primary |
347 | + - Authentication backends (GoBackend): the primary |
348 | purpose of auth backends is to provide the logic to parse requests' data |
349 | based on the API implementation currently in use. They can also be used |
350 | to create authentication requests. They must implement the following |
351 | @@ -212,69 +212,9 @@ |
352 | Params=dict(AuthTag=username, Password=password)) |
353 | |
354 | |
355 | -class PythonBackend(object): |
356 | - """Authentication backend for the Juju Python implementation. |
357 | - |
358 | - A login request looks like the following: |
359 | - |
360 | - { |
361 | - 'request_id': 42, |
362 | - 'op': 'login', |
363 | - 'user': 'admin', |
364 | - 'password': 'ADMIN-SECRET', |
365 | - } |
366 | - |
367 | - A successful login response includes these fields: |
368 | - |
369 | - { |
370 | - 'request_id': 42, |
371 | - 'op': 'login', |
372 | - 'user': 'admin', |
373 | - 'password': 'ADMIN-SECRET', |
374 | - 'result': True, |
375 | - } |
376 | - |
377 | - A login failure response is like the following: |
378 | - |
379 | - { |
380 | - 'request_id': 42, |
381 | - 'op': 'login', |
382 | - 'user': 'admin', |
383 | - 'password': 'ADMIN-SECRET', |
384 | - 'err': True, |
385 | - } |
386 | - """ |
387 | - |
388 | - def get_request_id(self, data): |
389 | - """Return the request identifier associated with the provided data.""" |
390 | - return data.get('request_id') |
391 | - |
392 | - def request_is_login(self, data): |
393 | - """Return True if data represents a login request, False otherwise.""" |
394 | - op = data.get('op') |
395 | - return (op == 'login') and ('user' in data) and ('password' in data) |
396 | - |
397 | - def get_credentials(self, data): |
398 | - """Parse the provided login data and return username and password.""" |
399 | - return data['user'], data['password'] |
400 | - |
401 | - def login_succeeded(self, data): |
402 | - """Return True if data represents a successful login, False otherwise. |
403 | - """ |
404 | - return data.get('result') and not data.get('err') |
405 | - |
406 | - def make_request(self, request_id, username, password): |
407 | - """Create and return an authentication request.""" |
408 | - return dict( |
409 | - request_id=request_id, |
410 | - op='login', |
411 | - user=username, |
412 | - password=password) |
413 | - |
414 | - |
415 | def get_backend(apiversion): |
416 | """Return the auth backend instance to use for the given API version.""" |
417 | - backend_class = {'go': GoBackend, 'python': PythonBackend}[apiversion] |
418 | + backend_class = {'go': GoBackend}[apiversion] |
419 | return backend_class() |
420 | |
421 | |
422 | |
423 | === modified file 'server/guiserver/tests/helpers.py' |
424 | --- server/guiserver/tests/helpers.py 2013-11-22 22:26:20 +0000 |
425 | +++ server/guiserver/tests/helpers.py 2014-01-16 20:33:25 +0000 |
426 | @@ -107,44 +107,6 @@ |
427 | Params={'Token': token}) |
428 | |
429 | |
430 | -class PythonAPITestMixin(object): |
431 | - """Add helper methods for testing the Python API implementation.""" |
432 | - |
433 | - def get_auth_backend(self): |
434 | - """Return an authentication backend suitable for the Python API.""" |
435 | - return auth.get_backend('python') |
436 | - |
437 | - def make_login_request( |
438 | - self, request_id=42, username='user', password='passwd', |
439 | - encoded=False): |
440 | - """Create and return a login request message. |
441 | - |
442 | - If encoded is set to True, the returned message will be JSON encoded. |
443 | - """ |
444 | - data = { |
445 | - 'request_id': request_id, |
446 | - 'op': 'login', |
447 | - 'user': username, |
448 | - 'password': password, |
449 | - } |
450 | - return json.dumps(data) if encoded else data |
451 | - |
452 | - def make_login_response( |
453 | - self, request_id=42, successful=True, encoded=False): |
454 | - """Create and return a login response message. |
455 | - |
456 | - If encoded is set to True, the returned message will be JSON encoded. |
457 | - By default, a successful response is returned. Set successful to False |
458 | - to return an authentication failure. |
459 | - """ |
460 | - data = {'request_id': request_id, 'op': 'login'} |
461 | - if successful: |
462 | - data['result'] = True |
463 | - else: |
464 | - data['err'] = True |
465 | - return json.dumps(data) if encoded else data |
466 | - |
467 | - |
468 | class BundlesTestMixin(object): |
469 | """Add helper methods for testing the GUI server bundles support.""" |
470 | |
471 | |
472 | === modified file 'server/guiserver/tests/test_auth.py' |
473 | --- server/guiserver/tests/test_auth.py 2013-11-28 16:43:00 +0000 |
474 | +++ server/guiserver/tests/test_auth.py 2014-01-16 20:33:25 +0000 |
475 | @@ -204,12 +204,6 @@ |
476 | self.assert_user('', '', False) |
477 | |
478 | |
479 | -class TestPythonAuthMiddleware( |
480 | - helpers.PythonAPITestMixin, AuthMiddlewareTestMixin, |
481 | - LogTrapTestCase, unittest.TestCase): |
482 | - pass |
483 | - |
484 | - |
485 | class BackendTestMixin(object): |
486 | """Include tests for the authentication backends. |
487 | |
488 | @@ -288,35 +282,6 @@ |
489 | self.assertFalse(is_login, request) |
490 | |
491 | |
492 | -class TestPythonBackend( |
493 | - helpers.PythonAPITestMixin, BackendTestMixin, unittest.TestCase): |
494 | - |
495 | - def test_request_is_not_login(self): |
496 | - # False is returned if the passed data is not a login request. |
497 | - requests = ( |
498 | - {}, |
499 | - { |
500 | - 'request_id': 42, |
501 | - 'op': 'INVALID', |
502 | - 'user': 'user', |
503 | - 'password': 'passwd', |
504 | - }, |
505 | - { |
506 | - 'request_id': 42, |
507 | - 'op': 'login', |
508 | - 'password': 'passwd', |
509 | - }, |
510 | - { |
511 | - 'request_id': 42, |
512 | - 'op': 'login', |
513 | - 'user': 'user', |
514 | - }, |
515 | - ) |
516 | - for request in requests: |
517 | - is_login = self.backend.request_is_login(request) |
518 | - self.assertFalse(is_login, request) |
519 | - |
520 | - |
521 | class TestAuthenticationTokenHandler(LogTrapTestCase, unittest.TestCase): |
522 | |
523 | def setUp(self): |
524 | |
525 | === modified file 'tests/20-functional.test' |
526 | --- tests/20-functional.test 2014-01-15 14:49:19 +0000 |
527 | +++ tests/20-functional.test 2014-01-16 20:33:25 +0000 |
528 | @@ -40,7 +40,8 @@ |
529 | ) |
530 | import example |
531 | |
532 | -JUJU_GUI_TEST_BRANCH = 'lp:~juju-gui/juju-gui/charm-tests-branch' |
533 | +JUJU_GUI_TEST_BRANCH = 'https://github.com/juju/juju-gui.git master' |
534 | + |
535 | try: |
536 | admin_secret = get_admin_secret() |
537 | except ValueError as err: |
538 | @@ -193,7 +194,7 @@ |
539 | self.assertTrue(server_info['sandbox']) |
540 | |
541 | def test_branch_source(self): |
542 | - # Ensure the Juju GUI is correctly deployed from a Bazaar branch. |
543 | + # Ensure the Juju GUI is correctly deployed from a Git branch. |
544 | options = {'juju-gui-source': JUJU_GUI_TEST_BRANCH} |
545 | self.service_name, unit_info, _ = juju_deploy_gui(options=options) |
546 | hostname = unit_info['public-address'] |
547 | |
548 | === modified file 'tests/deploy.py' |
549 | --- tests/deploy.py 2013-11-27 14:37:06 +0000 |
550 | +++ tests/deploy.py 2014-01-16 20:33:25 +0000 |
551 | @@ -33,14 +33,17 @@ |
552 | ) |
553 | |
554 | |
555 | -rsync = command('rsync', '-a', '--exclude', '.bzr', '--exclude', '/tests') |
556 | +rsync = command('rsync', '-a', |
557 | + '--exclude', '.git', |
558 | + '--exclude', '.bzr', |
559 | + '--exclude', '/tests') |
560 | |
561 | |
562 | def setup_repository(name, source, series='precise'): |
563 | """Create a temporary Juju repository to use for charm deployment. |
564 | |
565 | Copy the charm files in source in the precise repository section, using the |
566 | - provided charm name and excluding the virtualenv and Bazaar directories. |
567 | + provided charm name and excluding the virtualenv and Git directories. |
568 | |
569 | Return the repository path. |
570 | """ |
571 | |
572 | === modified file 'tests/test_deploy.py' |
573 | --- tests/test_deploy.py 2013-11-27 14:37:06 +0000 |
574 | +++ tests/test_deploy.py 2014-01-16 20:33:25 +0000 |
575 | @@ -51,10 +51,6 @@ |
576 | self.addCleanup(shutil.rmtree, self.source) |
577 | # Create a file in the source dir. |
578 | _, self.root_file = tempfile.mkstemp(dir=self.source) |
579 | - # Create a Bazaar repository directory with a file in it. |
580 | - bzr_dir = os.path.join(self.source, '.bzr') |
581 | - os.mkdir(bzr_dir) |
582 | - tempfile.mkstemp(dir=bzr_dir) |
583 | # Create a tests directory including a .venv directory and a file. |
584 | self.tests_dir = os.path.join(self.source, 'tests') |
585 | venv_dir = os.path.join(self.tests_dir, '.venv') |
586 | |
587 | === modified file 'tests/test_utils.py' |
588 | --- tests/test_utils.py 2014-01-15 12:03:24 +0000 |
589 | +++ tests/test_utils.py 2014-01-16 20:33:25 +0000 |
590 | @@ -1,6 +1,6 @@ |
591 | # This file is part of the Juju GUI, which lets users view and manage Juju |
592 | # environments within a graphical interface (https://launchpad.net/juju-gui). |
593 | -# Copyright (C) 2012-2013 Canonical Ltd. |
594 | +# Copyright (C) 2012-2014 Canonical Ltd. |
595 | # |
596 | # This program is free software: you can redistribute it and/or modify it under |
597 | # the terms of the GNU Affero General Public License version 3, as published by |
598 | @@ -368,7 +368,7 @@ |
599 | self.add('juju-gui-1.2.3.4.tgz') # Wrong version. |
600 | self.add('juju-gui-1.2.3.build.42.tgz') # Missing "+" separator. |
601 | self.add('juju-gui-1.2.3+built.42.tgz') # Typo. |
602 | - self.add('juju-gui-1.2.3+build.42.47.tgz') # Invalid bzr revno. |
603 | + self.add('juju-gui-1.2.3+build.42.47.tgz') # Invalid revno. |
604 | self.add('juju-gui-1.2.3+build.42.bz2') # Wrong file extension again. |
605 | with self.mock_releases_dir(): |
606 | with self.assert_error(): |
607 | @@ -507,12 +507,6 @@ |
608 | self.assertEqual('http://example.com/0.1.1.tgz', url) |
609 | self.assertEqual('0.1.1.tgz', name) |
610 | |
611 | - def test_latest_trunk_release(self): |
612 | - # Ensure the correct URL is returned for the latest trunk release. |
613 | - url, name = get_launchpad_release(self.project, 'trunk', None) |
614 | - self.assertEqual('http://example.com/0.1.1+build.1.tgz', url) |
615 | - self.assertEqual('0.1.1+build.1.tgz', name) |
616 | - |
617 | def test_specific_stable_release(self): |
618 | # Ensure the correct URL is returned for a specific version of the |
619 | # stable release. |
620 | @@ -520,14 +514,6 @@ |
621 | self.assertEqual('http://example.com/0.1.0.tgz', url) |
622 | self.assertEqual('0.1.0.tgz', name) |
623 | |
624 | - def test_specific_trunk_release(self): |
625 | - # Ensure the correct URL is returned for a specific version of the |
626 | - # trunk release. |
627 | - url, name = get_launchpad_release( |
628 | - self.project, 'trunk', '0.1.0+build.1') |
629 | - self.assertEqual('http://example.com/0.1.0+build.1.tgz', url) |
630 | - self.assertEqual('0.1.0+build.1.tgz', name) |
631 | - |
632 | def test_series_not_found(self): |
633 | # A ValueError is raised if the series cannot be found. |
634 | with self.assertRaises(ValueError) as cm: |
635 | @@ -665,47 +651,38 @@ |
636 | expected = ('stable', None) |
637 | self.assertTupleEqual(expected, parse_source('stable')) |
638 | |
639 | - def test_latest_trunk_release(self): |
640 | - # Ensure the latest trunk release is correctly parsed. |
641 | - expected = ('trunk', None) |
642 | - self.assertTupleEqual(expected, parse_source('trunk')) |
643 | + def test_latest_develop_release(self): |
644 | + # Ensure the latest develop branch release is correctly parsed. |
645 | + expected = ('develop', None) |
646 | + self.assertTupleEqual(expected, parse_source('develop')) |
647 | |
648 | - def test_stable_release(self): |
649 | + @mock.patch('utils.log') |
650 | + def test_stable_release(self, *args): |
651 | # Ensure a specific stable release is correctly parsed. |
652 | expected = ('stable', '0.1.0') |
653 | self.assertTupleEqual(expected, parse_source('0.1.0')) |
654 | |
655 | - def test_trunk_release(self): |
656 | - # Ensure a specific trunk release is correctly parsed. |
657 | - expected = ('trunk', '0.1.0+build.1') |
658 | - self.assertTupleEqual(expected, parse_source('0.1.0+build.1')) |
659 | - |
660 | - def test_bzr_branch(self): |
661 | - # Ensure a Bazaar branch is correctly parsed. |
662 | - sources = ('lp:example', 'http://bazaar.launchpad.net/example') |
663 | - for source in sources: |
664 | - expected = ('branch', (source, None)) |
665 | - self.assertEqual(expected, parse_source(source)) |
666 | - |
667 | - def test_bzr_branch_and_revision(self): |
668 | - # A Bazaar branch is correctly parsed when including revision. |
669 | - sources = ('lp:example:42', 'http://bazaar.launchpad.net/example:1') |
670 | - for source in sources: |
671 | - expected = ('branch', tuple(source.rsplit(':', 1))) |
672 | + def test_git_branch(self): |
673 | + # Ensure a Git branch is correctly parsed. |
674 | + source = 'https://github.com/juju/juju-gui.git' |
675 | + expected = ('branch', (source, None)) |
676 | + self.assertEqual(expected, parse_source(source)) |
677 | + |
678 | + def test_git_branch_and_revision(self): |
679 | + # A Git branch is correctly parsed when including revision. |
680 | + sources = ( |
681 | + 'https://github.com/juju/juju-gui.git test_feature', |
682 | + 'https://github.com/juju/juju-gui.git @de5e6', |
683 | + ) |
684 | + |
685 | + for source in sources: |
686 | + expected = ('branch', tuple(source.rsplit(' ', 1))) |
687 | self.assertEqual(expected, parse_source(source)) |
688 | |
689 | def test_url(self): |
690 | expected = ('url', 'http://example.com/gui') |
691 | self.assertTupleEqual( |
692 | - expected, parse_source('url:http://example.com/gui')) |
693 | - |
694 | - def test_file_url(self): |
695 | - expected = ('url', 'file:///foo/bar') |
696 | - self.assertTupleEqual(expected, parse_source('url:/foo/bar')) |
697 | - |
698 | - def test_relative_file_url(self): |
699 | - expected = ('url', 'file:///current/dir/foo/bar') |
700 | - self.assertTupleEqual(expected, parse_source('url:foo/bar')) |
701 | + expected, parse_source('http://example.com/gui')) |
702 | |
703 | |
704 | class TestRenderToFile(unittest.TestCase): |
Reviewers: mp+201442_ code.launchpad. net,
Message:
Please take a look.
Description:
Change juju-gui-source to be git-enabled.
- Allow pulling from various repo urls
- Support checking out a branch name
- Support checkout out a direct sha
- Remove support for the trunk releases.
The list of what you can check out is simplified a bit. You can easily
use the
git access, url, or a local file in the releases directory to enable
loading
the gui with any combination of code you would like to use.
Drive by removing some left over bits of the PyJuju branch previously.
QA:
juju boostrap /jujucharms. com/juju- ui/version. js
make deploy
# make sure the gui is running off the latest release. You can check
the
# local equivelent of https:/
Run the follow config changes and after each make sure that the version
is
correct for what you've requested. You can get the sha values from
looking in
Github.
https:/ /github. com/juju/ juju-gui/ commits/ develop
# The develop support source= "develop" /github. com/juju/ juju-gui. git network-prototype" /github. com/juju/ juju-gui. git @c7ddd186"
juju set juju-gui juju-gui-
# Supports the HEAD of a branch specified.
juju set juju-gui
juju-gui-source="https:/
# Supports an older commit in the main develop line.
juju set juju-gui
juju-gui-source="https:/
https:/ /code.launchpad .net/~rharding/ charms/ precise/ juju-gui/ git-ify/ +merge/ 201442
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/52790043/
Affected files (+134, -248 lines): guiserver/ auth.py guiserver/ tests/helpers. py guiserver/ tests/test_ auth.py
M README.md
A [revision details]
M config.yaml
M hooks/backend.py
M hooks/install
M hooks/utils.py
M server/
M server/
M server/
M tests/test_utils.py