Beispiel #1
0
class AgentManager(periodic_task.PeriodicTasks):
    """Cyborg Agent manager main class."""

    RPC_API_VERSION = '1.0'
    target = messaging.Target(version=RPC_API_VERSION)

    def __init__(self, topic, host=None):
        super(AgentManager, self).__init__(CONF)
        self.topic = topic
        self.host = host or CONF.host
        self.fpga_driver = FPGADriver()
        self.cond_api = cond_api.ConductorAPI()
        self._rt = ResourceTracker(host, self.cond_api)

    def periodic_tasks(self, context, raise_on_error=False):
        return self.run_periodic_tasks(context, raise_on_error=raise_on_error)

    def hardware_list(self, context, values):
        """List installed hardware."""
        pass

    def fpga_program(self, context, accelerator, image):
        """ Program a FPGA regoin, image can be a url or local file"""
        # TODO (Shaohe Feng) Get image from glance.
        # And add claim and rollback logical.
        raise NotImplementedError()

    @periodic_task.periodic_task(run_immediately=True)
    def update_available_resource(self, context, startup=True):
        """update all kinds of accelerator resources from their drivers."""
        self._rt.update_usage(context)
Beispiel #2
0
class AgentManager(periodic_task.PeriodicTasks):
    """Cyborg Agent manager main class."""

    RPC_API_VERSION = '1.0'
    target = messaging.Target(version=RPC_API_VERSION)

    def __init__(self, topic, host=None):
        super(AgentManager, self).__init__(CONF)
        self.topic = topic
        self.host = host or CONF.host
        self.fpga_driver = FPGADriver()
        self.cond_api = cond_api.ConductorAPI()
        self.agent_api = AgentAPI()
        self.image_api = ImageAPI()
        self._rt = ResourceTracker(host, self.cond_api)

    def periodic_tasks(self, context, raise_on_error=False):
        return self.run_periodic_tasks(context, raise_on_error=raise_on_error)

    def fpga_program_v2(self, context, controlpath_id, bitstream_uuid,
                        driver_name):
        # TODO() Use tempfile module?
        download_path = "/tmp/" + bitstream_uuid + ".gbs"
        self.image_api.download(context,
                                bitstream_uuid,
                                dest_path=download_path)
        driver = self.fpga_driver.create(driver_name)
        ret = driver.program_v2(controlpath_id, download_path)
        LOG.info('Driver program() API returned code %s', ret)
        os.remove(download_path)

    @periodic_task.periodic_task(run_immediately=True)
    def update_available_resource(self, context, startup=True):
        """Update all kinds of accelerator resources from their drivers."""
        self._rt.update_usage(context)
Beispiel #3
0
class AgentManager(periodic_task.PeriodicTasks):
    """Cyborg Agent manager main class."""

    RPC_API_VERSION = '1.0'
    target = messaging.Target(version=RPC_API_VERSION)

    def __init__(self, topic, host=None):
        super(AgentManager, self).__init__(CONF)
        self.topic = topic
        self.host = host or CONF.host
        self.fpga_driver = FPGADriver()
        self.cond_api = cond_api.ConductorAPI()
        self.agent_api = AgentAPI()
        self.image_api = ImageAPI()
        self._rt = ResourceTracker(host, self.cond_api)

    def periodic_tasks(self, context, raise_on_error=False):
        return self.run_periodic_tasks(context, raise_on_error=raise_on_error)

    def hardware_list(self, context, values):
        """List installed hardware."""
        pass

    def fpga_program(self, context, deployable_uuid, image_uuid):
        """ Program a FPGA regoin, image can be a url or local file"""
        # TODO (Shaohe Feng) Get image from glance.
        # And add claim and rollback logical.
        path = self._download_bitstream(context, image_uuid)
        dep = self.cond_api.deployable_get(context, deployable_uuid)
        driver = self.fpga_driver.create(dep.vendor)
        driver.program(dep.address, path)

    def _download_bitstream(self, context, bitstream_uuid):
        """download the bistream

        :param context: the context
        :param bistream_uuid: v4 uuid of the bitstream to reprogram
        :returns: the path to bitstream downloaded, None if fail to download
        """
        download_path = "/tmp/" + bitstream_uuid + ".bin"
        self.image_api.download(context,
                                bitstream_uuid,
                                dest_path=download_path)
        return download_path

    @periodic_task.periodic_task(run_immediately=True)
    def update_available_resource(self, context, startup=True):
        """update all kinds of accelerator resources from their drivers."""
        self._rt.update_usage(context)
