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)
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)
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)
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)
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)
def setUp(self): super(TestResourceTracker, self).setUp() self.syspath = sysinfo.SYS_FPGA sysinfo.SYS_FPGA = "/sys/class/fpga" tmp_sys_dir = self.useFixture(fixtures.TempDir()) prepare_test_data.create_fake_sysfs(tmp_sys_dir.path) sysinfo.SYS_FPGA = os.path.join( tmp_sys_dir.path, sysinfo.SYS_FPGA.split("/", 1)[-1]) utils.SYS_FPGA_PATH = sysinfo.SYS_FPGA self.host = CONF.host self.cond_api = cond_api.ConductorAPI() self.rt = ResourceTracker(self.host, self.cond_api)
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)
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)
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)
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)
class TestResourceTracker(base.TestCase): """Test Agent ResourceTracker """ def setUp(self): super(TestResourceTracker, self).setUp() self.syspath = sysinfo.SYS_FPGA sysinfo.SYS_FPGA = "/sys/class/fpga" tmp_sys_dir = self.useFixture(fixtures.TempDir()) prepare_test_data.create_fake_sysfs(tmp_sys_dir.path) sysinfo.SYS_FPGA = os.path.join( tmp_sys_dir.path, sysinfo.SYS_FPGA.split("/", 1)[-1]) utils.SYS_FPGA_PATH = sysinfo.SYS_FPGA self.host = CONF.host self.cond_api = cond_api.ConductorAPI() self.rt = ResourceTracker(self.host, self.cond_api) def tearDown(self): super(TestResourceTracker, self).tearDown() sysinfo.SYS_FPGA = self.syspath utils.SYS_FPGA_PATH = self.syspath 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_get_fpga_devices(self): expect = { '0000:5e:00.0': { 'function': 'pf', 'assignable': False, 'pr_num': '1', 'name': 'intel-fpga-dev.0', 'interface_type': 'pci', 'vendor_id': '0x8086', 'devices': '0000:5e:00.0', 'regions': [{ 'function': 'vf', 'assignable': True, 'name': 'intel-fpga-dev.2', 'interface_type': 'pci', 'vendor_id': '0x8086', 'devices': '0000:5e:00.1', 'parent_devices': '0000:5e:00.0', 'path': '%s/intel-fpga-dev.2' % sysinfo.SYS_FPGA, 'product_id': '0xbcc1'}], 'parent_devices': '', 'path': '%s/intel-fpga-dev.0' % sysinfo.SYS_FPGA, 'product_id': '0xbcc0'}, '0000:5e:00.1': { 'function': 'vf', 'assignable': True, 'name': 'intel-fpga-dev.2', 'interface_type': 'pci', 'vendor_id': '0x8086', 'devices': '0000:5e:00.1', 'parent_devices': '0000:5e:00.0', 'path': '%s/intel-fpga-dev.2' % sysinfo.SYS_FPGA, 'product_id': '0xbcc1'}, '0000:be:00.0': { 'function': 'pf', 'assignable': True, 'pr_num': '0', 'name': 'intel-fpga-dev.1', 'interface_type': 'pci', 'vendor_id': '0x8086', 'devices': '0000:be:00.0', 'parent_devices': '', 'path': '%s/intel-fpga-dev.1' % sysinfo.SYS_FPGA, 'product_id': '0xbcc0'}} fpgas = self.rt._get_fpga_devices() self.assertDictEqual(expect, fpgas)