Merge lp:~soren/nova/virt-layer-cleanup into lp:~hudson-openstack/nova/trunk
- virt-layer-cleanup
- Merge into trunk
Proposed by
Soren Hansen
Status: | Merged |
---|---|
Approved by: | Vish Ishaya |
Approved revision: | 1468 |
Merged at revision: | 1474 |
Proposed branch: | lp:~soren/nova/virt-layer-cleanup |
Merge into: | lp:~hudson-openstack/nova/trunk |
Diff against target: |
815 lines (+270/-297) 2 files modified
nova/virt/driver.py (+267/-24) nova/virt/fake.py (+3/-273) |
To merge this branch: | bzr merge lp:~soren/nova/virt-layer-cleanup |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Dan Prince (community) | Approve | ||
Brian Lamar (community) | Approve | ||
Review via email: mp+72173@code.launchpad.net |
Commit message
Move documentation from nova.virt.fake into nova.virt.driver.
Description of the change
I'm working on cleaning a bunch of things up in the virt layer. This is the first, simple step.
What I've done is simply to move the documentation from nova.virt.fake to nova.virt.driver, remove all claims that these calls "are asynchronous and will return a task", because they're not and they don't. :)
To post a comment you must log in.
Revision history for this message
Dan Prince (dan-prince) : | # |
review:
Approve
Revision history for this message
Soren Hansen (soren) wrote : | # |
> Not sure why the documentation was in fake.py in the first place...
We didn't always have the abstract class.
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : | # |
There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.
Revision history for this message
Soren Hansen (soren) wrote : | # |
hello-o?
Revision history for this message
Vish Ishaya (vishvananda) wrote : | # |
retrying
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'nova/virt/driver.py' |
2 | --- nova/virt/driver.py 2011-08-13 05:36:10 +0000 |
3 | +++ nova/virt/driver.py 2011-08-19 18:12:26 +0000 |
4 | @@ -62,11 +62,41 @@ |
5 | class ComputeDriver(object): |
6 | """Base class for compute drivers. |
7 | |
8 | - Lots of documentation is currently on fake.py. |
9 | + The interface to this class talks in terms of 'instances' (Amazon EC2 and |
10 | + internal Nova terminology), by which we mean 'running virtual machine' |
11 | + (XenAPI terminology) or domain (Xen or libvirt terminology). |
12 | + |
13 | + An instance has an ID, which is the identifier chosen by Nova to represent |
14 | + the instance further up the stack. This is unfortunately also called a |
15 | + 'name' elsewhere. As far as this layer is concerned, 'instance ID' and |
16 | + 'instance name' are synonyms. |
17 | + |
18 | + Note that the instance ID or name is not human-readable or |
19 | + customer-controlled -- it's an internal ID chosen by Nova. At the |
20 | + nova.virt layer, instances do not have human-readable names at all -- such |
21 | + things are only known higher up the stack. |
22 | + |
23 | + Most virtualization platforms will also have their own identity schemes, |
24 | + to uniquely identify a VM or domain. These IDs must stay internal to the |
25 | + platform-specific layer, and never escape the connection interface. The |
26 | + platform-specific layer is responsible for keeping track of which instance |
27 | + ID maps to which platform-specific ID, and vice versa. |
28 | + |
29 | + In contrast, the list_disks and list_interfaces calls may return |
30 | + platform-specific IDs. These identify a specific virtual disk or specific |
31 | + virtual network interface, and these IDs are opaque to the rest of Nova. |
32 | + |
33 | + Some methods here take an instance of nova.compute.service.Instance. This |
34 | + is the datastructure used by nova.compute to store details regarding an |
35 | + instance, and pass them into this layer. This layer is responsible for |
36 | + translating that generic datastructure into terms that are specific to the |
37 | + virtualization platform. |
38 | + |
39 | """ |
40 | |
41 | def init_host(self, host): |
42 | - """Adopt existing VM's running here""" |
43 | + """Initialize anything that is necessary for the driver to function, |
44 | + including catching up with currently running VM's on the given host.""" |
45 | # TODO(Vek): Need to pass context in for access to auth_token |
46 | raise NotImplementedError() |
47 | |
48 | @@ -74,6 +104,7 @@ |
49 | """Get the current status of an instance, by name (not ID!) |
50 | |
51 | Returns a dict containing: |
52 | + |
53 | :state: the running state, one of the power_state codes |
54 | :max_mem: (int) the maximum memory in KBytes allowed |
55 | :mem: (int) the memory in KBytes used by the domain |
56 | @@ -84,6 +115,10 @@ |
57 | raise NotImplementedError() |
58 | |
59 | def list_instances(self): |
60 | + """ |
61 | + Return the names of all the instances known to the virtualization |
62 | + layer, as a list. |
63 | + """ |
64 | # TODO(Vek): Need to pass context in for access to auth_token |
65 | raise NotImplementedError() |
66 | |
67 | @@ -94,28 +129,53 @@ |
68 | |
69 | def spawn(self, context, instance, |
70 | network_info=None, block_device_info=None): |
71 | - """Launch a VM for the specified instance""" |
72 | + """ |
73 | + Create a new instance/VM/domain on the virtualization platform. |
74 | + |
75 | + Once this successfully completes, the instance should be |
76 | + running (power_state.RUNNING). |
77 | + |
78 | + If this fails, any partial instance should be completely |
79 | + cleaned up, and the virtualization platform should be in the state |
80 | + that it was before this call began. |
81 | + |
82 | + :param context: security context |
83 | + :param instance: Instance of {nova.compute.service.Instance}. |
84 | + This function should use the data there to guide |
85 | + the creation of the new instance. |
86 | + :param network_info: |
87 | + :py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info` |
88 | + :param block_device_info: |
89 | + """ |
90 | raise NotImplementedError() |
91 | |
92 | def destroy(self, instance, network_info, cleanup=True): |
93 | """Destroy (shutdown and delete) the specified instance. |
94 | |
95 | The given parameter is an instance of nova.compute.service.Instance, |
96 | - and so the instance is being specified as instance.name. |
97 | - |
98 | - The work will be done asynchronously. This function returns a |
99 | - task that allows the caller to detect when it is complete. |
100 | |
101 | If the instance is not found (for example if networking failed), this |
102 | function should still succeed. It's probably a good idea to log a |
103 | warning in that case. |
104 | |
105 | + :param instance: Instance of {nova.compute.service.Instance} and so |
106 | + the instance is being specified as instance.name. |
107 | + :param network_info: |
108 | + :py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info` |
109 | + :param cleanup: |
110 | + |
111 | """ |
112 | # TODO(Vek): Need to pass context in for access to auth_token |
113 | raise NotImplementedError() |
114 | |
115 | def reboot(self, instance, network_info): |
116 | - """Reboot specified VM""" |
117 | + """Reboot the specified instance. |
118 | + |
119 | + :param instance: Instance of {nova.compute.service.Instance} and so |
120 | + the instance is being specified as instance.name. |
121 | + :param network_info: |
122 | + :py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info` |
123 | + """ |
124 | # TODO(Vek): Need to pass context in for access to auth_token |
125 | raise NotImplementedError() |
126 | |
127 | @@ -140,31 +200,60 @@ |
128 | raise NotImplementedError() |
129 | |
130 | def get_host_ip_addr(self): |
131 | + """ |
132 | + Retrieves the IP address of the dom0 |
133 | + """ |
134 | # TODO(Vek): Need to pass context in for access to auth_token |
135 | raise NotImplementedError() |
136 | |
137 | def attach_volume(self, context, instance_id, volume_id, mountpoint): |
138 | + """Attach the disk at device_path to the instance at mountpoint""" |
139 | raise NotImplementedError() |
140 | |
141 | def detach_volume(self, context, instance_id, volume_id): |
142 | + """Detach the disk attached to the instance at mountpoint""" |
143 | raise NotImplementedError() |
144 | |
145 | - def compare_cpu(self, context, cpu_info): |
146 | + def compare_cpu(self, cpu_info): |
147 | + """Compares given cpu info against host |
148 | + |
149 | + Before attempting to migrate a VM to this host, |
150 | + compare_cpu is called to ensure that the VM will |
151 | + actually run here. |
152 | + |
153 | + :param cpu_info: (str) JSON structure describing the source CPU. |
154 | + :returns: None if migration is acceptable |
155 | + :raises: :py:class:`~nova.exception.InvalidCPUInfo` if migration |
156 | + is not acceptable. |
157 | + """ |
158 | raise NotImplementedError() |
159 | |
160 | def migrate_disk_and_power_off(self, instance, dest): |
161 | - """Transfers the VHD of a running instance to another host, then shuts |
162 | - off the instance copies over the COW disk""" |
163 | + """ |
164 | + Transfers the disk of a running instance in multiple phases, turning |
165 | + off the instance before the end. |
166 | + """ |
167 | # TODO(Vek): Need to pass context in for access to auth_token |
168 | raise NotImplementedError() |
169 | |
170 | def snapshot(self, context, instance, image_id): |
171 | - """Create snapshot from a running VM instance.""" |
172 | + """ |
173 | + Snapshots the specified instance. |
174 | + |
175 | + The given parameter is an instance of nova.compute.service.Instance, |
176 | + and so the instance is being specified as instance.name. |
177 | + |
178 | + The second parameter is the name of the snapshot. |
179 | + """ |
180 | raise NotImplementedError() |
181 | |
182 | def finish_migration(self, context, instance, disk_info, network_info, |
183 | resize_instance): |
184 | - """Completes a resize, turning on the migrated instance""" |
185 | + """Completes a resize, turning on the migrated instance |
186 | + |
187 | + :param network_info: |
188 | + :py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info` |
189 | + """ |
190 | raise NotImplementedError() |
191 | |
192 | def revert_migration(self, instance): |
193 | @@ -173,7 +262,7 @@ |
194 | raise NotImplementedError() |
195 | |
196 | def pause(self, instance, callback): |
197 | - """Pause VM instance""" |
198 | + """Pause the specified instance.""" |
199 | # TODO(Vek): Need to pass context in for access to auth_token |
200 | raise NotImplementedError() |
201 | |
202 | @@ -218,15 +307,15 @@ |
203 | post_method, recover_method): |
204 | """Spawning live_migration operation for distributing high-load. |
205 | |
206 | - :params ctxt: security context |
207 | - :params instance_ref: |
208 | + :param ctxt: security context |
209 | + :param instance_ref: |
210 | nova.db.sqlalchemy.models.Instance object |
211 | instance object that is migrated. |
212 | - :params dest: destination host |
213 | - :params post_method: |
214 | + :param dest: destination host |
215 | + :param post_method: |
216 | post operation method. |
217 | expected nova.compute.manager.post_live_migration. |
218 | - :params recover_method: |
219 | + :param recover_method: |
220 | recovery method when any exception occurs. |
221 | expected nova.compute.manager.recover_live_migration. |
222 | |
223 | @@ -235,15 +324,69 @@ |
224 | raise NotImplementedError() |
225 | |
226 | def refresh_security_group_rules(self, security_group_id): |
227 | + """This method is called after a change to security groups. |
228 | + |
229 | + All security groups and their associated rules live in the datastore, |
230 | + and calling this method should apply the updated rules to instances |
231 | + running the specified security group. |
232 | + |
233 | + An error should be raised if the operation cannot complete. |
234 | + |
235 | + """ |
236 | # TODO(Vek): Need to pass context in for access to auth_token |
237 | raise NotImplementedError() |
238 | |
239 | def refresh_security_group_members(self, security_group_id): |
240 | + """This method is called when a security group is added to an instance. |
241 | + |
242 | + This message is sent to the virtualization drivers on hosts that are |
243 | + running an instance that belongs to a security group that has a rule |
244 | + that references the security group identified by `security_group_id`. |
245 | + It is the responsiblity of this method to make sure any rules |
246 | + that authorize traffic flow with members of the security group are |
247 | + updated and any new members can communicate, and any removed members |
248 | + cannot. |
249 | + |
250 | + Scenario: |
251 | + * we are running on host 'H0' and we have an instance 'i-0'. |
252 | + * instance 'i-0' is a member of security group 'speaks-b' |
253 | + * group 'speaks-b' has an ingress rule that authorizes group 'b' |
254 | + * another host 'H1' runs an instance 'i-1' |
255 | + * instance 'i-1' is a member of security group 'b' |
256 | + |
257 | + When 'i-1' launches or terminates we will recieve the message |
258 | + to update members of group 'b', at which time we will make |
259 | + any changes needed to the rules for instance 'i-0' to allow |
260 | + or deny traffic coming from 'i-1', depending on if it is being |
261 | + added or removed from the group. |
262 | + |
263 | + In this scenario, 'i-1' could just as easily have been running on our |
264 | + host 'H0' and this method would still have been called. The point was |
265 | + that this method isn't called on the host where instances of that |
266 | + group are running (as is the case with |
267 | + :method:`refresh_security_group_rules`) but is called where references |
268 | + are made to authorizing those instances. |
269 | + |
270 | + An error should be raised if the operation cannot complete. |
271 | + |
272 | + """ |
273 | # TODO(Vek): Need to pass context in for access to auth_token |
274 | raise NotImplementedError() |
275 | |
276 | def refresh_provider_fw_rules(self, security_group_id): |
277 | - """See: nova/virt/fake.py for docs.""" |
278 | + """This triggers a firewall update based on database changes. |
279 | + |
280 | + When this is called, rules have either been added or removed from the |
281 | + datastore. You can retrieve rules with |
282 | + :method:`nova.db.api.provider_fw_rule_get_all`. |
283 | + |
284 | + Provider rules take precedence over security group rules. If an IP |
285 | + would be allowed by a security group ingress rule, but blocked by |
286 | + a provider rule, then packets from the IP are dropped. This includes |
287 | + intra-project traffic in the case of the allow_project_net_traffic |
288 | + flag for the libvirt-derived classes. |
289 | + |
290 | + """ |
291 | # TODO(Vek): Need to pass context in for access to auth_token |
292 | raise NotImplementedError() |
293 | |
294 | @@ -284,18 +427,38 @@ |
295 | raise NotImplementedError() |
296 | |
297 | def set_admin_password(self, context, instance_id, new_pass=None): |
298 | - """Set the root/admin password for an instance on this server.""" |
299 | + """ |
300 | + Set the root password on the specified instance. |
301 | + |
302 | + The first parameter is an instance of nova.compute.service.Instance, |
303 | + and so the instance is being specified as instance.name. The second |
304 | + parameter is the value of the new password. |
305 | + """ |
306 | raise NotImplementedError() |
307 | |
308 | def inject_file(self, instance, b64_path, b64_contents): |
309 | - """Create a file on the VM instance. The file path and contents |
310 | - should be base64-encoded. |
311 | + """ |
312 | + Writes a file on the specified instance. |
313 | + |
314 | + The first parameter is an instance of nova.compute.service.Instance, |
315 | + and so the instance is being specified as instance.name. The second |
316 | + parameter is the base64-encoded path to which the file is to be |
317 | + written on the instance; the third is the contents of the file, also |
318 | + base64-encoded. |
319 | """ |
320 | # TODO(Vek): Need to pass context in for access to auth_token |
321 | raise NotImplementedError() |
322 | |
323 | def agent_update(self, instance, url, md5hash): |
324 | - """Update agent on the VM instance.""" |
325 | + """ |
326 | + Update agent on the specified instance. |
327 | + |
328 | + The first parameter is an instance of nova.compute.service.Instance, |
329 | + and so the instance is being specified as instance.name. The second |
330 | + parameter is the URL of the agent to be fetched and updated on the |
331 | + instance; the third is the md5 hash of the file for verification |
332 | + purposes. |
333 | + """ |
334 | # TODO(Vek): Need to pass context in for access to auth_token |
335 | raise NotImplementedError() |
336 | |
337 | @@ -322,3 +485,83 @@ |
338 | """Plugs in VIFs to networks.""" |
339 | # TODO(Vek): Need to pass context in for access to auth_token |
340 | raise NotImplementedError() |
341 | + |
342 | + def update_host_status(self): |
343 | + """Refresh host stats""" |
344 | + raise NotImplementedError() |
345 | + |
346 | + def get_host_stats(self, refresh=False): |
347 | + """Return currently known host stats""" |
348 | + raise NotImplementedError() |
349 | + |
350 | + def list_disks(self, instance_name): |
351 | + """ |
352 | + Return the IDs of all the virtual disks attached to the specified |
353 | + instance, as a list. These IDs are opaque to the caller (they are |
354 | + only useful for giving back to this layer as a parameter to |
355 | + disk_stats). These IDs only need to be unique for a given instance. |
356 | + |
357 | + Note that this function takes an instance ID. |
358 | + """ |
359 | + raise NotImplementedError() |
360 | + |
361 | + def list_interfaces(self, instance_name): |
362 | + """ |
363 | + Return the IDs of all the virtual network interfaces attached to the |
364 | + specified instance, as a list. These IDs are opaque to the caller |
365 | + (they are only useful for giving back to this layer as a parameter to |
366 | + interface_stats). These IDs only need to be unique for a given |
367 | + instance. |
368 | + |
369 | + Note that this function takes an instance ID. |
370 | + """ |
371 | + raise NotImplementedError() |
372 | + |
373 | + def resize(self, instance, flavor): |
374 | + """ |
375 | + Resizes/Migrates the specified instance. |
376 | + |
377 | + The flavor parameter determines whether or not the instance RAM and |
378 | + disk space are modified, and if so, to what size. |
379 | + """ |
380 | + raise NotImplementedError() |
381 | + |
382 | + def block_stats(self, instance_name, disk_id): |
383 | + """ |
384 | + Return performance counters associated with the given disk_id on the |
385 | + given instance_name. These are returned as [rd_req, rd_bytes, wr_req, |
386 | + wr_bytes, errs], where rd indicates read, wr indicates write, req is |
387 | + the total number of I/O requests made, bytes is the total number of |
388 | + bytes transferred, and errs is the number of requests held up due to a |
389 | + full pipeline. |
390 | + |
391 | + All counters are long integers. |
392 | + |
393 | + This method is optional. On some platforms (e.g. XenAPI) performance |
394 | + statistics can be retrieved directly in aggregate form, without Nova |
395 | + having to do the aggregation. On those platforms, this method is |
396 | + unused. |
397 | + |
398 | + Note that this function takes an instance ID. |
399 | + """ |
400 | + raise NotImplementedError() |
401 | + |
402 | + def interface_stats(self, instance_name, iface_id): |
403 | + """ |
404 | + Return performance counters associated with the given iface_id on the |
405 | + given instance_id. These are returned as [rx_bytes, rx_packets, |
406 | + rx_errs, rx_drop, tx_bytes, tx_packets, tx_errs, tx_drop], where rx |
407 | + indicates receive, tx indicates transmit, bytes and packets indicate |
408 | + the total number of bytes or packets transferred, and errs and dropped |
409 | + is the total number of packets failed / dropped. |
410 | + |
411 | + All counters are long integers. |
412 | + |
413 | + This method is optional. On some platforms (e.g. XenAPI) performance |
414 | + statistics can be retrieved directly in aggregate form, without Nova |
415 | + having to do the aggregation. On those platforms, this method is |
416 | + unused. |
417 | + |
418 | + Note that this function takes an instance ID. |
419 | + """ |
420 | + raise NotImplementedError() |
421 | |
422 | === modified file 'nova/virt/fake.py' |
423 | --- nova/virt/fake.py 2011-08-15 20:31:43 +0000 |
424 | +++ nova/virt/fake.py 2011-08-19 18:12:26 +0000 |
425 | @@ -48,37 +48,7 @@ |
426 | |
427 | |
428 | class FakeConnection(driver.ComputeDriver): |
429 | - """ |
430 | - The interface to this class talks in terms of 'instances' (Amazon EC2 and |
431 | - internal Nova terminology), by which we mean 'running virtual machine' |
432 | - (XenAPI terminology) or domain (Xen or libvirt terminology). |
433 | - |
434 | - An instance has an ID, which is the identifier chosen by Nova to represent |
435 | - the instance further up the stack. This is unfortunately also called a |
436 | - 'name' elsewhere. As far as this layer is concerned, 'instance ID' and |
437 | - 'instance name' are synonyms. |
438 | - |
439 | - Note that the instance ID or name is not human-readable or |
440 | - customer-controlled -- it's an internal ID chosen by Nova. At the |
441 | - nova.virt layer, instances do not have human-readable names at all -- such |
442 | - things are only known higher up the stack. |
443 | - |
444 | - Most virtualization platforms will also have their own identity schemes, |
445 | - to uniquely identify a VM or domain. These IDs must stay internal to the |
446 | - platform-specific layer, and never escape the connection interface. The |
447 | - platform-specific layer is responsible for keeping track of which instance |
448 | - ID maps to which platform-specific ID, and vice versa. |
449 | - |
450 | - In contrast, the list_disks and list_interfaces calls may return |
451 | - platform-specific IDs. These identify a specific virtual disk or specific |
452 | - virtual network interface, and these IDs are opaque to the rest of Nova. |
453 | - |
454 | - Some methods here take an instance of nova.compute.service.Instance. This |
455 | - is the datastructure used by nova.compute to store details regarding an |
456 | - instance, and pass them into this layer. This layer is responsible for |
457 | - translating that generic datastructure into terms that are specific to the |
458 | - virtualization platform. |
459 | - """ |
460 | + """Fake hypervisor driver""" |
461 | |
462 | def __init__(self): |
463 | self.instances = {} |
464 | @@ -105,17 +75,9 @@ |
465 | return cls._instance |
466 | |
467 | def init_host(self, host): |
468 | - """ |
469 | - Initialize anything that is necessary for the driver to function, |
470 | - including catching up with currently running VM's on the given host. |
471 | - """ |
472 | return |
473 | |
474 | def list_instances(self): |
475 | - """ |
476 | - Return the names of all the instances known to the virtualization |
477 | - layer, as a list. |
478 | - """ |
479 | return self.instances.keys() |
480 | |
481 | def _map_to_instance_info(self, instance): |
482 | @@ -131,167 +93,54 @@ |
483 | |
484 | def spawn(self, context, instance, |
485 | network_info=None, block_device_info=None): |
486 | - """ |
487 | - Create a new instance/VM/domain on the virtualization platform. |
488 | - |
489 | - The given parameter is an instance of nova.compute.service.Instance. |
490 | - This function should use the data there to guide the creation of |
491 | - the new instance. |
492 | - |
493 | - The work will be done asynchronously. This function returns a |
494 | - task that allows the caller to detect when it is complete. |
495 | - |
496 | - Once this successfully completes, the instance should be |
497 | - running (power_state.RUNNING). |
498 | - |
499 | - If this fails, any partial instance should be completely |
500 | - cleaned up, and the virtualization platform should be in the state |
501 | - that it was before this call began. |
502 | - """ |
503 | - |
504 | name = instance.name |
505 | state = power_state.RUNNING |
506 | fake_instance = FakeInstance(name, state) |
507 | self.instances[name] = fake_instance |
508 | |
509 | def snapshot(self, context, instance, name): |
510 | - """ |
511 | - Snapshots the specified instance. |
512 | - |
513 | - The given parameter is an instance of nova.compute.service.Instance, |
514 | - and so the instance is being specified as instance.name. |
515 | - |
516 | - The second parameter is the name of the snapshot. |
517 | - |
518 | - The work will be done asynchronously. This function returns a |
519 | - task that allows the caller to detect when it is complete. |
520 | - """ |
521 | pass |
522 | |
523 | def reboot(self, instance, network_info): |
524 | - """ |
525 | - Reboot the specified instance. |
526 | - |
527 | - The given parameter is an instance of nova.compute.service.Instance, |
528 | - and so the instance is being specified as instance.name. |
529 | - |
530 | - The work will be done asynchronously. This function returns a |
531 | - task that allows the caller to detect when it is complete. |
532 | - """ |
533 | pass |
534 | |
535 | def get_host_ip_addr(self): |
536 | - """ |
537 | - Retrieves the IP address of the dom0 |
538 | - """ |
539 | - pass |
540 | + return '192.168.0.1' |
541 | |
542 | def resize(self, instance, flavor): |
543 | - """ |
544 | - Resizes/Migrates the specified instance. |
545 | - |
546 | - The flavor parameter determines whether or not the instance RAM and |
547 | - disk space are modified, and if so, to what size. |
548 | - |
549 | - The work will be done asynchronously. This function returns a task |
550 | - that allows the caller to detect when it is complete. |
551 | - """ |
552 | pass |
553 | |
554 | def set_admin_password(self, instance, new_pass): |
555 | - """ |
556 | - Set the root password on the specified instance. |
557 | - |
558 | - The first parameter is an instance of nova.compute.service.Instance, |
559 | - and so the instance is being specified as instance.name. The second |
560 | - parameter is the value of the new password. |
561 | - |
562 | - The work will be done asynchronously. This function returns a |
563 | - task that allows the caller to detect when it is complete. |
564 | - """ |
565 | pass |
566 | |
567 | def inject_file(self, instance, b64_path, b64_contents): |
568 | - """ |
569 | - Writes a file on the specified instance. |
570 | - |
571 | - The first parameter is an instance of nova.compute.service.Instance, |
572 | - and so the instance is being specified as instance.name. The second |
573 | - parameter is the base64-encoded path to which the file is to be |
574 | - written on the instance; the third is the contents of the file, also |
575 | - base64-encoded. |
576 | - |
577 | - The work will be done asynchronously. This function returns a |
578 | - task that allows the caller to detect when it is complete. |
579 | - """ |
580 | pass |
581 | |
582 | def agent_update(self, instance, url, md5hash): |
583 | - """ |
584 | - Update agent on the specified instance. |
585 | - |
586 | - The first parameter is an instance of nova.compute.service.Instance, |
587 | - and so the instance is being specified as instance.name. The second |
588 | - parameter is the URL of the agent to be fetched and updated on the |
589 | - instance; the third is the md5 hash of the file for verification |
590 | - purposes. |
591 | - |
592 | - The work will be done asynchronously. This function returns a |
593 | - task that allows the caller to detect when it is complete. |
594 | - """ |
595 | pass |
596 | |
597 | def rescue(self, context, instance, callback, network_info): |
598 | - """ |
599 | - Rescue the specified instance. |
600 | - """ |
601 | pass |
602 | |
603 | def unrescue(self, instance, callback, network_info): |
604 | - """ |
605 | - Unrescue the specified instance. |
606 | - """ |
607 | pass |
608 | |
609 | def poll_rescued_instances(self, timeout): |
610 | - """Poll for rescued instances""" |
611 | pass |
612 | |
613 | def migrate_disk_and_power_off(self, instance, dest): |
614 | - """ |
615 | - Transfers the disk of a running instance in multiple phases, turning |
616 | - off the instance before the end. |
617 | - """ |
618 | - pass |
619 | - |
620 | - def attach_disk(self, instance, disk_info): |
621 | - """ |
622 | - Attaches the disk to an instance given the metadata disk_info |
623 | - """ |
624 | pass |
625 | |
626 | def pause(self, instance, callback): |
627 | - """ |
628 | - Pause the specified instance. |
629 | - """ |
630 | pass |
631 | |
632 | def unpause(self, instance, callback): |
633 | - """ |
634 | - Unpause the specified instance. |
635 | - """ |
636 | pass |
637 | |
638 | def suspend(self, instance, callback): |
639 | - """ |
640 | - suspend the specified instance |
641 | - """ |
642 | pass |
643 | |
644 | def resume(self, instance, callback): |
645 | - """ |
646 | - resume the specified instance |
647 | - """ |
648 | pass |
649 | |
650 | def destroy(self, instance, network_info, cleanup=True): |
651 | @@ -303,25 +152,12 @@ |
652 | (key, self.instances)) |
653 | |
654 | def attach_volume(self, instance_name, device_path, mountpoint): |
655 | - """Attach the disk at device_path to the instance at mountpoint""" |
656 | return True |
657 | |
658 | def detach_volume(self, instance_name, mountpoint): |
659 | - """Detach the disk attached to the instance at mountpoint""" |
660 | return True |
661 | |
662 | def get_info(self, instance_name): |
663 | - """ |
664 | - Get a block of information about the given instance. This is returned |
665 | - as a dictionary containing 'state': The power_state of the instance, |
666 | - 'max_mem': The maximum memory for the instance, in KiB, 'mem': The |
667 | - current memory the instance has, in KiB, 'num_cpu': The current number |
668 | - of virtual CPUs the instance has, 'cpu_time': The total CPU time used |
669 | - by the instance, in nanoseconds. |
670 | - |
671 | - This method should raise exception.NotFound if the hypervisor has no |
672 | - knowledge of the instance |
673 | - """ |
674 | if instance_name not in self.instances: |
675 | raise exception.InstanceNotFound(instance_id=instance_name) |
676 | i = self.instances[instance_name] |
677 | @@ -332,69 +168,18 @@ |
678 | 'cpu_time': 0} |
679 | |
680 | def get_diagnostics(self, instance_name): |
681 | - pass |
682 | + return {} |
683 | |
684 | def list_disks(self, instance_name): |
685 | - """ |
686 | - Return the IDs of all the virtual disks attached to the specified |
687 | - instance, as a list. These IDs are opaque to the caller (they are |
688 | - only useful for giving back to this layer as a parameter to |
689 | - disk_stats). These IDs only need to be unique for a given instance. |
690 | - |
691 | - Note that this function takes an instance ID. |
692 | - """ |
693 | return ['A_DISK'] |
694 | |
695 | def list_interfaces(self, instance_name): |
696 | - """ |
697 | - Return the IDs of all the virtual network interfaces attached to the |
698 | - specified instance, as a list. These IDs are opaque to the caller |
699 | - (they are only useful for giving back to this layer as a parameter to |
700 | - interface_stats). These IDs only need to be unique for a given |
701 | - instance. |
702 | - |
703 | - Note that this function takes an instance ID. |
704 | - """ |
705 | return ['A_VIF'] |
706 | |
707 | def block_stats(self, instance_name, disk_id): |
708 | - """ |
709 | - Return performance counters associated with the given disk_id on the |
710 | - given instance_name. These are returned as [rd_req, rd_bytes, wr_req, |
711 | - wr_bytes, errs], where rd indicates read, wr indicates write, req is |
712 | - the total number of I/O requests made, bytes is the total number of |
713 | - bytes transferred, and errs is the number of requests held up due to a |
714 | - full pipeline. |
715 | - |
716 | - All counters are long integers. |
717 | - |
718 | - This method is optional. On some platforms (e.g. XenAPI) performance |
719 | - statistics can be retrieved directly in aggregate form, without Nova |
720 | - having to do the aggregation. On those platforms, this method is |
721 | - unused. |
722 | - |
723 | - Note that this function takes an instance ID. |
724 | - """ |
725 | return [0L, 0L, 0L, 0L, None] |
726 | |
727 | def interface_stats(self, instance_name, iface_id): |
728 | - """ |
729 | - Return performance counters associated with the given iface_id on the |
730 | - given instance_id. These are returned as [rx_bytes, rx_packets, |
731 | - rx_errs, rx_drop, tx_bytes, tx_packets, tx_errs, tx_drop], where rx |
732 | - indicates receive, tx indicates transmit, bytes and packets indicate |
733 | - the total number of bytes or packets transferred, and errs and dropped |
734 | - is the total number of packets failed / dropped. |
735 | - |
736 | - All counters are long integers. |
737 | - |
738 | - This method is optional. On some platforms (e.g. XenAPI) performance |
739 | - statistics can be retrieved directly in aggregate form, without Nova |
740 | - having to do the aggregation. On those platforms, this method is |
741 | - unused. |
742 | - |
743 | - Note that this function takes an instance ID. |
744 | - """ |
745 | return [0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L] |
746 | |
747 | def get_console_output(self, instance): |
748 | @@ -416,67 +201,12 @@ |
749 | 'password': 'fakepassword'} |
750 | |
751 | def refresh_security_group_rules(self, security_group_id): |
752 | - """This method is called after a change to security groups. |
753 | - |
754 | - All security groups and their associated rules live in the datastore, |
755 | - and calling this method should apply the updated rules to instances |
756 | - running the specified security group. |
757 | - |
758 | - An error should be raised if the operation cannot complete. |
759 | - |
760 | - """ |
761 | return True |
762 | |
763 | def refresh_security_group_members(self, security_group_id): |
764 | - """This method is called when a security group is added to an instance. |
765 | - |
766 | - This message is sent to the virtualization drivers on hosts that are |
767 | - running an instance that belongs to a security group that has a rule |
768 | - that references the security group identified by `security_group_id`. |
769 | - It is the responsiblity of this method to make sure any rules |
770 | - that authorize traffic flow with members of the security group are |
771 | - updated and any new members can communicate, and any removed members |
772 | - cannot. |
773 | - |
774 | - Scenario: |
775 | - * we are running on host 'H0' and we have an instance 'i-0'. |
776 | - * instance 'i-0' is a member of security group 'speaks-b' |
777 | - * group 'speaks-b' has an ingress rule that authorizes group 'b' |
778 | - * another host 'H1' runs an instance 'i-1' |
779 | - * instance 'i-1' is a member of security group 'b' |
780 | - |
781 | - When 'i-1' launches or terminates we will recieve the message |
782 | - to update members of group 'b', at which time we will make |
783 | - any changes needed to the rules for instance 'i-0' to allow |
784 | - or deny traffic coming from 'i-1', depending on if it is being |
785 | - added or removed from the group. |
786 | - |
787 | - In this scenario, 'i-1' could just as easily have been running on our |
788 | - host 'H0' and this method would still have been called. The point was |
789 | - that this method isn't called on the host where instances of that |
790 | - group are running (as is the case with |
791 | - :method:`refresh_security_group_rules`) but is called where references |
792 | - are made to authorizing those instances. |
793 | - |
794 | - An error should be raised if the operation cannot complete. |
795 | - |
796 | - """ |
797 | return True |
798 | |
799 | def refresh_provider_fw_rules(self): |
800 | - """This triggers a firewall update based on database changes. |
801 | - |
802 | - When this is called, rules have either been added or removed from the |
803 | - datastore. You can retrieve rules with |
804 | - :method:`nova.db.api.provider_fw_rule_get_all`. |
805 | - |
806 | - Provider rules take precedence over security group rules. If an IP |
807 | - would be allowed by a security group ingress rule, but blocked by |
808 | - a provider rule, then packets from the IP are dropped. This includes |
809 | - intra-project traffic in the case of the allow_project_net_traffic |
810 | - flag for the libvirt-derived classes. |
811 | - |
812 | - """ |
813 | pass |
814 | |
815 | def update_available_resource(self, ctxt, host): |
Not sure why the documentation was in fake.py in the first place...