Added downloading bitstream when programming fpga
How to test the flow of program process manually: 1. generate the fake env by the follow command cat > ./fake_env.sh << EOL SYSINFO=cyborg/accelerator/drivers/fpga/intel/sysinfo.py UTILS=cyborg/accelerator/drivers/fpga/utils.py sed -i -e 's/^\(SYS_FPGA\) = "\(\/sys\/class\/fpga\)"$/\1 = "\/tmp\2"/g' $SYSINFO sed -i -e 's/^\(SYS_FPGA_PATH\) = "\(\/sys\/class\/fpga\)"$/\1 = "\/tmp\2"/g' $UTILS python cyborg/tests/unit/accelerator/drivers/fpga/intel/prepare_test_data.py LOG=/tmp/intel_fpga_program.log sudo echo 'echo fpgaconf \$@ '"|tee $LOG" > /usr/bin/fpgaconf sudo echo "date |tee -a $LOG" >> /usr/bin/fpgaconf sudo echo "echo 'Program intel FPGA successfully' |tee -a $LOG" >> /usr/bin/fpgaconf sudo chmod a+x /usr/bin/fpgaconf EOL chmod a+x ./fake_env.sh sudo ./fake_env.sh 2. Please use curl command as follows: curl -s -X PATCH -H "X-Auth-Token: $OS_TOKEN" -H "Content-Type: application/json"\ -d '[{ "path": "/program", "op": "replace", "value": [{ "image_uuid": "{image_uuid}" }] }]'\ http://{host_ip}:6666/v1/accelerators/deployables/{deployable_uuid}/program 3. Checke the /tmp/intel_fpga_program.log it should see the infomation as the follow exmaple: $ cat /tmp/intel_fpga_program.log fpgaconf -b 04 -d 00 -f 1 4047d422-5d2f-432c-b87f-5e1749e95ee6.bin Sat Oct 27 15:08:34 UTC 2018 Program intel FPGA successfully Change-Id: I70ff5edac65fe9e9ec1783d62c2ecd21ac5fab18
This commit is contained in:
parent
156c9f18e5
commit
0bd8a7d9de
|
@ -46,7 +46,7 @@ class IntelFPGADriver(FPGADriver):
|
|||
else:
|
||||
bdf = sysinfo.get_bdf_by_path(path)
|
||||
bdfs = sysinfo.split_bdf(bdf)
|
||||
cmd = ["sudo", "fpgaconf"]
|
||||
cmd = ["sudo", "/usr/bin/fpgaconf"]
|
||||
for i in zip(["-b", "-d", "-f"], bdfs):
|
||||
cmd.extend(i)
|
||||
cmd.append(image)
|
||||
|
|
|
@ -18,6 +18,8 @@ from oslo_service import periodic_task
|
|||
|
||||
from cyborg.accelerator.drivers.fpga.base import FPGADriver
|
||||
from cyborg.agent.resource_tracker import ResourceTracker
|
||||
from cyborg.agent.rpcapi import AgentAPI
|
||||
from cyborg.image.api import API as ImageAPI
|
||||
from cyborg.conductor import rpcapi as cond_api
|
||||
from cyborg.conf import CONF
|
||||
|
||||
|
@ -34,6 +36,8 @@ class AgentManager(periodic_task.PeriodicTasks):
|
|||
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):
|
||||
|
@ -43,11 +47,27 @@ class AgentManager(periodic_task.PeriodicTasks):
|
|||
"""List installed hardware."""
|
||||
pass
|
||||
|
||||
def fpga_program(self, context, accelerator, image):
|
||||
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.
|
||||
raise NotImplementedError()
|
||||
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):
|
||||
|
|
|
@ -21,7 +21,7 @@ import oslo_messaging as messaging
|
|||
from cyborg.common import constants
|
||||
from cyborg.common import rpc
|
||||
from cyborg.objects import base as objects_base
|
||||
|
||||
from cyborg import objects
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
@ -50,3 +50,20 @@ class AgentAPI(object):
|
|||
def hardware_list(self, context, values):
|
||||
"""Signal the agent to find local hardware."""
|
||||
pass
|
||||
|
||||
def program_fpga_with_bitstream(self,
|
||||
context,
|
||||
deployable_uuid,
|
||||
bitstream_uuid):
|
||||
"""Actiion to program a target FPGA"""
|
||||
version = '1.0'
|
||||
|
||||
dpl_get = objects.Deployable.get(context, deployable_uuid)
|
||||
if not dpl_get:
|
||||
# TODO (Li Liu) throw an exception here
|
||||
return 0
|
||||
|
||||
cctxt = self.client.prepare(server=dpl_get.host, version=version)
|
||||
return cctxt.call(context, 'fpga_program',
|
||||
deployable_uuid=deployable_uuid,
|
||||
image_uuid=bitstream_uuid)
|
||||
|
|
|
@ -22,6 +22,7 @@ from wsme import types as wtypes
|
|||
from cyborg.api.controllers import base
|
||||
from cyborg.api.controllers import link
|
||||
from cyborg.api.controllers.v1 import accelerators
|
||||
from cyborg.api.controllers.v1 import deployables
|
||||
from cyborg.api import expose
|
||||
|
||||
|
||||
|
@ -51,6 +52,7 @@ class Controller(rest.RestController):
|
|||
"""Version 1 API controller root"""
|
||||
|
||||
accelerators = accelerators.AcceleratorsController()
|
||||
deployables = deployables.DeployablesController()
|
||||
|
||||
@expose.expose(V1)
|
||||
def get(self):
|
||||
|
|
|
@ -28,6 +28,7 @@ from cyborg.common import exception
|
|||
from cyborg.common import policy
|
||||
from cyborg import objects
|
||||
from cyborg.quota import QUOTAS
|
||||
from cyborg.agent.rpcapi import AgentAPI
|
||||
|
||||
|
||||
class Deployable(base.APIBase):
|
||||
|
@ -151,10 +152,14 @@ class DeployablesController(base.CyborgController):
|
|||
"""
|
||||
|
||||
image_uuid = program_info[0]['value'][0]['image_uuid']
|
||||
agent_api = AgentAPI()
|
||||
obj_dep = objects.Deployable.get(pecan.request.context, uuid)
|
||||
# Set attribute of the new bitstream/image information
|
||||
obj_dep.add_attribute(pecan.request.context, 'image_uuid', image_uuid)
|
||||
# TODO (Li Liu) Trigger the program api in Agnet.
|
||||
agent_api.program_fpga_with_bitstream(pecan.request.context,
|
||||
uuid,
|
||||
image_uuid)
|
||||
return Deployable.convert_with_links(obj_dep)
|
||||
|
||||
@policy.authorize_wsgi("cyborg:deployable", "create", False)
|
||||
|
|
|
@ -92,7 +92,7 @@ class TestFPGADriver(base.TestCase):
|
|||
b = "0x5e"
|
||||
d = "0x00"
|
||||
f = "0x0"
|
||||
expect_cmd = ['sudo', 'fpgaconf', '-b', b,
|
||||
expect_cmd = ['sudo', '/usr/bin/fpgaconf', '-b', b,
|
||||
'-d', d, '-f', f, '/path/image']
|
||||
mock_popen.return_value = p()
|
||||
intel = FPGADriver.create("intel")
|
||||
|
|
|
@ -80,7 +80,7 @@ class TestIntelFPGADriver(base.TestCase):
|
|||
b = "0x5e"
|
||||
d = "0x00"
|
||||
f = "0x0"
|
||||
expect_cmd = ['sudo', 'fpgaconf', '-b', b,
|
||||
expect_cmd = ['sudo', '/usr/bin/fpgaconf', '-b', b,
|
||||
'-d', d, '-f', f, '/path/image']
|
||||
mock_popen.return_value = p()
|
||||
intel = IntelFPGADriver()
|
||||
|
|
|
@ -19,6 +19,7 @@ from six.moves import http_client
|
|||
from cyborg.api.controllers.v1.deployables import Deployable
|
||||
from cyborg.tests.unit.api.controllers.v1 import base as v1_test
|
||||
from cyborg.tests.unit import fake_deployable
|
||||
from cyborg.agent.rpcapi import AgentAPI
|
||||
|
||||
|
||||
class TestFPGAProgramController(v1_test.APITestV1):
|
||||
|
@ -29,13 +30,15 @@ class TestFPGAProgramController(v1_test.APITestV1):
|
|||
self.deployable_uuids = ['0acbf8d6-e02a-4394-aae3-57557d209498']
|
||||
|
||||
@mock.patch('cyborg.objects.Deployable.get')
|
||||
def test_program(self, mock_get_dep):
|
||||
@mock.patch('cyborg.agent.rpcapi.AgentAPI.program_fpga_with_bitstream')
|
||||
def test_program(self, mock_program, mock_get_dep):
|
||||
self.headers['X-Roles'] = 'admin'
|
||||
self.headers['Content-Type'] = 'application/json'
|
||||
dep_uuid = self.deployable_uuids[0]
|
||||
fake_dep = fake_deployable.fake_deployable_obj(self.context,
|
||||
uuid=dep_uuid)
|
||||
mock_get_dep.return_value = fake_dep
|
||||
mock_program.return_value = None
|
||||
body = [{"image_uuid": "9a17439a-85d0-4c53-a3d3-0f68a2eac896"}]
|
||||
response = self.\
|
||||
patch_json('/accelerators/deployables/%s/program' % dep_uuid,
|
||||
|
|
Loading…
Reference in New Issue