Merge lp:~free.ekanayaka/landscape-client/juju-machine-info into lp:~landscape/landscape-client/trunk

Proposed by Free Ekanayaka
Status: Merged
Approved by: Free Ekanayaka
Approved revision: 786
Merged at revision: 783
Proposed branch: lp:~free.ekanayaka/landscape-client/juju-machine-info
Merge into: lp:~landscape/landscape-client/trunk
Diff against target: 332 lines (+68/-37)
9 files modified
landscape/broker/registration.py (+1/-1)
landscape/broker/service.py (+2/-2)
landscape/broker/tests/helpers.py (+1/-11)
landscape/broker/tests/test_exchange.py (+1/-2)
landscape/broker/tests/test_registration.py (+0/-1)
landscape/lib/juju.py (+29/-9)
landscape/lib/tests/test_juju.py (+23/-10)
landscape/monitor/jujuinfo.py (+9/-1)
landscape/monitor/tests/test_jujuinfo.py (+2/-0)
To merge this branch: bzr merge lp:~free.ekanayaka/landscape-client/juju-machine-info
Reviewer Review Type Date Requested Status
Adam Collard (community) Approve
Alberto Donato (community) Approve
Review via email: mp+231895@code.launchpad.net

Commit message

This branch changes the get_juju_info utility to return information
about the Juju machine ID the client runs in. Since we're in the
middle of the transition, both the old info with unit names and the
new info with the machine ID are returned. When the transition completes
in the server too the old info can be dropped.

Description of the change

This branch changes the get_juju_info utility to return information
about the Juju machine ID the client runs in. Since we're in the
middle of the transition, both the old info with unit names and the
new info with the machine ID are returned. When the transition completes
in the server too the old info can be dropped.

To post a comment you must log in.
784. By Free Ekanayaka

Fix failing tests

Revision history for this message
Adam Collard (adam-collard) wrote :

3 inline comments

review: Needs Information
Revision history for this message
Alberto Donato (ack) wrote :

Code looks good, just a question:

what's the plan for the charm? Will we just add the "machine-id" and keep "unit-name" for backwards compatibility?

review: Needs Information
Revision history for this message
Free Ekanayaka (free.ekanayaka) wrote :

Alberto: for the charm we don't need backward compatibility since never released and LDS with support for Juju integration. So the current code in the charm is basically dead code from the user perspective, and we can change it to send just machine-id. Said that, for sake of our internal migration we'll keep both for a bit, till we complete the process.

Revision history for this message
Free Ekanayaka (free.ekanayaka) wrote :

Thanks Adam, replied/fixed all three issues.

785. By Free Ekanayaka

Address review comments

Revision history for this message
Alberto Donato (ack) wrote :

+1!

review: Approve
Revision history for this message
Adam Collard (adam-collard) wrote :

Thanks Free.

Lint issue:

landscape/broker/tests/test_registration.py:5: 'SERVER_API' imported but unused

Otherwise looks good. +1

review: Approve
786. By Free Ekanayaka

