[WIP] overview in table form, test
This commit is contained in:
parent
fc364f0fc6
commit
92d44f5c94
133
frappyman.py
133
frappyman.py
@ -32,6 +32,10 @@ from .base import ServiceManager, ServiceDown, UsageError
|
|||||||
from .seaman import SeaManager
|
from .seaman import SeaManager
|
||||||
|
|
||||||
|
|
||||||
|
MAIN = 1
|
||||||
|
STICK = 2
|
||||||
|
|
||||||
|
|
||||||
class Namespace(dict):
|
class Namespace(dict):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self['Node'] = self.node
|
self['Node'] = self.node
|
||||||
@ -58,6 +62,83 @@ class Namespace(dict):
|
|||||||
__builtins__ = builtins
|
__builtins__ = builtins
|
||||||
|
|
||||||
|
|
||||||
|
def make_proposed(givencfgs, ourcfgs, seacfgs, sea_info, strict=False):
|
||||||
|
overview = {}
|
||||||
|
for service in 'main', 'stick':
|
||||||
|
given = givencfgs.get(service)
|
||||||
|
if given:
|
||||||
|
overview.setdefault(service, {})['given'] = given
|
||||||
|
frappy = ourcfgs.get(service)
|
||||||
|
if frappy:
|
||||||
|
overview.setdefault(service, {})['frappy'] = frappy
|
||||||
|
for addon in givencfgs.get('addons', '').split(','):
|
||||||
|
addon = addon.strip()
|
||||||
|
if addon:
|
||||||
|
overview.setdefault(addon, {})['given'] = addon
|
||||||
|
for addon in ourcfgs.get('addons', '').split(','):
|
||||||
|
addon = addon.strip()
|
||||||
|
if addon:
|
||||||
|
overview.setdefault(addon, {})['frappy'] = addon
|
||||||
|
|
||||||
|
error = False
|
||||||
|
result = {}
|
||||||
|
addons = set()
|
||||||
|
for i, seacfg in enumerate(seacfgs):
|
||||||
|
if i == 0:
|
||||||
|
key, ext = 'main', '.config'
|
||||||
|
elif i == 1:
|
||||||
|
key, ext = 'stick', '.stick'
|
||||||
|
else:
|
||||||
|
key, ext = None, '.addon'
|
||||||
|
available = sea_info.get(seacfg + ext, ())
|
||||||
|
if available:
|
||||||
|
proposed = list(available)[0] if len(available) == 1 else None
|
||||||
|
if not proposed:
|
||||||
|
for item in available:
|
||||||
|
if item == overview.get(key or item, {}).get('given'):
|
||||||
|
proposed = item
|
||||||
|
if item == overview.get(key or item, {}).get('frappy'):
|
||||||
|
frappy = item
|
||||||
|
if frappy and not proposed:
|
||||||
|
proposed = frappy
|
||||||
|
if proposed:
|
||||||
|
itemdict = overview.setdefault(key or proposed, {})
|
||||||
|
given = itemdict.get('given')
|
||||||
|
itemdict.update(name=(key or 'addon'), sea=seacfg,
|
||||||
|
remark='ok' if given == proposed else f'change to {proposed}')
|
||||||
|
if key:
|
||||||
|
result[key] = given
|
||||||
|
else:
|
||||||
|
addons.add(given)
|
||||||
|
else:
|
||||||
|
for item in available:
|
||||||
|
overview.setdefault(item, {}).update(name=item, remark='ambiguous', sea=seacfg)
|
||||||
|
error = True
|
||||||
|
else:
|
||||||
|
overview.setdefault(key or seacfg, {}).update(name=key or '', sea=seacfg, remark='missing frappy config')
|
||||||
|
error = True
|
||||||
|
|
||||||
|
if addons:
|
||||||
|
result['addons'] = ','.join(addons)
|
||||||
|
|
||||||
|
if error and strict:
|
||||||
|
result = {}
|
||||||
|
else:
|
||||||
|
for service, cfg in ourcfgs.items():
|
||||||
|
key = cfg if service is 'addons' else service
|
||||||
|
if cfg:
|
||||||
|
prop = result.get(service, '')
|
||||||
|
if prop == cfg:
|
||||||
|
result[service] = True
|
||||||
|
|
||||||
|
columns = ['name', 'given', 'frappy', 'sea', 'remark']
|
||||||
|
rows = [columns[:-1] + [' ']] + [[d.get(c) or '' for c in columns] for d in overview.values()]
|
||||||
|
wid = [max(len(v) for v in column) for column in zip(*rows)]
|
||||||
|
# insert title lines
|
||||||
|
rows.insert(1, ['-' * w for w in wid])
|
||||||
|
return result, [' '.join(v.ljust(w) for w, v in zip(wid, row)) for row in rows]
|
||||||
|
|
||||||
|
|
||||||
class FrappyManager(ServiceManager):
|
class FrappyManager(ServiceManager):
|
||||||
group = 'frappy'
|
group = 'frappy'
|
||||||
services = ('main', 'stick', 'addons')
|
services = ('main', 'stick', 'addons')
|
||||||
@ -290,40 +371,30 @@ class FrappyManager(ServiceManager):
|
|||||||
except Exception:
|
except Exception:
|
||||||
return cfg + '?'
|
return cfg + '?'
|
||||||
|
|
||||||
def guess_cfgs(self, ins, cfgs):
|
def propose_cfgs(self, ins, givencfgs, strict=False):
|
||||||
|
"""get proposed configuration and an overview of the running servers
|
||||||
|
|
||||||
|
:param ins: the instance to be checked for
|
||||||
|
:param givencfgs: a dict <service> of cfg given by the ECS
|
||||||
|
:param strict: in case of errors (ambiguities or missing frappy config files)
|
||||||
|
proposed will be return as None
|
||||||
|
|
||||||
|
:return: a tuple (<overview>, <proposed>)
|
||||||
|
where <overview> is information from running servers:
|
||||||
|
a dict <item> of dict with optional items 'given', 'frappy', 'sea', 'proposed', 'error'
|
||||||
|
|
||||||
|
given: the values for the cfgs argument
|
||||||
|
frappy: the cfg from running frappy servers
|
||||||
|
sea: the sea config file running
|
||||||
|
proposed: proposed configuration for the ECS
|
||||||
|
error: information about missing or ambiguous cfg files
|
||||||
|
"""
|
||||||
|
ourcfgs = self.get_cfg(ins, None)
|
||||||
sea = SeaManager()
|
sea = SeaManager()
|
||||||
seacfgs = sea.get_cfg(ins, 'sea').split('/')
|
seacfgs = sea.get_cfg(ins, 'sea').split('/')
|
||||||
sea_info = {}
|
|
||||||
if len(seacfgs) < 2:
|
if len(seacfgs) < 2:
|
||||||
seacfgs.append('')
|
seacfgs.append('')
|
||||||
|
sea_info = {}
|
||||||
self.all_cfg(ins, None, sea_info=sea_info)
|
self.all_cfg(ins, None, sea_info=sea_info)
|
||||||
|
return self.make_proposed(givencfgs, ourcfgs, seacfgs, sea_info, strict)
|
||||||
|
|
||||||
guess = defaultdict(lambda: defaultdict(list))
|
|
||||||
|
|
||||||
def check_cfg(service, ext, frappyset, seacfgs):
|
|
||||||
for seacfg in seacfgs:
|
|
||||||
available = sea_info.get(seacfg + ext, ())
|
|
||||||
if available:
|
|
||||||
for a in available:
|
|
||||||
if a in frappyset:
|
|
||||||
guess[service]['ok'].append(a)
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
if len(available) == 1:
|
|
||||||
available = next(iter(available))
|
|
||||||
# available is either a string or a set of strings
|
|
||||||
guess[service]['proposed'].append(available)
|
|
||||||
else:
|
|
||||||
guess[service]['missing'].append(seacfg)
|
|
||||||
|
|
||||||
main = cfgs.get('main')
|
|
||||||
check_cfg('main', '.config', set() if main is None else {main}, {seacfgs[0]})
|
|
||||||
|
|
||||||
if len(seacfgs) > 1:
|
|
||||||
stick = cfgs.get('stick')
|
|
||||||
check_cfg('stick', '.stick', set() if stick is None else {stick}, {seacfgs[1]})
|
|
||||||
|
|
||||||
if len(seacfgs) > 2:
|
|
||||||
addons = set(cfgs.get('addons').split(','))
|
|
||||||
check_cfg('addons', '.addons', set(addons), set(seacfgs[2:]))
|
|
||||||
return guess
|
|
||||||
|
24
test_proposed.py
Normal file
24
test_proposed.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import pytest
|
||||||
|
from servicemanager.frappyman import make_proposed
|
||||||
|
|
||||||
|
sea_info = {
|
||||||
|
'ma10.config': {'ma10'},
|
||||||
|
'ma10.stick': {'ma10stick', 'ma10'},
|
||||||
|
'rt.addon': {'rt', 'roomt'},
|
||||||
|
'befilter.addon': {'befilter'},
|
||||||
|
}
|
||||||
|
|
||||||
|
given = dict(main='ma10', stick='ma10stick')
|
||||||
|
cfgs = dict(given)
|
||||||
|
seacfg = ['ma10', 'ma10']
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('given, current, seacfg, output, proposed, proposedstrict', [
|
||||||
|
|
||||||
|
])
|
||||||
|
def test_proposed(given, current, seacfg, output, proposed, proposedstrict):
|
||||||
|
prop, overview = make_proposed(given, current, seacfg, sea_info)
|
||||||
|
assert overview == output
|
||||||
|
assert prop == proposed
|
||||||
|
props, overview = make_proposed(given, current, seacfg, sea_info, True)
|
||||||
|
assert overview == output
|
||||||
|
assert props == proposedstrict
|
Loading…
x
Reference in New Issue
Block a user