risotto is now a lib

This commit is contained in:
Emmanuel Garette 2021-05-24 20:41:04 +02:00
parent 9d4644bedf
commit 4853bb47f0
6 changed files with 67 additions and 43 deletions

View File

@ -113,12 +113,12 @@ if 'PASSWORD_ADMIN_EMAIL' in environ:
PASSWORD_ADMIN_EMAIL = environ['PASSWORD_ADMIN_EMAIL'] PASSWORD_ADMIN_EMAIL = environ['PASSWORD_ADMIN_EMAIL']
else: else:
# this parameter is mandatory # 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: if 'PASSWORD_ADMIN_PASSWORD' in environ:
PASSWORD_ADMIN_PASSWORD = environ['PASSWORD_ADMIN_PASSWORD'] PASSWORD_ADMIN_PASSWORD = environ['PASSWORD_ADMIN_PASSWORD']
else: else:
# this parameter is mandatory # 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: if 'PASSWORD_DEVICE_IDENTIFIER' in environ:
PASSWORD_DEVICE_IDENTIFIER = environ['PASSWORD_DEVICE_IDENTIFIER'] PASSWORD_DEVICE_IDENTIFIER = environ['PASSWORD_DEVICE_IDENTIFIER']
else: else:
@ -135,11 +135,11 @@ else:
if 'PKI_ADMIN_PASSWORD' in environ: if 'PKI_ADMIN_PASSWORD' in environ:
PKI_ADMIN_PASSWORD = environ['PKI_ADMIN_PASSWORD'] PKI_ADMIN_PASSWORD = environ['PKI_ADMIN_PASSWORD']
else: else:
PKI_ADMIN_PASSWORD = config['PKI_ADMIN_PASSWORD'] PKI_ADMIN_PASSWORD = config.get('PKI_ADMIN_PASSWORD', 'XXX')
if 'PKI_ADMIN_EMAIL' in environ: if 'PKI_ADMIN_EMAIL' in environ:
PKI_ADMIN_EMAIL = environ['PKI_ADMIN_EMAIL'] PKI_ADMIN_EMAIL = environ['PKI_ADMIN_EMAIL']
else: else:
PKI_ADMIN_EMAIL = config['PKI_ADMIN_EMAIL'] PKI_ADMIN_EMAIL = config.get('PKI_ADMIN_EMAIL', 'XXX')
if 'PKI_URL' in environ: if 'PKI_URL' in environ:
PKI_URL = environ['PKI_URL'] PKI_URL = environ['PKI_URL']
else: else:

View File

