Exemple #1
0
    def mounted_on_same_shared_storage(self, context, instance_ref, dest):
        """Check if the src and dest host mount same shared storage.

        At first, dest host creates temp file, and src host can see
        it if they mounts same shared storage. Then src host erase it.

        :param context: security context
        :param instance_ref: cinder.db.sqlalchemy.models.Instance object
        :param dest: destination host

        """

        src = instance_ref['host']
        dst_t = rpc.queue_get_for(context, FLAGS.compute_topic, dest)
        src_t = rpc.queue_get_for(context, FLAGS.compute_topic, src)

        filename = rpc.call(context, dst_t,
                            {"method": 'create_shared_storage_test_file'})

        try:
            # make sure existence at src host.
            ret = rpc.call(context, src_t,
                        {"method": 'check_shared_storage_test_file',
                        "args": {'filename': filename}})

        finally:
            rpc.cast(context, dst_t,
                    {"method": 'cleanup_shared_storage_test_file',
                    "args": {'filename': filename}})

        return ret
Exemple #2
0
    def test_cast_to_volume_host_update_db_with_volume_id(self):
        host = 'fake_host1'
        method = 'fake_method'
        fake_kwargs = {'volume_id': 31337, 'extra_arg': 'meow'}
        queue = 'fake_queue'

        self.mox.StubOutWithMock(timeutils, 'utcnow')
        self.mox.StubOutWithMock(db, 'volume_update')
        self.mox.StubOutWithMock(rpc, 'queue_get_for')
        self.mox.StubOutWithMock(rpc, 'cast')

        timeutils.utcnow().AndReturn('fake-now')
        db.volume_update(self.context, 31337, {
            'host': host,
            'scheduled_at': 'fake-now'
        })
        rpc.queue_get_for(self.context, FLAGS.volume_topic,
                          host).AndReturn(queue)
        rpc.cast(self.context, queue, {'method': method, 'args': fake_kwargs})

        self.mox.ReplayAll()
        driver.cast_to_volume_host(self.context,
                                   host,
                                   method,
                                   update_db=True,
                                   **fake_kwargs)
Exemple #3
0
    def test_cast_to_volume_host_no_update_db(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, FLAGS.volume_topic, host).AndReturn(queue)
        rpc.cast(self.context, queue, {"method": method, "args": fake_kwargs})

        self.mox.ReplayAll()
        driver.cast_to_volume_host(self.context, host, method, update_db=False, **fake_kwargs)
Exemple #4
0
 def delete_backup(self, ctxt, host, backup_id):
     LOG.debug("delete_backup  rpcapi backup_id %s", backup_id)
     topic = rpc.queue_get_for(ctxt, self.topic, host)
     self.cast(ctxt,
               self.make_msg('delete_backup',
                             backup_id=backup_id),
               topic=topic)
Exemple #5
0
 def create_export(self, ctxt, volume):
     return self.call(ctxt,
                      self.make_msg('create_export',
                                    volume_id=volume['id']),
                      topic=rpc.queue_get_for(ctxt, self.topic,
                                              volume['host']),
                      version='1.13')
Exemple #6
0
 def copy_volume_to_image(self, ctxt, volume, image_id):
     self.cast(ctxt, self.make_msg('copy_volume_to_image',
                                   volume_id=volume['id'],
                                   image_id=image_id),
               topic=rpc.queue_get_for(ctxt,
                                       self.topic,
                                       volume['host']))
Exemple #7
0
 def rename_volume(self, ctxt, volume, new_name_id):
     self.call(ctxt,
               self.make_msg('rename_volume',
                             volume_id=volume['id'],
                             new_name_id=new_name_id),
               topic=rpc.queue_get_for(ctxt, self.topic, volume['host']),
               version='1.8')
Exemple #8
0
 def accept_transfer(self, ctxt, volume, new_user, new_project):
     self.cast(
         ctxt,
         self.make_msg("accept_transfer", volume_id=volume["id"], new_user=new_user, new_project=new_project),
         topic=rpc.queue_get_for(ctxt, self.topic, volume["host"]),
         version="1.9",
     )
Exemple #9
0
 def remove_from_compute(self, context, volume, instance_id, host):
     """Remove volume from specified compute host."""
     rpc.call(context,
              rpc.queue_get_for(context, FLAGS.compute_topic, host),
              {"method": "remove_volume_connection",
               "args": {'instance_id': instance_id,
                        'volume_id': volume['id']}})
Exemple #10
0
 def remove_from_compute(self, context, volume, instance_id, host):
     """Remove volume from specified compute host."""
     rpc.call(context,
              rpc.queue_get_for(context, FLAGS.compute_topic, host),
              {"method": "remove_volume_connection",
               "args": {'instance_id': instance_id,
                        'volume_id': volume['id']}})