Beispiel #4
0
class AgentManager(periodic_task.PeriodicTasks):
    """Cyborg Agent manager main class.

    API version history:

    | 1.0 - Initial version.

    """

    RPC_API_VERSION = '1.0'
    target = messaging.Target(version=RPC_API_VERSION)

    def __init__(self, topic, host=None):
        super(AgentManager, self).__init__(CONF)
        self.topic = topic
        self.host = host or CONF.host
        self.fpga_driver = FPGADriver()
        self.cond_api = cond_api.ConductorAPI()
        self.agent_api = AgentAPI()
        self.image_api = ImageAPI()
        self._rt = ResourceTracker(host, self.cond_api)

    def periodic_tasks(self, context, raise_on_error=False):
        return self.run_periodic_tasks(context, raise_on_error=raise_on_error)

    def fpga_program(self, context, controlpath_id, bitstream_uuid,
                     driver_name):
        bitstream_uuid = str(bitstream_uuid)
        if not uuidutils.is_uuid_like(bitstream_uuid):
            raise exception.InvalidUUID(uuid=bitstream_uuid)
        download_path = tempfile.NamedTemporaryFile(suffix=".gbs",
                                                    prefix=bitstream_uuid)
        self.image_api.download(context,
                                bitstream_uuid,
                                dest_path=download_path.name)
        try:
            driver = self.fpga_driver.create(driver_name)
            ret = driver.program(controlpath_id, download_path.name)
            LOG.info('Driver program() API returned %s', ret)
        finally:
            LOG.debug('Remove tmp bitstream file: %s', download_path.name)
            os.remove(download_path.name)
        return ret

    @periodic_task.periodic_task(run_immediately=True)
    def update_available_resource(self, context, startup=True):
        """Update all kinds of accelerator resources from their drivers."""
        self._rt.update_usage(context)
Beispiel #5
0
class AgentManager(periodic_task.PeriodicTasks):
    """Cyborg Agent manager main class."""

    RPC_API_VERSION = '1.0'
    target = messaging.Target(version=RPC_API_VERSION)

    def __init__(self, topic, host=None):
        super(AgentManager, self).__init__(CONF)
        #can only use in the same node, change it to RPC to conductor
        self.conductor_api = conductor_api.ConductorAPI()
        self.topic = topic
        self.host = host or CONF.host
        self.fpga_driver = FPGADriver()
        self._rt = ResourceTracker(host, self.conductor_api)
        self.gpu_driver = GPUDriver()

    def periodic_tasks(self, context, raise_on_error=False):
        #        self.update_available_resource(context)
        return self.run_periodic_tasks(context, raise_on_error=raise_on_error)

    def hardware_list(self, context, values):
        """List installed hardware."""
        pass

    def fpga_program(self, context, accelerator, image):
        """Program a FPGA region, image can be a url or local file."""
        #TODO Get image from glance
        # And add claim and rollback logical
        raise NotImplementedError()

    @periodic_task.periodic_task(run_immediately=True)
    def update_available_resource(self, context, startup=True):
        """update all kinds of accelerator resources from their drivers."""
        driver = netronome.NETRONOMEDRIVER()
        port_resource = driver.get_available_resource()
        if port_resource:
            self.conductor_api.port_bulk_create(context, port_resource)
        self._rt.update_usage(context)
class TestResourceTracker(base.TestCase):
    """Test Agent ResourceTracker """

    def setUp(self):
        super(TestResourceTracker, self).setUp()
        self.host = CONF.host
        self.cond_api = cond_api.ConductorAPI()
        self.rt = ResourceTracker(self.host, self.cond_api)

    def test_update_usage(self):
        """Update the resource usage and stats after a change in an
        instance
        """
        # FIXME(Shaohe Feng) need add testcase. How to check the fpgas
        # has stored into DB by conductor correctly?
        pass

    def test_initialize_acc_drivers(self):
        enabled_drivers = ['intel_fpga_driver']
        self.rt._initialize_drivers(enabled_drivers=enabled_drivers)
        drivers = self.rt.acc_drivers
        self.assertEqual(len(drivers), len(enabled_drivers))

    def test_initialize_invalid_driver(self):
        enabled_drivers = ['invalid_driver']
        self.assertRaises(exception.InvalidDriver, self.rt._initialize_drivers,
                          enabled_drivers)

    @mock.patch('cyborg.agent.resource_tracker.LOG')
    def test_update_usage_failed_parent_provider(self, mock_log):
        with mock.patch.object(self.rt.conductor_api, 'report_data') as m:
            m.side_effect = exception.PlacementResourceProviderNotFound(
                resource_provider='foo')
            self.rt.update_usage(None)
            m.assert_called_once_with(None, 'fake-mini', [])
        mock_log.error.assert_called_once_with('Unable to report usage: %s',
                                               m.side_effect)