@ -12,7 +12,7 @@ except:
from .config import get_config from .config import get_config
from .utils import _, tiramisu_display_name from .utils import _, tiramisu_display_name
from .logger import log from .logger import log
from .dispatcher import dispatcher from .dispatcher import get_dispatcher
from .context import Context from .context import Context
@ -25,7 +25,7 @@ class Controller:
def __init__(self, def __init__(self,
test: bool, test: bool,
) -> None: ) -> None:
pass self.dispatcher = get_dispatcher()
async def call(self, async def call(self,
uri: str, uri: str,
@ -42,11 +42,11 @@ class Controller:
module = message.split('.', 1)[0] module = message.split('.', 1)[0]
if current_module != module: if current_module != module:
raise ValueError(_(f'cannot call to external module ("{module}") to the URI "{uri}" from "{current_module}"')) raise ValueError(_(f'cannot call to external module ("{module}") to the URI "{uri}" from "{current_module}"'))
return await dispatcher.call(version, return await self.dispatcher.call(version,
message, message,
risotto_context, risotto_context,
**kwargs, **kwargs,
) )
async def publish(self, async def publish(self,
uri: str, uri: str,
@ -58,11 +58,11 @@ class Controller:
if args: if args:
raise ValueError(_(f'the URI "{uri}" can only be published with keyword arguments')) raise ValueError(_(f'the URI "{uri}" can only be published with keyword arguments'))
version, message = uri.split('.', 1) version, message = uri.split('.', 1)
await dispatcher.publish(version, await self.dispatcher.publish(version,
message, message,
risotto_context, risotto_context,
**kwargs, **kwargs,
) )
@staticmethod @staticmethod
async def check_role(uri: str, async def check_role(uri: str,
@ -70,7 +70,7 @@ class Controller:
**kwargs: dict, **kwargs: dict,
) -> None: ) -> None:
# create a new config # 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.property.read_write()
await config.option('message').value.set(uri) await config.option('message').value.set(uri)
subconfig = config.option(uri) subconfig = config.option(uri)
@ -83,10 +83,10 @@ class Controller:
raise ValueError(_(f'unknown parameter in "{uri}": "{key}"')) raise ValueError(_(f'unknown parameter in "{uri}": "{key}"'))
except ValueOptionError as err: except ValueOptionError as err:
raise ValueError(_(f'invalid parameter in "{uri}": {err}')) raise ValueError(_(f'invalid parameter in "{uri}": {err}'))
await dispatcher.check_role(subconfig, await self.dispatcher.check_role(subconfig,
username, username,
uri, uri,
) )
async def on_join(self, async def on_join(self,
risotto_context, risotto_context,
@ -101,17 +101,18 @@ class TiramisuController(Controller):
if not 'dataset_name' in vars(self): if not 'dataset_name' in vars(self):
raise Exception(f'please specify "dataset_name" to "{self.__class__.__name__}"') 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) self.tiramisu_cache_root_path = join(get_config()['cache']['root_path'], self.dataset_name)
super().__init__(test)
if not test: if not test:
db_conf = get_config()['database']['tiramisu_dsn'] db_conf = get_config()['database']['tiramisu_dsn']
self.save_storage = Storage(engine='postgres') self.save_storage = Storage(engine='postgres')
self.save_storage.setting(dsn=db_conf) self.save_storage.setting(dsn=db_conf)
if self.dataset_name != 'servermodel': if self.dataset_name != 'servermodel':
self.optiondescription = None self.optiondescription = None
dispatcher.set_function('v1.setting.dataset.updated', self.dispatcher.set_function('v1.setting.dataset.updated',
None, None,
TiramisuController.dataset_updated, TiramisuController.dataset_updated,
self.__class__.__module__, self.__class__.__module__,
) )
async def on_join(self, async def on_join(self,
risotto_context: Context, risotto_context: Context,

View File

@ -18,6 +18,9 @@ from .context import Context
from . import register from . import register
DISPATCHER = None
class CallDispatcher: class CallDispatcher:
async def valid_call_returns(self, async def valid_call_returns(self,
risotto_context: Context, risotto_context: Context,
@ -492,5 +495,9 @@ class Dispatcher(register.RegisterDispatcher,
return returns return returns
dispatcher = Dispatcher() def get_dispatcher():
register.dispatcher = dispatcher global DISPATCHER
if DISPATCHER is None:
DISPATCHER = Dispatcher()
register.dispatcher = DISPATCHER
return DISPATCHER

View File

@ -7,7 +7,7 @@ except:
from tiramisu import Config, default_storage from tiramisu import Config, default_storage
from .dispatcher import dispatcher from .dispatcher import get_dispatcher
from .utils import _ from .utils import _
from .context import Context from .context import Context
from .error import CallError, NotAllowedError, RegistrationError from .error import CallError, NotAllowedError, RegistrationError
@ -70,6 +70,7 @@ class extra_route_handler:
if function_name != 'risotto.http': if function_name != 'risotto.http':
risotto_module_name, submodule_name = function_name.split('.', 2)[:-1] risotto_module_name, submodule_name = function_name.split('.', 2)[:-1]
module_name = risotto_module_name.split('_')[-1] module_name = risotto_module_name.split('_')[-1]
dispatcher = get_dispatcher()
kwargs['self'] = dispatcher.injected_self[module_name + '.' + submodule_name] kwargs['self'] = dispatcher.injected_self[module_name + '.' + submodule_name]
try: try:
returns = await cls.function(**kwargs) returns = await cls.function(**kwargs)
@ -93,6 +94,7 @@ async def handle(request):
risotto_context = create_context(request) risotto_context = create_context(request)
kwargs = await request.json() kwargs = await request.json()
try: try:
dispatcher = get_dispatcher()
pattern = dispatcher.messages[version][message]['pattern'] pattern = dispatcher.messages[version][message]['pattern']
if pattern == 'rpc': if pattern == 'rpc':
method = dispatcher.call method = dispatcher.call
@ -142,6 +144,7 @@ async def api(request,
# check all URI that have an associated role # check all URI that have an associated role
# all URI without role is concidered has a private URI # all URI without role is concidered has a private URI
uris = [] uris = []
dispatcher = get_dispatcher()
async with dispatcher.pool.acquire() as connection: async with dispatcher.pool.acquire() as connection:
async with connection.transaction(): async with connection.transaction():
# Check role with ACL # Check role with ACL
@ -167,6 +170,7 @@ async def get_app(loop):
""" build all routes """ build all routes
""" """
global extra_routes, extra_statics global extra_routes, extra_statics
dispatcher = get_dispatcher()
services.link_to_dispatcher(dispatcher) services.link_to_dispatcher(dispatcher)
app = Application(loop=loop) app = Application(loop=loop)
routes = [] routes = []

View File

@ -67,7 +67,16 @@ def zone_information(**kwargs):
class Image: 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() self.parse_applications()
def parse_applications(self) -> None: def parse_applications(self) -> None:
@ -110,6 +119,7 @@ class Image:
def list_images(self): def list_images(self):
print(self.builds)
for build in self.builds: for build in self.builds:
dependencies = [self.applications[build]['path']] dependencies = [self.applications[build]['path']]
self.calc_depends(dependencies, build) self.calc_depends(dependencies, build)
@ -125,8 +135,8 @@ class Image:
if not isdir(subdir): if not isdir(subdir):
makedirs(subdir) makedirs(subdir)
for filename in filenames: for filename in filenames:
path = join(dir_name, filename) path = join(dir_name, filename)
sub_dst_path = join(subdir, filename) sub_dst_path = join(subdir, filename)
if isfile(sub_dst_path): if isfile(sub_dst_path):
raise Exception(_(f'Try to copy {sub_dst_path} which is already exists')) raise Exception(_(f'Try to copy {sub_dst_path} which is already exists'))
copy2(path, sub_dst_path) copy2(path, sub_dst_path)
@ -197,16 +207,16 @@ class Image:
for dir_name, subdir_names, filenames in walk(path): for dir_name, subdir_names, filenames in walk(path):
subpath = dir_name[root_len:] subpath = dir_name[root_len:]
for filename in filenames: 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() ctl_sum = sha512(fh.read()).hexdigest()
files.append(f'{subpath}/{filename}/ctl_sum') files.append(f'{subpath}/{filename}/ctl_sum')
return sha512('\n'.join(files).encode()).hexdigest() return sha512('\n'.join(files).encode()).hexdigest()
async def build(self) -> None: async def build(self) -> None:
if isdir(PACKER_TMP_DIRECTORY): if isdir(self.tmp_dir):
rmtree(PACKER_TMP_DIRECTORY) rmtree(self.tmp_dir)
for application, dependencies_path in self.list_images(): 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()), application + '_' + str(time()),
) )
makedirs(packer_tmp_directory) makedirs(packer_tmp_directory)
@ -218,7 +228,7 @@ class Image:
self.merge_funcs(config, dependencies_path, packer_tmp_directory) self.merge_funcs(config, dependencies_path, packer_tmp_directory)
packer_configuration = await self.get_packer_information(config, packer_tmp_directory) packer_configuration = await self.get_packer_information(config, packer_tmp_directory)
# OS image needed ? # OS image needed ?
packer_dst_os_filename = join(IMAGES_DIRECTORY, packer_dst_os_filename = join(self.image_dir,
'os', 'os',
packer_configuration['os_name'] + '_' + packer_configuration['os_version'] + '.img', packer_configuration['os_name'] + '_' + packer_configuration['os_version'] + '.img',
) )
@ -243,7 +253,7 @@ class Image:
packer_configuration, packer_configuration,
) )
recipe_checksum = self.do_recipe_checksum(packer_tmp_img_directory) 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', f'{recipe_checksum}.img',
) )
self.build_image(packer_dst_filename, self.build_image(packer_dst_filename,

View File

@ -19,8 +19,8 @@ from .utils import _
MESSAGE_ROOT_PATH = get_config()['global']['message_root_path'] MESSAGE_ROOT_PATH = get_config()['global']['message_root_path']
groups.addgroup('message') groups.addgroup('message')
MESSAGE_TRANSLATION = translation('risotto-message', join(MESSAGE_ROOT_PATH, '..', 'locale')).gettext CUSTOMTYPES = None
MESSAGE_TRANSLATION = None
class DictOption(Option): class DictOption(Option):
@ -593,6 +593,11 @@ def get_messages(current_module_names,
): ):
"""generate description from yml files """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 = {}
optiondescriptions_info = {} optiondescriptions_info = {}
messages = list(list_messages(uris, messages = list(list_messages(uris,
@ -632,6 +637,3 @@ def get_messages(current_module_names,
optiondescriptions, optiondescriptions,
) )
return optiondescriptions_info, root return optiondescriptions_info, root
CUSTOMTYPES = load_customtypes()