def host_schedule(rpc_method, context, base_options, instance_type, availability_zone, injected_files, admin_password, image, num_instances, requested_networks, block_device_mapping, security_group, filter_properties): instance_uuid = base_options.get('uuid') now = utils.utcnow() self.db.instance_update(context, instance_uuid, {'host': target_host, 'scheduled_at': now}) rpc.cast(context, rpc.queue_get_for(context, CONF.compute_topic, target_host), {"method": "run_instance", "args": {"instance_uuid": instance_uuid, "availability_zone": availability_zone, "admin_password": admin_password, "injected_files": injected_files, "requested_networks": requested_networks}}) # Instance was already created before calling scheduler return self.get(context, instance_uuid)
def _cast_create_volume(self, context, volume_id, snapshot_id, reservations): # NOTE(Rongze Zhu): It is a simple solution for bug 1008866 # If snapshot_id is set, make the call create volume directly to # the volume host where the snapshot resides instead of passing it # through the scheduer. So snapshot can be copy to new volume. if snapshot_id and FLAGS.snapshot_same_host: snapshot_ref = self.db.snapshot_get(context, snapshot_id) src_volume_ref = self.db.volume_get(context, snapshot_ref['volume_id']) topic = rpc.queue_get_for(context, FLAGS.volume_topic, src_volume_ref['host']) rpc.cast(context, topic, {"method": "create_volume", "args": {"volume_id": volume_id, "snapshot_id": snapshot_id}}) else: rpc.cast(context, FLAGS.scheduler_topic, {"method": "create_volume", "args": {"topic": FLAGS.volume_topic, "volume_id": volume_id, "snapshot_id": snapshot_id, "reservations": reservations}})
def cast_to_network_host(context, host, method, **kwargs): """Cast request to a network host queue""" rpc.cast(context, rpc.queue_get_for(context, 'network', host), {"method": method, "args": kwargs}) LOG.debug(_("Casted '%(method)s' to network '%(host)s'") % locals())
def _create_snapshot(self, context, volume, name, description, force=False): check_policy(context, 'create_snapshot', volume) if ((not force) and (volume['status'] != "available")): msg = _("must be available") raise exception.InvalidVolume(reason=msg) options = { 'volume_id': volume['id'], 'user_id': context.user_id, 'project_id': context.project_id, 'status': "creating", 'progress': '0%', 'volume_size': volume['size'], 'display_name': name, 'display_description': description} snapshot = self.db.snapshot_create(context, options) host = volume['host'] rpc.cast(context, rpc.queue_get_for(context, FLAGS.volume_topic, host), {"method": "create_snapshot", "args": {"volume_id": volume['id'], "snapshot_id": snapshot['id']}}) return snapshot
def copy_volume_to_image(self, context, volume, metadata, force): """Create a new image from the specified volume.""" self._check_volume_availability(context, volume, force) recv_metadata = self.image_service.create(context, metadata) self.update(context, volume, {'status': 'uploading'}) rpc.cast(context, rpc.queue_get_for(context, FLAGS.volume_topic, volume['host']), {"method": "copy_volume_to_image", "args": {"volume_id": volume['id'], "image_id": recv_metadata['id']}}) response = {"id": volume['id'], "updated_at": volume['updated_at'], "status": 'uploading', "display_description": volume['display_description'], "size": volume['size'], "volume_type": volume['volume_type'], "image_id": recv_metadata['id'], "container_format": recv_metadata['container_format'], "disk_format": recv_metadata['disk_format'], "image_name": recv_metadata.get('name', None) } return response
def launch_instance(self, context, instance_uuid, params={}): pid = context.project_id uid = context.user_id # TODO(dscannell): Need to figure out how these quota reservations work and what # we need to do with them. num_instances, reservations = self._check_quota(context, instance_uuid) instance = self.get(context, instance_uuid) if not(self._is_instance_blessed(context, instance_uuid)): # The instance is not blessed. We can't launch new instances from it. raise exception.NovaException( _(("Instance %s is not blessed. " + "Please bless the instance before launching from it.") % instance_uuid)) # Create a new launched instance. new_instance_ref = self._copy_instance(context, instance_uuid, "clone", launch=True) LOG.debug(_("Casting to scheduler for %(pid)s/%(uid)s's" " instance %(instance_uuid)s") % locals()) rpc.cast(context, FLAGS.scheduler_topic, {"method": "launch_instance", "args": {"topic": FLAGS.gridcentric_topic, "instance_uuid": new_instance_ref['uuid'], "params": params}}) return self.get(context, new_instance_ref['uuid'])
def _cast_gridcentric_message(self, method, context, instance_uuid, host=None, params=None): """Generic handler for RPC casts to gridcentric. This does not block for a response. :param params: Optional dictionary of arguments to be passed to the gridcentric worker :returns: None """ if not params: params = {} if not host: instance = self.get(context, instance_uuid) host = instance['host'] if not host: queue = CONF.gridcentric_topic else: queue = rpc.queue_get_for(context, CONF.gridcentric_topic, host) params['instance_uuid'] = instance_uuid kwargs = {'method': method, 'args': params} rpc.cast(context, queue, kwargs)
def _cast_create_volume(self, context, volume_id, snapshot_id, reservations): # NOTE(Rongze Zhu): It is a simple solution for bug 1008866 # If snapshot_id is set, make the call create volume directly to # the volume host where the snapshot resides instead of passing it # through the scheduer. So snapshot can be copy to new volume. if snapshot_id and FLAGS.snapshot_same_host: snapshot_ref = self.db.snapshot_get(context, snapshot_id) src_volume_ref = self.db.volume_get(context, snapshot_ref['volume_id']) topic = rpc.queue_get_for(context, FLAGS.volume_topic, src_volume_ref['host']) rpc.cast( context, topic, { "method": "create_volume", "args": { "volume_id": volume_id, "snapshot_id": snapshot_id } }) else: self.scheduler_rpcapi.create_volume(context, volume_id, snapshot_id, reservations)
def delete(self, context, volume, force=False): volume_id = volume['id'] if not volume['host']: # NOTE(vish): scheduling failed, so delete it # Note(zhiteng): update volume quota reservation try: reservations = QUOTAS.reserve(context, volumes=-1, gigabytes=-volume['size']) except Exception: reservations = None LOG.exception(_("Failed to update quota for deleting volume.")) self.db.volume_destroy(context, volume_id) if reservations: QUOTAS.commit(context, reservations) return if not force and volume['status'] not in ["available", "error"]: msg = _("Volume status must be available or error") raise exception.InvalidVolume(reason=msg) snapshots = self.db.snapshot_get_all_for_volume(context, volume_id) if len(snapshots): msg = _("Volume still has %d dependent snapshots") % len(snapshots) raise exception.InvalidVolume(reason=msg) now = timeutils.utcnow() self.db.volume_update(context, volume_id, {'status': 'deleting', 'terminated_at': now}) host = volume['host'] rpc.cast(context, rpc.queue_get_for(context, FLAGS.volume_topic, host), {"method": "delete_volume", "args": {"volume_id": volume_id}})
def delete(self, context, volume): volume_id = volume['id'] if not volume['host']: # NOTE(vish): scheduling failed, so delete it self.db.volume_destroy(context, volume_id) return if volume['status'] not in ["available", "error"]: msg = _("Volume status must be available or error") raise exception.InvalidVolume(reason=msg) snapshots = self.db.snapshot_get_all_for_volume(context, volume_id) if len(snapshots): msg = _("Volume still has %d dependent snapshots") % len(snapshots) raise exception.InvalidVolume(reason=msg) now = timeutils.utcnow() self.db.volume_update(context, volume_id, { 'status': 'deleting', 'terminated_at': now }) host = volume['host'] rpc.cast(context, rpc.queue_get_for(context, FLAGS.volume_topic, host), { "method": "delete_volume", "args": { "volume_id": volume_id } })
def host_schedule(rpc_method, context, base_options, instance_type, availability_zone, injected_files, admin_password, image, num_instances, requested_networks, block_device_mapping, security_group, filter_properties): instance_uuid = base_options.get('uuid') now = utils.utcnow() self.db.instance_update(context, instance_uuid, { 'host': target_host, 'scheduled_at': now }) rpc.cast( context, rpc.queue_get_for(context, CONF.compute_topic, target_host), { "method": "run_instance", "args": { "instance_uuid": instance_uuid, "availability_zone": availability_zone, "admin_password": admin_password, "injected_files": injected_files, "requested_networks": requested_networks } }) # Instance was already created before calling scheduler return self.get(context, instance_uuid)
def proxy_rpc_to_manager(self, message, host_name, rpc_message, topic, timeout): """Proxy RPC to the given compute topic.""" # Check that the host exists. self.db.service_get_by_compute_host(message.ctxt, host_name) if message.need_response: return rpc.call(message.ctxt, topic, rpc_message, timeout=timeout) rpc.cast(message.ctxt, topic, rpc_message)
def _create_snapshot(self, context, volume, name, description, force=False): check_policy(context, 'create_snapshot', volume) if ((not force) and (volume['status'] != "available")): msg = _("must be available") raise exception.InvalidVolume(reason=msg) options = { 'volume_id': volume['id'], 'user_id': context.user_id, 'project_id': context.project_id, 'status': "creating", 'progress': '0%', 'volume_size': volume['size'], 'display_name': name, 'display_description': description } snapshot = self.db.snapshot_create(context, options) host = volume['host'] rpc.cast( context, rpc.queue_get_for(context, FLAGS.volume_topic, host), { "method": "create_snapshot", "args": { "volume_id": volume['id'], "snapshot_id": snapshot['id'] } }) return snapshot
def add_fixed_ip_to_instance(self, context, instance, network_id): """Adds a fixed ip to instance from specified network.""" args = {'instance_id': instance['id'], 'host': instance['host'], 'network_id': network_id} rpc.cast(context, FLAGS.network_topic, {'method': 'add_fixed_ip_to_instance', 'args': args})
def release_floating_ip(self, context, address, affect_auto_assigned=False): """Removes floating ip with address from a project. (deallocates)""" rpc.cast(context, FLAGS.network_topic, {'method': 'deallocate_floating_ip', 'args': {'address': address, 'affect_auto_assigned': affect_auto_assigned}})
def launch_instance(self, context, instance_uuid, params={}): pid = context.project_id uid = context.user_id instance = self.get(context, instance_uuid) if not (self._is_instance_blessed(context, instance_uuid)): # The instance is not blessed. We can't launch new instances from it. raise exception.NovaException( _(("Instance %s is not blessed. " + "Please bless the instance before launching from it.") % instance_uuid)) # Set up security groups to be added - we are passed in names, but need ID's security_group_names = params.pop('security_groups', None) if security_group_names != None: security_groups = [ self.db.security_group_get_by_name(context, context.project_id, sg) for sg in security_group_names ] else: security_groups = None reservations = self._acquire_addition_reservation(context, instance) try: # Create a new launched instance. new_instance_ref = self._copy_instance( context, instance_uuid, params.get('name', "%s-%s" % (instance['display_name'], "clone")), launch=True, new_user_data=params.pop('user_data', None), security_groups=security_groups) LOG.debug( _("Casting to scheduler for %(pid)s/%(uid)s's" " instance %(instance_uuid)s") % locals()) # FIXME: The Folsom scheduler removed support for calling # arbitrary functions via the scheduler. Damn. So now we # have to make scheduling decisions internally. Until this # is sorted, we will simply cast the message and let a random # host pick it up. Note that this is simply a stopgap measure. rpc.cast( context, CONF.gridcentric_topic, { "method": "launch_instance", "args": { "instance_uuid": new_instance_ref['uuid'], "params": params } }) self._commit_reservation(context, reservations) except: self._rollback_reservation(context, reservations) raise return self.get(context, new_instance_ref['uuid'])
def deallocate_for_instance(self, context, instance, **kwargs): """Deallocates all network structures related to instance.""" args = kwargs args['instance_id'] = instance['id'] args['project_id'] = instance['project_id'] args['host'] = instance['host'] rpc.cast(context, FLAGS.network_topic, {'method': 'deallocate_for_instance', 'args': args})
def remove_fixed_ip_from_instance(self, context, instance, address): """Removes a fixed ip from instance from specified network.""" args = {'instance_id': instance['id'], 'host': instance['host'], 'address': address} rpc.cast(context, FLAGS.network_topic, {'method': 'remove_fixed_ip_from_instance', 'args': args})
def cast_to_compute_host(context, host, method, **kwargs): """Cast request to a compute host queue""" instance_uuid = kwargs.get("instance_uuid", None) if instance_uuid: instance_update_db(context, instance_uuid, host) rpc.cast(context, rpc.queue_get_for(context, "compute", host), {"method": method, "args": kwargs}) LOG.debug(_("Casted '%(method)s' to compute '%(host)s'") % locals())
def cast_to_volume_host(context, host, method, **kwargs): """Cast request to a volume host queue""" volume_id = kwargs.get("volume_id", None) if volume_id is not None: now = timeutils.utcnow() db.volume_update(context, volume_id, {"host": host, "scheduled_at": now}) rpc.cast(context, rpc.queue_get_for(context, "volume", host), {"method": method, "args": kwargs}) LOG.debug(_("Casted '%(method)s' to volume '%(host)s'") % locals())
def cast_to_compute_host(context, host, method, **kwargs): """Cast request to a compute host queue""" instance_uuid = kwargs.get('instance_uuid', None) if instance_uuid: instance_update_db(context, instance_uuid, host) rpc.cast(context, rpc.queue_get_for(context, 'compute', host), {"method": method, "args": kwargs}) LOG.debug(_("Casted '%(method)s' to compute '%(host)s'") % locals())
def cast_to_host(context, topic, host, method, **kwargs): """Generic cast to host""" topic_mapping = {"compute": cast_to_compute_host, "volume": cast_to_volume_host, "network": cast_to_network_host} func = topic_mapping.get(topic) if func: func(context, host, method, **kwargs) else: rpc.cast(context, rpc.queue_get_for(context, topic, host), {"method": method, "args": kwargs}) LOG.debug(_("Casted '%(method)s' to %(topic)s '%(host)s'") % locals())
def create(self, context, size, name, description, snapshot=None, volume_type=None, metadata=None, availability_zone=None): check_policy(context, 'create') if snapshot is not None: if snapshot['status'] != "available": msg = _("status must be available") raise exception.InvalidSnapshot(reason=msg) if not size: size = snapshot['volume_size'] snapshot_id = snapshot['id'] else: snapshot_id = None try: reservations = QUOTAS.reserve(context, volumes=1, gigabytes=size) except exception.OverQuota: pid = context.project_id LOG.warn(_("Quota exceeded for %(pid)s, tried to create" " %(size)sG volume") % locals()) raise exception.VolumeSizeTooLarge() if availability_zone is None: availability_zone = FLAGS.storage_availability_zone if volume_type is None: volume_type_id = None else: volume_type_id = volume_type.get('id', None) options = { 'size': size, 'user_id': context.user_id, 'project_id': context.project_id, 'snapshot_id': snapshot_id, 'availability_zone': availability_zone, 'status': "creating", 'attach_status': "detached", 'display_name': name, 'display_description': description, 'volume_type_id': volume_type_id, 'metadata': metadata, } volume = self.db.volume_create(context, options) rpc.cast(context, FLAGS.scheduler_topic, {"method": "create_volume", "args": {"topic": FLAGS.volume_topic, "volume_id": volume['id'], "snapshot_id": snapshot_id, "reservations": reservations}}) return volume
def delete_snapshot(self, context, snapshot): if snapshot['status'] not in ["available", "error"]: msg = _("Volume Snapshot status must be available or error") raise exception.InvalidVolume(reason=msg) self.db.snapshot_update(context, snapshot['id'], {'status': 'deleting'}) volume = self.db.volume_get(context, snapshot['volume_id']) host = volume['host'] rpc.cast(context, rpc.queue_get_for(context, FLAGS.volume_topic, host), {"method": "delete_snapshot", "args": {"snapshot_id": snapshot['id']}})
def cast_to_compute_host(context, host, method, update_db=True, **kwargs): """Cast request to a compute host queue""" if update_db: # fall back on the id if the uuid is not present instance_id = kwargs.get("instance_id", None) instance_uuid = kwargs.get("instance_uuid", instance_id) if instance_uuid is not None: now = timeutils.utcnow() db.instance_update(context, instance_uuid, {"host": host, "scheduled_at": now}) rpc.cast(context, rpc.queue_get_for(context, "compute", host), {"method": method, "args": kwargs}) LOG.debug(_("Casted '%(method)s' to compute '%(host)s'") % locals())
def cast_to_volume_host(context, host, method, **kwargs): """Cast request to a volume host queue""" volume_id = kwargs.get('volume_id', None) if volume_id is not None: now = timeutils.utcnow() db.volume_update(context, volume_id, {'host': host, 'scheduled_at': now}) rpc.cast(context, rpc.queue_get_for(context, 'volume', host), {"method": method, "args": kwargs}) LOG.debug(_("Casted '%(method)s' to volume '%(host)s'") % locals())
def cast_to_volume_host(context, host, method, update_db=True, **kwargs): """Cast request to a volume host queue""" if update_db: volume_id = kwargs.get('volume_id', None) if volume_id is not None: now = timeutils.utcnow() db.volume_update(context, volume_id, {'host': host, 'scheduled_at': now}) rpc.cast(context, rpc.queue_get_for(context, 'volume', host), {"method": method, "args": kwargs}) LOG.debug(_("Casted '%(method)s' to volume '%(host)s'") % locals())
def cast(self, context, msg, topic=None, version=None): """rpc.cast() a remote method. :param context: The request context :param msg: The message to send, including the method and args. :param topic: Override the topic for this message. :param version: (Optional) Override the requested API version in this message. :returns: None. rpc.cast() does not wait on any return value from the remote method. """ self._set_version(msg, version) rpc.cast(context, self._get_topic(topic), msg)
def test_cast_to_network_host(self): host = 'fake_host1' method = 'fake_method' fake_kwargs = {'extra_arg': 'meow'} queue = 'fake_queue' self.mox.StubOutWithMock(rpc, 'queue_get_for') self.mox.StubOutWithMock(rpc, 'cast') rpc.queue_get_for(self.context, 'network', host).AndReturn(queue) rpc.cast(self.context, queue, {'method': method, 'args': fake_kwargs}) self.mox.ReplayAll() driver.cast_to_network_host(self.context, host, method, **fake_kwargs)
def test_cast_to_compute_host_update_db_without_instance_uuid(self): host = 'fake_host1' method = 'fake_method' fake_kwargs = {'extra_arg': 'meow'} queue = 'fake_queue' self.mox.StubOutWithMock(rpc, 'queue_get_for') self.mox.StubOutWithMock(rpc, 'cast') rpc.queue_get_for(self.context, 'compute', host).AndReturn(queue) rpc.cast(self.context, queue, {'method': method, 'args': fake_kwargs}) self.mox.ReplayAll() driver.cast_to_compute_host(self.context, host, method, **fake_kwargs)
def test_cast_to_network_host(self): host = "fake_host1" method = "fake_method" fake_kwargs = {"extra_arg": "meow"} queue = "fake_queue" self.mox.StubOutWithMock(rpc, "queue_get_for") self.mox.StubOutWithMock(rpc, "cast") rpc.queue_get_for(self.context, "network", host).AndReturn(queue) rpc.cast(self.context, queue, {"method": method, "args": fake_kwargs}) self.mox.ReplayAll() driver.cast_to_network_host(self.context, host, method, **fake_kwargs)
def cast_to_host(context, topic, host, method, **kwargs): """Generic cast to host""" topic_mapping = {CONF.compute_topic: cast_to_compute_host} func = topic_mapping.get(topic) if func: cast_to_compute_host(context, host, method, **kwargs) else: rpc.cast(context, rpc.queue_get_for(context, topic, host), {"method": method, "args": kwargs}) LOG.debug(_("Casted '%(method)s' to %(topic)s '%(host)s'") % locals())
def test_cast_to_compute_host_update_db_without_instance_uuid(self): host = "fake_host1" method = "fake_method" fake_kwargs = {"extra_arg": "meow"} queue = "fake_queue" self.mox.StubOutWithMock(rpc, "queue_get_for") self.mox.StubOutWithMock(rpc, "cast") rpc.queue_get_for(self.context, "compute", host).AndReturn(queue) rpc.cast(self.context, queue, {"method": method, "args": fake_kwargs}) self.mox.ReplayAll() driver.cast_to_compute_host(self.context, host, method, **fake_kwargs)
def cast_to_compute_host(context, host, method, update_db=True, **kwargs): """Cast request to a compute host queue""" if update_db: # fall back on the id if the uuid is not present instance_id = kwargs.get('instance_id', None) instance_uuid = kwargs.get('instance_uuid', instance_id) if instance_uuid is not None: now = timeutils.utcnow() db.instance_update(context, instance_uuid, {'host': host, 'scheduled_at': now}) rpc.cast(context, rpc.queue_get_for(context, 'compute', host), {"method": method, "args": kwargs}) LOG.debug(_("Casted '%(method)s' to compute '%(host)s'") % locals())
def launch_instance(self, context, instance_uuid, params={}): pid = context.project_id uid = context.user_id instance = self.get(context, instance_uuid) if not(self._is_instance_blessed(context, instance_uuid)): # The instance is not blessed. We can't launch new instances from it. raise exception.NovaException( _(("Instance %s is not blessed. " + "Please bless the instance before launching from it.") % instance_uuid)) # Set up security groups to be added - we are passed in names, but need ID's security_group_names = params.pop('security_groups', None) if security_group_names != None: security_groups = [self.db.security_group_get_by_name(context, context.project_id, sg) for sg in security_group_names] else: security_groups = None reservations = self._acquire_addition_reservation(context, instance) try: # Create a new launched instance. new_instance_ref = self._copy_instance(context, instance_uuid, params.get('name', "%s-%s" % (instance['display_name'], "clone")), launch=True, new_user_data=params.pop('user_data', None), security_groups=security_groups) LOG.debug(_("Casting to scheduler for %(pid)s/%(uid)s's" " instance %(instance_uuid)s") % locals()) # FIXME: The Folsom scheduler removed support for calling # arbitrary functions via the scheduler. Damn. So now we # have to make scheduling decisions internally. Until this # is sorted, we will simply cast the message and let a random # host pick it up. Note that this is simply a stopgap measure. rpc.cast(context, CONF.gridcentric_topic, {"method": "launch_instance", "args": {"instance_uuid": new_instance_ref['uuid'], "params": params}}) self._commit_reservation(context, reservations) except: self._rollback_reservation(context, reservations) raise return self.get(context, new_instance_ref['uuid'])
def cast_to_host(context, topic, host, method, update_db=True, **kwargs): """Generic cast to host""" topic_mapping = { "compute": cast_to_compute_host, "volume": cast_to_volume_host, 'network': cast_to_network_host} func = topic_mapping.get(topic) if func: func(context, host, method, update_db=update_db, **kwargs) else: rpc.cast(context, rpc.queue_get_for(context, topic, host), {"method": method, "args": kwargs}) LOG.debug(_("Casted '%(method)s' to %(topic)s '%(host)s'") % locals())
def forward_request(context, request_type, master, aggregate_id, slave_compute, slave_address, slave_uuid): """Casts add/remove requests to the pool master.""" # replace the address from the xenapi connection url # because this might be 169.254.0.1, i.e. xenapi # NOTE: password in clear is not great, but it'll do for now sender_url = swap_xapi_host(FLAGS.xenapi_connection_url, slave_address) rpc.cast(context, rpc.queue_get_for(context, FLAGS.compute_topic, master), {"method": request_type, "args": {"aggregate_id": aggregate_id, "host": slave_compute, "url": sender_url, "user": FLAGS.xenapi_connection_username, "passwd": FLAGS.xenapi_connection_password, "compute_uuid": vm_utils.get_this_vm_uuid(), "xenhost_uuid": slave_uuid, }, })
def test_cast_to_compute_host_update_db_with_instance_uuid(self): host = "fake_host1" method = "fake_method" fake_kwargs = {"instance_uuid": "fake_uuid", "extra_arg": "meow"} queue = "fake_queue" self.mox.StubOutWithMock(timeutils, "utcnow") self.mox.StubOutWithMock(db, "instance_update") self.mox.StubOutWithMock(rpc, "queue_get_for") self.mox.StubOutWithMock(rpc, "cast") timeutils.utcnow().AndReturn("fake-now") db.instance_update(self.context, "fake_uuid", {"host": None, "scheduled_at": "fake-now"}) rpc.queue_get_for(self.context, "compute", host).AndReturn(queue) rpc.cast(self.context, queue, {"method": method, "args": fake_kwargs}) self.mox.ReplayAll() driver.cast_to_compute_host(self.context, host, method, **fake_kwargs)
def test_cast_to_host_unknown_topic(self): host = 'fake_host1' method = 'fake_method' fake_kwargs = {'extra_arg': 'meow'} topic = 'unknown' queue = 'fake_queue' self.mox.StubOutWithMock(rpc, 'queue_get_for') self.mox.StubOutWithMock(rpc, 'cast') rpc.queue_get_for(self.context, topic, host).AndReturn(queue) rpc.cast(self.context, queue, {'method': method, 'args': fake_kwargs}) self.mox.ReplayAll() driver.cast_to_host(self.context, topic, host, method, update_db=False, **fake_kwargs)
def forward_request(context, request_type, master, aggregate_id, slave_compute, slave_address, slave_uuid): """Casts add/remove requests to the pool master.""" # replace the address from the xenapi connection url # because this might be 169.254.0.1, i.e. xenapi # NOTE: password in clear is not great, but it'll do for now sender_url = swap_xapi_host(FLAGS.xenapi_connection_url, slave_address) rpc.cast( context, rpc.queue_get_for(context, FLAGS.compute_topic, master), { "method": request_type, "args": { "aggregate_id": aggregate_id, "host": slave_compute, "url": sender_url, "user": FLAGS.xenapi_connection_username, "passwd": FLAGS.xenapi_connection_password, "compute_uuid": vm_utils.get_this_vm_uuid(), "xenhost_uuid": slave_uuid, }, })
def test_proxy_rpc_to_manager_cast(self): fake_topic = 'fake-topic' fake_rpc_message = 'fake-rpc-message' fake_host_name = 'fake-host-name' self.mox.StubOutWithMock(self.tgt_db_inst, 'service_get_by_compute_host') self.mox.StubOutWithMock(rpc, 'cast') self.tgt_db_inst.service_get_by_compute_host(self.ctxt, fake_host_name) rpc.cast(self.ctxt, fake_topic, fake_rpc_message) self.mox.ReplayAll() self.src_msg_runner.proxy_rpc_to_manager( self.ctxt, self.tgt_cell_name, fake_host_name, fake_topic, fake_rpc_message, False, timeout=None)
def test_cast_to_compute_host_update_db_with_instance_uuid(self): host = 'fake_host1' method = 'fake_method' fake_kwargs = {'instance_uuid': 'fake_uuid', 'extra_arg': 'meow'} queue = 'fake_queue' self.mox.StubOutWithMock(timeutils, 'utcnow') self.mox.StubOutWithMock(db, 'instance_update') self.mox.StubOutWithMock(rpc, 'queue_get_for') self.mox.StubOutWithMock(rpc, 'cast') timeutils.utcnow().AndReturn('fake-now') db.instance_update(self.context, 'fake_uuid', { 'host': None, 'scheduled_at': 'fake-now' }) rpc.queue_get_for(self.context, 'compute', host).AndReturn(queue) rpc.cast(self.context, queue, {'method': method, 'args': fake_kwargs}) self.mox.ReplayAll() driver.cast_to_compute_host(self.context, host, method, **fake_kwargs)
def _cast_gridcentric_message(self, method, context, instance_uuid, host=None, params=None): """Generic handler for RPC casts to gridcentric. This does not block for a response. :param params: Optional dictionary of arguments to be passed to the gridcentric worker :returns: None """ if not params: params = {} if not host: instance = self.get(context, instance_uuid) host = instance["host"] if not host: queue = FLAGS.gridcentric_topic else: queue = self.db.queue_get_for(context, FLAGS.gridcentric_topic, host) params["instance_uuid"] = instance_uuid kwargs = {"method": method, "args": params} rpc.cast(context, queue, kwargs)
def install_policy(self, context, policy_ini_string, wait): validated = False faults = [] for host in self._list_cobalt_hosts(context): queue = rpc.queue_get_for(context, CONF.cobalt_topic, host) args = { "method": "install_policy", "args": { "policy_ini_string": policy_ini_string }, } if (not validated) or wait: try: rpc.call(context, queue, args) validated = True except Exception, ex: faults.append((host, str(ex))) if not wait: raise exception.NovaException( _("Failed to install policy on host %s: %s" % \ (host, str(ex)))) else: rpc.cast(context, queue, args)
def create(self, context, size, name, description, snapshot=None, volume_type=None, metadata=None, availability_zone=None): check_policy(context, 'create') if snapshot is not None: if snapshot['status'] != "available": msg = _("status must be available") raise exception.InvalidSnapshot(reason=msg) if not size: size = snapshot['volume_size'] snapshot_id = snapshot['id'] else: snapshot_id = None if not isinstance(size, int) or size <= 0: msg = _('Volume size must be an integer and greater than 0') raise exception.InvalidInput(reason=msg) try: reservations = QUOTAS.reserve(context, volumes=1, gigabytes=size) except exception.OverQuota as e: overs = e.kwargs['overs'] usages = e.kwargs['usages'] quotas = e.kwargs['quotas'] def _consumed(name): return (usages[name]['reserved'] + usages[name]['in_use']) pid = context.project_id if 'gigabytes' in overs: consumed = _consumed('gigabytes') quota = quotas['gigabytes'] LOG.warn( _("Quota exceeded for %(pid)s, tried to create " "%(size)sG volume (%(consumed)dG of %(quota)dG " "already consumed)") % locals()) raise exception.VolumeSizeTooLarge() elif 'volumes' in overs: consumed = _consumed('volumes') LOG.warn( _("Quota exceeded for %(pid)s, tried to create " "volume (%(consumed)d volumes already consumed)") % locals()) raise exception.VolumeLimitExceeded(allowed=quotas['volumes']) if availability_zone is None: availability_zone = FLAGS.storage_availability_zone if volume_type is None: volume_type_id = None else: volume_type_id = volume_type.get('id', None) options = { 'size': size, 'user_id': context.user_id, 'project_id': context.project_id, 'snapshot_id': snapshot_id, 'availability_zone': availability_zone, 'status': "creating", 'attach_status': "detached", 'display_name': name, 'display_description': description, 'volume_type_id': volume_type_id, 'metadata': metadata, } volume = self.db.volume_create(context, options) rpc.cast( context, FLAGS.scheduler_topic, { "method": "create_volume", "args": { "topic": FLAGS.volume_topic, "volume_id": volume['id'], "snapshot_id": snapshot_id, "reservations": reservations } }) return volume
def add_network_to_project(self, context, project_id): """Force adds another network to a project.""" rpc.cast(context, FLAGS.network_topic, {'method': 'add_network_to_project', 'args': {'project_id': project_id}})