Merge lp:~frankban/juju-quickstart/bundle-v4-api into lp:juju-quickstart

Proposed by Francesco Banconi
Status: Merged
Merged at revision: 140
Proposed branch: lp:~frankban/juju-quickstart/bundle-v4-api
Merge into: lp:juju-quickstart
Diff against target: 369 lines (+111/-36)
7 files modified
README.rst (+1/-1)
quickstart/app.py (+22/-4)
quickstart/models/bundles.py (+17/-12)
quickstart/settings.py (+9/-3)
quickstart/tests/models/test_bundles.py (+18/-1)
quickstart/tests/test_app.py (+34/-4)
tox.ini (+10/-11)
To merge this branch: bzr merge lp:~frankban/juju-quickstart/bundle-v4-api
Reviewer Review Type Date Requested Status
j.c.sackett (community) Approve
Madison Scott-Clary (community) code Approve
Review via email: mp+267807@code.launchpad.net

Description of the change

Send the actual bundle version to GUI server.

When deploying bundles, if not taken from the
charm store (in which case they are always v4 bundles),
check the bundle syntax version and properly
inform the GUI server about whether a legacy
or new-style bundle is being deployed.
This is done if the GUI unit supports new bundle
v4, otherwise still try to proceed with the
deployment process, pretending a v3 bundle has been
provided.

Drop support for utopic and add support for wily.

Also update default Juju GUI revisions.

Tests: `make check`.

QA: deploy a bundle v4, preferably with unit placement,
e.g.: `devenv/bin/juju-quickstart -u http://dpaste.com/2E1JA1E.txt`.
The uncommitted state should co-locate units in the proper way,
thanks to the GUI fixes from Madison. Now remove the -u flag:
`devenv/bin/juju-quickstart http://dpaste.com/2E1JA1E.txt` and check
that also the GUI server is able to properly deploy v4 bundles.
But also try the usual mediawiki-single, etc...
Run quickstart again, run the interactive mode, ensure
quickstart works as usual, this branch will be the 2.2.1 release.

To post a comment you must log in.
Revision history for this message
j.c.sackett (jcsackett) wrote :

Francesco--

Thanks, this looks good. I noted one typo, and I have one question about what things look like to the end user in the worst case; otherwise LGTM.

review: Approve
Revision history for this message
j.c.sackett (jcsackett) wrote :

QA notes:

When running with -u everything worked great.

When running without the -u I got the following error in the GUI.

"n error occurred while deploying the bundle: Invalid service placement nova-compute to ceph/0 Invalid service placement nova-compute to ceph/1 Invalid service placement nova-compute to ceph/2 Invalid service placement ceph-radosgw to lxc:ceph/1 Invalid service placement neutron-api to lxc:ceph/0 Invalid service placement nova-cloud-controller to lxc:ceph/2 Invalid service placement keystone to lxc:ceph/0 Invalid service placement cinder to lxc:ceph/2 Invalid service placement openstack-dashboard to lxc:ceph/1 Invalid service placement glance to lxc:ceph/1"

Not sure if this is a qa error or an indication that I've got the wrong thing running. I'm running trusty/juju-gui-38, which is the minimum listed revision for V4 bundles; is there a restriction on which providers this works on? I'm using a local env.

Revision history for this message
Francesco Banconi (frankban) wrote :

Thanks for the review JC, replied in line.

146. By Francesco Banconi

Fix typo.

Revision history for this message
Francesco Banconi (frankban) wrote :

I cannot dupe this QA problem.
Could you please run "devenv/bin/juju-quickstart -e ec2 http://dpaste.com/2E1JA1E.txt --debug" again? Thanks!

Revision history for this message
j.c.sackett (jcsackett) wrote :

On EC2 I'm getting the same issue, log is https://pastebin.canonical.com/137407/

Revision history for this message
Francesco Banconi (frankban) wrote :