Exemple #11
0
 def rename_volume(self, ctxt, volume, new_name_id):
     self.call(ctxt,
               self.make_msg('rename_volume',
                             volume_id=volume['id'],
                             new_name_id=new_name_id),
               topic=rpc.queue_get_for(ctxt, self.topic, volume['host']),
               version='1.8')
Exemple #12
0
    def _cast_create_volume(self, context, request_spec, filter_properties):

        # 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 scheduler. So snapshot can be copy to new volume.

        volume_id = request_spec['volume_id']
        snapshot_id = request_spec['snapshot_id']
        image_id = request_spec['image_id']

        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'])
            # bypass scheduler and send request directly to volume
            rpc.cast(context,
                     topic,
                     {"method": "create_volume",
                      "args": {"volume_id": volume_id,
                               "snapshot_id": snapshot_id,
                               "image_id": image_id}})
        else:
            self.scheduler_rpcapi.create_volume(context,
                FLAGS.volume_topic,
                volume_id,
                snapshot_id,
                image_id,
                request_spec=request_spec,
                filter_properties=filter_properties)
Exemple #13
0
 def create_backup(self, ctxt, host, backup_id, volume_id):
     LOG.debug("create_backup in rpcapi backup_id %s", backup_id)
     topic = rpc.queue_get_for(ctxt, self.topic, host)
     LOG.debug("create queue topic=%s", topic)
     self.cast(ctxt,
               self.make_msg('create_backup', backup_id=backup_id),
               topic=topic)
 def delete_replica(self, ctxt, secondary, relationship):
     return self.call(ctxt,
                      self.make_msg('delete_replica',
                                    relationship_id=relationship['id']),
                      topic=rpc.queue_get_for(ctxt, self.topic,
                                              secondary['host']),
                      version='1.12')
Exemple #15
0
 def copy_volume_to_image(self, ctxt, volume, image_meta):
     self.cast(ctxt,
               self.make_msg('copy_volume_to_image',
                             volume_id=volume['id'],
                             image_meta=image_meta),
               topic=rpc.queue_get_for(ctxt, self.topic, volume['host']),
               version='1.3')
Exemple #16
0
 def initialize_connection(self, ctxt, volume, connector):
     return self.call(ctxt, self.make_msg('initialize_connection',
                                          volume_id=volume['id'],
                                          connector=connector),
                      topic=rpc.queue_get_for(ctxt,
                                              self.topic,
                                              volume['host']))
Exemple #17
0
 def initialize_connection(self, context, volume, connector):
     host = volume['host']
     queue = rpc.queue_get_for(context, FLAGS.volume_topic, host)
     return rpc.call(context, queue,
                     {"method": "initialize_connection",
                      "args": {"volume_id": volume['id'],
                               "connector": connector}})
 def initialize_connection(self, ctxt, volume, connector):
     return self.call(ctxt, self.make_msg('initialize_connection',
                                          volume_id=volume['id'],
                                          connector=connector),
                      topic=rpc.queue_get_for(ctxt,
                                              self.topic,
                                              volume['host']))
Exemple #19
0
    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
Exemple #20
0
 def create_volume(
     self,
     ctxt,
     volume,
     host,
     request_spec,
     filter_properties,
     allow_reschedule=True,
     snapshot_id=None,
     image_id=None,
     source_volid=None,
 ):
     self.cast(
         ctxt,
         self.make_msg(
             "create_volume",
             volume_id=volume["id"],
             request_spec=request_spec,
             filter_properties=filter_properties,
             allow_reschedule=allow_reschedule,
             snapshot_id=snapshot_id,
             image_id=image_id,
             source_volid=source_volid,
         ),
         topic=rpc.queue_get_for(ctxt, self.topic, host),
         version="1.4",
     )
Exemple #21
0
 def accept_transfer(self, ctxt, volume):
     self.cast(
         ctxt,
         self.make_msg("accept_transfer", volume_id=volume["id"]),
         topic=rpc.queue_get_for(ctxt, self.topic, volume["host"]),
         version="1.5",
     )
Exemple #22
0
 def delete_backup(self, ctxt, host, backup_id):
     LOG.debug("delete_backup  rpcapi backup_id %s", backup_id)
     topic = rpc.queue_get_for(ctxt, self.topic, host)
     self.cast(ctxt,
               self.make_msg('delete_backup',
                             backup_id=backup_id),
               topic=topic)
