""" service compares rhel oval with alma ovals and errata ovals results available via API Call """ import copy import logging from logging.handlers import RotatingFileHandler import threading from time import sleep from ipaddress import IPv4Address import json from aiohttp import web from .config import get_config, Config from .comparer import comparer_run # This dict holds all current differences diffs = {} diffs_lock = threading.Lock() async def web_handler(_): """ web_handler returns diffs as JSON file """ data = {} try: diffs_lock.acquire() data = copy.deepcopy(diffs) diffs_lock.release() except Exception as err: # pylint: disable=broad-except logging.critical("Unhandled exeption %s", err, exc_info=True) return web.json_response(data=data) def webserver_run(server_ip: IPv4Address, server_port: str): """ webserver_run starts webserver component """ app = web.Application() app.add_routes([web.get('/', web_handler)]) web.run_app(app=app, host=str(server_ip), port=server_port) def diff_checker(config: Config): """ Runs comparer component in infinite loop """ while True: logging.info("Start comparing") # generating new diff try: result = comparer_run(config) except Exception as err: # pylint: disable=broad-except logging.critical("Unhandled exeption %s", err, exc_info=True) else: logging.info("Finished comparing, updating diff dict") diffs_lock.acquire() global diffs # pylint: disable=invalid-name,global-statement diffs = result diffs_lock.release() # dumping logging.info("Saving results to disk") try: with open(config.diff_file, 'w', encoding='utf-8') as flw: json.dump(result, flw, indent=4) except Exception as err: # pylint: disable=broad-except logging.critical("Unhandled exeption %s", err, exc_info=True) logging.info("Done") logging.info("Finished comparing, go to sleep for %d minutes", config.update_interval_minutes) sleep(config.update_interval_minutes * 60) def start(yaml_path: str): """ start starts comparer and webserver components each component runs in it`s own thread """ config = get_config(yaml_path) # making sure that parent directories exist for path in [config.log_file, config.log_file]: if not path.parent.exists(): path.parent.mkdir() # configuring logging logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(funcName)s %(message)s', handlers=[RotatingFileHandler(config.log_file, maxBytes=10000000, backupCount=3)]) logging.info("Trying to load diff file from disk") try: with open(config.diff_file, 'r', encoding='utf-8') as flr: loaded_data = json.load(flr) diffs_lock.acquire() global diffs # pylint: disable=invalid-name,global-statement diffs = loaded_data diffs_lock.release() except Exception as err: # pylint: disable=broad-except logging.warning('Cant load data from disk %s', err) else: logging.info('Diff file was loaded') logging.info("Starting diff_checker in background") thread = threading.Thread(target=diff_checker, args=(config,)) thread.daemon = True thread.start() logging.info("Starting webserver") webserver_run(config.server_ip, config.server_port)