Merge lp:~frankban/juju-quickstart/initial-vivid-support into lp:juju-quickstart
- initial-vivid-support
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 114 |
Proposed branch: | lp:~frankban/juju-quickstart/initial-vivid-support |
Merge into: | lp:juju-quickstart |
Diff against target: |
202 lines (+36/-28) 6 files modified
quickstart/__init__.py (+1/-1) quickstart/app.py (+3/-3) quickstart/netutils.py (+3/-3) quickstart/settings.py (+9/-7) quickstart/tests/test_app.py (+9/-9) quickstart/tests/test_netutils.py (+11/-5) |
To merge this branch: | bzr merge lp:~frankban/juju-quickstart/initial-vivid-support |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juju GUI Hackers | Pending | ||
Review via email:
|
Commit message
Description of the change
Use charm store API to retrieve GUI revision.
This branch includes the following small fixes
in preparation for the 1.6 release:
- bump version up to 1.6.0;
- use the charm store API to retrieve the URL
of the last revision of the juju-gui charm;
- add initial support for vivid: the new series can now
be selected as default bootstrap node series when
creating/editing environments.
Tests: `make check`.
QA:
- just run `.venv/bin/python juju-quickstart` as
usual, locally and on a ec2 environment
(it would be nice if both precise and trusty
are used as default series in this QA); check
that vivid can be added as a default-series
in the environment edit view; check that
the last Juju GUI revision is correctly retrieved.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Francesco Banconi (frankban) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Martin Hilton (martin-hilton) wrote : | # |
LGTM, No QA (yet)
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Martin Hilton (martin-hilton) wrote : | # |
On 2015/01/12 18:02:13, martin.hilton wrote:
> LGTM, No QA (yet)
QA OK
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Roger Peppe (rogpeppe) wrote : | # |
On 2015/01/12 19:46:50, martin.hilton wrote:
> On 2015/01/12 18:02:13, martin.hilton wrote:
> > LGTM, No QA (yet)
> QA OK
LGTM
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Francesco Banconi (frankban) wrote : | # |
*** Submitted:
Use charm store API to retrieve GUI revision.
This branch includes the following small fixes
in preparation for the 1.6 release:
- bump version up to 1.6.0;
- use the charm store API to retrieve the URL
of the last revision of the juju-gui charm;
- add initial support for vivid: the new series can now
be selected as default bootstrap node series when
creating/editing environments.
Tests: `make check`.
QA:
- just run `.venv/bin/python juju-quickstart` as
usual, locally and on a ec2 environment
(it would be nice if both precise and trusty
are used as default series in this QA); check
that vivid can be added as a default-series
in the environment edit view; check that
the last Juju GUI revision is correctly retrieved.
R=martin.hilton, rog
CC=
https:/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Francesco Banconi (frankban) wrote : | # |
Thanks for the reviews!
Preview Diff
1 | === modified file 'quickstart/__init__.py' | |||
2 | --- quickstart/__init__.py 2014-11-10 11:27:04 +0000 | |||
3 | +++ quickstart/__init__.py 2015-01-12 17:54:09 +0000 | |||
4 | @@ -45,7 +45,7 @@ | |||
5 | 45 | Once Juju has been installed, the command can also be run as a juju plugin, | 45 | Once Juju has been installed, the command can also be run as a juju plugin, |
6 | 46 | without the hyphen ("juju quickstart"). | 46 | without the hyphen ("juju quickstart"). |
7 | 47 | """ | 47 | """ |
9 | 48 | VERSION = (1, 5, 0) | 48 | VERSION = (1, 6, 0) |
10 | 49 | 49 | ||
11 | 50 | 50 | ||
12 | 51 | def get_version(): | 51 | def get_version(): |
13 | 52 | 52 | ||
14 | === modified file 'quickstart/app.py' | |||
15 | --- quickstart/app.py 2014-12-16 14:12:44 +0000 | |||
16 | +++ quickstart/app.py 2015-01-12 17:54:09 +0000 | |||
17 | @@ -386,8 +386,8 @@ | |||
18 | 386 | unit. | 386 | unit. |
19 | 387 | 387 | ||
20 | 388 | If the charm URL is not provided, and the service is not already deployed, | 388 | If the charm URL is not provided, and the service is not already deployed, |
23 | 389 | the function tries to retrieve it from the charmworld API. In this case a | 389 | the function tries to retrieve it from the charm store API. In this case a |
24 | 390 | default charm URL is used if charmworld is not available. | 390 | default charm URL is used if the charm store service is not available. |
25 | 391 | 391 | ||
26 | 392 | Return a tuple including the following values: | 392 | Return a tuple including the following values: |
27 | 393 | - charm_url: the charm URL that will be used to deploy the service; | 393 | - charm_url: the charm URL that will be used to deploy the service; |
28 | @@ -418,7 +418,7 @@ | |||
29 | 418 | else: | 418 | else: |
30 | 419 | series = settings.JUJU_GUI_SUPPORTED_SERIES[-1] | 419 | series = settings.JUJU_GUI_SUPPORTED_SERIES[-1] |
31 | 420 | try: | 420 | try: |
33 | 421 | # Try to get the charm URL from charmworld. | 421 | # Try to get the charm URL from the charm store API. |
34 | 422 | charm_url = netutils.get_charm_url(series) | 422 | charm_url = netutils.get_charm_url(series) |
35 | 423 | except (IOError, ValueError) as err: | 423 | except (IOError, ValueError) as err: |
36 | 424 | # Fall back to the default URL for the current series. | 424 | # Fall back to the default URL for the current series. |
37 | 425 | 425 | ||
38 | === modified file 'quickstart/netutils.py' | |||
39 | --- quickstart/netutils.py 2014-11-12 16:40:54 +0000 | |||
40 | +++ quickstart/netutils.py 2015-01-12 17:54:09 +0000 | |||
41 | @@ -69,10 +69,10 @@ | |||
42 | 69 | Raise an IOError if any problems occur connecting to the API endpoint. | 69 | Raise an IOError if any problems occur connecting to the API endpoint. |
43 | 70 | Raise a ValueError if the API returns invalid data. | 70 | Raise a ValueError if the API returns invalid data. |
44 | 71 | """ | 71 | """ |
46 | 72 | url = settings.CHARMWORLD_API.format( | 72 | url = settings.CHARMSTORE_API.format( |
47 | 73 | series=series, charm=settings.JUJU_GUI_CHARM_NAME) | 73 | series=series, charm=settings.JUJU_GUI_CHARM_NAME) |
50 | 74 | charm_info = json.loads(urlread(url)) | 74 | data = json.loads(urlread(url)) |
51 | 75 | charm_url = charm_info.get('charm', {}).get('url') | 75 | charm_url = data.get('Id') |
52 | 76 | if charm_url is None: | 76 | if charm_url is None: |
53 | 77 | raise ValueError(b'unable to find the charm URL') | 77 | raise ValueError(b'unable to find the charm URL') |
54 | 78 | return charm_url | 78 | return charm_url |
55 | 79 | 79 | ||
56 | === modified file 'quickstart/settings.py' | |||
57 | --- quickstart/settings.py 2014-11-10 11:39:40 +0000 | |||
58 | +++ quickstart/settings.py 2015-01-12 17:54:09 +0000 | |||
59 | @@ -29,17 +29,19 @@ | |||
60 | 29 | UNKNOWN_PLATFORM = object() | 29 | UNKNOWN_PLATFORM = object() |
61 | 30 | WINDOWS = object() | 30 | WINDOWS = object() |
62 | 31 | 31 | ||
64 | 32 | # The base charmworld API URL containing information about charms. | 32 | # The base charm store API URL containing information about charms. |
65 | 33 | # This URL must be formatted with a series and a charm name. | 33 | # This URL must be formatted with a series and a charm name. |
67 | 34 | CHARMWORLD_API = 'http://manage.jujucharms.com/api/3/charm/{series}/{charm}' | 34 | CHARMSTORE_API = ( |
68 | 35 | 'https://api.jujucharms.com' | ||
69 | 36 | '/charmstore/v4/{series}/{charm}/meta/id') | ||
70 | 35 | 37 | ||
71 | 36 | # The default Juju GUI charm URLs for each supported series. Used when it is | 38 | # The default Juju GUI charm URLs for each supported series. Used when it is |
74 | 37 | # not possible to retrieve the charm URL from the charmworld API, e.g. due to | 39 | # not possible to retrieve the charm URL from the charm store API, e.g. due to |
75 | 38 | # temporary connection/charmworld errors. | 40 | # temporary connection/charm store errors. |
76 | 39 | # Keep this list sorted by release date (older first). | 41 | # Keep this list sorted by release date (older first). |
77 | 40 | DEFAULT_CHARM_URLS = collections.OrderedDict(( | 42 | DEFAULT_CHARM_URLS = collections.OrderedDict(( |
80 | 41 | ('precise', 'cs:precise/juju-gui-97'), | 43 | ('precise', 'cs:precise/juju-gui-104'), |
81 | 42 | ('trusty', 'cs:trusty/juju-gui-9'), | 44 | ('trusty', 'cs:trusty/juju-gui-16'), |
82 | 43 | )) | 45 | )) |
83 | 44 | 46 | ||
84 | 45 | # The quickstart app short description. | 47 | # The quickstart app short description. |
85 | @@ -62,7 +64,7 @@ | |||
86 | 62 | 64 | ||
87 | 63 | # The possible values for the environments.yaml default-series field. | 65 | # The possible values for the environments.yaml default-series field. |
88 | 64 | JUJU_DEFAULT_SERIES = ( | 66 | JUJU_DEFAULT_SERIES = ( |
90 | 65 | 'precise', 'quantal', 'raring', 'saucy', 'trusty', 'utopic') | 67 | 'precise', 'quantal', 'raring', 'saucy', 'trusty', 'utopic', 'vivid') |
91 | 66 | 68 | ||
92 | 67 | # Retrieve the current juju-core home. | 69 | # Retrieve the current juju-core home. |
93 | 68 | JUJU_HOME = os.getenv('JUJU_HOME', '~/.juju') | 70 | JUJU_HOME = os.getenv('JUJU_HOME', '~/.juju') |
94 | 69 | 71 | ||
95 | === modified file 'quickstart/tests/test_app.py' | |||
96 | --- quickstart/tests/test_app.py 2014-12-16 14:12:44 +0000 | |||
97 | +++ quickstart/tests/test_app.py 2015-01-12 17:54:09 +0000 | |||
98 | @@ -922,8 +922,8 @@ | |||
99 | 922 | check_preexisting) | 922 | check_preexisting) |
100 | 923 | # There is no need to call status if the environment was just created. | 923 | # There is no need to call status if the environment was just created. |
101 | 924 | self.assertFalse(env.get_status.called) | 924 | self.assertFalse(env.get_status.called) |
104 | 925 | # The charm URL has been retrieved from charmworld based on the current | 925 | # The charm URL has been retrieved from the charm store API based on |
105 | 926 | # bootstrap node series. | 926 | # the current bootstrap node series. |
106 | 927 | self.assertEqual('cs:trusty/juju-gui-42', url) | 927 | self.assertEqual('cs:trusty/juju-gui-42', url) |
107 | 928 | mock_get_charm_url.assert_called_once_with(bootstrap_node_series) | 928 | mock_get_charm_url.assert_called_once_with(bootstrap_node_series) |
108 | 929 | # Since the bootstrap node series is supported by the GUI charm, the | 929 | # Since the bootstrap node series is supported by the GUI charm, the |
109 | @@ -957,8 +957,8 @@ | |||
110 | 957 | check_preexisting) | 957 | check_preexisting) |
111 | 958 | # The environment status has been retrieved. | 958 | # The environment status has been retrieved. |
112 | 959 | env.get_status.assert_called_once_with() | 959 | env.get_status.assert_called_once_with() |
115 | 960 | # The charm URL has been retrieved from charmworld based on the current | 960 | # The charm URL has been retrieved from the charm store API based on |
116 | 961 | # bootstrap node series. | 961 | # the current bootstrap node series. |
117 | 962 | self.assertEqual('cs:precise/juju-gui-42', url) | 962 | self.assertEqual('cs:precise/juju-gui-42', url) |
118 | 963 | mock_get_charm_url.assert_called_once_with(bootstrap_node_series) | 963 | mock_get_charm_url.assert_called_once_with(bootstrap_node_series) |
119 | 964 | # Since the bootstrap node series is supported by the GUI charm, the | 964 | # Since the bootstrap node series is supported by the GUI charm, the |
120 | @@ -1012,8 +1012,8 @@ | |||
121 | 1012 | url, machine, service_data, unit_data = app.check_environment( | 1012 | url, machine, service_data, unit_data = app.check_environment( |
122 | 1013 | env, 'my-gui', charm_url, env_type, bootstrap_node_series, | 1013 | env, 'my-gui', charm_url, env_type, bootstrap_node_series, |
123 | 1014 | check_preexisting) | 1014 | check_preexisting) |
126 | 1015 | # The charm URL has been retrieved from charmworld using the most | 1015 | # The charm URL has been retrieved from the charm store API using the |
127 | 1016 | # recent supported series. | 1016 | # most recent supported series. |
128 | 1017 | self.assertEqual('cs:trusty/juju-gui-42', url) | 1017 | self.assertEqual('cs:trusty/juju-gui-42', url) |
129 | 1018 | mock_get_charm_url.assert_called_once_with('trusty') | 1018 | mock_get_charm_url.assert_called_once_with('trusty') |
130 | 1019 | # The Juju GUI unit cannot be deployed to saucy machine 0. | 1019 | # The Juju GUI unit cannot be deployed to saucy machine 0. |
131 | @@ -1037,7 +1037,7 @@ | |||
132 | 1037 | url, machine, service_data, unit_data = app.check_environment( | 1037 | url, machine, service_data, unit_data = app.check_environment( |
133 | 1038 | env, 'my-gui', charm_url, env_type, bootstrap_node_series, | 1038 | env, 'my-gui', charm_url, env_type, bootstrap_node_series, |
134 | 1039 | check_preexisting) | 1039 | check_preexisting) |
136 | 1040 | # The charm URL has been correctly retrieved from charmworld. | 1040 | # The charm URL has been correctly retrieved from the charm store API. |
137 | 1041 | self.assertEqual('cs:trusty/juju-gui-42', url) | 1041 | self.assertEqual('cs:trusty/juju-gui-42', url) |
138 | 1042 | # The Juju GUI unit cannot be deployed to localhost. | 1042 | # The Juju GUI unit cannot be deployed to localhost. |
139 | 1043 | self.assertIsNone(machine) | 1043 | self.assertIsNone(machine) |
140 | @@ -1058,7 +1058,7 @@ | |||
141 | 1058 | 1058 | ||
142 | 1059 | def test_default_charm_url(self, mock_print): | 1059 | def test_default_charm_url(self, mock_print): |
143 | 1060 | # A default charm URL suitable to be deployed in the bootstrap node is | 1060 | # A default charm URL suitable to be deployed in the bootstrap node is |
145 | 1061 | # returned if the charmworld API is not reachable. | 1061 | # returned if the charm store API is not reachable. |
146 | 1062 | env = self.make_env() | 1062 | env = self.make_env() |
147 | 1063 | charm_url = None | 1063 | charm_url = None |
148 | 1064 | env_type = 'ec2' | 1064 | env_type = 'ec2' |
149 | @@ -1074,7 +1074,7 @@ | |||
150 | 1074 | 1074 | ||
151 | 1075 | def test_most_recent_default_charm_url(self, mock_print): | 1075 | def test_most_recent_default_charm_url(self, mock_print): |
152 | 1076 | # The default charm URL corresponding to the most recent series | 1076 | # The default charm URL corresponding to the most recent series |
154 | 1077 | # supported by the GUI is returned if the charmworld API is not | 1077 | # supported by the GUI is returned if the charm store API is not |
155 | 1078 | # reachable and the bootstrap node cannot host the Juju GUI unit. | 1078 | # reachable and the bootstrap node cannot host the Juju GUI unit. |
156 | 1079 | env = self.make_env() | 1079 | env = self.make_env() |
157 | 1080 | charm_url = None | 1080 | charm_url = None |
158 | 1081 | 1081 | ||
159 | === modified file 'quickstart/tests/test_netutils.py' | |||
160 | --- quickstart/tests/test_netutils.py 2014-11-12 16:40:54 +0000 | |||
161 | +++ quickstart/tests/test_netutils.py 2015-01-12 17:54:09 +0000 | |||
162 | @@ -107,12 +107,17 @@ | |||
163 | 107 | 107 | ||
164 | 108 | def test_charm_url(self): | 108 | def test_charm_url(self): |
165 | 109 | # The Juju GUI charm URL is correctly returned. | 109 | # The Juju GUI charm URL is correctly returned. |
167 | 110 | contents = json.dumps({'charm': {'url': 'cs:trusty/juju-gui-42'}}) | 110 | contents = json.dumps({ |
168 | 111 | 'Id': 'cs:trusty/juju-gui-42', | ||
169 | 112 | 'Series': 'trusty', | ||
170 | 113 | 'Name': 'juju-gui', | ||
171 | 114 | 'Revision': 42, | ||
172 | 115 | }) | ||
173 | 111 | with self.patch_urlread(contents=contents) as mock_urlread: | 116 | with self.patch_urlread(contents=contents) as mock_urlread: |
174 | 112 | charm_url = netutils.get_charm_url('trusty') | 117 | charm_url = netutils.get_charm_url('trusty') |
175 | 113 | self.assertEqual('cs:trusty/juju-gui-42', charm_url) | 118 | self.assertEqual('cs:trusty/juju-gui-42', charm_url) |
176 | 114 | mock_urlread.assert_called_once_with( | 119 | mock_urlread.assert_called_once_with( |
178 | 115 | 'http://manage.jujucharms.com/api/3/charm/trusty/juju-gui') | 120 | 'https://api.jujucharms.com/charmstore/v4/trusty/juju-gui/meta/id') |
179 | 116 | 121 | ||
180 | 117 | def test_io_error(self): | 122 | def test_io_error(self): |
181 | 118 | # IOErrors are properly propagated. | 123 | # IOErrors are properly propagated. |
182 | @@ -120,17 +125,18 @@ | |||
183 | 120 | with self.assertRaises(IOError) as context_manager: | 125 | with self.assertRaises(IOError) as context_manager: |
184 | 121 | netutils.get_charm_url('precise') | 126 | netutils.get_charm_url('precise') |
185 | 122 | mock_urlread.assert_called_once_with( | 127 | mock_urlread.assert_called_once_with( |
187 | 123 | 'http://manage.jujucharms.com/api/3/charm/precise/juju-gui') | 128 | 'https://api.jujucharms.com/charmstore/v4/precise/juju-gui/meta/id' |
188 | 129 | ) | ||
189 | 124 | self.assertEqual('bad wolf', bytes(context_manager.exception)) | 130 | self.assertEqual('bad wolf', bytes(context_manager.exception)) |
190 | 125 | 131 | ||
191 | 126 | def test_value_error(self): | 132 | def test_value_error(self): |
192 | 127 | # A ValueError is raised if the API response is not valid. | 133 | # A ValueError is raised if the API response is not valid. |
194 | 128 | contents = json.dumps({'charm': {}}) | 134 | contents = json.dumps({'invalid': {}}) |
195 | 129 | with self.patch_urlread(contents=contents) as mock_urlread: | 135 | with self.patch_urlread(contents=contents) as mock_urlread: |
196 | 130 | with self.assertRaises(ValueError) as context_manager: | 136 | with self.assertRaises(ValueError) as context_manager: |
197 | 131 | netutils.get_charm_url('trusty') | 137 | netutils.get_charm_url('trusty') |
198 | 132 | mock_urlread.assert_called_once_with( | 138 | mock_urlread.assert_called_once_with( |
200 | 133 | 'http://manage.jujucharms.com/api/3/charm/trusty/juju-gui') | 139 | 'https://api.jujucharms.com/charmstore/v4/trusty/juju-gui/meta/id') |
201 | 134 | self.assertEqual( | 140 | self.assertEqual( |
202 | 135 | 'unable to find the charm URL', bytes(context_manager.exception)) | 141 | 'unable to find the charm URL', bytes(context_manager.exception)) |
203 | 136 | 142 |
Reviewers: mp+246199_ code.launchpad. net,
Message:
Please take a look.
Description:
Use charm store API to retrieve GUI revision.
This branch includes the following small fixes
in preparation for the 1.6 release:
- bump version up to 1.6.0;
- use the charm store API to retrieve the URL
of the last revision of the juju-gui charm;
- add initial support for vivid: the new series can now
be selected as default bootstrap node series when
creating/editing environments.
Tests: `make check`.
QA:
- just run `.venv/bin/python juju-quickstart` as
usual, locally and on a ec2 environment
(it would be nice if both precise and trusty
are used as default series in this QA); check
that vivid can be added as a default-series
in the environment edit view; check that
the last Juju GUI revision is correctly retrieved.
https:/ /code.launchpad .net/~frankban/ juju-quickstart /initial- vivid-support/ +merge/ 246199
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/197740043/
Affected files (+38, -28 lines): __init_ _.py netutils. py settings. py tests/test_ app.py tests/test_ netutils. py
A [revision details]
M quickstart/
M quickstart/app.py
M quickstart/
M quickstart/
M quickstart/
M quickstart/
Index: [revision details]
=== added file '[revision details]'
--- [revision details] 2012-01-01 00:00:00 +0000
+++ [revision details] 2012-01-01 00:00:00 +0000
@@ -0,0 +1,2 @@
+Old revision:
<email address hidden>
+New revision:
<email address hidden>
Index: quickstart/ __init_ _.py __init_ _.py' __init_ _.py 2014-11-10 11:27:04 +0000 __init_ _.py 2015-01-12 14:30:44 +0000
=== modified file 'quickstart/
--- quickstart/
+++ quickstart/
@@ -45,7 +45,7 @@
Once Juju has been installed, the command can also be run as a juju plugin,
without the hyphen ("juju quickstart").
"""
-VERSION = (1, 5, 0)
+VERSION = (1, 6, 0)
def get_version():
Index: quickstart/app.py
=== modified file 'quickstart/app.py'
--- quickstart/app.py 2014-12-16 14:12:44 +0000
+++ quickstart/app.py 2015-01-12 15:00:52 +0000
@@ -386,8 +386,8 @@
unit.
If the charm URL is not provided, and the service is not already
deployed,
- the function tries to retrieve it from the charmworld API. In this
case a
- default charm URL is used if charmworld is not available.
+ the function tries to retrieve it from the charm store API. In this
case a
+ default charm URL is used if the charm store service is not available.
Return a tuple including the following values:
series = settings. JUJU_GUI_ SUPPORTED_ SERIES[ -1]
charm_ url = netutils. get_charm_ url(series)
except (IOError, ValueError) as err:
- charm_url: the charm URL that will be used to deploy the service;
@@ -418,7 +418,7 @@
else:
try:
- # Try to get the charm URL from charmworld.
+ # Try to get the charm URL from the charm store API.
# Fall back to the default URL for the current series.
Index:...