class FakeVolume(object): def __init__(self, parent, owner, id, size, display_name, display_description): self.parent = parent self.owner = owner # This is a context. self.id = id self.size = size self.display_name = display_name self.display_description = display_description self.events = EventSimulator() self.schedule_status("BUILD", 0.0) def __repr__(self): return ("FakeVolume(id=%s, size=%s, " "display_name=%s, display_description=%s)") % (self.id, self.size, self.display_name, self.display_description) def schedule_status(self, new_status, time_from_now): """Makes a new status take effect at the given time.""" def set_status(): self._current_status = new_status self.events.add_event(time_from_now, set_status) @property def status(self): return self._current_status
def start_mysql_with_conf_changes(self, updated_memory_size): from reddwarf.instance.models import InstanceServiceStatus from reddwarf.instance.models import ServiceStatuses def update_db(): status = InstanceServiceStatus.find_by(instance_id=self.id) status.status = ServiceStatuses.RUNNING status.save() EventSimulator.add_event(0.5, update_db)
def stop_mysql(self): from reddwarf.instance.models import InstanceServiceStatus from reddwarf.instance.models import ServiceStatuses def update_db(): status = InstanceServiceStatus.find_by(instance_id=self.id) status.status = ServiceStatuses.SHUTDOWN status.save() EventSimulator.add_event(0.5, update_db)
def prepare(self, databases, memory_mb, users, device_path=None, mount_point=None): from reddwarf.instance.models import InstanceServiceStatus from reddwarf.instance.models import ServiceStatuses def update_db(): status = InstanceServiceStatus.find_by(instance_id=self.id) status.status = ServiceStatuses.RUNNING status.save() EventSimulator.add_event(2.0, update_db)
class FakeVolume(object): def __init__(self, parent, owner, id, size, display_name, display_description): self.attachments = [] self.parent = parent self.owner = owner # This is a context. self.id = id self.size = size self.display_name = display_name self.display_description = display_description self.events = EventSimulator() self._current_status = "BUILD" # For some reason we grab this thing from device then call it mount # point. self.device = "/var/lib/mysql" def __repr__(self): msg = ("FakeVolume(id=%s, size=%s, display_name=%s, " "display_description=%s, _current_status=%s)") params = (self.id, self.size, self.display_name, self.display_description, self._current_status) return (msg % params) @property def availability_zone(self): return "fake-availability-zone" @property def created_at(self): return "2001-01-01-12:30:30" def get(self, key): return getattr(self, key) def schedule_status(self, new_status, time_from_now): """Makes a new status take effect at the given time.""" def set_status(): self._current_status = new_status self.events.add_event(time_from_now, set_status) def set_attachment(self, server_id): """Fake method we've added to set attachments. Idempotent.""" for attachment in self.attachments: if attachment['server_id'] == server_id: return # Do nothing self.attachments.append({ 'server_id': server_id, 'device': self.device }) @property def status(self): return self._current_status
class FakeServer(object): def __init__(self, parent, owner, id, name, image_id, flavor_ref, block_device_mapping): self.owner = owner # This is a context. self.id = id self.parent = parent self.name = name self.image_id = image_id self.flavor_ref = flavor_ref self.events = EventSimulator() self.schedule_status("BUILD", 0.0) LOG.debug("block_device_mapping = %s" % block_device_mapping) self.block_device_mapping = block_device_mapping @property def addresses(self): return {"private": [{"addr":"123.123.123.123"}]} def delete(self): self.schedule_status = [] self._current_status = "SHUTDOWN" self.parent.schedule_delete(self.id, 1.5) @property def flavor(self): return FLAVORS.get_by_href(self.flavor_ref).to_dict() @property def links(self): return [{ "href": "https://localhost:9999/v1.0/1234/instances/%s" % self.id, "rel": link_type } for link_type in ['self', 'bookmark']] def schedule_status(self, new_status, time_from_now): """Makes a new status take effect at the given time.""" def set_status(): self._current_status = new_status self.events.add_event(time_from_now, set_status) @property def status(self): return self._current_status @property def created(self): return "2012-01-25T21:55:51Z" @property def updated(self): return "2012-01-25T21:55:51Z"
class FakeVolume(object): def __init__(self, parent, owner, id, size, display_name, display_description): self.attachments = [] self.parent = parent self.owner = owner # This is a context. self.id = id self.size = size self.display_name = display_name self.display_description = display_description self.events = EventSimulator() self._current_status = "BUILD" # For some reason we grab this thing from device then call it mount # point. self.device = "/var/lib/mysql" def __repr__(self): msg = ("FakeVolume(id=%s, size=%s, display_name=%s, " "display_description=%s, _current_status=%s)") params = (self.id, self.size, self.display_name, self.display_description, self._current_status) return (msg % params) @property def availability_zone(self): return "fake-availability-zone" @property def created_at(self): return "2001-01-01-12:30:30" def get(self, key): return getattr(self, key) def schedule_status(self, new_status, time_from_now): """Makes a new status take effect at the given time.""" def set_status(): self._current_status = new_status self.events.add_event(time_from_now, set_status) def set_attachment(self, server_id): """Fake method we've added to set attachments. Idempotent.""" for attachment in self.attachments: if attachment['server_id'] == server_id: return # Do nothing self.attachments.append({'server_id': server_id, 'device': self.device}) @property def status(self): return self._current_status
def __init__(self, parent, owner, id, size, display_name, display_description): self.attachments = [] self.parent = parent self.owner = owner # This is a context. self.id = id self.size = size self.display_name = display_name self.display_description = display_description self.events = EventSimulator() self._current_status = "BUILD" # For some reason we grab this thing from device then call it mount # point. self.device = "/var/lib/mysql"
def prepare(self, memory_mb, databases, users, device_path=None, mount_point=None): from reddwarf.instance.models import InstanceServiceStatus from reddwarf.instance.models import ServiceStatuses from reddwarf.guestagent.models import AgentHeartBeat LOG.debug("users... %s" % users) LOG.debug("databases... %s" % databases) self.create_user(users) self.create_database(databases) def update_db(): status = InstanceServiceStatus.find_by(instance_id=self.id) status.status = ServiceStatuses.RUNNING status.save() AgentHeartBeat.create(instance_id=self.id) EventSimulator.add_event(2.0, update_db)
class FakeVolumes(object): def __init__(self, context): self.context = context self.db = FAKE_VOLUMES_DB self.events = EventSimulator() def can_see(self, id): """Can this FakeVolumes, with its context, see some resource?""" server = self.db[id] return (self.context.is_admin or server.owner.tenant == self.context.tenant) def get(self, id): if id not in self.db: LOG.error("Couldn't find volume id %s, collection=%s" % (id, self.db)) raise nova_exceptions.NotFound(404, "Not found") else: if self.can_see(id): return self.db[id] else: raise nova_exceptions.NotFound(404, "Bad permissions") def create(self, size, display_name=None, display_description=None): id = "FAKE_VOL_%s" % uuid.uuid4() volume = FakeVolume(self, self.context, id, size, display_name, display_description) self.db[id] = volume if size == 9: volume.schedule_status("error", 2) else: volume.schedule_status("available", 2) LOG.info("FAKE_VOLUMES_DB : %s" % FAKE_VOLUMES_DB) return volume def list(self, detailed=True): return [self.db[key] for key in self.db] def resize(self, volume_id, new_size): LOG.debug("Resize volume id (%s) to size (%s)" % (volume_id, new_size)) volume = self.get(volume_id) def finish_resize(): volume._current_status = "in-use" volume.size = new_size self.events.add_event(1.0, finish_resize)
class FakeServers(object): def __init__(self, context, flavors): self.context = context self.db = FAKE_SERVERS_DB self.flavors = flavors self.next_id = 10 self.events = EventSimulator() def can_see(self, id): """Can this FakeServers, with its context, see some resource?""" server = self.db[id] return self.context.is_admin or \ server.owner.tenant == self.context.tenant def create(self, name, image_id, flavor_ref, files, block_device_mapping): id = "FAKE_%d" % self.next_id self.next_id += 1 server = FakeServer(self, self.context, id, name, image_id, flavor_ref, block_device_mapping) self.db[id] = server server.schedule_status("ACTIVE", 1) LOG.info("FAKE_SERVERS_DB : %s" % str(FAKE_SERVERS_DB)) return server def get(self, id): if id not in self.db: LOG.error("Couldn't find server id %s, collection=%s" % (id, self.db)) raise nova_exceptions.NotFound(404, "Not found") else: if self.can_see(id): return self.db[id] else: raise nova_exceptions.NotFound(404, "Bad permissions") def list(self): return [v for (k, v) in self.db.items() if self.can_see(v.id)] def schedule_delete(self, id, time_from_now): def delete_server(): LOG.info("Simulated event ended, deleting server %s." % id) del self.db[id] self.events.add_event(time_from_now, delete_server)
def __init__(self, parent, owner, id, size, display_name, display_description): self.parent = parent self.owner = owner # This is a context. self.id = id self.size = size self.display_name = display_name self.display_description = display_description self.events = EventSimulator() self.schedule_status("BUILD", 0.0)
def __init__(self, parent, owner, id, name, image_id, flavor_ref, block_device_mapping): self.owner = owner # This is a context. self.id = id self.parent = parent self.name = name self.image_id = image_id self.flavor_ref = flavor_ref self.events = EventSimulator() self.schedule_status("BUILD", 0.0) LOG.debug("block_device_mapping = %s" % block_device_mapping) self.block_device_mapping = block_device_mapping
def prepare(self, memory_mb, databases, users, device_path=None, mount_point=None): from reddwarf.instance.models import InstanceServiceStatus from reddwarf.instance.models import ServiceStatuses from reddwarf.guestagent.models import AgentHeartBeat LOG.debug("users... %s" % users) LOG.debug("databases... %s" % databases) self.create_user(users) self.create_database(databases) def update_db(): status = InstanceServiceStatus.find_by(instance_id=self.id) status.status = ServiceStatuses.RUNNING status.save() AgentHeartBeat.create(instance_id=self.id) EventSimulator.add_event(1.0, update_db)
def __init__(self, parent, owner, id, name, image_id, flavor_ref, block_device_mapping, volumes): self.owner = owner # This is a context. self.id = id self.parent = parent self.name = name self.image_id = image_id self.flavor_ref = flavor_ref self.events = EventSimulator() self.schedule_status("BUILD", 0.0) self.volumes = volumes for volume in self.volumes: volume.set_attachment(id)
def __init__(self, parent, owner, id, name, image_id, flavor_ref, block_device_mapping, volumes): self.owner = owner # This is a context. self.id = id self.parent = parent self.name = name self.image_id = image_id self.flavor_ref = flavor_ref self.events = EventSimulator() self.schedule_status("BUILD", 0.0) self.volumes = volumes # This is used by "RdServers". Its easier to compute the # fake value in this class's initializer. self._local_id = self.next_local_id self.next_local_id += 1 info_vols = [] for volume in self.volumes: info_vols.append({'id': volume.id}) volume.set_attachment(id) self.host = "fake_host" self._info = {'os:volumes': info_vols}
class FakeVolume(object): def __init__(self, parent, owner, id, size, display_name, display_description): self.attachments = [] self.parent = parent self.owner = owner # This is a context. self.id = id self.size = size self.display_name = display_name self.display_description = display_description self.events = EventSimulator() self.schedule_status("BUILD", 0.0) def __repr__(self): return ("FakeVolume(id=%s, size=%s, " "display_name=%s, display_description=%s)") % (self.id, self.size, self.display_name, self.display_description) def get(self, key): return getattr(self, key) def schedule_status(self, new_status, time_from_now): """Makes a new status take effect at the given time.""" def set_status(): self._current_status = new_status self.events.add_event(time_from_now, set_status) def set_attachment(self, server_id): """Fake method we've added to set attachments. Idempotent.""" for attachment in self.attachments: if attachment['server_id'] == server_id: return # Do nothing self.attachments.append({'server_id':server_id}) @property def status(self): return self._current_status
class FakeServer(object): next_local_id = 0 def __init__(self, parent, owner, id, name, image_id, flavor_ref, block_device_mapping, volumes): self.owner = owner # This is a context. self.id = id self.parent = parent self.name = name self.image_id = image_id self.flavor_ref = flavor_ref self.events = EventSimulator() self.schedule_status("BUILD", 0.0) self.volumes = volumes # This is used by "RdServers". Its easier to compute the # fake value in this class's initializer. self._local_id = self.next_local_id self.next_local_id += 1 info_vols = [] for volume in self.volumes: info_vols.append({'id': volume.id}) volume.set_attachment(id) self.host = "fake_host" self._info = {'os:volumes': info_vols} @property def addresses(self): return {"private": [{"addr": "123.123.123.123"}]} def confirm_resize(self): if self.status != "VERIFY_RESIZE": raise RuntimeError("Not in resize confirm mode.") self._current_status = "ACTIVE" def reboot(self): LOG.debug("Rebooting server %s" % (self.id)) self._current_status = "REBOOT" eventlet.sleep(1) self._current_status = "ACTIVE" self.parent.schedule_simulate_running_server(self.id, 1.5) def delete(self): self.schedule_status = [] # TODO(pdmars): This is less than ideal, but a quick way to force it # into the error state before scheduling the delete. if (self.name.endswith("_DELETE_ERROR") and self._current_status != "SHUTDOWN"): # Fail to delete properly the first time, just set the status # to SHUTDOWN and break. It's important that we only fail to delete # once in fake mode. self._current_status = "SHUTDOWN" return self._current_status = "SHUTDOWN" self.parent.schedule_delete(self.id, 1.5) @property def flavor(self): return FLAVORS.get_by_href(self.flavor_ref).to_dict() @property def links(self): url = "https://localhost:9999/v1.0/1234/instances/%s" % self.id return [{ "href": url, "rel": link_type } for link_type in ['self', 'bookmark']] def resize(self, new_flavor_id): self._current_status = "RESIZE" def set_to_confirm_mode(): self._current_status = "VERIFY_RESIZE" def set_flavor(): flavor = self.parent.flavors.get(new_flavor_id) self.flavor_ref = flavor.links[0]['href'] self.events.add_event(1, set_to_confirm_mode) self.events.add_event(1, set_flavor) def schedule_status(self, new_status, time_from_now): """Makes a new status take effect at the given time.""" def set_status(): self._current_status = new_status self.events.add_event(time_from_now, set_status) @property def status(self): return self._current_status @property def created(self): return "2012-01-25T21:55:51Z" @property def updated(self): return "2012-01-25T21:55:51Z" @property def tenant(self): # This is on the RdServer extension type. return self.owner.tenant @property def tenant_id(self): return self.owner.tenant
def __init__(self, context, servers): self.context = context self.db = FAKE_SERVERS_DB self.servers = servers self.events = EventSimulator()
def __init__(self, context): self.context = context self.db = FAKE_VOLUMES_DB self.events = EventSimulator()
class FakeServer(object): def __init__(self, parent, owner, id, name, image_id, flavor_ref, block_device_mapping, volumes): self.owner = owner # This is a context. self.id = id self.parent = parent self.name = name self.image_id = image_id self.flavor_ref = flavor_ref self.events = EventSimulator() self.schedule_status("BUILD", 0.0) self.volumes = volumes for volume in self.volumes: volume.set_attachment(id) @property def addresses(self): return {"private": [{"addr":"123.123.123.123"}]} def confirm_resize(self): if self.status != "VERIFY_RESIZE": raise RuntimeError("Not in resize confirm mode.") self._current_status = "ACTIVE" def delete(self): self.schedule_status = [] self._current_status = "SHUTDOWN" self.parent.schedule_delete(self.id, 1.5) @property def flavor(self): return FLAVORS.get_by_href(self.flavor_ref).to_dict() @property def links(self): return [{ "href": "https://localhost:9999/v1.0/1234/instances/%s" % self.id, "rel": link_type } for link_type in ['self', 'bookmark']] def resize(self, new_flavor_id): self._current_status = "RESIZE" def set_to_confirm_mode(): self._current_status = "VERIFY_RESIZE" def set_flavor(): flavor = self.parent.flavors.get(new_flavor_id) self.flavor_ref = flavor.links[0]['href'] self.events.add_event(1, set_to_confirm_mode) self.events.add_event(1, set_flavor) def schedule_status(self, new_status, time_from_now): """Makes a new status take effect at the given time.""" def set_status(): self._current_status = new_status self.events.add_event(time_from_now, set_status) @property def status(self): return self._current_status @property def created(self): return "2012-01-25T21:55:51Z" @property def updated(self): return "2012-01-25T21:55:51Z"
def __init__(self, context, flavors): self.context = context self.db = FAKE_SERVERS_DB self.flavors = flavors self.events = EventSimulator()
class FakeServers(object): def __init__(self, context, flavors): self.context = context self.db = FAKE_SERVERS_DB self.flavors = flavors self.events = EventSimulator() def can_see(self, id): """Can this FakeServers, with its context, see some resource?""" server = self.db[id] return (self.context.is_admin or server.owner.tenant == self.context.tenant) def create(self, name, image_id, flavor_ref, files=None, block_device_mapping=None, volume=None): id = "FAKE_%s" % uuid.uuid4() if volume: volume = self.volumes.create(volume['size'], volume['name'], volume['description']) while volume.status == "BUILD": eventlet.sleep(0.1) if volume.status != "available": LOG.info("volume status = %s" % volume.status) raise nova_exceptions.ClientException("Volume was bad!") mapping = "%s::%s:%s" % (volume.id, volume.size, 1) block_device_mapping = {'vdb': mapping} volumes = [volume] else: volumes = self._get_volumes_from_bdm(block_device_mapping) server = FakeServer(self, self.context, id, name, image_id, flavor_ref, block_device_mapping, volumes) self.db[id] = server if name.endswith('SERVER_ERROR'): raise nova_exceptions.ClientException("Fake server create error.") server.schedule_status("ACTIVE", 1) LOG.info("FAKE_SERVERS_DB : %s" % str(FAKE_SERVERS_DB)) return server def _get_volumes_from_bdm(self, block_device_mapping): volumes = [] if block_device_mapping is not None: # block_device_mapping is a dictionary, where the key is the # device name on the compute instance and the mapping info is a # set of fields in a string, seperated by colons. # For each device, find the volume, and record the mapping info # to another fake object and attach it to the volume # so that the fake API can later retrieve this. for device in block_device_mapping: mapping = block_device_mapping[device] (id, _type, size, delete_on_terminate) = mapping.split(":") volume = self.volumes.get(id) volume.mapping = FakeBlockDeviceMappingInfo( id, device, _type, size, delete_on_terminate) volumes.append(volume) return volumes def get(self, id): if id not in self.db: LOG.error("Couldn't find server id %s, collection=%s" % (id, self.db)) raise nova_exceptions.NotFound(404, "Not found") else: if self.can_see(id): return self.db[id] else: raise nova_exceptions.NotFound(404, "Bad permissions") def get_server_volumes(self, server_id): """Fake method we've added to grab servers from the volume.""" return [ volume.mapping for volume in self.get(server_id).volumes if volume.mapping is not None ] def list(self): return [v for (k, v) in self.db.items() if self.can_see(v.id)] def schedule_delete(self, id, time_from_now): def delete_server(): LOG.info("Simulated event ended, deleting server %s." % id) del self.db[id] self.events.add_event(time_from_now, delete_server) def schedule_simulate_running_server(self, id, time_from_now): def set_server_running(): from reddwarf.instance.models import DBInstance from reddwarf.instance.models import InstanceServiceStatus from reddwarf.instance.models import ServiceStatuses instance = DBInstance.find_by(compute_instance_id=id) LOG.debug("Setting server %s to running" % instance.id) status = InstanceServiceStatus.find_by(instance_id=instance.id) status.status = ServiceStatuses.RUNNING status.save() self.events.add_event(time_from_now, set_server_running)
class FakeServers(object): def __init__(self, context, flavors): self.context = context self.db = FAKE_SERVERS_DB self.flavors = flavors self.events = EventSimulator() def can_see(self, id): """Can this FakeServers, with its context, see some resource?""" server = self.db[id] return (self.context.is_admin or server.owner.tenant == self.context.tenant) def create(self, name, image_id, flavor_ref, files=None, block_device_mapping=None, volume=None): id = "FAKE_%s" % uuid.uuid4() if volume: volume = self.volumes.create(volume['size'], volume['name'], volume['description']) while volume.status == "BUILD": eventlet.sleep(0.1) if volume.status != "available": LOG.info("volume status = %s" % volume.status) raise nova_exceptions.ClientException("Volume was bad!") mapping = "%s::%s:%s" % (volume.id, volume.size, 1) block_device_mapping = {'vdb': mapping} volumes = [volume] else: volumes = self._get_volumes_from_bdm(block_device_mapping) server = FakeServer(self, self.context, id, name, image_id, flavor_ref, block_device_mapping, volumes) self.db[id] = server if name.endswith('SERVER_ERROR'): raise nova_exceptions.ClientException("Fake server create error.") server.schedule_status("ACTIVE", 1) LOG.info("FAKE_SERVERS_DB : %s" % str(FAKE_SERVERS_DB)) return server def _get_volumes_from_bdm(self, block_device_mapping): volumes = [] if block_device_mapping is not None: # block_device_mapping is a dictionary, where the key is the # device name on the compute instance and the mapping info is a # set of fields in a string, seperated by colons. # For each device, find the volume, and record the mapping info # to another fake object and attach it to the volume # so that the fake API can later retrieve this. for device in block_device_mapping: mapping = block_device_mapping[device] (id, _type, size, delete_on_terminate) = mapping.split(":") volume = self.volumes.get(id) volume.mapping = FakeBlockDeviceMappingInfo( id, device, _type, size, delete_on_terminate) volumes.append(volume) return volumes def get(self, id): if id not in self.db: LOG.error("Couldn't find server id %s, collection=%s" % (id, self.db)) raise nova_exceptions.NotFound(404, "Not found") else: if self.can_see(id): return self.db[id] else: raise nova_exceptions.NotFound(404, "Bad permissions") def get_server_volumes(self, server_id): """Fake method we've added to grab servers from the volume.""" return [volume.mapping for volume in self.get(server_id).volumes if volume.mapping is not None] def list(self): return [v for (k, v) in self.db.items() if self.can_see(v.id)] def schedule_delete(self, id, time_from_now): def delete_server(): LOG.info("Simulated event ended, deleting server %s." % id) del self.db[id] self.events.add_event(time_from_now, delete_server) def schedule_simulate_running_server(self, id, time_from_now): def set_server_running(): from reddwarf.instance.models import DBInstance from reddwarf.instance.models import InstanceServiceStatus from reddwarf.instance.models import ServiceStatuses instance = DBInstance.find_by(compute_instance_id=id) LOG.debug("Setting server %s to running" % instance.id) status = InstanceServiceStatus.find_by(instance_id=instance.id) status.status = ServiceStatuses.RUNNING status.save() self.events.add_event(time_from_now, set_server_running)
class FakeServer(object): next_local_id = 0 def __init__(self, parent, owner, id, name, image_id, flavor_ref, block_device_mapping, volumes): self.owner = owner # This is a context. self.id = id self.parent = parent self.name = name self.image_id = image_id self.flavor_ref = flavor_ref self.events = EventSimulator() self.schedule_status("BUILD", 0.0) self.volumes = volumes # This is used by "RdServers". Its easier to compute the # fake value in this class's initializer. self._local_id = self.next_local_id self.next_local_id += 1 info_vols = [] for volume in self.volumes: info_vols.append({'id': volume.id}) volume.set_attachment(id) self.host = "fake_host" self._info = {'os:volumes': info_vols} @property def addresses(self): return {"private": [{"addr":"123.123.123.123"}]} def confirm_resize(self): if self.status != "VERIFY_RESIZE": raise RuntimeError("Not in resize confirm mode.") self._current_status = "ACTIVE" def reboot(self): LOG.debug("Rebooting server %s" % (self.id)) self._current_status = "REBOOT" eventlet.sleep(1) self._current_status = "ACTIVE" self.parent.schedule_simulate_running_server(self.id, 1.5) def delete(self): self.schedule_status = [] # TODO(pdmars): This is less than ideal, but a quick way to force it # into the error state before scheduling the delete. if (self.name.endswith("_DELETE_ERROR") and self._current_status != "SHUTDOWN"): # Fail to delete properly the first time, just set the status # to SHUTDOWN and break. It's important that we only fail to delete # once in fake mode. self._current_status = "SHUTDOWN" return self._current_status = "SHUTDOWN" self.parent.schedule_delete(self.id, 1.5) @property def flavor(self): return FLAVORS.get_by_href(self.flavor_ref).to_dict() @property def links(self): url = "https://localhost:9999/v1.0/1234/instances/%s" % self.id return [{"href": url, "rel": link_type} for link_type in ['self', 'bookmark']] def resize(self, new_flavor_id): self._current_status = "RESIZE" def set_to_confirm_mode(): self._current_status = "VERIFY_RESIZE" def set_flavor(): flavor = self.parent.flavors.get(new_flavor_id) self.flavor_ref = flavor.links[0]['href'] self.events.add_event(1, set_to_confirm_mode) self.events.add_event(1, set_flavor) def schedule_status(self, new_status, time_from_now): """Makes a new status take effect at the given time.""" def set_status(): self._current_status = new_status self.events.add_event(time_from_now, set_status) @property def status(self): return self._current_status @property def created(self): return "2012-01-25T21:55:51Z" @property def updated(self): return "2012-01-25T21:55:51Z" @property def tenant(self): # This is on the RdServer extension type. return self.owner.tenant @property def tenant_id(self): return self.owner.tenant
class FakeServers(object): def __init__(self, context, flavors): self.context = context self.db = FAKE_SERVERS_DB self.flavors = flavors self.next_id = 10 self.events = EventSimulator() def can_see(self, id): """Can this FakeServers, with its context, see some resource?""" server = self.db[id] return self.context.is_admin or \ server.owner.tenant == self.context.tenant def create(self, name, image_id, flavor_ref, files, block_device_mapping): id = "FAKE_%d" % self.next_id self.next_id += 1 volumes = self._get_volumes_from_bdm(block_device_mapping) server = FakeServer(self, self.context, id, name, image_id, flavor_ref, block_device_mapping, volumes) self.db[id] = server server.schedule_status("ACTIVE", 1) LOG.info("FAKE_SERVERS_DB : %s" % str(FAKE_SERVERS_DB)) return server def _get_volumes_from_bdm(self, block_device_mapping): volumes = [] if block_device_mapping is not None: # block_device_mapping is a dictionary, where the key is the # device name on the compute instance and the mapping info is a # set of fields in a string, seperated by colons. # For each device, find the volume, and record the mapping info # to another fake object and attach it to the volume # so that the fake API can later retrieve this. for device in block_device_mapping: mapping = block_device_mapping[device] (id, _type, size, delete_on_terminate) = mapping.split(":") volume = self.volumes.get(id) volume.mapping = FakeBlockDeviceMappingInfo(id, device, _type, size, delete_on_terminate) volumes.append(volume) return volumes def get(self, id): if id not in self.db: LOG.error("Couldn't find server id %s, collection=%s" % (id, self.db)) raise nova_exceptions.NotFound(404, "Not found") else: if self.can_see(id): return self.db[id] else: raise nova_exceptions.NotFound(404, "Bad permissions") def get_server_volumes(self, server_id): """Fake method we've added to grab servers from the volume.""" return [volume.mapping for volume in self.get(server_id).volumes if volume.mapping is not None] def list(self): return [v for (k, v) in self.db.items() if self.can_see(v.id)] def schedule_delete(self, id, time_from_now): def delete_server(): LOG.info("Simulated event ended, deleting server %s." % id) del self.db[id] self.events.add_event(time_from_now, delete_server)