Browse Source

drop BoardStatus from the db.. all user is managed by BoardImpl now..

This may come back in the future, but it will be in BoardImpl, and will
contain more state such that a resume will have all the attribute's
current state in addition to checkout and the like.
main
John-Mark Gurney 3 years ago
parent
commit
d89c90ffda
2 changed files with 37 additions and 57 deletions
  1. +36
    -48
      bitelab/__init__.py
  2. +1
    -9
      bitelab/data.py

+ 36
- 48
bitelab/__init__.py View File

@@ -320,7 +320,7 @@ class BoardImpl:
self.setupscript = setupscript
self.options = options
self.reserved = False
self.user = None
self._user = None
self.attrmap = {}
self.lock = asyncio.Lock()
for i in options:
@@ -364,7 +364,7 @@ class BoardImpl:

self.add_info(json.loads(stdout))

self.user = user
self._user = user
self.reserved = True

await self.activate()
@@ -400,6 +400,7 @@ class BoardImpl:

self.clean_info()

self._user = None
self.reserved = False

async def update_attrs(self, **attrs):
@@ -470,6 +471,10 @@ class BoardImpl:
for i in set(self.attrcache) - set(self.attrmap):
del self.attrcache[i]

@property
def user(self):
return self._user

@property
def attrs(self):
return dict(self.attrcache)
@@ -597,11 +602,6 @@ def get_data(settings: config.Settings = Depends(get_settings)):
async def real_get_boardmanager(settings, data):
brdmgr = BoardManager.from_settings(settings)

# Clean up the database
# XXX - This isn't a complete fix, we need a better solution.
all = await data.BoardStatus.objects.all()
await asyncio.gather(*(x.delete() for x in all))

return brdmgr

_global_lock = asyncio.Lock()
@@ -647,18 +647,16 @@ async def validate_board_params(board_id, data, brdmgr, user=None, token=None):
if user is None:
user = await lookup_user(token, data)

try:
brduser = await data.BoardStatus.objects.get(board=board_id)
except orm.exceptions.NoMatch:
if brd.user is None:
raise BITEError(
status_code=HTTP_400_BAD_REQUEST,
errobj=Error(error='Board not reserved.',
board=Board.from_orm(brd)))