Exemple #23
0
 def initialize_connection(self, context, volume, connector):
     host = volume['host']
     queue = rpc.queue_get_for(context, FLAGS.volume_topic, host)
     return rpc.call(context, queue,
                     {"method": "initialize_connection",
                      "args": {"volume_id": volume['id'],
                               "connector": connector}})
 def replication_swap(self, ctxt, relationship):
     host = relationship['primary_volume']['host']
     return self.cast(ctxt,
                      self.make_msg('replication_swap',
                                    relationship_id=relationship['id']),
                      topic=rpc.queue_get_for(ctxt, self.topic, host),
                      version='1.12')
Exemple #25
0
 def create_export(self, ctxt, volume):
     return self.call(
         ctxt,
         self.make_msg("create_export", volume_id=volume["id"]),
         topic=rpc.queue_get_for(ctxt, self.topic, volume["host"]),
         version="1.13",
     )
Exemple #26
0
    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}})
Exemple #27
0
    def _cast_create_volume(self, context, volume_id, snapshot_id,
                            image_id):

        # 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,
                               "image_id": image_id}})
        else:
            rpc.cast(context,
                     FLAGS.scheduler_topic,
                     {"method": "create_volume",
                      "args": {"topic": FLAGS.volume_topic,
                               "volume_id": volume_id,
                               "snapshot_id": snapshot_id,
                               "image_id": image_id}})
Exemple #28
0
 def extend_volume(self, ctxt, volume, new_size):
     self.cast(
         ctxt,
         self.make_msg("extend_volume", volume_id=volume["id"], new_size=new_size),
         topic=rpc.queue_get_for(ctxt, self.topic, volume["host"]),
         version="1.6",
     )
Exemple #29
0
 def copy_volume_to_image(self, ctxt, volume, image_meta):
     self.cast(
         ctxt,
         self.make_msg("copy_volume_to_image", volume_id=volume["id"], image_meta=image_meta),
         topic=rpc.queue_get_for(ctxt, self.topic, volume["host"]),
         version="1.3",
     )
Exemple #30
0
 def create_export(self, ctxt, volume):
     return self.call(ctxt, self.make_msg('create_export',
                                          volume_id=volume['id']),
                      topic=rpc.queue_get_for(ctxt,
                                              self.topic,
                                              volume['host']),
                      version='1.13')
Exemple #31
0
    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
Exemple #32
0
    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 extend_volume(self, ctxt, volume, new_size):
     self.cast(ctxt,
               self.make_msg('extend_volume',
                             volume_id=volume['id'],
                             new_size=new_size),
               topic=rpc.queue_get_for(ctxt, self.topic, volume['host']),
               version='1.6')
 def accept_transfer(self, ctxt, volume, new_user, new_project):
     self.cast(ctxt,
               self.make_msg('accept_transfer',
                             volume_id=volume['id'],
                             new_user=new_user,
                             new_project=new_project),
               topic=rpc.queue_get_for(ctxt, self.topic, volume['host']),
               version='1.9')
 def terminate_connection(self, ctxt, volume, connector, force=False):
     return self.call(ctxt, self.make_msg('terminate_connection',
                                          volume_id=volume['id'],
                                          connector=connector,
                                          force=force),
                      topic=rpc.queue_get_for(ctxt,
                                              self.topic,
                                              volume['host']))
Exemple #36
0
 def create_backup(self, ctxt, host, backup_id, volume_id):
     LOG.debug("create_backup in rpcapi backup_id %s", backup_id)
     topic = rpc.queue_get_for(ctxt, self.topic, host)
     LOG.debug("create queue topic=%s", topic)
     self.cast(ctxt,
               self.make_msg('create_backup',
                             backup_id=backup_id),
               topic=topic)
Exemple #37
0
 def attach_volume(self, ctxt, volume, instance_uuid, mountpoint):
     return self.call(ctxt,
                      self.make_msg('attach_volume',
                                    volume_id=volume['id'],
                                    instance_uuid=instance_uuid,
                                    mountpoint=mountpoint),
                      topic=rpc.queue_get_for(ctxt, self.topic,
                                              volume['host']))
Exemple #38
0
 def attach(self, context, volume, instance_uuid, mountpoint):
     host = volume['host']
     queue = rpc.queue_get_for(context, FLAGS.volume_topic, host)
     return rpc.call(context, queue,
                     {"method": "attach_volume",
                      "args": {"volume_id": volume['id'],
                               "instance_uuid": instance_uuid,
                               "mountpoint": mountpoint}})
Exemple #39
0
 def migrate_volume(self, ctxt, volume, dest_host, force_host_copy):
     host_p = {"host": dest_host.host, "capabilities": dest_host.capabilities}
     self.cast(
         ctxt,
         self.make_msg("migrate_volume", volume_id=volume["id"], host=host_p, force_host_copy=force_host_copy),
         topic=rpc.queue_get_for(ctxt, self.topic, volume["host"]),
         version="1.8",
     )
