From 4853bb47f06cc36b783d83f351be2aeca28df687 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Mon, 24 May 2021 20:41:04 +0200 Subject: [PATCH] risotto is now a lib --- src/risotto/config.py | 8 +++---- src/risotto/controller.py | 45 ++++++++++++++++++++------------------- src/risotto/dispatcher.py | 11 ++++++++-- src/risotto/http.py | 6 +++++- src/risotto/image.py | 28 ++++++++++++++++-------- src/risotto/message.py | 12 ++++++----- 6 files changed, 67 insertions(+), 43 deletions(-) diff --git a/src/risotto/config.py b/src/risotto/config.py index bae6488..1b98c2f 100644 --- a/src/risotto/config.py +++ b/src/risotto/config.py @@ -113,12 +113,12 @@ if 'PASSWORD_ADMIN_EMAIL' in environ: PASSWORD_ADMIN_EMAIL = environ['PASSWORD_ADMIN_EMAIL'] else: # this parameter is mandatory - PASSWORD_ADMIN_EMAIL = config['PASSWORD_ADMIN_EMAIL'] + PASSWORD_ADMIN_EMAIL = config.get('PASSWORD_ADMIN_EMAIL', 'XXX') if 'PASSWORD_ADMIN_PASSWORD' in environ: PASSWORD_ADMIN_PASSWORD = environ['PASSWORD_ADMIN_PASSWORD'] else: # this parameter is mandatory - PASSWORD_ADMIN_PASSWORD = config['PASSWORD_ADMIN_PASSWORD'] + PASSWORD_ADMIN_PASSWORD = config.get('PASSWORD_ADMIN_PASSWORD', 'XXX') if 'PASSWORD_DEVICE_IDENTIFIER' in environ: PASSWORD_DEVICE_IDENTIFIER = environ['PASSWORD_DEVICE_IDENTIFIER'] else: @@ -135,11 +135,11 @@ else: if 'PKI_ADMIN_PASSWORD' in environ: PKI_ADMIN_PASSWORD = environ['PKI_ADMIN_PASSWORD'] else: - PKI_ADMIN_PASSWORD = config['PKI_ADMIN_PASSWORD'] + PKI_ADMIN_PASSWORD = config.get('PKI_ADMIN_PASSWORD', 'XXX') if 'PKI_ADMIN_EMAIL' in environ: PKI_ADMIN_EMAIL = environ['PKI_ADMIN_EMAIL'] else: - PKI_ADMIN_EMAIL = config['PKI_ADMIN_EMAIL'] + PKI_ADMIN_EMAIL = config.get('PKI_ADMIN_EMAIL', 'XXX') if 'PKI_URL' in environ: PKI_URL = environ['PKI_URL'] else: diff --git a/src/risotto/controller.py b/src/risotto/controller.py index 50d5ca9..16dfa87 100644 --- a/src/risotto/controller.py +++ b/src/risotto/controller.py @@ -12,7 +12,7 @@ except: from .config import get_config from .utils import _, tiramisu_display_name from .logger import log -from .dispatcher import dispatcher +from .dispatcher import get_dispatcher from .context import Context @@ -25,7 +25,7 @@ class Controller: def __init__(self, test: bool, ) -> None: - pass + self.dispatcher = get_dispatcher() async def call(self, uri: str, @@ -42,11 +42,11 @@ class Controller: module = message.split('.', 1)[0] if current_module != module: raise ValueError(_(f'cannot call to external module ("{module}") to the URI "{uri}" from "{current_module}"')) - return await dispatcher.call(version, - message, - risotto_context, - **kwargs, - ) + return await self.dispatcher.call(version, + message, + risotto_context, + **kwargs, + ) async def publish(self, uri: str, @@ -58,11 +58,11 @@ class Controller: if args: raise ValueError(_(f'the URI "{uri}" can only be published with keyword arguments')) version, message = uri.split('.', 1) - await dispatcher.publish(version, - message, - risotto_context, - **kwargs, - ) + await self.dispatcher.publish(version, + message, + risotto_context, + **kwargs, + ) @staticmethod async def check_role(uri: str, @@ -70,7 +70,7 @@ class Controller: **kwargs: dict, ) -> None: # create a new config - async with await Config(dispatcher.option) as config: + async with await Config(self.dispatcher.option) as config: await config.property.read_write() await config.option('message').value.set(uri) subconfig = config.option(uri) @@ -83,10 +83,10 @@ class Controller: raise ValueError(_(f'unknown parameter in "{uri}": "{key}"')) except ValueOptionError as err: raise ValueError(_(f'invalid parameter in "{uri}": {err}')) - await dispatcher.check_role(subconfig, - username, - uri, - ) + await self.dispatcher.check_role(subconfig, + username, + uri, + ) async def on_join(self, risotto_context, @@ -101,17 +101,18 @@ class TiramisuController(Controller): if not 'dataset_name' in vars(self): raise Exception(f'please specify "dataset_name" to "{self.__class__.__name__}"') self.tiramisu_cache_root_path = join(get_config()['cache']['root_path'], self.dataset_name) + super().__init__(test) if not test: db_conf = get_config()['database']['tiramisu_dsn'] self.save_storage = Storage(engine='postgres') self.save_storage.setting(dsn=db_conf) if self.dataset_name != 'servermodel': self.optiondescription = None - dispatcher.set_function('v1.setting.dataset.updated', - None, - TiramisuController.dataset_updated, - self.__class__.__module__, - ) + self.dispatcher.set_function('v1.setting.dataset.updated', + None, + TiramisuController.dataset_updated, + self.__class__.__module__, + ) async def on_join(self, risotto_context: Context, diff --git a/src/risotto/dispatcher.py b/src/risotto/dispatcher.py index ddda87e..3a4123e 100644 --- a/src/risotto/dispatcher.py +++ b/src/risotto/dispatcher.py @@ -18,6 +18,9 @@ from .context import Context from . import register +DISPATCHER = None + + class CallDispatcher: async def valid_call_returns(self, risotto_context: Context, @@ -492,5 +495,9 @@ class Dispatcher(register.RegisterDispatcher, return returns -dispatcher = Dispatcher() -register.dispatcher = dispatcher +def get_dispatcher(): + global DISPATCHER + if DISPATCHER is None: + DISPATCHER = Dispatcher() + register.dispatcher = DISPATCHER + return DISPATCHER diff --git a/src/risotto/http.py b/src/risotto/http.py index 151f6e5..9250e21 100644 --- a/src/risotto/http.py +++ b/src/risotto/http.py @@ -7,7 +7,7 @@ except: from tiramisu import Config, default_storage -from .dispatcher import dispatcher +from .dispatcher import get_dispatcher from .utils import _ from .context import Context from .error import CallError, NotAllowedError, RegistrationError @@ -70,6 +70,7 @@ class extra_route_handler: if function_name != 'risotto.http': risotto_module_name, submodule_name = function_name.split('.', 2)[:-1] module_name = risotto_module_name.split('_')[-1] + dispatcher = get_dispatcher() kwargs['self'] = dispatcher.injected_self[module_name + '.' + submodule_name] try: returns = await cls.function(**kwargs) @@ -93,6 +94,7 @@ async def handle(request): risotto_context = create_context(request) kwargs = await request.json() try: + dispatcher = get_dispatcher() pattern = dispatcher.messages[version][message]['pattern'] if pattern == 'rpc': method = dispatcher.call @@ -142,6 +144,7 @@ async def api(request, # check all URI that have an associated role # all URI without role is concidered has a private URI uris = [] + dispatcher = get_dispatcher() async with dispatcher.pool.acquire() as connection: async with connection.transaction(): # Check role with ACL @@ -167,6 +170,7 @@ async def get_app(loop): """ build all routes """ global extra_routes, extra_statics + dispatcher = get_dispatcher() services.link_to_dispatcher(dispatcher) app = Application(loop=loop) routes = [] diff --git a/src/risotto/image.py b/src/risotto/image.py index cda153e..52e4c0b 100644 --- a/src/risotto/image.py +++ b/src/risotto/image.py @@ -67,7 +67,16 @@ def zone_information(**kwargs): class Image: - def __init__(self): + def __init__(self, + image_dir: str=None, + tmp_dir: str=None, + ): + if image_dir is None: + image_dir = IMAGES_DIRECTORY + self.image_dir = image_dir + if tmp_dir is None: + tmp_dir = PACKER_TMP_DIRECTORY + self.tmp_dir = tmp_dir self.parse_applications() def parse_applications(self) -> None: @@ -110,6 +119,7 @@ class Image: def list_images(self): + print(self.builds) for build in self.builds: dependencies = [self.applications[build]['path']] self.calc_depends(dependencies, build) @@ -125,8 +135,8 @@ class Image: if not isdir(subdir): makedirs(subdir) for filename in filenames: - path = join(dir_name, filename) - sub_dst_path = join(subdir, filename) + path = join(dir_name, filename) + sub_dst_path = join(subdir, filename) if isfile(sub_dst_path): raise Exception(_(f'Try to copy {sub_dst_path} which is already exists')) copy2(path, sub_dst_path) @@ -197,16 +207,16 @@ class Image: for dir_name, subdir_names, filenames in walk(path): subpath = dir_name[root_len:] for filename in filenames: - with open(join(dir_name, filename), 'rb') as fh: + with open(join(dir_name, filename), 'rb') as fh: ctl_sum = sha512(fh.read()).hexdigest() files.append(f'{subpath}/{filename}/ctl_sum') return sha512('\n'.join(files).encode()).hexdigest() async def build(self) -> None: - if isdir(PACKER_TMP_DIRECTORY): - rmtree(PACKER_TMP_DIRECTORY) + if isdir(self.tmp_dir): + rmtree(self.tmp_dir) for application, dependencies_path in self.list_images(): - packer_tmp_directory = join(PACKER_TMP_DIRECTORY, + packer_tmp_directory = join(self.tmp_dir, application + '_' + str(time()), ) makedirs(packer_tmp_directory) @@ -218,7 +228,7 @@ class Image: self.merge_funcs(config, dependencies_path, packer_tmp_directory) packer_configuration = await self.get_packer_information(config, packer_tmp_directory) # OS image needed ? - packer_dst_os_filename = join(IMAGES_DIRECTORY, + packer_dst_os_filename = join(self.image_dir, 'os', packer_configuration['os_name'] + '_' + packer_configuration['os_version'] + '.img', ) @@ -243,7 +253,7 @@ class Image: packer_configuration, ) recipe_checksum = self.do_recipe_checksum(packer_tmp_img_directory) - packer_dst_filename = join(IMAGES_DIRECTORY, + packer_dst_filename = join(self.image_dir, f'{recipe_checksum}.img', ) self.build_image(packer_dst_filename, diff --git a/src/risotto/message.py b/src/risotto/message.py index ed8dd14..b10960e 100644 --- a/src/risotto/message.py +++ b/src/risotto/message.py @@ -19,8 +19,8 @@ from .utils import _ MESSAGE_ROOT_PATH = get_config()['global']['message_root_path'] groups.addgroup('message') -MESSAGE_TRANSLATION = translation('risotto-message', join(MESSAGE_ROOT_PATH, '..', 'locale')).gettext - +CUSTOMTYPES = None +MESSAGE_TRANSLATION = None class DictOption(Option): @@ -593,6 +593,11 @@ def get_messages(current_module_names, ): """generate description from yml files """ + global MESSAGE_TRANSLATION, CUSTOMTYPES + if MESSAGE_TRANSLATION is None: + MESSAGE_TRANSLATION = translation('risotto-message', join(MESSAGE_ROOT_PATH, '..', 'locale')).gettext + if CUSTOMTYPES is None: + CUSTOMTYPES = load_customtypes() optiondescriptions = {} optiondescriptions_info = {} messages = list(list_messages(uris, @@ -632,6 +637,3 @@ def get_messages(current_module_names, optiondescriptions, ) return optiondescriptions_info, root - - -CUSTOMTYPES = load_customtypes()