if user != brduser.user:
if user != brd.user:
raise BITEError(
status_code=HTTP_403_FORBIDDEN,
errobj=Error(error='Board reserved by %s.' % repr(brduser.user),
errobj=Error(error='Board reserved by %s.' % repr(brd.user),
board=Board.from_orm(brd)))

yield brd
@@ -725,18 +723,7 @@ async def reserve_board(board_id_or_class,
brd = brdmgr.boards[board_id]

async with brd.lock:
try:
obrdreq = await data.BoardStatus.objects.create(board=board_id,
user=user)
# XXX - There is a bug in orm where the returned
# object has an incorrect board value
# see: https://github.com/encode/orm/issues/47
#assert obrdreq.board == board_id and \
# obrdreq.user == user
brdreq = await data.BoardStatus.objects.get(board=board_id,
user=user)
# XXX - orm isn't doing it's job here
except sqlite3.IntegrityError:
if brd.user is not None:
raise BITEError(
status_code=HTTP_409_CONFLICT,
errobj=Error(error='Board currently reserved.',
@@ -747,7 +734,6 @@ async def reserve_board(board_id_or_class,
try:
await brd.reserve(user, sshpubkey)
except Exception as e:
await brdreq.delete()
if isinstance(e, RuntimeError):
retcode, stderr = e.args
raise BITEError(
@@ -890,21 +876,19 @@ async def release_board(board_id, user: str = Depends(lookup_user),
# XXX - how to handle a release error?
await log_event('release', user=user, board=brd)

try:
brduser = await data.BoardStatus.objects.get(board=board_id)
if user != brduser.user:
raise BITEError(
status_code=HTTP_403_FORBIDDEN,
errobj=Error(error='Board reserved by %s.' % repr(brduser.user),
board=Board.from_orm(brd)))

except orm.exceptions.NoMatch:
if brd.user is None:
raise BITEError(
status_code=HTTP_400_BAD_REQUEST,
errobj=Error(error='Board not reserved.',
board=Board.from_orm(brd)),
)

if user != brd.user:
raise BITEError(
status_code=HTTP_403_FORBIDDEN,
errobj=Error(error='Board reserved by %s.' % repr(brd.user),
board=Board.from_orm(brd)))

try:
await brd.release()
except RuntimeError as e:
@@ -914,8 +898,6 @@ async def release_board(board_id, user: str = Depends(lookup_user),
board=Board.from_orm(brd)),
)

await data.BoardStatus.delete(brduser)

await brd.update()

return brd
@@ -1040,9 +1022,16 @@ class TestWebSocket(TestCommon):
shutil.rmtree(self.basetempdir)
self.basetempdir = None

@patch('bitelab.snmp.snmpset')
@patch('bitelab.snmp.snmpget')
@patch('asyncio.create_subprocess_exec')
@timeout(2)
async def test_exec_sshd(self, cse):
async def test_exec_sshd(self, cse, sg, ss):

# that snmpget and snmpset returns False
sg.return_value = False
ss.return_value = False

def wrapper(corofun):
async def foo(*args, **kwargs):
r = await corofun(*args, **kwargs)
@@ -1077,8 +1066,6 @@ class TestWebSocket(TestCommon):
# that when the board is reserved by the wrong user
wrap_subprocess_exec(cse, stdout=b'{}', retcode=0)
brd = self.brdmgr.boards['cora-1']
obrdreq = await self.data.BoardStatus.objects.create(
board='cora-1', user='bar')
async with brd.lock:
await brd.reserve('bar')

@@ -1086,12 +1073,10 @@ class TestWebSocket(TestCommon):
with self.assertRaisesRegex(RuntimeError, 'Board reserved by \'bar\'.'):
await client.exec([ 'sshd', '-i' ], stdin=1, stdout=2)

brduser = await self.data.BoardStatus.objects.get(board='cora-1')
obrdreq = await self.data.BoardStatus.delete(brduser)

# that when the board is reserved by the correct user
obrdreq = await self.data.BoardStatus.objects.create(
board='cora-1', user='foo')
async with brd.lock:
await brd.release()
await brd.reserve('foo')

echodata = b'somedata'
wrap_subprocess_exec(cse, stdout=echodata, retcode=0)
@@ -1197,8 +1182,6 @@ class TestBiteLabAPI(TestCommon):
attrs = dict(iface='a', ip='b', devfsrule='c')
async with brd.lock:
await brd.reserve('foo')
obrdreq = await data.BoardStatus.objects.create(
board='cora-1', user='foo')
brd.attrcache.update(attrs)

# that when the script fails
@@ -1214,6 +1197,7 @@ class TestBiteLabAPI(TestCommon):
# and returns the correct data
info = Error(error='Failed to release board, ret: 1, stderr: b\'error\'',
board=Board(name='cora-1',
user='foo',
brdclass='cora-z7s',
reserved=True,
attrs=attrs,
@@ -1291,6 +1275,7 @@ class TestBiteLabAPI(TestCommon):

# and returns the correct data
brdinfo = Board(name='cora-1',
user='foo',
brdclass='cora-z7s',
reserved=True,
attrs=dict(power=False,
@@ -1351,6 +1336,7 @@ class TestBiteLabAPI(TestCommon):
# and returns the correct data
info = {
'name': 'cora-1',
'user': None,
'brdclass': 'cora-z7s',
'reserved': False,
'attrs': { 'power': False },
@@ -1402,6 +1388,7 @@ class TestBiteLabAPI(TestCommon):
info = {
'cora-1': {
'name': 'cora-1',
'user': None,
'brdclass': 'cora-z7s',
'reserved': False,
'attrs': { 'power': False },
@@ -1426,6 +1413,7 @@ class TestBiteLabAPI(TestCommon):
# and returns the correct data
info = {
'name': 'cora-1',
'user': None,
'brdclass': 'cora-z7s',
'reserved': False,
'attrs': { 'power': True },
@@ -1465,8 +1453,6 @@ class TestBiteLabAPI(TestCommon):
brd = self.brdmgr.boards['cora-1']
async with brd.lock:
await brd.reserve('foo')
obrdreq = await data.BoardStatus.objects.create(
board='cora-1', user='foo')

# that setting the board attributes
res = await self.client.post('/board/cora-1/attrs',
@@ -1483,6 +1469,7 @@ class TestBiteLabAPI(TestCommon):
# and returns the correct data
info = {
'name': 'cora-1',
'user': 'foo',
'brdclass': 'cora-z7s',
'reserved': True,
'attrs': { 'power': False },
@@ -1509,6 +1496,7 @@ class TestBiteLabAPI(TestCommon):
# and returns the correct data
info = {
'name': 'cora-1',
'user': 'foo',
'brdclass': 'cora-z7s',
'reserved': True,
'attrs': { 'power': True },


+ 1
- 9
bitelab/data.py View File

@@ -53,6 +53,7 @@ class BoardClassInfo(BaseModel):

class Board(BaseModel):
name: str
user: Optional[str]
brdclass: str
reserved: bool
attrs: Dict[str, Any] = Field(default_factory=dict)
@@ -76,15 +77,6 @@ class DataWrapper(object):
def make_orm(database):
metadata = sqlalchemy.MetaData()

class BoardStatus(orm.Model):
__tablename__ = 'boardstatus'
__database__ = database
__metadata__ = metadata

board = orm.Text(primary_key=True)
user = orm.Text(index=True)
time_reserved = orm.DateTime(default=lambda: datetime.utcnow())

class APIKey(orm.Model):
__tablename__ = 'apikeys'
__database__ = database


Loading…
Cancel
Save