From the logs it seems that quickstart is not considering the bundle a v4 one ("Version": 4 is not included in the params of the Import WebSocket request).
This is not the case here locally. So could you please make another attempt, just to exclude local misconfigurations? "make clean", then "make" and then "devenv/bin/juju-quickstart -e ec2 http://dpaste.com/2E1JA1E.txt --debug" again? Thanks a lot.

Revision history for this message
Madison Scott-Clary (makyo) wrote :

LGTM, thanks for the update

review: Approve (code)
Revision history for this message
j.c.sackett (jcsackett) wrote :

After blowing away the branch and getting this again, it seems to work. I see Version: 4 in the bundle output and the bundle has deployed.

QA OK.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'README.rst'
--- README.rst 2015-08-07 10:24:11 +0000
+++ README.rst 2015-08-12 16:25:17 +0000
@@ -34,7 +34,7 @@
34------------------34------------------
3535
36Juju Quickstart is available on Ubuntu releases 12.04 LTS (precise), 14.04 LTS36Juju Quickstart is available on Ubuntu releases 12.04 LTS (precise), 14.04 LTS
37(trusty), 15.04 (vivid) and on OS X (10.7 and later).37(trusty), 15.04 (vivid), 15.10 (wily) and on OS X (10.7 and later).
3838
39Starting from version 1.5.0, Juju Quickstart only supports Juju >= 1.18.1.39Starting from version 1.5.0, Juju Quickstart only supports Juju >= 1.18.1.
4040
4141
=== modified file 'quickstart/app.py'
--- quickstart/app.py 2015-06-05 13:07:47 +0000
+++ quickstart/app.py 2015-08-12 16:25:17 +0000
@@ -683,10 +683,28 @@
683683
684 print('requesting a deployment of {} with the following services:\n'684 print('requesting a deployment of {} with the following services:\n'
685 ' {}'.format(bundle, services))685 ' {}'.format(bundle, services))
686 # XXX frankban 2015-02-26: use new bundle format if the GUI server is686 version = bundle.version
687 # capable of handling bundle deployments with the API version 4.687
688 yaml = bundle.serialize_legacy()688 if version > 3:
689 version = 3689 # The bundle uses a new-style syntax. Check whether the currently used
690 # GUI server is capable of handling new-style bundles.
691 revision = settings.MINIMUM_REVISIONS_FOR_V4_BUNDLES[charm_ref.series]
692 if jujugui.is_promulgated(charm_ref) and charm_ref.revision < revision:
693 logging.warn(
694 'new style bundle syntax is not supported by currently '
695 'deployed Juju GUI charm ({}): trying to deploy the bundle '
696 'using old syntax'.format(charm_ref))
697 # Pretend the bundle is a legacy one. Note that this might not work
698 # depending on whether new style unit placement is used in the
699 # bundle contents.
700 yaml = bundle.serialize_legacy()
701 version = 3
702 else:
703 yaml = bundle.serialize()
704 else:
705 # The bundle uses the legacy syntax.
706 yaml = bundle.serialize_legacy()
707
690 # XXX frankban 2015-02-26: find and implement a better way to increase the708 # XXX frankban 2015-02-26: find and implement a better way to increase the
691 # bundle deployments count.709 # bundle deployments count.
692 bundle_id = None if ref is None else ref.charmworld_id710 bundle_id = None if ref is None else ref.charmworld_id
693711
=== modified file 'quickstart/models/bundles.py'
--- quickstart/models/bundles.py 2015-05-13 08:46:33 +0000
+++ quickstart/models/bundles.py 2015-08-12 16:25:17 +0000
@@ -63,7 +63,7 @@
63class Bundle(object):63class Bundle(object):
64 """Store information about a charm store bundle entity"""64 """Store information about a charm store bundle entity"""
6565
66 def __init__(self, data, reference=None):66 def __init__(self, data, reference=None, version=4):
67 """Initialize the bundle.67 """Initialize the bundle.
6868
69 The data argument is the bundle YAML decoded content.69 The data argument is the bundle YAML decoded content.
@@ -72,6 +72,7 @@
72 """72 """
73 self.data = data73 self.data = data
74 self.reference = reference74 self.reference = reference
75 self.version = version
7576
76 def __str__(self):77 def __str__(self):
77 """Return the byte string representation of this bundle."""78 """Return the byte string representation of this bundle."""
@@ -118,7 +119,7 @@
118119
119120
120def from_source(source, name=None):121def from_source(source, name=None):
121 """Return a bundle YAML encoded string and id from the given source.122 """Return a bundle instance from the given source.
122123
123 The source argument is a string, and can be provided as:124 The source argument is a string, and can be provided as:
124125
@@ -167,16 +168,18 @@
167 is_remote = source.startswith('http://') or source.startswith('https://')168 is_remote = source.startswith('http://') or source.startswith('https://')
168 if has_extension and not is_remote:169 if has_extension and not is_remote:
169 # The source refers to a local file.170 # The source refers to a local file.
170 data = _parse_and_flatten_yaml(_retrieve_from_file(source), name)171 content = _retrieve_from_file(source)
171 return Bundle(data)172 data, version = _parse_and_flatten_yaml(content, name)
173 return Bundle(data, version=version)
172174
173 try:175 try:
174 reference = references.Reference.from_jujucharms_url(source)176 reference = references.Reference.from_jujucharms_url(source)
175 except ValueError:177 except ValueError:
176 if is_remote:178 if is_remote:
177 # The source is an arbitrary URL to a YAML/JSON content.179 # The source is an arbitrary URL to a YAML/JSON content.
178 data = _parse_and_flatten_yaml(_retrieve_from_url(source), name)180 content = _retrieve_from_url(source)
179 return Bundle(data)181 data, version = _parse_and_flatten_yaml(content, name)
182 return Bundle(data, version=version)
180 # No other options are available.183 # No other options are available.
181 raise184 raise
182185
@@ -214,7 +217,8 @@
214 Note that charmworld URLs always represent a bundle.217 Note that charmworld URLs always represent a bundle.
215218
216 Return a Bundle instance which includes the retrieved data and the bundle219 Return a Bundle instance which includes the retrieved data and the bundle
217 reference corresponding to the given charmworld URL.220 reference corresponding to the given charmworld URL. The returned bundle
221 is retrieved from the charm store and always uses version 4 syntax.
218 Raise a ValueError if the provided URL is not valid, or if the bundle222 Raise a ValueError if the provided URL is not valid, or if the bundle
219 content is not valid.223 content is not valid.
220 Raise a IOError if a problem is encountered while fetching the YAML224 Raise a IOError if a problem is encountered while fetching the YAML
@@ -325,8 +329,8 @@
325329
326 The content is provided as a YAML encoded string and can be either a new330 The content is provided as a YAML encoded string and can be either a new
327 style flat bundle or a legacy bundle format.331 style flat bundle or a legacy bundle format.
328 In both cases, the returned YAML decoded data represents a new style332 In both cases, the returned YAML decoded data represents a single flat
329 bundle (API version 4).333 bundle. The version is returned as an integer number.
330334
331 Raise a ValueError if:335 Raise a ValueError if:
332 - the bundle YAML contents are not parsable by YAML;336 - the bundle YAML contents are not parsable by YAML;
@@ -338,17 +342,18 @@
338 """342 """
339 data = charmstore.load_bundle_yaml(content)343 data = charmstore.load_bundle_yaml(content)
340 _ensure_is_dict(data)344 _ensure_is_dict(data)
345 version = 4
341 if is_legacy_bundle(data):346 if is_legacy_bundle(data):
342 data = _flatten_data(data, name)347 data = _flatten_data(data, name)
348 version = 3
343 validate(data)349 validate(data)
344 return data350 return data, version
345351
346352
347def _flatten_data(data, name):353def _flatten_data(data, name):
348 """Retrieve the bundle content from data for a specific bundle name.354 """Retrieve the bundle content from data for a specific bundle name.
349355
350 The returned YAML decoded data represents a new style bundle356 The returned YAML decoded data represents a single flat bundle.
351 (API version 4).
352357
353 Raise a ValueError if:358 Raise a ValueError if:
354 - the YAML data is not properly structured;359 - the YAML data is not properly structured;
355360
=== modified file 'quickstart/settings.py'
--- quickstart/settings.py 2015-06-17 14:02:03 +0000
+++ quickstart/settings.py 2015-08-12 16:25:17 +0000
@@ -37,8 +37,8 @@
37# temporary connection/charm store errors.37# temporary connection/charm store errors.
38# Keep this list sorted by release date (older first).38# Keep this list sorted by release date (older first).
39DEFAULT_CHARM_URLS = collections.OrderedDict((39DEFAULT_CHARM_URLS = collections.OrderedDict((
40 ('precise', 'cs:precise/juju-gui-117'),40 ('precise', 'cs:precise/juju-gui-121'),
41 ('trusty', 'cs:trusty/juju-gui-32'),41 ('trusty', 'cs:trusty/juju-gui-38'),
42))42))
4343
44# The quickstart app short description.44# The quickstart app short description.
@@ -61,7 +61,8 @@
6161
62# The possible values for the environments.yaml default-series field.62# The possible values for the environments.yaml default-series field.
63JUJU_DEFAULT_SERIES = (63JUJU_DEFAULT_SERIES = (
64 'precise', 'quantal', 'raring', 'saucy', 'trusty', 'utopic', 'vivid')64 'precise', 'quantal', 'raring', 'saucy', 'trusty', 'utopic', 'vivid',
65 'wily')
6566
66# Retrieve the current juju-core home.67# Retrieve the current juju-core home.
67JUJU_HOME = os.getenv('JUJU_HOME', '~/.juju')68JUJU_HOME = os.getenv('JUJU_HOME', '~/.juju')
@@ -96,3 +97,8 @@
96# deployments. Assume not listed series to always support uncommitted state.97# deployments. Assume not listed series to always support uncommitted state.
97MINIMUM_REVISIONS_FOR_UNCOMMITTED_BUNDLES = collections.defaultdict(98MINIMUM_REVISIONS_FOR_UNCOMMITTED_BUNDLES = collections.defaultdict(
98 lambda: 0, {'precise': 115, 'trusty': 28})99 lambda: 0, {'precise': 115, 'trusty': 28})
100
101# The minimum Juju GUI charm revision supporting bundle syntax version 4.
102# Assume not listed series to always support v4 syntax.
103MINIMUM_REVISIONS_FOR_V4_BUNDLES = collections.defaultdict(
104 lambda: 0, {'precise': 121, 'trusty': 38})
99105
=== modified file 'quickstart/tests/models/test_bundles.py'
--- quickstart/tests/models/test_bundles.py 2015-05-13 08:46:33 +0000
+++ quickstart/tests/models/test_bundles.py 2015-08-12 16:25:17 +0000
@@ -44,9 +44,19 @@
44 self.bundle_data, reference=self.reference)44 self.bundle_data, reference=self.reference)
4545
46 def test_attributes(self):46 def test_attributes(self):
47 # The bundle data and the optional reference are stored as attributes.47 # The bundle data, the optional reference and the default version are
48 # stored as attributes.
48 self.assertEqual(self.bundle_data, self.bundle.data)49 self.assertEqual(self.bundle_data, self.bundle.data)
49 self.assertEqual(self.reference, self.bundle.reference)50 self.assertEqual(self.reference, self.bundle.reference)
51 self.assertEqual(4, self.bundle.version)
52
53 def test_version_and_no_reference(self):
54 # The bundle syntax version can be provided as an argument. The bundle
55 # reference is optional.
56 bundle = bundles.Bundle(self.bundle_data, version=3)
57 self.assertEqual(self.bundle_data, bundle.data)
58 self.assertIsNone(bundle.reference)
59 self.assertEqual(3, bundle.version)
5060
51 def test_string(self):61 def test_string(self):
52 # The bundle correctly represents itself as a string.62 # The bundle correctly represents itself as a string.
@@ -144,6 +154,7 @@
144 bundle = bundles.from_source('bundle:mediawiki/single')154 bundle = bundles.from_source('bundle:mediawiki/single')
145 self.assertEqual(self.bundle_data, bundle.data)155 self.assertEqual(self.bundle_data, bundle.data)
146 self.assertEqual('cs:bundle/mediawiki-single', bundle.reference.id())156 self.assertEqual('cs:bundle/mediawiki-single', bundle.reference.id())
157 self.assertEqual(4, bundle.version)
147 # The charmworld id is properly set when passing charmworld URLs.158 # The charmworld id is properly set when passing charmworld URLs.
148 # XXX frankban 2015-03-09: remove this check once we get rid of the159 # XXX frankban 2015-03-09: remove this check once we get rid of the
149 # charmworld id concept.160 # charmworld id concept.
@@ -184,6 +195,7 @@
184 bundle = bundles.from_source('bundle:mediawiki/bundle1')195 bundle = bundles.from_source('bundle:mediawiki/bundle1')
185 self.assertEqual(self.bundle_data, bundle.data)196 self.assertEqual(self.bundle_data, bundle.data)
186 self.assertEqual('cs:bundle/mediawiki', bundle.reference.id())197 self.assertEqual('cs:bundle/mediawiki', bundle.reference.id())
198 self.assertEqual(4, bundle.version)
187 # The charmworld id is properly set when passing charmworld URLs.199 # The charmworld id is properly set when passing charmworld URLs.
188 # XXX frankban 2015-03-09: remove this check once we get rid of the200 # XXX frankban 2015-03-09: remove this check once we get rid of the
189 # charmworld id concept.201 # charmworld id concept.
@@ -334,6 +346,7 @@
334 bundle = bundles.from_source('django')346 bundle = bundles.from_source('django')
335 self.assertEqual(self.bundle_data, bundle.data)347 self.assertEqual(self.bundle_data, bundle.data)
336 self.assertEqual('cs:bundle/django', bundle.reference.id())348 self.assertEqual('cs:bundle/django', bundle.reference.id())
349 self.assertEqual(4, bundle.version)
337 mock_urlread.assert_called_once_with(350 mock_urlread.assert_called_once_with(
338 settings.CHARMSTORE_API + 'bundle/django/archive/bundle.yaml')351 settings.CHARMSTORE_API + 'bundle/django/archive/bundle.yaml')
339352
@@ -402,6 +415,7 @@
402 bundle = bundles.from_source(path)415 bundle = bundles.from_source(path)
403 self.assertEqual(self.bundle_data, bundle.data)416 self.assertEqual(self.bundle_data, bundle.data)
404 self.assertIsNone(bundle.reference)417 self.assertIsNone(bundle.reference)
418 self.assertEqual(4, bundle.version)
405419
406 def test_local_file_legacy_bundle(self):420 def test_local_file_legacy_bundle(self):
407 # A bundle instance can be created from a local file source including421 # A bundle instance can be created from a local file source including
@@ -419,6 +433,7 @@
419 bundle = bundles.from_source(path)433 bundle = bundles.from_source(path)
420 self.assertEqual(legacy_bundle_data['bundle'], bundle.data)434 self.assertEqual(legacy_bundle_data['bundle'], bundle.data)
421 self.assertIsNone(bundle.reference)435 self.assertIsNone(bundle.reference)
436 self.assertEqual(3, bundle.version)
422437
423 def test_local_file_not_found(self):438 def test_local_file_not_found(self):
424 # An IOError is raised if a local file source cannot be found.439 # An IOError is raised if a local file source cannot be found.
@@ -485,6 +500,7 @@
485 bundle = bundles.from_source('https://1.2.3.4')500 bundle = bundles.from_source('https://1.2.3.4')
486 self.assertEqual(self.bundle_data, bundle.data)501 self.assertEqual(self.bundle_data, bundle.data)
487 self.assertIsNone(bundle.reference)502 self.assertIsNone(bundle.reference)
503 self.assertEqual(4, bundle.version)
488 mock_urlread.assert_called_once_with('https://1.2.3.4')504 mock_urlread.assert_called_once_with('https://1.2.3.4')
489505
490 def test_remote_url_legacy_bundle(self):506 def test_remote_url_legacy_bundle(self):
@@ -496,6 +512,7 @@
496 bundle = bundles.from_source('https://1.2.3.4:8000', 'bundle2')512 bundle = bundles.from_source('https://1.2.3.4:8000', 'bundle2')
497 self.assertEqual(self.legacy_bundle_data['bundle2'], bundle.data)513 self.assertEqual(self.legacy_bundle_data['bundle2'], bundle.data)
498 self.assertIsNone(bundle.reference)514 self.assertIsNone(bundle.reference)
515 self.assertEqual(3, bundle.version)
499 mock_urlread.assert_called_once_with('https://1.2.3.4:8000')516 mock_urlread.assert_called_once_with('https://1.2.3.4:8000')
500517
501 def test_remote_url_not_reachable(self):518 def test_remote_url_not_reachable(self):
502519
=== modified file 'quickstart/tests/test_app.py'
--- quickstart/tests/test_app.py 2015-06-05 13:07:47 +0000
+++ quickstart/tests/test_app.py 2015-08-12 16:25:17 +0000
@@ -1759,10 +1759,8 @@
1759 env, uncommitted = mock.Mock(), False1759 env, uncommitted = mock.Mock(), False
1760 token = app.deploy_bundle(env, self.bundle, uncommitted, self.charm)1760 token = app.deploy_bundle(env, self.bundle, uncommitted, self.charm)
1761 self.assertIsNone(token)1761 self.assertIsNone(token)
1762 # For the time being, the bundle version 3 is deployed by default.
1763 expected_yaml = yaml.safe_dump({'bundle': self.bundle_data})
1764 env.deploy_bundle.assert_called_once_with(1762 env.deploy_bundle.assert_called_once_with(
1765 expected_yaml, 3, bundle_id=None)1763 yaml.safe_dump(self.bundle_data), 4, bundle_id=None)
1766 self.assertFalse(env.set_changes.called)1764 self.assertFalse(env.set_changes.called)
1767 self.assertFalse(env.close.called)1765 self.assertFalse(env.close.called)
1768 self.assertEqual(2, mock_print.call_count)1766 self.assertEqual(2, mock_print.call_count)
@@ -1775,6 +1773,38 @@
1775 'use the GUI to check the bundle deployment progress'),1773 'use the GUI to check the bundle deployment progress'),
1776 ])1774 ])
17771775
1776 def test_legacy_bundle_deployment(self, mock_print):
1777 # A bundle with legacy v3 bundle syntax is successfully deployed.
1778 env, uncommitted = mock.Mock(), False
1779 bundle = bundles.Bundle(self.bundle_data, version=3)
1780 token = app.deploy_bundle(env, bundle, uncommitted, self.charm)
1781 self.assertIsNone(token)
1782 expected_yaml = yaml.safe_dump({'bundle': self.bundle_data})
1783 env.deploy_bundle.assert_called_once_with(
1784 expected_yaml, 3, bundle_id=None)
1785 self.assertFalse(env.set_changes.called)
1786 self.assertFalse(env.close.called)
1787
1788 def test_bundle_deployment_v4_not_supported(self, mock_print):
1789 # The bundle deployment falls back to version 3 syntax if the Juju GUI
1790 # unit is not recent enough. In this case there is no guarantee that
1791 # the deployment succeeds.
1792 env, uncommitted = mock.Mock(), False
1793 charm = references.Reference.from_string('cs:trusty/juju-gui-36')
1794 expected_logs = [
1795 'new style bundle syntax is not supported by currently deployed '
1796 'Juju GUI charm (cs:trusty/juju-gui-36): trying to deploy the '
1797 'bundle using old syntax'
1798 ]
1799 with helpers.assert_logs(expected_logs, level='warn'):
1800 token = app.deploy_bundle(env, self.bundle, uncommitted, charm)
1801 self.assertIsNone(token)
1802 expected_yaml = yaml.safe_dump({'bundle': self.bundle_data})
1803 env.deploy_bundle.assert_called_once_with(
1804 expected_yaml, 3, bundle_id=None)
1805 self.assertFalse(env.set_changes.called)
1806 self.assertFalse(env.close.called)
1807
1778 def test_bundle_deployment_with_id(self, mock_print):1808 def test_bundle_deployment_with_id(self, mock_print):
1779 # If the bundle reference includes the charmworld id, it is passed when1809 # If the bundle reference includes the charmworld id, it is passed when
1780 # calling the GUI server API.1810 # calling the GUI server API.
@@ -1787,7 +1817,7 @@
1787 bundle = bundles.Bundle(self.bundle_data, reference=ref)1817 bundle = bundles.Bundle(self.bundle_data, reference=ref)
1788 app.deploy_bundle(env, bundle, uncommitted, self.charm)1818 app.deploy_bundle(env, bundle, uncommitted, self.charm)
1789 env.deploy_bundle.assert_called_once_with(1819 env.deploy_bundle.assert_called_once_with(
1790 self.bundle.serialize_legacy(), 3, bundle_id='django/single')1820 self.bundle.serialize(), 4, bundle_id='django/single')
17911821
1792 def test_api_error(self, mock_print):1822 def test_api_error(self, mock_print):
1793 # A ProgramExit is raised if an error occurs while deploying the1823 # A ProgramExit is raised if an error occurs while deploying the
17941824
=== modified file 'tox.ini'
--- tox.ini 2015-08-07 10:24:11 +0000
+++ tox.ini 2015-08-12 16:25:17 +0000
@@ -18,7 +18,7 @@
18# The envlist option must only include platform scenarios. In essence, those18# The envlist option must only include platform scenarios. In essence, those
19# are used to test Juju Quickstart with the specific dependencies present in19# are used to test Juju Quickstart with the specific dependencies present in
20# each supported OS platform.20# each supported OS platform.
21envlist = pypi,ppa,trusty,utopic,vivid21envlist = pypi,ppa,trusty,vivid,wily
2222
23# Define the base requirements and commands to use when testing the program.23# Define the base requirements and commands to use when testing the program.
2424
@@ -86,16 +86,6 @@
86 PyYAML==3.1086 PyYAML==3.10
87 urwid==1.1.187 urwid==1.1.1
8888
89[testenv:utopic]
90deps =
91 {[testenv]deps}
92 # Ubuntu 14.10 (utopic) distro dependencies.
93 websocket-client==0.12.0
94 jujuclient==0.17.5
95 jujubundlelib==0.1.9
96 PyYAML==3.11
97 urwid==1.2.1
98
99[testenv:vivid]89[testenv:vivid]
100deps =90deps =
101 {[testenv]deps}91 {[testenv]deps}
@@ -106,6 +96,15 @@
106 PyYAML==3.1196 PyYAML==3.11
107 urwid==1.2.197 urwid==1.2.1
10898
99[testenv:wily]
100deps =
101 {[testenv]deps}
102 # Ubuntu 15.10 (wily) distro dependencies.
103 websocket-client==0.18.0
104 jujuclient==0.50.1
105 jujubundlelib==0.1.9
106 PyYAML==3.11
107 urwid==1.2.1
109108
110# Define additional tox targets to be used to validate and lint the code.109# Define additional tox targets to be used to validate and lint the code.
111110

Subscribers

People subscribed via source and target branches