|
|
|
@ -54,11 +54,19 @@ class Variables(MutableMapping):
|
|
|
|
|
def __getattribute__(self, name):
|
|
|
|
|
if name == '_Variables__attrs':
|
|
|
|
|
return super().__getattribute__(name)
|
|
|
|
|
if name == 'available_packages':
|
|
|
|
|
return super().__getattribute__(name)
|
|
|
|
|
try:
|
|
|
|
|
return self.__attrs[name]
|
|
|
|
|
except KeyError:
|
|
|
|
|
raise AttributeError(name)
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def available_packages(self):
|
|
|
|
|
packages = set(self.__attrs.keys())
|
|
|
|
|
packages.update({'custom'})
|
|
|
|
|
return packages
|
|
|
|
|
|
|
|
|
|
def __getitem__(self, name):
|
|
|
|
|
return self.__attrs[name]
|
|
|
|
|
|
|
|
|
@ -84,7 +92,8 @@ class ParametersProcessor:
|
|
|
|
|
'autoupdate', 'env', 'force', 'source', 'format',
|
|
|
|
|
'unbound', 'mirror', 'run', 'exec', 'env',
|
|
|
|
|
'package', 'merge', 'postmerge', 'action',
|
|
|
|
|
'rebuild', 'restart', 'stop', 'start'}
|
|
|
|
|
'rebuild', 'restart', 'stop', 'start', 'handler',
|
|
|
|
|
'notify'}
|
|
|
|
|
|
|
|
|
|
inheritable_parameters = {'chmod', 'chown', 'autoupdate', 'env',
|
|
|
|
|
'package', 'action'}
|
|
|
|
@ -135,7 +144,10 @@ class ParametersProcessor:
|
|
|
|
|
'source': self.check_source_parameter,
|
|
|
|
|
'force': self.check_force_parameter,
|
|
|
|
|
'env': self.check_env_parameter,
|
|
|
|
|
'merge': self.check_merge_parameter
|
|
|
|
|
'merge': self.check_merge_parameter,
|
|
|
|
|
'format': self.check_format_parameter,
|
|
|
|
|
'handler': self.check_handler_parameter,
|
|
|
|
|
'notify': self.check_notify_parameter
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
# Если добавляемый параметр должен быть проверен после того, как
|
|
|
|
@ -297,13 +309,6 @@ class ParametersProcessor:
|
|
|
|
|
raise IncorrectParameter(
|
|
|
|
|
"'restart' parameter value is not correct")
|
|
|
|
|
|
|
|
|
|
def check_format_parameter(self, parameter_value):
|
|
|
|
|
if parameter_value in self.available_formats:
|
|
|
|
|
return parameter_value
|
|
|
|
|
else:
|
|
|
|
|
raise IncorrectParameter(
|
|
|
|
|
"'format' parameter value is not available")
|
|
|
|
|
|
|
|
|
|
def check_stop_parameter(self, parameter_value):
|
|
|
|
|
if not parameter_value and isinstance(parameter_value, bool):
|
|
|
|
|
raise IncorrectParameter("'stop' parameter value is empty")
|
|
|
|
@ -426,7 +431,35 @@ class ParametersProcessor:
|
|
|
|
|
return parameter_value
|
|
|
|
|
else:
|
|
|
|
|
raise IncorrectParameter(
|
|
|
|
|
"'autoupdate' parameter value is not bool")
|
|
|
|
|
"'autoupdate' parameter value is not bool.")
|
|
|
|
|
|
|
|
|
|
def check_format_parameter(self, parameter_value):
|
|
|
|
|
if self.template_type == DIR:
|
|
|
|
|
raise IncorrectParameter("'format' parameter is redundant for"
|
|
|
|
|
" directory templates.")
|
|
|
|
|
if isinstance(parameter_value, str):
|
|
|
|
|
if parameter_value not in self.available_formats:
|
|
|
|
|
raise IncorrectParameter(f"'{parameter_value}' value of the"
|
|
|
|
|
" 'format' parameter is not"
|
|
|
|
|
" available.")
|
|
|
|
|
return parameter_value
|
|
|
|
|
raise IncorrectParameter("'format' parameter must be string value not"
|
|
|
|
|
f" {type(parameter_value)}.")
|
|
|
|
|
|
|
|
|
|
def check_handler_parameter(self, parameter_value):
|
|
|
|
|
if isinstance(parameter_value, str):
|
|
|
|
|
return parameter_value
|
|
|
|
|
raise IncorrectParameter("'handler' parameter must be string"
|
|
|
|
|
f" value not {type(parameter_value)}.")
|
|
|
|
|
|
|
|
|
|
def check_notify_parameter(self, parameter_value):
|
|
|
|
|
if isinstance(parameter_value, list):
|
|
|
|
|
return parameter_value
|
|
|
|
|
elif isinstance(parameter_value, str):
|
|
|
|
|
return [parameter.strip() for parameter in
|
|
|
|
|
parameter_value.split(',')]
|
|
|
|
|
raise IncorrectParameter("'notify' parameter must be string or list"
|
|
|
|
|
f" value not {type(parameter_value)}.")
|
|
|
|
|
|
|
|
|
|
# Методы для проверки параметров после разбора всего шаблона.
|
|
|
|
|
|
|
|
|
@ -879,7 +912,7 @@ class CalculateExtension(Extension):
|
|
|
|
|
check_template_node)
|
|
|
|
|
check_template.render(__datavars__=self._datavars)
|
|
|
|
|
|
|
|
|
|
elif (self.stream.current.type == 'name'
|
|
|
|
|
elif (self._is_variable_name(self.stream.current)
|
|
|
|
|
or self.stream.current.type == 'lparen'
|
|
|
|
|
or self.stream.current.type == 'integer'):
|
|
|
|
|
# разбираем условие. Если условие False -- кидаем исключение.
|
|
|
|
@ -887,9 +920,16 @@ class CalculateExtension(Extension):
|
|
|
|
|
if not condition_result:
|
|
|
|
|
raise ConditionFailed('Condition is failed',
|
|
|
|
|
lineno=self.stream.current.lineno)
|
|
|
|
|
elif self.stream.current.type == 'name':
|
|
|
|
|
raise TemplateSyntaxError(
|
|
|
|
|
f"Unknown identifier '{self.stream.current.value}'"
|
|
|
|
|
" in calculate tag.",
|
|
|
|
|
lineno=self.stream.current.lineno)
|
|
|
|
|
else:
|
|
|
|
|
raise TemplateSyntaxError('Name is expected in calculate tag.',
|
|
|
|
|
lineno=self.stream.current.lineno)
|
|
|
|
|
raise TemplateSyntaxError(
|
|
|
|
|
f"Can not parse token '{self.stream.current.value}'"
|
|
|
|
|
" in caluculate tag.",
|
|
|
|
|
lineno=self.stream.current.lineno)
|
|
|
|
|
expect_comma_flag = True
|
|
|
|
|
|
|
|
|
|
# dictionary_node = nodes.Dict(pairs_list)
|
|
|
|
@ -901,6 +941,17 @@ class CalculateExtension(Extension):
|
|
|
|
|
|
|
|
|
|
return nodes.Output([nodes.Const('')], lineno=lineno)
|
|
|
|
|
|
|
|
|
|
def _is_variable_name(self, token):
|
|
|
|
|
if not token.type == 'name':
|
|
|
|
|
return False
|
|
|
|
|
if (token.value in self._datavars.available_packages or
|
|
|
|
|
token.value in self.environment.globals):
|
|
|
|
|
return True
|
|
|
|
|
for env in self.environment.context_class._env_set:
|
|
|
|
|
if token.value in self._datavars[env]:
|
|
|
|
|
return True
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def check_parameter(self, parameter_name, parameter_value, context):
|
|
|
|
|
self.parameters_processor.check_template_parameter(
|
|
|
|
|
parameter_name,
|
|
|
|
@ -913,6 +964,7 @@ class CalculateExtension(Extension):
|
|
|
|
|
'''Метод для разбора условий из тега calculate.'''
|
|
|
|
|
# лучший способ -- парсим в AST дерево, после чего компилируем и
|
|
|
|
|
# выполняем его.
|
|
|
|
|
print('GET CONDITION')
|
|
|
|
|
self.condition_result = False
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
@ -929,9 +981,11 @@ class CalculateExtension(Extension):
|
|
|
|
|
template = self.environment.from_string(condition_template)
|
|
|
|
|
|
|
|
|
|
template.render(__datavars__=self._datavars)
|
|
|
|
|
except Exception:
|
|
|
|
|
except Exception as error:
|
|
|
|
|
print('Error during running condition:', str(error))
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
print('condition result:', self.condition_result)
|
|
|
|
|
return self.condition_result
|
|
|
|
|
|
|
|
|
|
# собираем исходный код условия из токенов.
|
|
|
|
@ -1210,7 +1264,7 @@ class CalculateExtension(Extension):
|
|
|
|
|
# контекста вo время парсинга.
|
|
|
|
|
env_names = parameter_value.split(',')
|
|
|
|
|
for name in env_names:
|
|
|
|
|
CalculateContext._env_set.add(name.strip())
|
|
|
|
|
self.environment.context_class._env_set.add(name.strip())
|
|
|
|
|
else:
|
|
|
|
|
parameter_rvalue = nodes.Const(True, lineno=lineno)
|
|
|
|
|
parameter_value = True
|
|
|
|
|