From 7cc025bef482552f9cbee78a69147d7340708704 Mon Sep 17 00:00:00 2001 From: Markus Zolliker Date: Tue, 17 Oct 2023 11:01:33 +0200 Subject: [PATCH] [WIP] introduce get_server_state propose_cfgs will be obsolete --- frappyman.py | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 131 insertions(+), 1 deletion(-) diff --git a/frappyman.py b/frappyman.py index c2f5e2f..02a604c 100644 --- a/frappyman.py +++ b/frappyman.py @@ -65,6 +65,7 @@ class Namespace(dict): SEAEXT = {'main': '.config', 'stick': '.stick'} +# TODO: put inline def get_service(key): return key if key in ('main', 'stick') else 'addons' @@ -169,6 +170,112 @@ def make_proposed(givencfgs, ourcfgs, seacfgs, sea_info, strict=False, giventitl return result, [' '.join(v.ljust(w) for w, v in zip(wid, row)) for row in rows] +def summarize_server_state(givencfgs, ourcfgs, seacfgs, sea_info, strict=False): + """get a guess for the configuration from information about running services + + :param givencfgs: dict of given configuration (from nicos cache) + :param outcfgs: dict of running configuration (frappy) + :param seacfgs: dict of running configuration (sea) + :param sea_info: dict of with info about sea configs + :param strict: when True return empty cfg result on error + :return: tuple (, , (, ), (, ) where: + : proposed config not sure + : dict of proposed cfg + : dict of items runnning in frappy servers (addons are separated) + : dict of items running on the sea server + : dict of given items (addons are separated) + : dict of actions / remarks + """ + givencfgs = dict(givencfgs) + addons = givencfgs.pop('addons', '') + for addon in addons.split(','): + addon = addon.strip() + if addon: + givencfgs[addon] = addon + frappycfgs = dict(ourcfgs) + addons = givencfgs.pop('addons', '') + for addon in addons.split(','): + addon = addon.strip() + if addon: + frappycfgs[addon] = addon + + seacfgfiles = [(c or '') + SEAEXT.get(s, '.addon') + for c, s in zip_longest(seacfgs, FrappyManager.services)] + seacfgset = set(seacfgfiles) + inverted_sea_info = {k: [] for k in seacfgfiles} + for cfg, seacfg in sea_info.items(): + if seacfg in seacfgset: + inverted_sea_info[seacfg].append(cfg) + error = False + result = {} + addons = set() + seacfgs = {} + remarks = {} + for seacfg, seacfgfile, key in zip_longest(seacfgs, seacfgfiles, ('main', 'stick')): + if not seacfg: + continue + available = inverted_sea_info[seacfgfile] + if available: + proposed = available[0] if len(available) == 1 else None + if not proposed: + running = None + for item in available: + if item == givencfgs.get(key or item): + proposed = item + if item == frappycfgs.get(key or item): + running = item + if running and not proposed: + proposed = running + if proposed: + pkey = key or proposed + given = givencfgs.get(pkey) + running = frappycfgs.get(pkey) + if running == proposed: + remarks[pkey] = '' if given == running else 'reconnect' + else: + remarks[pkey] = 'restart' + + seacfgs[pkey] = seacfg + if key: + result[key] = proposed + else: + addons.add(proposed) + else: + for item in available: + remarks[item] = 'ambiguous' + seacfgs[item] = seacfg + error = True + else: + pkey = key or seacfg + seacfg[pkey] = seacfg + remarks[pkey] = 'missing frappy config' + error = True + restart = set() + for key, running in frappycfgs.items(): + if running: + service = get_service(key) + if service == 'addons': + addons.add(running) + if not seacfgs.get(key): + if sea_info.get(running): + restart.add(service) + remarks[key] = 'restart to start sea' + elif givencfgs.get(key) != running: + remarks[key] = 'reconnect' + elif remarks.get(key) is None: + remarks[key] = '' + if addons: + result['addons'] = ','.join(addons) + + if not error: + for service, cfg in ourcfgs.items(): + if cfg: + prop = result.get(service, '') + if prop == cfg and service not in restart: + result[service] = True + return error, result, (ourcfgs, seacfgs), (givencfgs, remarks) + + class FrappyManager(ServiceManager): group = 'frappy' services = ('main', 'stick', 'addons') @@ -429,5 +536,28 @@ class FrappyManager(ServiceManager): seacfgs.append('') sea_info = {} self.all_cfg(ins, None, sea_info=sea_info) - return self.make_proposed(givencfgs, ourcfgs, seacfgs, sea_info, strict) + return make_proposed(givencfgs, ourcfgs, seacfgs, sea_info, strict) + + def get_server_state(self, ins, givencfgs): + """get proposed configuration and an overview of the running servers + + :param ins: the instance to be checked for + :param givencfgs: a dict of cfg given by the ECS + + :return: tuple (, , (, ), (, ) where: + : proposed config not sure + : dict of proposed cfg + : dict of items runnning in frappy servers (addons are separated) + : dict of items running on the sea server + : dict of given items (addons are separated) + : dict of actions / remarks + """ + ourcfgs = self.get_cfg(ins, None) + sea = SeaManager() + seacfgs = sea.get_cfg(ins, 'sea').split('/') + if len(seacfgs) < 2: + seacfgs.append('') + sea_info = {} + self.all_cfg(ins, None, sea_info=sea_info) + return summarize_server_state(givencfgs, ourcfgs, seacfgs, sea_info)