Fix lint

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'landscape/broker/registration.py'
2--- landscape/broker/registration.py 2014-07-16 18:04:22 +0000
3+++ landscape/broker/registration.py 2014-08-28 07:37:26 +0000
4@@ -126,7 +126,7 @@
5
6 def _get_juju_data(self):
7 """Load Juju information."""
8- juju_info = get_juju_info(self._config)
9+ juju_info = get_juju_info(self._config)[0]
10 if juju_info is None:
11 return None
12 self._juju_data = juju_info # A list of dicts
13
14=== modified file 'landscape/broker/service.py'
15--- landscape/broker/service.py 2013-05-07 22:47:06 +0000
16+++ landscape/broker/service.py 2014-08-28 07:37:26 +0000
17@@ -1,7 +1,7 @@
18 """Deployment code for the monitor."""
19
20 import os
21-from landscape.lib.fetch import fetch_async
22+
23 from landscape.service import LandscapeService, run_landscape_service
24 from landscape.amp import ComponentPublisher
25 from landscape.broker.registration import RegistrationHandler, Identity
26@@ -61,7 +61,7 @@
27 self.reactor, self.identity, self.exchanger, config)
28 self.registration = RegistrationHandler(
29 config, self.identity, self.reactor, self.exchanger, self.pinger,
30- self.message_store, fetch_async)
31+ self.message_store)
32 self.broker = BrokerServer(self.config, self.reactor, self.exchanger,
33 self.registration, self.message_store,
34 self.pinger)
35
36=== modified file 'landscape/broker/tests/helpers.py'
37--- landscape/broker/tests/helpers.py 2014-06-09 08:18:05 +0000
38+++ landscape/broker/tests/helpers.py 2014-08-28 07:37:26 +0000
39@@ -7,7 +7,6 @@
40 """
41 import os
42
43-from landscape.lib.fetch import fetch_async
44 from landscape.lib.persist import Persist
45 from landscape.watchdog import bootstrap_list
46 from landscape.reactor import FakeReactor
47@@ -112,20 +111,12 @@
48 The following attributes will be set in your test case:
49
50 - C{handler}: A L{RegistrationHandler}.
51-
52- - C{fetch_func}: The C{fetch_async} function used by the C{handler}, it
53- can be customised by test cases.
54 """
55
56 def set_up(self, test_case):
57 super(RegistrationHelper, self).set_up(test_case)
58 test_case.pinger = Pinger(test_case.reactor, test_case.identity,
59 test_case.exchanger, test_case.config)
60-
61- def fetch_func(*args, **kwargs):
62- return test_case.fetch_func(*args, **kwargs)
63-
64- test_case.fetch_func = fetch_async
65 test_case.config.cloud = getattr(test_case, "cloud", False)
66 if hasattr(test_case, "juju_contents"):
67 if not os.path.exists(test_case.config.juju_directory):
68@@ -135,8 +126,7 @@
69 dirname=test_case.config.juju_directory, suffix=".json")
70 test_case.handler = RegistrationHandler(
71 test_case.config, test_case.identity, test_case.reactor,
72- test_case.exchanger, test_case.pinger, test_case.mstore,
73- fetch_async=fetch_func)
74+ test_case.exchanger, test_case.pinger, test_case.mstore)
75
76
77 class BrokerServerHelper(RegistrationHelper):
78
79=== modified file 'landscape/broker/tests/test_exchange.py'
80--- landscape/broker/tests/test_exchange.py 2014-07-16 11:41:29 +0000
81+++ landscape/broker/tests/test_exchange.py 2014-08-28 07:37:26 +0000
82@@ -1,7 +1,6 @@
83 from landscape import SERVER_API, CLIENT_API
84 from landscape.lib.persist import Persist
85 from landscape.lib.hashlib import md5
86-from landscape.lib.fetch import fetch_async
87 from landscape.schema import Message, Int
88 from landscape.broker.config import BrokerConfiguration
89 from landscape.broker.exchange import get_accepted_types_diff, MessageExchange
90@@ -1061,7 +1060,7 @@
91 # message types that we want to catch as well
92 self.handler = RegistrationHandler(
93 self.config, self.identity, self.reactor, self.exchanger,
94- self.pinger, self.mstore, fetch_async)
95+ self.pinger, self.mstore)
96
97 def test_register_accepted_message_type(self):
98 self.exchanger.register_client_accepted_message_type("type-B")
99
100=== modified file 'landscape/broker/tests/test_registration.py'
101--- landscape/broker/tests/test_registration.py 2014-07-24 12:21:06 +0000
102+++ landscape/broker/tests/test_registration.py 2014-08-28 07:37:26 +0000
103@@ -2,7 +2,6 @@
104 import logging
105 import socket
106
107-from landscape import SERVER_API
108 from landscape.broker.registration import (
109 InvalidCredentialsError, Identity)
110 from landscape.tests.helpers import LandscapeTest
111
112=== modified file 'landscape/lib/juju.py'
113--- landscape/lib/juju.py 2014-06-11 08:47:29 +0000
114+++ landscape/lib/juju.py 2014-08-28 07:37:26 +0000
115@@ -9,22 +9,28 @@
116
117 def get_juju_info(config):
118 """
119- Returns the list of Juju info or C{None} if the path referenced from
120+ Returns available Juju info or C{None} if the path referenced from
121 L{config} is not a valid directory.
122
123- The list of juju info is constructed by appending all the contents of
124+ XXX At the moment this function returns a 2-tuple because we're
125+ transitioning from unit-computer associations to machine-computer
126+ associations. Once the transition is completed in the server, the
127+ old format can be dropped.
128+
129+ The list of old juju info is constructed by appending all the contents of
130 *.json files found in the path referenced from the L{config}.
131 """
132 juju_directory = config.juju_directory
133 legacy_juju_file = config.juju_filename
134
135+ new_juju_info = {}
136 juju_info_list = []
137 juju_file_list = glob("%s/*.json" % juju_directory)
138
139 if os.path.exists(legacy_juju_file):
140 juju_file_list.append(legacy_juju_file)
141
142- for juju_file in juju_file_list:
143+ for index, juju_file in enumerate(juju_file_list):
144
145 json_contents = read_file(juju_file)
146 try:
147@@ -36,11 +42,25 @@
148 logging.exception(
149 "Error attempting to read JSON from %s" % juju_file)
150 return None
151- else:
152- if "api-addresses" in juju_info:
153- split = juju_info["api-addresses"].split()
154- juju_info["api-addresses"] = split
155- juju_info_list.append(juju_info)
156+
157+ if "api-addresses" in juju_info:
158+ split = juju_info["api-addresses"].split()
159+ juju_info["api-addresses"] = split
160+
161+ # Strip away machine-id, which is not understood by the old format
162+ machine_id = juju_info.pop("machine-id", None)
163+
164+ if index == 0 and machine_id is not None:
165+ # We care only about the first file, as the machine ID is the same
166+ # for all
167+ new_juju_info["environment-uuid"] = juju_info["environment-uuid"]
168+ new_juju_info["api-addresses"] = juju_info["api-addresses"]
169+ new_juju_info["machine-id"] = machine_id
170+
171+ juju_info_list.append(juju_info)
172
173 juju_info_list.sort(key=lambda x: x["unit-name"])
174- return juju_info_list or None
175+
176+ if juju_info_list:
177+ return juju_info_list, new_juju_info
178+ return None
179
180=== modified file 'landscape/lib/tests/test_juju.py'
181--- landscape/lib/tests/test_juju.py 2014-06-11 08:47:29 +0000
182+++ landscape/lib/tests/test_juju.py 2014-08-28 07:37:26 +0000
183@@ -6,11 +6,13 @@
184
185
186 SAMPLE_JUJU_INFO = json.dumps({"environment-uuid": "DEAD-BEEF",
187+ "machine-id": "1",
188 "unit-name": "service/0",
189 "api-addresses": "10.0.3.1:17070",
190 "private-address": "127.0.0.1"})
191
192 SAMPLE_JUJU_INFO_2 = json.dumps({"environment-uuid": "DEAD-BEEF",
193+ "machine-id": "1",
194 "unit-name": "service-2/0",
195 "api-addresses": "10.0.3.2:17070",
196 "private-address": "127.0.0.1"})
197@@ -28,11 +30,23 @@
198 return self.makeFile(
199 contents, dirname=self.stub_config.juju_directory, suffix=".json")
200
201+ def test_get_juju_info(self):
202+ """
203+ L{get_juju_info} parses JSON data from the '*.json' files in the
204+ juju_directory. A single file is present.
205+ """
206+ self._create_tmp_juju_file(SAMPLE_JUJU_INFO)
207+ _, juju_info = get_juju_info(self.stub_config)
208+ self.assertEqual(
209+ {u"environment-uuid": "DEAD-BEEF",
210+ u"machine-id": "1",
211+ u"api-addresses": ["10.0.3.1:17070"]}, juju_info)
212+
213 def test_get_juju_info_sample_data(self):
214 """L{get_juju_info} parses JSON data from the '*.json' files in the
215 juju_directory. A single file is present."""
216 self._create_tmp_juju_file(SAMPLE_JUJU_INFO)
217- juju_info = get_juju_info(self.stub_config)
218+ juju_info, _ = get_juju_info(self.stub_config)
219 self.assertEqual([
220 {u"environment-uuid": "DEAD-BEEF",
221 u"unit-name": "service/0",
222@@ -45,7 +59,7 @@
223 landscape-client charm."""
224 self.stub_config = self.Config(self.makeDir(), self.makeFile(
225 content=SAMPLE_JUJU_INFO, basename="juju-info", suffix=".json"))
226- juju_info = get_juju_info(self.stub_config)
227+ juju_info, _ = get_juju_info(self.stub_config)
228 self.assertEqual([
229 {u"environment-uuid": "DEAD-BEEF",
230 u"unit-name": "service/0",
231@@ -59,7 +73,7 @@
232 """
233 self._create_tmp_juju_file(SAMPLE_JUJU_INFO)
234 self._create_tmp_juju_file(SAMPLE_JUJU_INFO_2)
235- juju_info = get_juju_info(self.stub_config)
236+ juju_info, _ = get_juju_info(self.stub_config)
237 self.assertEqual([
238 {u"environment-uuid": "DEAD-BEEF",
239 u"unit-name": "service-2/0",
240@@ -77,7 +91,7 @@
241 self._create_tmp_juju_file(SAMPLE_JUJU_INFO)
242 self.makeFile(SAMPLE_JUJU_INFO_2, suffix=".txt",
243 dirname=self.stub_config.juju_directory)
244- juju_info = get_juju_info(self.stub_config)
245+ juju_info, _ = get_juju_info(self.stub_config)
246 self.assertEqual([
247 {u"environment-uuid": "DEAD-BEEF",
248 u"unit-name": "service/0",
249@@ -89,10 +103,9 @@
250 If L{get_juju_info} is called with a configuration pointing to
251 an empty file, it returns C{None}.
252 """
253+ self.log_helper.ignore_errors(ValueError)
254 self._create_tmp_juju_file("")
255- juju_info = get_juju_info(self.stub_config)
256- self.log_helper.ignore_errors(ValueError)
257- self.assertEqual(juju_info, None)
258+ self.assertIs(None, get_juju_info(self.stub_config))
259 self.assertIn("Error attempting to read JSON", self.logfile.getvalue())
260
261 def test_get_juju_info_no_json_file(self):
262@@ -100,19 +113,19 @@
263 If L{get_juju_info} is called with a configuration pointing to
264 a directory containing no json files, it returns None.
265 """
266- juju_info = get_juju_info(self.stub_config)
267- self.assertIs(juju_info, None)
268+ self.assertIs(None, get_juju_info(self.stub_config))
269
270 def test_get_juju_info_multiple_endpoints(self):
271 """L{get_juju_info} turns space separated API addresses into a list."""
272 juju_multiple_endpoints = json.dumps({
273 "environment-uuid": "DEAD-BEEF",
274+ "machine-id": "0",
275 "unit-name": "service/0",
276 "api-addresses": "10.0.3.1:17070 10.0.3.2:18080",
277 "private-address": "127.0.0.1"})
278
279 self._create_tmp_juju_file(juju_multiple_endpoints)
280- juju_info = get_juju_info(self.stub_config)
281+ juju_info, _ = get_juju_info(self.stub_config)
282 self.assertEqual([
283 {"environment-uuid": "DEAD-BEEF",
284 "unit-name": "service/0",
285
286=== modified file 'landscape/monitor/jujuinfo.py'
287--- landscape/monitor/jujuinfo.py 2014-06-30 18:40:29 +0000
288+++ landscape/monitor/jujuinfo.py 2014-08-28 07:37:26 +0000
289@@ -5,7 +5,12 @@
290
291
292 class JujuInfo(MonitorPlugin):
293- """Plugin for reporting Juju information."""
294+ """Plugin for reporting Juju information.
295+
296+ XXX this plugin is going to be dropped when the transition from
297+ unit-computer association to machine-computer association is
298+ completed on the server.
299+ """
300
301 persist_name = "juju-info"
302 scope = "juju"
303@@ -35,6 +40,9 @@
304 """
305 juju_info = get_juju_info(self.registry.config)
306
307+ if juju_info:
308+ juju_info = juju_info[0]
309+
310 if juju_info != self._persist.get("juju-info"):
311 self._persist.set("juju-info", juju_info)
312 message = {"type": "juju-units-info",
313
314=== modified file 'landscape/monitor/tests/test_jujuinfo.py'
315--- landscape/monitor/tests/test_jujuinfo.py 2014-06-27 11:02:24 +0000
316+++ landscape/monitor/tests/test_jujuinfo.py 2014-08-28 07:37:26 +0000
317@@ -6,6 +6,7 @@
318
319
320 SAMPLE_JUJU_INFO = json.dumps({"environment-uuid": "DEAD-BEEF",
321+ "machine-id": "1",
322 "unit-name": "juju-unit-name",
323 "api-addresses": "10.0.3.1:17070",
324 "private-address": "127.0.0.1"})
325@@ -72,6 +73,7 @@
326
327 self.makeFile(
328 json.dumps({"environment-uuid": "FEED-BEEF",
329+ "machine-id": "1",
330 "unit-name": "changed-unit-name",
331 "api-addresses": "10.0.3.2:17070",
332 "private-address": "127.0.1.1"}),

Subscribers

People subscribed via source and target branches

to all changes: