Merge lp:~jaypipes/nova/compute-manager-instance-data into lp:~hudson-openstack/nova/trunk
- compute-manager-instance-data
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Eric Day |
Approved revision: | 376 |
Merged at revision: | 388 |
Proposed branch: | lp:~jaypipes/nova/compute-manager-instance-data |
Merge into: | lp:~hudson-openstack/nova/trunk |
Diff against target: |
443 lines (+104/-78) 7 files modified
nova/api/ec2/cloud.py (+18/-16) nova/api/openstack/servers.py (+12/-15) nova/compute/manager.py (+40/-0) nova/db/sqlalchemy/api.py (+22/-44) nova/db/sqlalchemy/models.py (+10/-0) nova/tests/api/openstack/fakes.py (+1/-0) nova/tests/api/openstack/test_servers.py (+1/-3) |
To merge this branch: | bzr merge lp:~jaypipes/nova/compute-manager-instance-data |
Related bugs: | |
Related blueprints: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Eric Day (community) | Approve | ||
Devin Carlen (community) | Approve | ||
Review via email: mp+39182@code.launchpad.net |
Commit message
Moves db writes into compute manager class. Cleans up sqlalchemy model/api to remove redundant calls for updating what is really a dict.
Description of the change
Moves db writes into compute manager class. Cleans up sqlalchemy model/api to remove redundant calls for updating what is really a dict.
Jay Pipes (jaypipes) wrote : | # |
On Mon, Oct 25, 2010 at 7:38 PM, Eric Day <email address hidden> wrote:
> Review: Needs Fixing
> The second part looks fine, but any reason you build a dict and pass that for instance_data rather than just using kwargs directly for create/
>
> self.compute_
>
> And then just use **kwargs inside the methods to pass to the DB layer?
Ya, good point :)
> Also, this has text conflicts with trunk and introduces pep8 violations. :)
I will fix em shortly.
Cheers!
jay
Eric Day (eday) wrote : | # |
Hmm, this might be too nit picky, but this still seems a bit more verbose than it needs to be. :)
For example, lines 18-24 could just be:
instance_ref = self.compute_
And create_instance would be changed to:
def create_
instance_ref = self.db.
inst_id = instance_ref['id']
...
Also, 57-62 could be:
self.compute_
And again use **kwargs directly in update_instance. I guess I just prefer passing kwargs directly rather than passing in a dict for these sorts of things.
Devin Carlen (devcamcar) wrote : | # |
Good stuff! Always love to see the middle tier emerge more.
Eric Day (eday) wrote : | # |
The 'updated_data' variable is no longer used (lines 54-56). Other than that, looks good!
Jay Pipes (jaypipes) wrote : | # |
OK, removed the updated_data variable.
Preview Diff
1 | === modified file 'nova/api/ec2/cloud.py' |
2 | --- nova/api/ec2/cloud.py 2010-10-26 00:44:23 +0000 |
3 | +++ nova/api/ec2/cloud.py 2010-10-28 15:46:05 +0000 |
4 | @@ -99,6 +99,7 @@ |
5 | """ |
6 | def __init__(self): |
7 | self.network_manager = utils.import_object(FLAGS.network_manager) |
8 | + self.compute_manager = utils.import_object(FLAGS.compute_manager) |
9 | self.setup() |
10 | |
11 | def __str__(self): |
12 | @@ -835,21 +836,21 @@ |
13 | elevated = context.elevated() |
14 | |
15 | for num in range(num_instances): |
16 | - instance_ref = db.instance_create(context, base_options) |
17 | + |
18 | + instance_ref = self.compute_manager.create_instance(context, |
19 | + security_groups, |
20 | + mac_address=utils.generate_mac(), |
21 | + launch_index=num, |
22 | + **base_options) |
23 | inst_id = instance_ref['id'] |
24 | |
25 | - for security_group_id in security_groups: |
26 | - db.instance_add_security_group(elevated, |
27 | - inst_id, |
28 | - security_group_id) |
29 | - |
30 | - inst = {} |
31 | - inst['mac_address'] = utils.generate_mac() |
32 | - inst['launch_index'] = num |
33 | internal_id = instance_ref['internal_id'] |
34 | ec2_id = internal_id_to_ec2_id(internal_id) |
35 | - inst['hostname'] = ec2_id |
36 | - db.instance_update(context, inst_id, inst) |
37 | + |
38 | + self.compute_manager.update_instance(context, |
39 | + inst_id, |
40 | + hostname=ec2_id) |
41 | + |
42 | # TODO(vish): This probably should be done in the scheduler |
43 | # or in compute as a call. The network should be |
44 | # allocated after the host is assigned and setup |
45 | @@ -895,11 +896,12 @@ |
46 | id_str) |
47 | continue |
48 | now = datetime.datetime.utcnow() |
49 | - db.instance_update(context, |
50 | - instance_ref['id'], |
51 | - {'state_description': 'terminating', |
52 | - 'state': 0, |
53 | - 'terminated_at': now}) |
54 | + self.compute_manager.update_instance(context, |
55 | + instance_ref['id'], |
56 | + state_description='terminating', |
57 | + state=0, |
58 | + terminated_at=now) |
59 | + |
60 | # FIXME(ja): where should network deallocate occur? |
61 | address = db.instance_get_floating_address(context, |
62 | instance_ref['id']) |
63 | |
64 | === modified file 'nova/api/openstack/servers.py' |
65 | --- nova/api/openstack/servers.py 2010-10-21 22:26:06 +0000 |
66 | +++ nova/api/openstack/servers.py 2010-10-28 15:46:05 +0000 |
67 | @@ -95,6 +95,7 @@ |
68 | db_driver = FLAGS.db_driver |
69 | self.db_driver = utils.import_object(db_driver) |
70 | self.network_manager = utils.import_object(FLAGS.network_manager) |
71 | + self.compute_manager = utils.import_object(FLAGS.compute_manager) |
72 | super(Controller, self).__init__() |
73 | |
74 | def index(self, req): |
75 | @@ -242,34 +243,30 @@ |
76 | inst['memory_mb'] = flavor['memory_mb'] |
77 | inst['vcpus'] = flavor['vcpus'] |
78 | inst['local_gb'] = flavor['local_gb'] |
79 | - |
80 | - ref = self.db_driver.instance_create(ctxt, inst) |
81 | - inst['id'] = ref.internal_id |
82 | - |
83 | inst['mac_address'] = utils.generate_mac() |
84 | - |
85 | - #TODO(dietz) is this necessary? |
86 | inst['launch_index'] = 0 |
87 | |
88 | - inst['hostname'] = str(ref.internal_id) |
89 | - self.db_driver.instance_update(ctxt, inst['id'], inst) |
90 | - |
91 | - network_manager = utils.import_object(FLAGS.network_manager) |
92 | - address = network_manager.allocate_fixed_ip(ctxt, |
93 | - inst['id']) |
94 | + ref = self.compute_manager.create_instance(ctxt, **inst) |
95 | + inst['id'] = ref['internal_id'] |
96 | + |
97 | + inst['hostname'] = str(ref['internal_id']) |
98 | + self.compute_manager.update_instance(ctxt, inst['id'], **inst) |
99 | + |
100 | + address = self.network_manager.allocate_fixed_ip(ctxt, |
101 | + inst['id']) |
102 | |
103 | # TODO(vish): This probably should be done in the scheduler |
104 | # network is setup when host is assigned |
105 | - network_topic = self._get_network_topic(ctxt, network_manager) |
106 | + network_topic = self._get_network_topic(ctxt) |
107 | rpc.call(ctxt, |
108 | network_topic, |
109 | {"method": "setup_fixed_ip", |
110 | "args": {"address": address}}) |
111 | return inst |
112 | |
113 | - def _get_network_topic(self, context, network_manager): |
114 | + def _get_network_topic(self, context): |
115 | """Retrieves the network host for a project""" |
116 | - network_ref = network_manager.get_network(context) |
117 | + network_ref = self.network_manager.get_network(context) |
118 | host = network_ref['host'] |
119 | if not host: |
120 | host = rpc.call(context, |
121 | |
122 | === modified file 'nova/compute/manager.py' |
123 | --- nova/compute/manager.py 2010-10-25 02:52:02 +0000 |
124 | +++ nova/compute/manager.py 2010-10-28 15:46:05 +0000 |
125 | @@ -69,6 +69,46 @@ |
126 | def refresh_security_group(self, context, security_group_id, **_kwargs): |
127 | yield self.driver.refresh_security_group(security_group_id) |
128 | |
129 | + def create_instance(self, context, security_groups=[], **kwargs): |
130 | + """Creates the instance in the datastore and returns the |
131 | + new instance as a mapping |
132 | + |
133 | + :param context: The security context |
134 | + :param security_groups: list of security group ids to |
135 | + attach to the instance |
136 | + :param **kwargs: All additional keyword args are treated |
137 | + as data fields of the instance to be |
138 | + created |
139 | + |
140 | + :retval Returns a mapping of the instance information |
141 | + that has just been created |
142 | + |
143 | + """ |
144 | + instance_ref = self.db.instance_create(context, kwargs) |
145 | + inst_id = instance_ref['id'] |
146 | + |
147 | + elevated = context.elevated() |
148 | + security_groups = kwargs.get('security_groups', []) |
149 | + for security_group_id in security_groups: |
150 | + self.db.instance_add_security_group(elevated, |
151 | + inst_id, |
152 | + security_group_id) |
153 | + return instance_ref |
154 | + |
155 | + def update_instance(self, context, instance_id, **kwargs): |
156 | + """Updates the instance in the datastore |
157 | + |
158 | + :param context: The security context |
159 | + :param instance_id: ID of the instance to update |
160 | + :param **kwargs: All additional keyword args are treated |
161 | + as data fields of the instance to be |
162 | + updated |
163 | + |
164 | + :retval None |
165 | + |
166 | + """ |
167 | + self.db.instance_update(context, instance_id, kwargs) |
168 | + |
169 | @defer.inlineCallbacks |
170 | @exception.wrap_exception |
171 | def run_instance(self, context, instance_id, **_kwargs): |
172 | |
173 | === modified file 'nova/db/sqlalchemy/api.py' |
174 | --- nova/db/sqlalchemy/api.py 2010-10-26 00:15:56 +0000 |
175 | +++ nova/db/sqlalchemy/api.py 2010-10-28 15:46:05 +0000 |
176 | @@ -236,8 +236,7 @@ |
177 | @require_admin_context |
178 | def service_create(context, values): |
179 | service_ref = models.Service() |
180 | - for (key, value) in values.iteritems(): |
181 | - service_ref[key] = value |
182 | + service_ref.update(values) |
183 | service_ref.save() |
184 | return service_ref |
185 | |
186 | @@ -247,8 +246,7 @@ |
187 | session = get_session() |
188 | with session.begin(): |
189 | service_ref = service_get(context, service_id, session=session) |
190 | - for (key, value) in values.iteritems(): |
191 | - service_ref[key] = value |
192 | + service_ref.update(values) |
193 | service_ref.save(session=session) |
194 | |
195 | |
196 | @@ -279,8 +277,7 @@ |
197 | @require_context |
198 | def floating_ip_create(context, values): |
199 | floating_ip_ref = models.FloatingIp() |
200 | - for (key, value) in values.iteritems(): |
201 | - floating_ip_ref[key] = value |
202 | + floating_ip_ref.update(values) |
203 | floating_ip_ref.save() |
204 | return floating_ip_ref['address'] |
205 | |
206 | @@ -451,8 +448,7 @@ |
207 | @require_context |
208 | def fixed_ip_create(_context, values): |
209 | fixed_ip_ref = models.FixedIp() |
210 | - for (key, value) in values.iteritems(): |
211 | - fixed_ip_ref[key] = value |
212 | + fixed_ip_ref.update(values) |
213 | fixed_ip_ref.save() |
214 | return fixed_ip_ref['address'] |
215 | |
216 | @@ -523,8 +519,7 @@ |
217 | fixed_ip_ref = fixed_ip_get_by_address(context, |
218 | address, |
219 | session=session) |
220 | - for (key, value) in values.iteritems(): |
221 | - fixed_ip_ref[key] = value |
222 | + fixed_ip_ref.update(values) |
223 | fixed_ip_ref.save(session=session) |
224 | |
225 | |
226 | @@ -537,8 +532,7 @@ |
227 | @require_context |
228 | def instance_create(context, values): |
229 | instance_ref = models.Instance() |
230 | - for (key, value) in values.iteritems(): |
231 | - instance_ref[key] = value |
232 | + instance_ref.update(values) |
233 | |
234 | session = get_session() |
235 | with session.begin(): |
236 | @@ -731,8 +725,7 @@ |
237 | session = get_session() |
238 | with session.begin(): |
239 | instance_ref = instance_get(context, instance_id, session=session) |
240 | - for (key, value) in values.iteritems(): |
241 | - instance_ref[key] = value |
242 | + instance_ref.update(values) |
243 | instance_ref.save(session=session) |
244 | |
245 | |
246 | @@ -754,8 +747,7 @@ |
247 | @require_context |
248 | def key_pair_create(context, values): |
249 | key_pair_ref = models.KeyPair() |
250 | - for (key, value) in values.iteritems(): |
251 | - key_pair_ref[key] = value |
252 | + key_pair_ref.update(values) |
253 | key_pair_ref.save() |
254 | return key_pair_ref |
255 | |
256 | @@ -870,8 +862,7 @@ |
257 | @require_admin_context |
258 | def network_create_safe(context, values): |
259 | network_ref = models.Network() |
260 | - for (key, value) in values.iteritems(): |
261 | - network_ref[key] = value |
262 | + network_ref.update(values) |
263 | try: |
264 | network_ref.save() |
265 | return network_ref |
266 | @@ -980,8 +971,7 @@ |
267 | session = get_session() |
268 | with session.begin(): |
269 | network_ref = network_get(context, network_id, session=session) |
270 | - for (key, value) in values.iteritems(): |
271 | - network_ref[key] = value |
272 | + network_ref.update(values) |
273 | network_ref.save(session=session) |
274 | |
275 | |
276 | @@ -1031,8 +1021,7 @@ |
277 | @require_admin_context |
278 | def export_device_create_safe(context, values): |
279 | export_device_ref = models.ExportDevice() |
280 | - for (key, value) in values.iteritems(): |
281 | - export_device_ref[key] = value |
282 | + export_device_ref.update(values) |
283 | try: |
284 | export_device_ref.save() |
285 | return export_device_ref |
286 | @@ -1060,8 +1049,7 @@ |
287 | |
288 | def auth_create_token(_context, token): |
289 | tk = models.AuthToken() |
290 | - for k, v in token.iteritems(): |
291 | - tk[k] = v |
292 | + tk.update(token) |
293 | tk.save() |
294 | return tk |
295 | |
296 | @@ -1087,8 +1075,7 @@ |
297 | @require_admin_context |
298 | def quota_create(context, values): |
299 | quota_ref = models.Quota() |
300 | - for (key, value) in values.iteritems(): |
301 | - quota_ref[key] = value |
302 | + quota_ref.update(values) |
303 | quota_ref.save() |
304 | return quota_ref |
305 | |
306 | @@ -1098,8 +1085,7 @@ |
307 | session = get_session() |
308 | with session.begin(): |
309 | quota_ref = quota_get(context, project_id, session=session) |
310 | - for (key, value) in values.iteritems(): |
311 | - quota_ref[key] = value |
312 | + quota_ref.update(values) |
313 | quota_ref.save(session=session) |
314 | |
315 | |
316 | @@ -1148,8 +1134,7 @@ |
317 | @require_context |
318 | def volume_create(context, values): |
319 | volume_ref = models.Volume() |
320 | - for (key, value) in values.iteritems(): |
321 | - volume_ref[key] = value |
322 | + volume_ref.update(values) |
323 | |
324 | session = get_session() |
325 | with session.begin(): |
326 | @@ -1306,8 +1291,7 @@ |
327 | session = get_session() |
328 | with session.begin(): |
329 | volume_ref = volume_get(context, volume_id, session=session) |
330 | - for (key, value) in values.iteritems(): |
331 | - volume_ref[key] = value |
332 | + volume_ref.update(values) |
333 | volume_ref.save(session=session) |
334 | |
335 | |
336 | @@ -1400,8 +1384,7 @@ |
337 | # FIXME(devcamcar): Unless I do this, rules fails with lazy load exception |
338 | # once save() is called. This will get cleaned up in next orm pass. |
339 | security_group_ref.rules |
340 | - for (key, value) in values.iteritems(): |
341 | - security_group_ref[key] = value |
342 | + security_group_ref.update(values) |
343 | security_group_ref.save() |
344 | return security_group_ref |
345 | |
346 | @@ -1455,8 +1438,7 @@ |
347 | @require_context |
348 | def security_group_rule_create(context, values): |
349 | security_group_rule_ref = models.SecurityGroupIngressRule() |
350 | - for (key, value) in values.iteritems(): |
351 | - security_group_rule_ref[key] = value |
352 | + security_group_rule_ref.update(values) |
353 | security_group_rule_ref.save() |
354 | return security_group_rule_ref |
355 | |
356 | @@ -1508,8 +1490,7 @@ |
357 | @require_admin_context |
358 | def user_create(_context, values): |
359 | user_ref = models.User() |
360 | - for (key, value) in values.iteritems(): |
361 | - user_ref[key] = value |
362 | + user_ref.update(values) |
363 | user_ref.save() |
364 | return user_ref |
365 | |
366 | @@ -1537,8 +1518,7 @@ |
367 | |
368 | def project_create(_context, values): |
369 | project_ref = models.Project() |
370 | - for (key, value) in values.iteritems(): |
371 | - project_ref[key] = value |
372 | + project_ref.update(values) |
373 | project_ref.save() |
374 | return project_ref |
375 | |
376 | @@ -1600,8 +1580,7 @@ |
377 | session = get_session() |
378 | with session.begin(): |
379 | user_ref = user_get(context, user_id, session=session) |
380 | - for (key, value) in values.iteritems(): |
381 | - user_ref[key] = value |
382 | + user_ref.update(values) |
383 | user_ref.save(session=session) |
384 | |
385 | |
386 | @@ -1609,8 +1588,7 @@ |
387 | session = get_session() |
388 | with session.begin(): |
389 | project_ref = project_get(context, project_id, session=session) |
390 | - for (key, value) in values.iteritems(): |
391 | - project_ref[key] = value |
392 | + project_ref.update(values) |
393 | project_ref.save(session=session) |
394 | |
395 | |
396 | |
397 | === modified file 'nova/db/sqlalchemy/models.py' |
398 | --- nova/db/sqlalchemy/models.py 2010-10-25 06:26:03 +0000 |
399 | +++ nova/db/sqlalchemy/models.py 2010-10-28 15:46:05 +0000 |
400 | @@ -82,6 +82,16 @@ |
401 | n = self._i.next().name |
402 | return n, getattr(self, n) |
403 | |
404 | + def update(self, values): |
405 | + """Make the model object behave like a dict""" |
406 | + for k, v in values.iteritems(): |
407 | + setattr(self, k, v) |
408 | + |
409 | + def iteritems(self): |
410 | + """Make the model object behave like a dict""" |
411 | + return iter(self) |
412 | + |
413 | + |
414 | # TODO(vish): Store images in the database instead of file system |
415 | #class Image(BASE, NovaBase): |
416 | # """Represents an image in the datastore""" |
417 | |
418 | === modified file 'nova/tests/api/openstack/fakes.py' |
419 | --- nova/tests/api/openstack/fakes.py 2010-10-22 07:48:27 +0000 |
420 | +++ nova/tests/api/openstack/fakes.py 2010-10-28 15:46:05 +0000 |
421 | @@ -30,6 +30,7 @@ |
422 | import nova.api.openstack.auth |
423 | from nova.image import service |
424 | from nova.image.services import glance |
425 | +from nova.tests import fake_flags |
426 | from nova.wsgi import Router |
427 | |
428 | |
429 | |
430 | === modified file 'nova/tests/api/openstack/test_servers.py' |
431 | --- nova/tests/api/openstack/test_servers.py 2010-10-22 07:48:27 +0000 |
432 | +++ nova/tests/api/openstack/test_servers.py 2010-10-28 15:46:05 +0000 |
433 | @@ -91,9 +91,7 @@ |
434 | pass |
435 | |
436 | def instance_create(context, inst): |
437 | - class Foo(object): |
438 | - internal_id = 1 |
439 | - return Foo() |
440 | + return {'id': 1, 'internal_id': 1} |
441 | |
442 | def fake_method(*args, **kwargs): |
443 | pass |
The second part looks fine, but any reason you build a dict and pass that for instance_data rather than just using kwargs directly for create/ update_ instance? For example:
self.compute_ manager. create_ instance( context, security_ groups= security_ groups, mac_address= utils.generate_ mac(), launch_index=num, **base_options)
And then just use **kwargs inside the methods to pass to the DB layer?
Also, this has text conflicts with trunk and introduces pep8 violations. :)