The part of the TemplateAction is implemented. A developing of the conflict solver is started.

packages
Иванов Денис 4 years ago
parent 23b7799aef
commit 85d7744ef0

@ -46,9 +46,9 @@ class BaseFormat():
if self._fatal_error_flag: if self._fatal_error_flag:
# Действия если файл невозможно разобрать. # Действия если файл невозможно разобрать.
print('Can not parse file.')
self._document_dictionary = OrderedDict() self._document_dictionary = OrderedDict()
return raise FormatError('line {} is not correct.'.
format(self._line_timer))
if self._is_match(): if self._is_match():
if self._is_ready_to_update(): if self._is_ready_to_update():
@ -56,10 +56,9 @@ class BaseFormat():
break break
else: else:
# Действия если не удалось разобрать строку. # Действия если не удалось разобрать строку.
print('Line', self._line_timer,
'is not correct. Can not parse file.')
self._document_dictionary = OrderedDict() self._document_dictionary = OrderedDict()
return raise FormatError('line {} is not correct.'.
format(self._line_timer))
self._line_timer += 1 self._line_timer += 1
@ -288,7 +287,8 @@ class BaseFormat():
**to_add_dictionary) **to_add_dictionary)
return full_diff, unchanged_set return full_diff, unchanged_set
def get_document_text(self): @property
def document_text(self):
file_loader = PackageLoader('calculate.templates.format', file_loader = PackageLoader('calculate.templates.format',
self.TEMPLATES_DIRECTORY) self.TEMPLATES_DIRECTORY)
formats_environment = Environment(loader=file_loader, formats_environment = Environment(loader=file_loader,

@ -124,7 +124,8 @@ class ContentsFormat(BaseFormat):
except ParseException: except ParseException:
return return
def get_document_text(self): @property
def document_text(self):
file_loader = PackageLoader('calculate.templates.format', file_loader = PackageLoader('calculate.templates.format',
self.TEMPLATES_DIRECTORY) self.TEMPLATES_DIRECTORY)
formats_environment = Environment(loader=file_loader, formats_environment = Environment(loader=file_loader,

@ -25,6 +25,7 @@ class JSONFormat(BaseFormat):
self._document_dictionary = json.loads(json_file_text, self._document_dictionary = json.loads(json_file_text,
object_pairs_hook=OrderedDict) object_pairs_hook=OrderedDict)
@property
def get_document_text(self): def get_document_text(self):
json_file_text = json.dumps(self._document_dictionary, indent=4) json_file_text = json.dumps(self._document_dictionary, indent=4)
return json_file_text return json_file_text

@ -407,7 +407,8 @@ class ProFTPDFormat(BaseFormat):
except ParseException: except ParseException:
return return
def get_document_text(self): @property
def document_text(self):
file_loader = PackageLoader('calculate.templates.format', file_loader = PackageLoader('calculate.templates.format',
self.TEMPLATES_DIRECTORY) self.TEMPLATES_DIRECTORY)
formats_environment = Environment(loader=file_loader) formats_environment = Environment(loader=file_loader)

@ -164,7 +164,8 @@ class XMLGConfFormat(BaseFormat):
element_name = ('', Element.tag) element_name = ('', Element.tag)
return OrderedDict({element_name: 'Unknown element'}) return OrderedDict({element_name: 'Unknown element'})
def get_document_text(self): @property
def document_text(self):
gconf_header = next(iter(self._document_dictionary)) gconf_header = next(iter(self._document_dictionary))
root = Element('gconf') root = Element('gconf')

@ -112,7 +112,8 @@ class XMLXfceFormat(BaseFormat):
element_name = ('', xml_element.tag) element_name = ('', xml_element.tag)
return OrderedDict({element_name: 'Unknown element'}) return OrderedDict({element_name: 'Unknown element'})
def get_document_text(self): @property
def document_text(self):
channel = next(iter(self._document_dictionary.keys())) channel = next(iter(self._document_dictionary.keys()))
channel_head = OrderedDict( channel_head = OrderedDict(
{key: value for key, value in {key: value for key, value in

@ -19,7 +19,7 @@ from ..utils.files import join_paths
# Типы шаблона: директория или файл. # Типы шаблона: директория или файл.
DIR, FILE = range(2) DIR, FILE, LINK = range(3)
class IncorrectParameter(Exception): class IncorrectParameter(Exception):
@ -81,9 +81,15 @@ class ParametersProcessor:
inheritable_parameters = {'chmod', 'chown', 'autoupdate', 'env', inheritable_parameters = {'chmod', 'chown', 'autoupdate', 'env',
'package', 'action'} 'package', 'action'}
file_default_parameters = {'chmod': 0o644,
'chown': {'uid': 0, 'gid': 0}}
directory_default_parameters = {'chmod': 0o755,
'chown': {'uid': 0, 'gid': 0}}
available_appends = set() available_appends = set()
available_formats = set() available_formats = dict()
format_is_inspected = False format_is_inspected = False
@ -248,6 +254,13 @@ class ParametersProcessor:
raise IncorrectParameter( raise IncorrectParameter(
"'restart' parameter value is not correct") "'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): def check_stop_parameter(self, parameter_value):
if parameter_value and isinstance(parameter_value, str): if parameter_value and isinstance(parameter_value, str):
return parameter_value return parameter_value
@ -445,8 +458,10 @@ class ParametersProcessor:
предоставляемых ими параметров.''' предоставляемых ими параметров.'''
if cls.format_is_inspected: if cls.format_is_inspected:
return return
parameters_set = set() parameters_set = set()
format_set = set() available_formats = dict()
format_directory_path = os.path.join(os.path.dirname(__file__), format_directory_path = os.path.join(os.path.dirname(__file__),
'format') 'format')
@ -466,14 +481,21 @@ class ParametersProcessor:
format_class = getattr(module, obj, False) format_class = getattr(module, obj, False)
if format_class: if format_class:
format_set.add(format_class.FORMAT) format_name = getattr(format_class,
parameters = getattr(format_class, 'FORMAT', False)
'FORMAT_PARAMETERS', set()) if not format_name:
parameters_set.update(parameters) continue
available_formats.update(
{format_name: format_class})
format_parameters = getattr(format_class,
'FORMAT_PARAMETERS',
set())
parameters_set.update(format_parameters)
except Exception: except Exception:
continue continue
cls.available_formats = format_set cls.available_formats = available_formats
cls.available_parameters.update(parameters_set) cls.available_parameters.update(parameters_set)
cls.formats_inspected = True cls.formats_inspected = True
@ -860,7 +882,7 @@ class CalculateExtension(Extension):
class TemplateEngine: class TemplateEngine:
def __init__(self, directory_path='/', def __init__(self, directory_path=None,
datavars_module=Variables(), datavars_module=Variables(),
appends_set=set(), appends_set=set(),
chroot_path='/'): chroot_path='/'):
@ -870,7 +892,6 @@ class TemplateEngine:
ParametersProcessor.available_parameters ParametersProcessor.available_parameters
CalculateExtension._datavars = datavars_module CalculateExtension._datavars = datavars_module
self.available_formats = ParametersProcessor.available_formats
self.available_appends = appends_set self.available_appends = appends_set
ParametersProcessor.available_appends = appends_set ParametersProcessor.available_appends = appends_set
@ -885,7 +906,11 @@ class TemplateEngine:
CalculateExtension.parameters_processor = self.parameters_processor CalculateExtension.parameters_processor = self.parameters_processor
self.environment = Environment(loader=FileSystemLoader(directory_path)) if directory_path is not None:
self.environment = Environment(
loader=FileSystemLoader(directory_path))
else:
self.environment = Environment()
self.calculate_extension = CalculateExtension( self.calculate_extension = CalculateExtension(
self.environment, self.environment,

@ -31,10 +31,18 @@ class TemplateAction:
def __init__(self, output_module=IOModule(), def __init__(self, output_module=IOModule(),
chroot_path='/', mounts=None): chroot_path='/', mounts=None):
self.output = output_module self.output = output_module
self.mounts = mounts self.mounts = mounts
self.chroot_path = chroot_path self.chroot_path = chroot_path
self.exec_list = OrderedDict() self.exec_list = OrderedDict()
self.directory_default_parameters =\
ParametersProcessor.directory_default_parameters
self.file_default_parameters =\
ParametersProcessor.file_default_parameters
self.DIRECTORY_APPENDS = { self.DIRECTORY_APPENDS = {
'remove': self._append_remove_directory, 'remove': self._append_remove_directory,
'clear': self._append_clear_directory, 'clear': self._append_clear_directory,

@ -1,26 +1,245 @@
from calculate.templates.template_engine import TemplateEngine, Variables,\ from calculate.templates.template_engine import TemplateEngine, Variables,\
ConditionFailed, DIR, FILE FILE, DIR, LINK,\
ParametersProcessor
from calculate.templates.template_processor import TemplateAction from calculate.templates.template_processor import TemplateAction
import shutil
import os
template_text = '''{% calculate append = 'join', path = '/etc/file.conf' %} template_text = '''{% calculate append = 'join' -%}
{% calculate package = "dev-lang/python" %} {% calculate package = 'dev-lang/python', format = 'samba' -%}
{% calculate name = 'filename', format = 'samba' %}
[section one] [section one]
parameter_1 = value_1 parameter_1 = {{ vars_1.value_1 }}
!parameter_2 = value_2 !parameter_2
'''
backup_template_text = '''{% calculate append = 'join' -%}
[section one]
parameter_1 = value
parameter_2 = value_2
''' '''
APPENDS_SET = TemplateAction().available_appends APPENDS_SET = TemplateAction().available_appends
template_engine = TemplateEngine(appends_set=APPENDS_SET) vars_1 = Variables({'value_1': 'value_1'})
template_engine.process_template_from_string(template_text, FILE) DATAVARS_MODULE = Variables({'vars_1': vars_1})
template_parameters = template_engine.parameters
target_path = '/etc/dir/file.conf' CHROOT_PATH = os.path.join(os.getcwd(), 'tests/templates/testfiles/test_root')
template_engine = TemplateEngine(datavars_module=DATAVARS_MODULE,
appends_set=APPENDS_SET,
chroot_path=CHROOT_PATH)
target_path = os.path.join(CHROOT_PATH,
'etc/dir/file.conf')
class TemplateActionError(Exception):
pass
class TargetFile:
type_checks = {DIR: os.path.isdir,
FILE: os.path.isfile,
LINK: os.path.islink}
def __init__(self, target_file_path, template_type, package=None):
self._file_path = target_file_path
self._package = package
if not os.path.exists(target_file_path):
pass
def check_conflicts(self, parameters):
pass
class TemplateActionDraft:
def __init__(self, datavars_module=Variables(), chroot_path='/'):
self.datavars_module = datavars_module
self.chroot_path = chroot_path
self.directory_default_parameters =\
ParametersProcessor.directory_default_parameters
self.file_default_parameters =\
ParametersProcessor.file_default_parameters
self.directory_appends = {'join': self._append_join_directory,
'remove': self._append_remove_directory,
'clear': self._append_clear_directory}
self.file_appends = {'join': self._append_join_file}
self.formats_classes = ParametersProcessor.available_formats
def use_directory_template(self, target_path, parameters):
print('Template parameters:')
parameters.print_parameters_for_debug()
self.template_parameters = parameters
self.directory_appends[self.template_parameters.append](target_path)
def use_file_template(self, target_path, parameters, template_text=''):
print('Template parameters:')
parameters.print_parameters_for_debug()
self.template_parameters = parameters
self.template_text = template_text
self.file_appends[self.template_parameters.append](target_path)
def use_template(target_path, parameters, chroot_path): def _append_join_directory(self, target_path):
print('Template parameters:') print("append = 'join'")
parameters.print_parameters_for_debug() if os.access(target_path, os.F_OK):
if self.template_parameters.chmod:
self.chmod_directory(target_path)
if self.template_parameters.chown:
self.chown_directory(target_path)
return
directories_to_create = [target_path]
directory_path = os.path.dirname(target_path)
while not os.access(directory_path, os.F_OK) and directory_path:
directories_to_create.append(directory_path)
directory_path = os.path.dirname(directory_path)
try:
current_mod, current_uid, current_gid = self.get_file_info(
directory_path,
'all')
current_owner = {'uid': current_uid, 'gid': current_gid}
except OSError:
raise TemplateActionError('No access to the directory: {}'.format(
directory_path))
directories_to_create.reverse()
for create_path in directories_to_create:
try:
os.mkdir(create_path)
if (self.template_parameters.chmod and
self.template_parameters.chmod != current_mod):
self.chmod_directory(create_path)
elif 'chmod' in self.directory_default_parameters:
self.chmod_directory(
create_path,
chmod_value=self.directory_default_parameters['chown'])
if (self.template_parameters.chown and
self.template_parameters.chown != current_owner):
self.chown_directory
elif 'chown' in self.directory_default_parameters:
self.chown_directory(
create_path,
chown_value=self.directory_default_parameters['chmod'])
except OSError as error:
raise TemplateActionError(
'Failed to create directory: {}, reason: {}'.
format(create_path, str(error)))
def _append_remove_directory(self, target_path):
print("append = 'remove'")
if os.path.isdir(target_path) or os.path.exists(target_path):
try:
if os.path.islink(target_path):
os.unlink(target_path)
else:
shutil.rmtree(target_path)
return True
except Exception as error:
self.output.set_error("Failed to delete the directory: {}".
format(target_path))
self.output.set_error("Reason: {}".
format(str(error)))
return False
else:
self.output.set_error("Failed to delete the directory: {}".
format(target_path))
self.output.set_error(
"Target file is not directory or not exists.".
format(target_path))
return False
def _append_clear_directory(self, target_path):
print("append = 'clear'")
if os.path.isdir(target_path):
if os.path.exists(target_path):
try:
if os.path.islink(target_path):
os.unlink(target_path)
else:
shutil.rmtree(target_path)
return
except Exception as error:
raise TemplateActionError(
("Failed to delete the directory: {},"
"reason: {}").format(target_path,
str(error)))
else:
error_message = "target directory does not exist"
else:
error_message = "target file is not directory"
raise TemplateActionError(
"Failed to delete the directory: {}, reason: {}.".
format(target_path, error_message))
def _append_skip_directory(self, target_path):
print("append = 'skip'")
return
def _append_join_file(self, target_path):
print("append = 'join'")
if not self.template_parameters.format:
print('Format not defined.')
return
format_class = self.formats_classes[self.template_parameters.format]
if os.path.exists(target_path):
with open(target_path, 'r') as original_file:
original_file_text = original_file.read()
print('ORIGINAL:')
print(original_file_text)
else:
open(target_path, 'w').close()
original_file_text = ''
original_object = format_class(original_file_text)
template_object = format_class(self.template_text)
print('TEMPLATE:')
print(self.template_text)
original_object.join_template(template_object)
print('RESULT:')
print(original_object.document_text)
def _append_clear_file(self, target_path):
print("append = 'clear'")
try:
with open(target_path, 'w') as file:
file.truncate(0)
except IOError:
raise TemplateActionError("Failed to clear the file: {}".
format(target_path))
return False
template_engine.process_template_from_string(template_text, FILE)
template_parameters = template_engine.parameters
template_text = template_engine.template_text
template_action_obj = TemplateActionDraft(datavars_module=DATAVARS_MODULE,
chroot_path=CHROOT_PATH)
use_template(target_path, template_parameters) result = template_action_obj.use_file_template(target_path,
template_parameters,
template_text=template_text)

@ -0,0 +1,5 @@
[section one]
parameter_1 = value
[section two]
parameter_3 = value_3
Loading…
Cancel
Save