1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
3
# Copyright 2010 United States Government as represented by the
4
# Administrator of the National Aeronautics and Space Administration.
6
# Copyright (c) 2010 Citrix Systems, Inc.
8
# Licensed under the Apache License, Version 2.0 (the "License"); you may
9
# not use this file except in compliance with the License. You may obtain
10
# a copy of the License at
12
# http://www.apache.org/licenses/LICENSE-2.0
14
# Unless required by applicable law or agreed to in writing, software
15
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17
# License for the specific language governing permissions and limitations
21
A fake (in-memory) hypervisor+api.
23
Allows nova testing w/o a hypervisor. This module also documents the
24
semantics of real hypervisor connections.
28
from nova.compute import power_state
30
from nova import exception
31
from nova import log as logging
32
from nova import utils
33
from nova.virt import driver
36
LOG = logging.getLogger(__name__)
39
def get_connection(_read_only):
40
# The read_only parameter is ignored.
41
return FakeConnection.instance()
44
class FakeInstance(object):
46
def __init__(self, name, state):
51
class FakeConnection(driver.ComputeDriver):
52
"""Fake hypervisor driver"""
57
'host_name-description': 'Fake Host',
58
'host_hostname': 'fake-mini',
59
'host_memory_total': 8000000000,
60
'host_memory_overhead': 10000000,
61
'host_memory_free': 7900000000,
62
'host_memory_free_computed': 7900000000,
63
'host_other_config': {},
64
'host_ip_address': '192.168.1.109',
66
'disk_available': 500000000000,
67
'disk_total': 600000000000,
68
'disk_used': 100000000000,
69
'host_uuid': 'cedb9b39-9388-41df-8891-c5c9a0c0fe5f',
70
'host_name_label': 'fake-mini'}
75
if not hasattr(cls, '_instance'):
79
def init_host(self, host):
82
def list_instances(self):
83
return self.instances.keys()
85
def _map_to_instance_info(self, instance):
86
instance = utils.check_isinstance(instance, FakeInstance)
87
info = driver.InstanceInfo(instance.name, instance.state)
90
def list_instances_detail(self):
92
for instance in self.instances.values():
93
info_list.append(self._map_to_instance_info(instance))
96
def plug_vifs(self, instance, network_info):
97
"""Plug VIFs into networks."""
100
def unplug_vifs(self, instance, network_info):
101
"""Unplug VIFs from networks."""
104
def spawn(self, context, instance, image_meta,
105
network_info=None, block_device_info=None):
107
state = power_state.RUNNING
108
fake_instance = FakeInstance(name, state)
109
self.instances[name] = fake_instance
111
def snapshot(self, context, instance, name):
112
if not instance['name'] in self.instances:
113
raise exception.InstanceNotRunning()
115
def reboot(self, instance, network_info, reboot_type,
116
block_device_info=None):
120
def get_host_ip_addr():
123
def resize(self, instance, flavor):
126
def set_admin_password(self, instance, new_pass):
129
def inject_file(self, instance, b64_path, b64_contents):
132
def agent_update(self, instance, url, md5hash):
135
def resume_state_on_host_boot(self, context, instance, network_info,
136
block_device_info=None):
139
def rescue(self, context, instance, network_info, image_meta):
142
def unrescue(self, instance, network_info):
145
def poll_rebooting_instances(self, timeout):
148
def poll_rescued_instances(self, timeout):
151
def migrate_disk_and_power_off(self, context, instance, dest,
152
instance_type, network_info):
155
def finish_revert_migration(self, instance, network_info):
158
def poll_unconfirmed_resizes(self, resize_confirm_window):
161
def pause(self, instance):
164
def unpause(self, instance):
167
def suspend(self, instance):
170
def resume(self, instance):
173
def destroy(self, instance, network_info, block_device_info=None):
174
key = instance['name']
175
if key in self.instances:
176
del self.instances[key]
178
LOG.warning("Key '%s' not in instances '%s'" %
179
(key, self.instances))
181
def attach_volume(self, connection_info, instance_name, mountpoint):
182
"""Attach the disk to the instance at mountpoint using info"""
183
if not instance_name in self._mounts:
184
self._mounts[instance_name] = {}
185
self._mounts[instance_name][mountpoint] = connection_info
188
def detach_volume(self, connection_info, instance_name, mountpoint):
189
"""Detach the disk attached to the instance"""
191
del self._mounts[instance_name][mountpoint]
196
def get_info(self, instance):
197
if instance['name'] not in self.instances:
198
raise exception.InstanceNotFound(instance_id=instance['name'])
199
i = self.instances[instance['name']]
200
return {'state': i.state,
206
def get_diagnostics(self, instance_name):
207
return 'FAKE_DIAGNOSTICS'
209
def get_all_bw_usage(self, start_time, stop_time=None):
210
"""Return bandwidth usage info for each interface on each
215
def list_disks(self, instance_name):
218
def list_interfaces(self, instance_name):
221
def block_stats(self, instance_name, disk_id):
222
return [0L, 0L, 0L, 0L, None]
224
def interface_stats(self, instance_name, iface_id):
225
return [0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L]
227
def get_console_output(self, instance):
228
return 'FAKE CONSOLE OUTPUT\nANOTHER\nLAST LINE'
230
def get_vnc_console(self, instance):
231
return {'internal_access_path': 'FAKE',
232
'host': 'fakevncconsole.com',
235
def get_console_pool_info(self, console_type):
236
return {'address': '127.0.0.1',
237
'username': 'fakeuser',
238
'password': 'fakepassword'}
240
def refresh_security_group_rules(self, security_group_id):
243
def refresh_security_group_members(self, security_group_id):
246
def refresh_provider_fw_rules(self):
249
def update_available_resource(self, ctxt, host):
250
"""Updates compute manager resource info on ComputeNode table.
252
Since we don't have a real hypervisor, pretend we have lots of
257
service_ref = db.service_get_all_compute_by_host(ctxt, host)[0]
258
except exception.NotFound:
259
raise exception.ComputeServiceUnavailable(host=host)
261
# Updating host information
268
'hypervisor_type': 'fake',
269
'hypervisor_version': '1.0',
270
'service_id': service_ref['id'],
273
compute_node_ref = service_ref['compute_node']
274
if not compute_node_ref:
275
LOG.info(_('Compute_service record created for %s ') % host)
276
db.compute_node_create(ctxt, dic)
278
LOG.info(_('Compute_service record updated for %s ') % host)
279
db.compute_node_update(ctxt, compute_node_ref[0]['id'], dic)
281
def compare_cpu(self, xml):
282
"""This method is supported only by libvirt."""
283
raise NotImplementedError('This method is supported only by libvirt.')
285
def ensure_filtering_rules_for_instance(self, instance_ref, network_info):
286
"""This method is supported only by libvirt."""
287
raise NotImplementedError('This method is supported only by libvirt.')
289
def get_instance_disk_info(self, instance_name):
290
"""This method is supported only by libvirt."""
293
def live_migration(self, context, instance_ref, dest,
294
post_method, recover_method, block_migration=False):
295
"""This method is supported only by libvirt."""
298
def finish_migration(self, context, migration, instance, disk_info,
299
network_info, image_meta, resize_instance):
302
def confirm_migration(self, migration, instance, network_info):
305
def pre_live_migration(self, block_device_info):
306
"""This method is supported only by libvirt."""
309
def unfilter_instance(self, instance_ref, network_info):
310
"""This method is supported only by libvirt."""
311
raise NotImplementedError('This method is supported only by libvirt.')
313
def test_remove_vm(self, instance_name):
314
""" Removes the named VM, as if it crashed. For testing"""
315
self.instances.pop(instance_name)
317
def update_host_status(self):
318
"""Return fake Host Status of ram, disk, network."""
319
return self.host_status
321
def get_host_stats(self, refresh=False):
322
"""Return fake Host Status of ram, disk, network."""
323
return self.host_status
325
def host_power_action(self, host, action):
326
"""Reboots, shuts down or powers up the host."""
329
def host_maintenance_mode(self, host, mode):
330
"""Start/Stop host maintenance window. On start, it triggers
331
guest VMs evacuation."""
334
def set_host_enabled(self, host, enabled):
335
"""Sets the specified host's ability to accept new instances."""
338
def get_disk_available_least(self):
342
def get_volume_connector(self, instance):
343
return {'ip': '127.0.0.1', 'initiator': 'fake'}