tiramisu is now async
This commit is contained in:
parent
41af2512b5
commit
1d25d3a582
@ -24,10 +24,10 @@ class CallDispatcher:
|
|||||||
log.error_msg(risotto_context, kwargs, msg)
|
log.error_msg(risotto_context, kwargs, msg)
|
||||||
raise NotAllowedError(msg)
|
raise NotAllowedError(msg)
|
||||||
|
|
||||||
def valid_call_returns(self,
|
async def valid_call_returns(self,
|
||||||
risotto_context: Context,
|
risotto_context: Context,
|
||||||
returns: Dict,
|
returns: Dict,
|
||||||
kwargs: Dict):
|
kwargs: Dict):
|
||||||
response = self.messages[risotto_context.version][risotto_context.message]['response']
|
response = self.messages[risotto_context.version][risotto_context.message]['response']
|
||||||
module_name = risotto_context.function.__module__.split('.')[-2]
|
module_name = risotto_context.function.__module__.split('.')[-2]
|
||||||
function_name = risotto_context.function.__name__
|
function_name = risotto_context.function.__name__
|
||||||
@ -47,11 +47,12 @@ class CallDispatcher:
|
|||||||
raise Exception('hu?')
|
raise Exception('hu?')
|
||||||
else:
|
else:
|
||||||
for ret in returns:
|
for ret in returns:
|
||||||
config = Config(response, display_name=lambda self, dyn_name: self.impl_getname())
|
config = await Config(response,
|
||||||
config.property.read_write()
|
display_name=lambda self, dyn_name: self.impl_getname())
|
||||||
|
await config.property.read_write()
|
||||||
try:
|
try:
|
||||||
for key, value in ret.items():
|
for key, value in ret.items():
|
||||||
config.option(key).value.set(value)
|
await config.option(key).value.set(value)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
err = _(f'function {module_name}.{function_name} return the unknown parameter "{key}"')
|
err = _(f'function {module_name}.{function_name} return the unknown parameter "{key}"')
|
||||||
log.error_msg(risotto_context, kwargs, err)
|
log.error_msg(risotto_context, kwargs, err)
|
||||||
@ -60,13 +61,13 @@ class CallDispatcher:
|
|||||||
err = _(f'function {module_name}.{function_name} return the parameter "{key}" with an unvalid value "{value}"')
|
err = _(f'function {module_name}.{function_name} return the parameter "{key}" with an unvalid value "{value}"')
|
||||||
log.error_msg(risotto_context, kwargs, err)
|
log.error_msg(risotto_context, kwargs, err)
|
||||||
raise CallError(str(err))
|
raise CallError(str(err))
|
||||||
config.property.read_only()
|
await config.property.read_only()
|
||||||
mandatories = list(config.value.mandatory())
|
mandatories = await config.value.mandatory()
|
||||||
if mandatories:
|
if mandatories:
|
||||||
mand = [mand.split('.')[-1] for mand in mandatories]
|
mand = [mand.split('.')[-1] for mand in mandatories]
|
||||||
raise ValueError(_(f'missing parameters in response: {mand} in message "{risotto_context.message}"'))
|
raise ValueError(_(f'missing parameters in response: {mand} in message "{risotto_context.message}"'))
|
||||||
try:
|
try:
|
||||||
config.value.dict()
|
await config.value.dict()
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
err = _(f'function {module_name}.{function_name} return an invalid response {err}')
|
err = _(f'function {module_name}.{function_name} return an invalid response {err}')
|
||||||
log.error_msg(risotto_context, kwargs, err)
|
log.error_msg(risotto_context, kwargs, err)
|
||||||
@ -91,10 +92,10 @@ class CallDispatcher:
|
|||||||
self.check_message_type(risotto_context,
|
self.check_message_type(risotto_context,
|
||||||
kwargs)
|
kwargs)
|
||||||
try:
|
try:
|
||||||
tiramisu_config = self.load_kwargs_to_config(risotto_context,
|
tiramisu_config = await self.load_kwargs_to_config(risotto_context,
|
||||||
kwargs)
|
kwargs)
|
||||||
function_obj = self.messages[version][message]
|
function_obj = self.messages[version][message]
|
||||||
kw = tiramisu_config.option(message).value.dict()
|
kw = await tiramisu_config.option(message).value.dict()
|
||||||
risotto_context.function = function_obj['function']
|
risotto_context.function = function_obj['function']
|
||||||
if function_obj['risotto_context']:
|
if function_obj['risotto_context']:
|
||||||
kw['risotto_context'] = risotto_context
|
kw['risotto_context'] = risotto_context
|
||||||
@ -126,9 +127,9 @@ class CallDispatcher:
|
|||||||
err)
|
err)
|
||||||
raise CallError(str(err))
|
raise CallError(str(err))
|
||||||
# valid returns
|
# valid returns
|
||||||
self.valid_call_returns(risotto_context,
|
await self.valid_call_returns(risotto_context,
|
||||||
returns,
|
returns,
|
||||||
kwargs)
|
kwargs)
|
||||||
# log the success
|
# log the success
|
||||||
log.info_msg(risotto_context,
|
log.info_msg(risotto_context,
|
||||||
kwargs,
|
kwargs,
|
||||||
@ -157,9 +158,9 @@ class PublishDispatcher:
|
|||||||
self.check_message_type(risotto_context,
|
self.check_message_type(risotto_context,
|
||||||
kwargs)
|
kwargs)
|
||||||
try:
|
try:
|
||||||
config = self.load_kwargs_to_config(risotto_context,
|
config = await self.load_kwargs_to_config(risotto_context,
|
||||||
kwargs)
|
kwargs)
|
||||||
config_arguments = config.option(message).value.dict()
|
config_arguments = await config.option(message).value.dict()
|
||||||
except CallError as err:
|
except CallError as err:
|
||||||
return
|
return
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
@ -247,28 +248,28 @@ class Dispatcher(register.RegisterDispatcher, CallDispatcher, PublishDispatcher)
|
|||||||
log.error_msg(risotto_context, kwargs, msg)
|
log.error_msg(risotto_context, kwargs, msg)
|
||||||
raise CallError(msg)
|
raise CallError(msg)
|
||||||
|
|
||||||
def load_kwargs_to_config(self,
|
async def load_kwargs_to_config(self,
|
||||||
risotto_context: Context,
|
risotto_context: Context,
|
||||||
kwargs: Dict):
|
kwargs: Dict):
|
||||||
""" create a new Config et set values to it
|
""" create a new Config et set values to it
|
||||||
"""
|
"""
|
||||||
# create a new config
|
# create a new config
|
||||||
config = Config(self.option)
|
config = await Config(self.option)
|
||||||
config.property.read_write()
|
await config.property.read_write()
|
||||||
# set message's option
|
# set message's option
|
||||||
config.option('message').value.set(risotto_context.message)
|
await config.option('message').value.set(risotto_context.message)
|
||||||
# store values
|
# store values
|
||||||
subconfig = config.option(risotto_context.message)
|
subconfig = config.option(risotto_context.message)
|
||||||
for key, value in kwargs.items():
|
for key, value in kwargs.items():
|
||||||
try:
|
try:
|
||||||
subconfig.option(key).value.set(value)
|
await subconfig.option(key).value.set(value)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
print_exc()
|
print_exc()
|
||||||
raise ValueError(_(f'unknown parameter "{key}"'))
|
raise ValueError(_(f'unknown parameter "{key}"'))
|
||||||
# check mandatories options
|
# check mandatories options
|
||||||
config.property.read_only()
|
await config.property.read_only()
|
||||||
mandatories = list(config.value.mandatory())
|
mandatories = await config.value.mandatory()
|
||||||
if mandatories:
|
if mandatories:
|
||||||
mand = [mand.split('.')[-1] for mand in mandatories]
|
mand = [mand.split('.')[-1] for mand in mandatories]
|
||||||
raise ValueError(_(f'missing parameters: {mand}'))
|
raise ValueError(_(f'missing parameters: {mand}'))
|
||||||
|
@ -89,10 +89,10 @@ async def handle(request):
|
|||||||
async def api(request, risotto_context):
|
async def api(request, risotto_context):
|
||||||
global tiramisu
|
global tiramisu
|
||||||
if not tiramisu:
|
if not tiramisu:
|
||||||
config = Config(get_messages(load_shortarg=True,
|
config = await Config(get_messages(load_shortarg=True,
|
||||||
only_public=True)[1])
|
only_public=True)[1])
|
||||||
config.property.read_write()
|
await config.property.read_write()
|
||||||
tiramisu = config.option.dict(remotable='none')
|
tiramisu = await config.option.dict(remotable='none')
|
||||||
return tiramisu
|
return tiramisu
|
||||||
|
|
||||||
|
|
||||||
@ -107,6 +107,7 @@ async def get_app(loop):
|
|||||||
load_services()
|
load_services()
|
||||||
app = Application(loop=loop)
|
app = Application(loop=loop)
|
||||||
routes = []
|
routes = []
|
||||||
|
await dispatcher.load()
|
||||||
for version, messages in dispatcher.messages.items():
|
for version, messages in dispatcher.messages.items():
|
||||||
print()
|
print()
|
||||||
print(_('======== Registered messages ========'))
|
print(_('======== Registered messages ========'))
|
||||||
|
@ -3,7 +3,7 @@ from os.path import join, basename, dirname
|
|||||||
from glob import glob
|
from glob import glob
|
||||||
|
|
||||||
from tiramisu import StrOption, IntOption, BoolOption, ChoiceOption, OptionDescription, SymLinkOption, \
|
from tiramisu import StrOption, IntOption, BoolOption, ChoiceOption, OptionDescription, SymLinkOption, \
|
||||||
Config, Calculation, Params, ParamOption, ParamValue, calc_value, calc_value_property_help, \
|
Calculation, Params, ParamOption, ParamValue, calc_value, calc_value_property_help, \
|
||||||
groups, Option
|
groups, Option
|
||||||
|
|
||||||
from yaml import load, SafeLoader
|
from yaml import load, SafeLoader
|
||||||
@ -616,12 +616,4 @@ def get_messages(load_shortarg=False, only_public=False):
|
|||||||
load_shortarg)
|
load_shortarg)
|
||||||
|
|
||||||
root = _get_root_option(select_option, optiondescriptions)
|
root = _get_root_option(select_option, optiondescriptions)
|
||||||
try:
|
|
||||||
config = Config(root)
|
|
||||||
except Exception as err:
|
|
||||||
raise Exception('error when generating root optiondescription: {}'.format(err))
|
|
||||||
|
|
||||||
config.property.read_write()
|
|
||||||
# config.property.add('demoting_error_warning')
|
|
||||||
# return needs, responses, config
|
|
||||||
return optiondescriptions_info, root
|
return optiondescriptions_info, root
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from tiramisu import Config
|
from tiramisu import Config
|
||||||
from inspect import signature
|
from inspect import signature
|
||||||
from typing import Callable, Optional
|
from typing import Callable, Optional
|
||||||
|
|
||||||
from .utils import undefined, _
|
from .utils import undefined, _
|
||||||
from .error import RegistrationError
|
from .error import RegistrationError
|
||||||
from .message import get_messages
|
from .message import get_messages
|
||||||
@ -47,22 +48,22 @@ class RegisterDispatcher:
|
|||||||
first_argument_index = 1
|
first_argument_index = 1
|
||||||
return [param.name for param in list(signature(function).parameters.values())[first_argument_index:]]
|
return [param.name for param in list(signature(function).parameters.values())[first_argument_index:]]
|
||||||
|
|
||||||
def valid_rpc_params(self,
|
async def valid_rpc_params(self,
|
||||||
version: str,
|
version: str,
|
||||||
message: str,
|
message: str,
|
||||||
function: Callable,
|
function: Callable,
|
||||||
module_name: str):
|
module_name: str):
|
||||||
""" parameters function must have strictly all arguments with the correct name
|
""" parameters function must have strictly all arguments with the correct name
|
||||||
"""
|
"""
|
||||||
def get_message_args():
|
async def get_message_args():
|
||||||
# load config
|
# load config
|
||||||
config = Config(self.option)
|
config = await Config(self.option)
|
||||||
config.property.read_write()
|
await config.property.read_write()
|
||||||
# set message to the uri name
|
# set message to the uri name
|
||||||
config.option('message').value.set(message)
|
await config.option('message').value.set(message)
|
||||||
# get message argument
|
# get message argument
|
||||||
subconfig = config.option(message)
|
dico = await config.option(message).value.dict()
|
||||||
return set(config.option(message).value.dict().keys())
|
return set(dico.keys())
|
||||||
|
|
||||||
def get_function_args():
|
def get_function_args():
|
||||||
function_args = self.get_function_args(function)
|
function_args = self.get_function_args(function)
|
||||||
@ -72,7 +73,7 @@ class RegisterDispatcher:
|
|||||||
return set(function_args)
|
return set(function_args)
|
||||||
|
|
||||||
# get message arguments
|
# get message arguments
|
||||||
message_args = get_message_args()
|
message_args = await get_message_args()
|
||||||
# get function arguments
|
# get function arguments
|
||||||
function_args = get_function_args()
|
function_args = get_function_args()
|
||||||
# compare message arguments with function parameter
|
# compare message arguments with function parameter
|
||||||
@ -90,22 +91,22 @@ class RegisterDispatcher:
|
|||||||
msg = _(' and ').join(msg)
|
msg = _(' and ').join(msg)
|
||||||
raise RegistrationError(_(f'error with {module_name}.{function_name} arguments: {msg}'))
|
raise RegistrationError(_(f'error with {module_name}.{function_name} arguments: {msg}'))
|
||||||
|
|
||||||
def valid_event_params(self,
|
async def valid_event_params(self,
|
||||||
version: str,
|
version: str,
|
||||||
message: str,
|
message: str,
|
||||||
function: Callable,
|
function: Callable,
|
||||||
module_name: str):
|
module_name: str):
|
||||||
""" parameters function validation for event messages
|
""" parameters function validation for event messages
|
||||||
"""
|
"""
|
||||||
def get_message_args():
|
async def get_message_args():
|
||||||
# load config
|
# load config
|
||||||
config = Config(self.option)
|
config = await Config(self.option)
|
||||||
config.property.read_write()
|
await config.property.read_write()
|
||||||
# set message to the message name
|
# set message to the message name
|
||||||
config.option('message').value.set(message)
|
await config.option('message').value.set(message)
|
||||||
# get message argument
|
# get message argument
|
||||||
subconfig = config.option(message)
|
dico = await config.option(message).value.dict()
|
||||||
return set(config.option(message).value.dict().keys())
|
return set(dico.keys())
|
||||||
|
|
||||||
def get_function_args():
|
def get_function_args():
|
||||||
function_args = self.get_function_args(function)
|
function_args = self.get_function_args(function)
|
||||||
@ -115,7 +116,7 @@ class RegisterDispatcher:
|
|||||||
return set(function_args)
|
return set(function_args)
|
||||||
|
|
||||||
# get message arguments
|
# get message arguments
|
||||||
message_args = get_message_args()
|
message_args = await get_message_args()
|
||||||
# get function arguments
|
# get function arguments
|
||||||
function_args = get_function_args()
|
function_args = get_function_args()
|
||||||
# compare message arguments with function parameter
|
# compare message arguments with function parameter
|
||||||
@ -159,18 +160,11 @@ class RegisterDispatcher:
|
|||||||
if 'function' in self.messages[version][message]:
|
if 'function' in self.messages[version][message]:
|
||||||
raise RegistrationError(_(f'uri {version}.{message} already registered'))
|
raise RegistrationError(_(f'uri {version}.{message} already registered'))
|
||||||
|
|
||||||
# valid function's arguments
|
# check notification
|
||||||
if self.messages[version][message]['pattern'] == 'rpc':
|
if self.messages[version][message]['pattern'] == 'rpc':
|
||||||
if notification is undefined:
|
if notification is undefined:
|
||||||
function_name = function.__name__
|
function_name = function.__name__
|
||||||
raise RegistrationError(_(f'notification is mandatory when registered "{message}" with "{module_name}.{function_name}" even if you set None'))
|
raise RegistrationError(_(f'notification is mandatory when registered "{message}" with "{module_name}.{function_name}" even if you set None'))
|
||||||
valid_params = self.valid_rpc_params
|
|
||||||
else:
|
|
||||||
valid_params = self.valid_event_params
|
|
||||||
valid_params(version,
|
|
||||||
message,
|
|
||||||
function,
|
|
||||||
module_name)
|
|
||||||
|
|
||||||
# register
|
# register
|
||||||
if self.messages[version][message]['pattern'] == 'rpc':
|
if self.messages[version][message]['pattern'] == 'rpc':
|
||||||
@ -253,3 +247,24 @@ class RegisterDispatcher:
|
|||||||
risotto_context.paths.append(f'{module_name}.on_join')
|
risotto_context.paths.append(f'{module_name}.on_join')
|
||||||
risotto_context.type = None
|
risotto_context.type = None
|
||||||
await module.on_join(risotto_context)
|
await module.on_join(risotto_context)
|
||||||
|
|
||||||
|
async def load(self):
|
||||||
|
# valid function's arguments
|
||||||
|
for version, messages in self.messages.items():
|
||||||
|
for message, message_infos in messages.items():
|
||||||
|
if message_infos['pattern'] == 'rpc':
|
||||||
|
module_name = message_infos['module']
|
||||||
|
function = message_infos['function']
|
||||||
|
await self.valid_rpc_params(version,
|
||||||
|
message,
|
||||||
|
function,
|
||||||
|
module_name)
|
||||||
|
else:
|
||||||
|
if 'functions' in message_infos:
|
||||||
|
for function_infos in message_infos['functions']:
|
||||||
|
module_name = function_infos['module']
|
||||||
|
function = function_infos['function']
|
||||||
|
await self.valid_event_params(version,
|
||||||
|
message,
|
||||||
|
function,
|
||||||
|
module_name)
|
||||||
|
@ -59,10 +59,10 @@ class Risotto(Controller):
|
|||||||
for servermodel in servermodels:
|
for servermodel in servermodels:
|
||||||
if 'servermodel_parents_id' in servermodel:
|
if 'servermodel_parents_id' in servermodel:
|
||||||
for servermodelparentid in servermodel['servermodel_parents_id']:
|
for servermodelparentid in servermodel['servermodel_parents_id']:
|
||||||
self.servermodel_legacy(risotto_context,
|
await self.servermodel_legacy(risotto_context,
|
||||||
servermodel['servermodel_name'],
|
servermodel['servermodel_name'],
|
||||||
servermodel['servermodel_id'],
|
servermodel['servermodel_id'],
|
||||||
servermodelparentid)
|
servermodelparentid)
|
||||||
|
|
||||||
def get_funcs_filename(self,
|
def get_funcs_filename(self,
|
||||||
servermodel_id: int):
|
servermodel_id: int):
|
||||||
@ -104,16 +104,16 @@ class Risotto(Controller):
|
|||||||
# # loads tiramisu config and store it
|
# # loads tiramisu config and store it
|
||||||
with open(cache_file) as fileio:
|
with open(cache_file) as fileio:
|
||||||
xmlroot = parse(fileio).getroot()
|
xmlroot = parse(fileio).getroot()
|
||||||
self.servermodel[servermodel_id] = self.build_metaconfig(servermodel_id,
|
self.servermodel[servermodel_id] = await self.build_metaconfig(servermodel_id,
|
||||||
servermodel_name,
|
servermodel_name,
|
||||||
xmlroot,
|
xmlroot,
|
||||||
funcs_file)
|
funcs_file)
|
||||||
|
|
||||||
def build_metaconfig(self,
|
async def build_metaconfig(self,
|
||||||
servermodel_id: int,
|
servermodel_id: int,
|
||||||
servermodel_name: str,
|
servermodel_name: str,
|
||||||
xmlroot: str,
|
xmlroot: str,
|
||||||
funcs_file: str) -> MetaConfig:
|
funcs_file: str) -> MetaConfig:
|
||||||
""" Build metaconfig for a servermodel
|
""" Build metaconfig for a servermodel
|
||||||
"""
|
"""
|
||||||
# build tiramisu's session ID
|
# build tiramisu's session ID
|
||||||
@ -123,44 +123,44 @@ class Risotto(Controller):
|
|||||||
funcs_file)
|
funcs_file)
|
||||||
|
|
||||||
# build servermodel metaconfig (v_xxx.m_v_xxx)
|
# build servermodel metaconfig (v_xxx.m_v_xxx)
|
||||||
metaconfig = MetaConfig([],
|
metaconfig = await MetaConfig([],
|
||||||
optiondescription=optiondescription,
|
optiondescription=optiondescription,
|
||||||
persistent=True,
|
persistent=True,
|
||||||
session_id=session_id,
|
session_id=session_id,
|
||||||
storage=self.save_storage)
|
storage=self.save_storage)
|
||||||
mixconfig = MixConfig(children=[],
|
mixconfig = await MixConfig(children=[],
|
||||||
optiondescription=optiondescription,
|
optiondescription=optiondescription,
|
||||||
persistent=True,
|
persistent=True,
|
||||||
session_id='m_' + session_id,
|
session_id='m_' + session_id,
|
||||||
storage=self.save_storage)
|
storage=self.save_storage)
|
||||||
metaconfig.config.add(mixconfig)
|
await metaconfig.config.add(mixconfig)
|
||||||
|
|
||||||
# change default rights
|
# change default rights
|
||||||
ro_origin = metaconfig.property.getdefault('read_only', 'append')
|
ro_origin = await metaconfig.property.getdefault('read_only', 'append')
|
||||||
ro_append = frozenset(ro_origin - {'force_store_value'})
|
ro_append = frozenset(ro_origin - {'force_store_value'})
|
||||||
rw_origin = metaconfig.property.getdefault('read_write', 'append')
|
rw_origin = await metaconfig.property.getdefault('read_write', 'append')
|
||||||
rw_append = frozenset(rw_origin - {'force_store_value'})
|
rw_append = frozenset(rw_origin - {'force_store_value'})
|
||||||
metaconfig.property.setdefault(ro_append, 'read_only', 'append')
|
await metaconfig.property.setdefault(ro_append, 'read_only', 'append')
|
||||||
metaconfig.property.setdefault(rw_append, 'read_write', 'append')
|
await metaconfig.property.setdefault(rw_append, 'read_write', 'append')
|
||||||
|
|
||||||
metaconfig.property.read_only()
|
await metaconfig.property.read_only()
|
||||||
metaconfig.permissive.add('basic')
|
await metaconfig.permissive.add('basic')
|
||||||
metaconfig.permissive.add('normal')
|
await metaconfig.permissive.add('normal')
|
||||||
metaconfig.permissive.add('expert')
|
await metaconfig.permissive.add('expert')
|
||||||
|
|
||||||
# set informtion and owner
|
# set informtion and owner
|
||||||
metaconfig.owner.set('v_{}'.format(servermodel_name))
|
await metaconfig.owner.set('v_{}'.format(servermodel_name))
|
||||||
metaconfig.information.set('servermodel_id', servermodel_id)
|
await metaconfig.information.set('servermodel_id', servermodel_id)
|
||||||
metaconfig.information.set('servermodel_name', servermodel_name)
|
await metaconfig.information.set('servermodel_name', servermodel_name)
|
||||||
|
|
||||||
# return configuration
|
# return configuration
|
||||||
return metaconfig
|
return metaconfig
|
||||||
|
|
||||||
def servermodel_legacy(self,
|
async def servermodel_legacy(self,
|
||||||
risotto_context: Context,
|
risotto_context: Context,
|
||||||
servermodel_name: str,
|
servermodel_name: str,
|
||||||
servermodel_id: int,
|
servermodel_id: int,
|
||||||
servermodel_parent_id: int) -> None:
|
servermodel_parent_id: int) -> None:
|
||||||
""" Make link between parent and children
|
""" Make link between parent and children
|
||||||
"""
|
"""
|
||||||
if servermodel_parent_id is None:
|
if servermodel_parent_id is None:
|
||||||
@ -173,7 +173,7 @@ class Risotto(Controller):
|
|||||||
msg)
|
msg)
|
||||||
return
|
return
|
||||||
servermodel_parent = self.servermodel[servermodel_parent_id]
|
servermodel_parent = self.servermodel[servermodel_parent_id]
|
||||||
servermodel_parent_name = servermodel_parent.information.get('servermodel_name')
|
servermodel_parent_name = await servermodel_parent.information.get('servermodel_name')
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
msg = _(f'Create legacy of servermodel {servermodel_name} ({servermodel_id}) with parent {servermodel_parent_name} ({servermodel_parent_id})')
|
msg = _(f'Create legacy of servermodel {servermodel_name} ({servermodel_id}) with parent {servermodel_parent_name} ({servermodel_parent_id})')
|
||||||
log.info_msg(risotto_context,
|
log.info_msg(risotto_context,
|
||||||
@ -181,9 +181,9 @@ class Risotto(Controller):
|
|||||||
msg)
|
msg)
|
||||||
|
|
||||||
# do link
|
# do link
|
||||||
mix = servermodel_parent.config.get('m_v_' + str(servermodel_parent_id))
|
mix = await servermodel_parent.config.get('m_v_' + str(servermodel_parent_id))
|
||||||
try:
|
try:
|
||||||
mix.config.add(self.servermodel[servermodel_id])
|
await mix.config.add(self.servermodel[servermodel_id])
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
log.error_msg(risotto_context,
|
log.error_msg(risotto_context,
|
||||||
@ -203,10 +203,10 @@ class Risotto(Controller):
|
|||||||
# loads servers
|
# loads servers
|
||||||
for server in servers:
|
for server in servers:
|
||||||
try:
|
try:
|
||||||
self.load_server(risotto_context,
|
await self.load_server(risotto_context,
|
||||||
server['server_id'],
|
server['server_id'],
|
||||||
server['server_name'],
|
server['server_name'],
|
||||||
server['server_servermodel_id'])
|
server['server_servermodel_id'])
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
print_exc()
|
print_exc()
|
||||||
@ -217,11 +217,11 @@ class Risotto(Controller):
|
|||||||
None,
|
None,
|
||||||
msg)
|
msg)
|
||||||
|
|
||||||
def load_server(self,
|
async def load_server(self,
|
||||||
risotto_context: Context,
|
risotto_context: Context,
|
||||||
server_id: int,
|
server_id: int,
|
||||||
server_name: str,
|
server_name: str,
|
||||||
server_servermodel_id: int) -> None:
|
server_servermodel_id: int) -> None:
|
||||||
""" Loads a server
|
""" Loads a server
|
||||||
"""
|
"""
|
||||||
if server_id in self.server:
|
if server_id in self.server:
|
||||||
@ -243,30 +243,30 @@ class Risotto(Controller):
|
|||||||
metaconfig = self.servermodel[server_servermodel_id]
|
metaconfig = self.servermodel[server_servermodel_id]
|
||||||
|
|
||||||
# create server configuration and server 'to deploy' configuration and store it
|
# create server configuration and server 'to deploy' configuration and store it
|
||||||
self.server[server_id] = {'server': self.build_config(session_id,
|
self.server[server_id] = {'server': await self.build_config(session_id,
|
||||||
server_id,
|
server_id,
|
||||||
server_name,
|
server_name,
|
||||||
metaconfig),
|
metaconfig),
|
||||||
'server_to_deploy': self.build_config(f'std_{server_id}',
|
'server_to_deploy': await self.build_config(f'std_{server_id}',
|
||||||
server_id,
|
server_id,
|
||||||
server_name,
|
server_name,
|
||||||
metaconfig),
|
metaconfig),
|
||||||
'funcs_file': self.get_funcs_filename(server_servermodel_id)}
|
'funcs_file': self.get_funcs_filename(server_servermodel_id)}
|
||||||
|
|
||||||
def build_config(self,
|
async def build_config(self,
|
||||||
session_id: str,
|
session_id: str,
|
||||||
server_id: int,
|
server_id: int,
|
||||||
server_name: str,
|
server_name: str,
|
||||||
metaconfig: MetaConfig) -> None:
|
metaconfig: MetaConfig) -> None:
|
||||||
""" build server's config
|
""" build server's config
|
||||||
"""
|
"""
|
||||||
config = metaconfig.config.new(session_id,
|
config = await metaconfig.config.new(session_id,
|
||||||
storage=self.save_storage,
|
storage=self.save_storage,
|
||||||
persistent=True)
|
persistent=True)
|
||||||
config.information.set('server_id', server_id)
|
await config.information.set('server_id', server_id)
|
||||||
config.information.set('server_name', server_name)
|
await config.information.set('server_name', server_name)
|
||||||
config.owner.set(server_name)
|
await config.owner.set(server_name)
|
||||||
config.property.read_only()
|
await config.property.read_only()
|
||||||
return config
|
return config
|
||||||
|
|
||||||
@register('v1.server.created')
|
@register('v1.server.created')
|
||||||
@ -277,10 +277,10 @@ class Risotto(Controller):
|
|||||||
server_servermodel_id: int) -> None:
|
server_servermodel_id: int) -> None:
|
||||||
""" Loads server's configuration when a new server is created
|
""" Loads server's configuration when a new server is created
|
||||||
"""
|
"""
|
||||||
self.load_server(risotto_context,
|
await self.load_server(risotto_context,
|
||||||
server_id,
|
server_id,
|
||||||
server_name,
|
server_name,
|
||||||
server_servermodel_id)
|
server_servermodel_id)
|
||||||
|
|
||||||
@register('v1.server.deleted')
|
@register('v1.server.deleted')
|
||||||
async def server_deleted(self,
|
async def server_deleted(self,
|
||||||
@ -288,10 +288,10 @@ class Risotto(Controller):
|
|||||||
# delete config to it's parents
|
# delete config to it's parents
|
||||||
for server_type in ['server', 'server_to_deploy']:
|
for server_type in ['server', 'server_to_deploy']:
|
||||||
config = self.server[server_id]['server']
|
config = self.server[server_id]['server']
|
||||||
for parent in config.config.parents():
|
for parent in await config.config.parents():
|
||||||
parent.config.pop(config.config.name())
|
await parent.config.pop(config.config.name())
|
||||||
delete_session(storage=self.save_storage,
|
delete_session(storage=self.save_storage,
|
||||||
session_id=config.config.name())
|
session_id=await config.config.name())
|
||||||
# delete metaconfig
|
# delete metaconfig
|
||||||
del self.server[server_id]
|
del self.server[server_id]
|
||||||
|
|
||||||
@ -319,27 +319,27 @@ class Risotto(Controller):
|
|||||||
servermodel_name)
|
servermodel_name)
|
||||||
if servermodel_parents_id is not None:
|
if servermodel_parents_id is not None:
|
||||||
for servermodelparentid in servermodel_parents_id:
|
for servermodelparentid in servermodel_parents_id:
|
||||||
self.servermodel_legacy(risotto_context,
|
await self.servermodel_legacy(risotto_context,
|
||||||
servermodel_name,
|
servermodel_name,
|
||||||
servermodel_id,
|
servermodel_id,
|
||||||
servermodelparentid)
|
servermodelparentid)
|
||||||
|
|
||||||
def servermodel_delete(self,
|
async def servermodel_delete(self,
|
||||||
servermodel_id: int) -> List[MetaConfig]:
|
servermodel_id: int) -> List[MetaConfig]:
|
||||||
metaconfig = self.servermodel.pop(servermodel_id)
|
metaconfig = self.servermodel.pop(servermodel_id)
|
||||||
mixconfig = next(metaconfig.config.list())
|
mixconfig = await metaconfig.config.list()[0]
|
||||||
children = []
|
children = []
|
||||||
for child in mixconfig.config.list():
|
for child in await mixconfig.config.list():
|
||||||
children.append(child)
|
children.append(child)
|
||||||
mixconfig.config.pop(child.config.name())
|
await mixconfig.config.pop(await child.config.name())
|
||||||
metaconfig.config.pop(mixconfig.config.name())
|
await metaconfig.config.pop(await mixconfig.config.name())
|
||||||
delete_session(storage=self.save_storage,
|
delete_session(storage=self.save_storage,
|
||||||
session_id=mixconfig.config.name())
|
session_id=await mixconfig.config.name())
|
||||||
del mixconfig
|
del mixconfig
|
||||||
for parent in metaconfig.config.parents():
|
for parent in await metaconfig.config.parents():
|
||||||
parent.config.pop(metaconfig.config.name())
|
await parent.config.pop(await metaconfig.config.name())
|
||||||
delete_session(storage=self.save_storage,
|
delete_session(storage=self.save_storage,
|
||||||
session_id=metaconfig.config.name())
|
session_id=await metaconfig.config.name())
|
||||||
return children
|
return children
|
||||||
|
|
||||||
@register('v1.servermodel.updated')
|
@register('v1.servermodel.updated')
|
||||||
@ -358,10 +358,10 @@ class Risotto(Controller):
|
|||||||
|
|
||||||
# store all informations
|
# store all informations
|
||||||
if servermodel_id in self.servermodel:
|
if servermodel_id in self.servermodel:
|
||||||
old_values = self.servermodel[servermodel_id].value.exportation()
|
old_values = await self.servermodel[servermodel_id].value.exportation()
|
||||||
old_permissives = self.servermodel[servermodel_id].permissive.exportation()
|
old_permissives = await self.servermodel[servermodel_id].permissive.exportation()
|
||||||
old_properties = self.servermodel[servermodel_id].property.exportation()
|
old_properties = await self.servermodel[servermodel_id].property.exportation()
|
||||||
children = self.servermodel_delete(servermodel_id)
|
children = await self.servermodel_delete(servermodel_id)
|
||||||
else:
|
else:
|
||||||
old_values = None
|
old_values = None
|
||||||
|
|
||||||
@ -373,14 +373,14 @@ class Risotto(Controller):
|
|||||||
|
|
||||||
# migrates informations
|
# migrates informations
|
||||||
if old_values is not None:
|
if old_values is not None:
|
||||||
self.servermodel[servermodel_id].value.importation(old_values)
|
await self.servermodel[servermodel_id].value.importation(old_values)
|
||||||
self.servermodel[servermodel_id].permissive.importation(old_permissives)
|
await self.servermodel[servermodel_id].permissive.importation(old_permissives)
|
||||||
self.servermodel[servermodel_id].property.importation(old_properties)
|
await self.servermodel[servermodel_id].property.importation(old_properties)
|
||||||
for child in children:
|
for child in children:
|
||||||
self.servermodel_legacy(risotto_context,
|
await self.servermodel_legacy(risotto_context,
|
||||||
child.information.get('servermodel_name'),
|
await child.information.get('servermodel_name'),
|
||||||
child.information.get('servermodel_id'),
|
await child.information.get('servermodel_id'),
|
||||||
servermodel_id)
|
servermodel_id)
|
||||||
|
|
||||||
@register('v1.config.configuration.server.get', None)
|
@register('v1.config.configuration.server.get', None)
|
||||||
async def get_configuration(self,
|
async def get_configuration(self,
|
||||||
@ -398,9 +398,9 @@ class Risotto(Controller):
|
|||||||
else:
|
else:
|
||||||
server = self.server[server_id]['server_to_deploy']
|
server = self.server[server_id]['server_to_deploy']
|
||||||
|
|
||||||
server.property.read_only()
|
await server.property.read_only()
|
||||||
try:
|
try:
|
||||||
configuration = server.value.dict(fullpath=True)
|
configuration = await server.value.dict(fullpath=True)
|
||||||
except:
|
except:
|
||||||
if deployed:
|
if deployed:
|
||||||
msg = _(f'No configuration available for server {server_id}')
|
msg = _(f'No configuration available for server {server_id}')
|
||||||
@ -423,19 +423,19 @@ class Risotto(Controller):
|
|||||||
config_std = self.server[server_id]['server_to_deploy']
|
config_std = self.server[server_id]['server_to_deploy']
|
||||||
|
|
||||||
# when deploy, calculate force_store_value
|
# when deploy, calculate force_store_value
|
||||||
ro = config_std.property.getdefault('read_only', 'append')
|
ro = await config_std.property.getdefault('read_only', 'append')
|
||||||
if 'force_store_value' not in ro:
|
if 'force_store_value' not in ro:
|
||||||
ro = frozenset(list(ro) + ['force_store_value'])
|
ro = frozenset(list(ro) + ['force_store_value'])
|
||||||
config_std.property.setdefault(ro, 'read_only', 'append')
|
await config_std.property.setdefault(ro, 'read_only', 'append')
|
||||||
rw = config_std.property.getdefault('read_write', 'append')
|
rw = await config_std.property.getdefault('read_write', 'append')
|
||||||
rw = frozenset(list(rw) + ['force_store_value'])
|
rw = frozenset(list(rw) + ['force_store_value'])
|
||||||
config_std.property.setdefault(rw, 'read_write', 'append')
|
await config_std.property.setdefault(rw, 'read_write', 'append')
|
||||||
config_std.property.add('force_store_value')
|
await config_std.property.add('force_store_value')
|
||||||
|
|
||||||
# copy informations from server 'to deploy' configuration to server configuration
|
# copy informations from server 'to deploy' configuration to server configuration
|
||||||
config.value.importation(config_std.value.exportation())
|
await config.value.importation(await config_std.value.exportation())
|
||||||
config.permissive.importation(config_std.permissive.exportation())
|
await config.permissive.importation(await config_std.permissive.exportation())
|
||||||
config.property.importation(config_std.property.exportation())
|
await config.property.importation(await config_std.property.exportation())
|
||||||
|
|
||||||
return {'server_id': server_id,
|
return {'server_id': server_id,
|
||||||
'deployed': True}
|
'deployed': True}
|
||||||
|
@ -98,11 +98,11 @@ class Risotto(Controller):
|
|||||||
session_id = 'z' + hexlify(urandom(23)).decode()
|
session_id = 'z' + hexlify(urandom(23)).decode()
|
||||||
if not session_id in sessions:
|
if not session_id in sessions:
|
||||||
break
|
break
|
||||||
storage.add_session(session_id,
|
await storage.add_session(session_id,
|
||||||
config,
|
config,
|
||||||
id,
|
id,
|
||||||
risotto_context.username,
|
risotto_context.username,
|
||||||
self.modify_storage)
|
self.modify_storage)
|
||||||
|
|
||||||
# return session's information
|
# return session's information
|
||||||
return self.get_session_informations(risotto_context,
|
return self.get_session_informations(risotto_context,
|
||||||
@ -135,11 +135,11 @@ class Risotto(Controller):
|
|||||||
if mode is not None:
|
if mode is not None:
|
||||||
if mode not in ('basic', 'normal', 'expert'):
|
if mode not in ('basic', 'normal', 'expert'):
|
||||||
raise Exception(f'unknown mode {mode}')
|
raise Exception(f'unknown mode {mode}')
|
||||||
storage.set_config_mode(session_id,
|
await storage.set_config_mode(session_id,
|
||||||
mode)
|
mode)
|
||||||
if debug is not None:
|
if debug is not None:
|
||||||
storage.set_config_debug(session_id,
|
await storage.set_config_debug(session_id,
|
||||||
debug)
|
debug)
|
||||||
return self.get_session_informations(risotto_context,
|
return self.get_session_informations(risotto_context,
|
||||||
session_id,
|
session_id,
|
||||||
type)
|
type)
|
||||||
@ -160,7 +160,7 @@ class Risotto(Controller):
|
|||||||
# if multi and not follower the value is in fact in value_multi
|
# if multi and not follower the value is in fact in value_multi
|
||||||
# FIXME option = session['option'].option(name).option
|
# FIXME option = session['option'].option(name).option
|
||||||
option = session['config'].option(name).option
|
option = session['config'].option(name).option
|
||||||
if option.ismulti() and not option.isfollower():
|
if await option.ismulti() and not await option.isfollower():
|
||||||
value = value_multi
|
value = value_multi
|
||||||
#FIXME namespace = session['namespace']
|
#FIXME namespace = session['namespace']
|
||||||
#FIXME update = {'name': f'{namespace}.{name}',
|
#FIXME update = {'name': f'{namespace}.{name}',
|
||||||
@ -170,7 +170,7 @@ class Risotto(Controller):
|
|||||||
if index is not None:
|
if index is not None:
|
||||||
update['index'] = index
|
update['index'] = index
|
||||||
updates = {'updates': [update]}
|
updates = {'updates': [update]}
|
||||||
ret = session['option'].updates(updates)
|
ret = await session['option'].updates(updates)
|
||||||
if update['name'] in ret:
|
if update['name'] in ret:
|
||||||
for val in ret[update['name']][index]:
|
for val in ret[update['name']][index]:
|
||||||
if isinstance(val, ValueError):
|
if isinstance(val, ValueError):
|
||||||
@ -190,14 +190,14 @@ class Risotto(Controller):
|
|||||||
session_id,
|
session_id,
|
||||||
type)
|
type)
|
||||||
try:
|
try:
|
||||||
session['config'].forcepermissive.option(session['namespace']).value.dict()
|
await session['config'].forcepermissive.option(session['namespace']).value.dict()
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
raise Exception(str(err))
|
raise Exception(str(err))
|
||||||
if type == 'server':
|
if type == 'server':
|
||||||
config = session['config']
|
config = session['config']
|
||||||
config.property.read_only()
|
await config.property.read_only()
|
||||||
mandatories = list(config.value.mandatory())
|
mandatories = list(await config.value.mandatory())
|
||||||
config.property.read_write()
|
await config.property.read_write()
|
||||||
if mandatories:
|
if mandatories:
|
||||||
# FIXME mandatories = [mandatory.split('.', 1)[1] for mandatory in mandatories]
|
# FIXME mandatories = [mandatory.split('.', 1)[1] for mandatory in mandatories]
|
||||||
if len(mandatories) == 1:
|
if len(mandatories) == 1:
|
||||||
@ -221,9 +221,11 @@ class Risotto(Controller):
|
|||||||
type)
|
type)
|
||||||
info = self.format_session(session_id, session)
|
info = self.format_session(session_id, session)
|
||||||
if name is not None:
|
if name is not None:
|
||||||
info['content'] = {name: session['option'].option(name).value.get()}
|
content = {name: await session['option'].option(name).value.get()}
|
||||||
else:
|
else:
|
||||||
info['content'] = session['option'].value.dict(fullpath=True)
|
content = await session['option'].value.dict(fullpath=True,
|
||||||
|
leader_to_list=True)
|
||||||
|
info['content'] = content
|
||||||
return info
|
return info
|
||||||
|
|
||||||
@register(['v1.session.server.stop', 'v1.session.servermodel.stop'], None)
|
@register(['v1.session.server.stop', 'v1.session.servermodel.stop'], None)
|
||||||
@ -243,8 +245,8 @@ class Risotto(Controller):
|
|||||||
config = config_module.servermodel[id_]
|
config = config_module.servermodel[id_]
|
||||||
if save:
|
if save:
|
||||||
modif_config = session['config']
|
modif_config = session['config']
|
||||||
config.value.importation(modif_config.value.exportation())
|
await config.value.importation(await modif_config.value.exportation())
|
||||||
config.permissive.importation(modif_config.permissive.exportation())
|
await config.permissive.importation(await modif_config.permissive.exportation())
|
||||||
storage.del_session(session_id)
|
storage.del_session(session_id)
|
||||||
return self.format_session(session_id, session)
|
return self.format_session(session_id, session)
|
||||||
|
|
||||||
@ -255,7 +257,7 @@ class Risotto(Controller):
|
|||||||
session_id: str) -> Dict:
|
session_id: str) -> Dict:
|
||||||
session = storage_server.get_session(session_id,
|
session = storage_server.get_session(session_id,
|
||||||
risotto_context.username)
|
risotto_context.username)
|
||||||
return session['option'].dict(remotable='all')
|
return await session['option'].dict(remotable='all')
|
||||||
|
|
||||||
@register_http('v1', '/config/servermodel/{session_id}')
|
@register_http('v1', '/config/servermodel/{session_id}')
|
||||||
async def get_servermodel_api(self,
|
async def get_servermodel_api(self,
|
||||||
@ -264,4 +266,4 @@ class Risotto(Controller):
|
|||||||
session_id: str) -> Dict:
|
session_id: str) -> Dict:
|
||||||
session = storage_servermodel.get_session(session_id,
|
session = storage_servermodel.get_session(session_id,
|
||||||
risotto_context.username)
|
risotto_context.username)
|
||||||
return session['option'].dict(remotable='all')
|
return await session['option'].dict(remotable='all')
|
||||||
|
@ -15,26 +15,26 @@ class Storage(object):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.sessions = {}
|
self.sessions = {}
|
||||||
|
|
||||||
def add_session(self,
|
async def add_session(self,
|
||||||
session_id: int,
|
session_id: int,
|
||||||
orig_config: Config,
|
orig_config: Config,
|
||||||
server_id: int,
|
server_id: int,
|
||||||
username: str,
|
username: str,
|
||||||
config_storage):
|
config_storage):
|
||||||
prefix_id = f'{session_id}_'
|
prefix_id = f'{session_id}_'
|
||||||
config_name = self.get_config_name(server_id)
|
config_name = self.get_config_name(server_id)
|
||||||
config_id = f'{prefix_id}{config_name}'
|
config_id = f'{prefix_id}{config_name}'
|
||||||
|
|
||||||
# copy Config and all it's parents
|
# copy Config and all it's parents
|
||||||
meta = orig_config.config.deepcopy(session_id=config_id,
|
meta = await orig_config.config.deepcopy(session_id=config_id,
|
||||||
storage=config_storage,
|
storage=config_storage,
|
||||||
metaconfig_prefix=prefix_id)
|
metaconfig_prefix=prefix_id)
|
||||||
|
|
||||||
# retrieve the copied config (not metaconfig)
|
# retrieve the copied config (not metaconfig)
|
||||||
config = meta
|
config = meta
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
children = list(config.config.list())
|
children = list(await config.config.list())
|
||||||
if not children:
|
if not children:
|
||||||
# it's an empty metaconfig
|
# it's an empty metaconfig
|
||||||
break
|
break
|
||||||
@ -42,7 +42,7 @@ class Storage(object):
|
|||||||
except:
|
except:
|
||||||
# it's a config, so no "list" method
|
# it's a config, so no "list" method
|
||||||
break
|
break
|
||||||
config.property.read_write()
|
await config.property.read_write()
|
||||||
# set the default owner
|
# set the default owner
|
||||||
self.set_owner(config,
|
self.set_owner(config,
|
||||||
username)
|
username)
|
||||||
@ -54,34 +54,34 @@ class Storage(object):
|
|||||||
'id': server_id,
|
'id': server_id,
|
||||||
'timestamp': int(time.time()),
|
'timestamp': int(time.time()),
|
||||||
'username': username}
|
'username': username}
|
||||||
self.set_config_mode(session_id,
|
await self.set_config_mode(session_id,
|
||||||
'normal')
|
'normal')
|
||||||
self.set_config_debug(session_id,
|
await self.set_config_debug(session_id,
|
||||||
False)
|
False)
|
||||||
self.set_namespace(session_id,
|
self.set_namespace(session_id,
|
||||||
'creole')
|
'creole')
|
||||||
|
|
||||||
def set_config_mode(self,
|
async def set_config_mode(self,
|
||||||
id: int,
|
id: int,
|
||||||
mode: str):
|
mode: str):
|
||||||
""" Define which edition mode to select
|
""" Define which edition mode to select
|
||||||
"""
|
"""
|
||||||
config = self.sessions[id]['config']
|
config = self.sessions[id]['config']
|
||||||
for mode_level in modes.values():
|
for mode_level in modes.values():
|
||||||
if modes[mode] < mode_level:
|
if modes[mode] < mode_level:
|
||||||
config.property.add(mode_level.name)
|
await config.property.add(mode_level.name)
|
||||||
else:
|
else:
|
||||||
config.property.pop(mode_level.name)
|
await config.property.pop(mode_level.name)
|
||||||
self.sessions[id]['mode'] = mode
|
self.sessions[id]['mode'] = mode
|
||||||
|
|
||||||
def set_config_debug(self, id_, is_debug):
|
async def set_config_debug(self, id_, is_debug):
|
||||||
""" Enable/Disable debug mode
|
""" Enable/Disable debug mode
|
||||||
"""
|
"""
|
||||||
config = self.sessions[id_]['config']
|
config = self.sessions[id_]['config']
|
||||||
if is_debug:
|
if is_debug:
|
||||||
config.property.pop('hidden')
|
await config.property.pop('hidden')
|
||||||
else:
|
else:
|
||||||
config.property.add('hidden')
|
await config.property.add('hidden')
|
||||||
self.sessions[id_]['debug'] = is_debug
|
self.sessions[id_]['debug'] = is_debug
|
||||||
|
|
||||||
def set_namespace(self,
|
def set_namespace(self,
|
||||||
|
Loading…
Reference in New Issue
Block a user