Exemple #40
0
 def terminate_connection(self, context, volume, connector):
     self.unreserve_volume(context, volume)
     host = volume['host']
     queue = rpc.queue_get_for(context, FLAGS.volume_topic, host)
     return rpc.call(context, queue,
                     {"method": "terminate_connection",
                      "args": {"volume_id": volume['id'],
                               "connector": connector}})
Exemple #41
0
 def attach_volume(self, ctxt, volume, instance_uuid, mountpoint):
     return self.call(ctxt, self.make_msg('attach_volume',
                                          volume_id=volume['id'],
                                          instance_uuid=instance_uuid,
                                          mountpoint=mountpoint),
                      topic=rpc.queue_get_for(ctxt,
                                              self.topic,
                                              volume['host']))
Exemple #42
0
 def terminate_connection(self, context, volume, connector):
     self.unreserve_volume(context, volume)
     host = volume['host']
     queue = rpc.queue_get_for(context, FLAGS.volume_topic, host)
     return rpc.call(context, queue,
                     {"method": "terminate_connection",
                      "args": {"volume_id": volume['id'],
                               "connector": connector}})
Exemple #43
0
 def terminate_connection(self, ctxt, volume, connector, force=False):
     return self.call(ctxt, self.make_msg('terminate_connection',
                                          volume_id=volume['id'],
                                          connector=connector,
                                          force=force),
                      topic=rpc.queue_get_for(ctxt,
                                              self.topic,
                                              volume['host']))
Exemple #44
0
 def attach(self, context, volume, instance_uuid, mountpoint):
     host = volume['host']
     queue = rpc.queue_get_for(context, FLAGS.volume_topic, host)
     return rpc.call(context, queue,
                     {"method": "attach_volume",
                      "args": {"volume_id": volume['id'],
                               "instance_uuid": instance_uuid,
                               "mountpoint": mountpoint}})
Exemple #45
0
 def detach(self, context, volume):
     host = volume['host']
     queue = rpc.queue_get_for(context, FLAGS.volume_topic, host)
     return rpc.call(context, queue, {
         "method": "detach_volume",
         "args": {
             "volume_id": volume['id']
         }
     })
 def migrate_volume_completion(self, ctxt, volume, new_volume, error):
     return self.call(ctxt,
                      self.make_msg('migrate_volume_completion',
                                    volume_id=volume['id'],
                                    new_volume_id=new_volume['id'],
                                    error=error),
                      topic=rpc.queue_get_for(ctxt, self.topic,
                                              volume['host']),
                      version='1.10')
Exemple #47
0
    def test_cast_to_volume_host_no_update_db(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, FLAGS.volume_topic,
                          host).AndReturn(queue)
        rpc.cast(self.context, queue, {'method': method, 'args': fake_kwargs})

        self.mox.ReplayAll()
        driver.cast_to_volume_host(self.context,
                                   host,
                                   method,
                                   update_db=False,
                                   **fake_kwargs)
 def migrate_volume(self, ctxt, volume, dest_host, force_host_copy):
     host_p = {'host': dest_host.host,
               'capabilities': dest_host.capabilities}
     self.cast(ctxt,
               self.make_msg('migrate_volume',
                             volume_id=volume['id'],
                             host=host_p,
                             force_host_copy=force_host_copy),
               topic=rpc.queue_get_for(ctxt, self.topic, volume['host']),
               version='1.8')
Exemple #49
0
 def export_record(self, ctxt, host, backup_id):
     LOG.debug(
         "export_record in rpcapi backup_id %(id)s "
         "on host %(host)s.", {
             'id': backup_id,
             'host': host
         })
     topic = rpc.queue_get_for(ctxt, self.topic, host)
     LOG.debug("export queue topic=%s" % topic)
     return self.call(ctxt,
                      self.make_msg('export_record', backup_id=backup_id),
                      topic=topic)
Exemple #50
0
 def delete_snapshot(self, context, snapshot, force=False):
     if not force and 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 attach_volume(self, ctxt, volume, instance_uuid, host_name,
                   mountpoint, mode):
     return self.call(ctxt, self.make_msg('attach_volume',
                                          volume_id=volume['id'],
                                          instance_uuid=instance_uuid,
                                          host_name=host_name,
                                          mountpoint=mountpoint,
                                          mode=mode),
                      topic=rpc.queue_get_for(ctxt,
                                              self.topic,
                                              volume['host']),
                      version='1.11')
Exemple #52
0
def cast_to_host(context, topic, host, method, update_db=True, **kwargs):
    """Generic cast to host"""

    topic_mapping = {"volume": cast_to_volume_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())
Exemple #53
0
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, FLAGS.volume_topic, host), {
        "method": method,
        "args": kwargs
    })
    LOG.debug(_("Casted '%(method)s' to host '%(host)s'") % locals())