|
|
|
@ -97,7 +97,6 @@ class CalculateConfigFile:
|
|
|
|
|
def set_files_md5(self, file_path, file_md5):
|
|
|
|
|
file_path = self._remove_chroot(file_path)
|
|
|
|
|
self._config_dictionary[file_path] = file_md5
|
|
|
|
|
|
|
|
|
|
self._unsaved_changes = True
|
|
|
|
|
|
|
|
|
|
def remove_file(self, file_path):
|
|
|
|
@ -108,7 +107,10 @@ class CalculateConfigFile:
|
|
|
|
|
|
|
|
|
|
def compare_md5(self, file_path, file_md5):
|
|
|
|
|
file_path = self._remove_chroot(file_path)
|
|
|
|
|
return self._config_dictionary[file_path] == file_md5
|
|
|
|
|
if file_path in self._config_dictionary:
|
|
|
|
|
return self._config_dictionary[file_path] == file_md5
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def save_changes(self):
|
|
|
|
|
config_file = write_file(self.cl_config_path)
|
|
|
|
@ -144,7 +146,6 @@ class TemplateWrapper:
|
|
|
|
|
config_archive_path = '/var/lib/calculate/config-archive'
|
|
|
|
|
|
|
|
|
|
package_atom_parser = PackageAtomParser(chroot_path=chroot_path)
|
|
|
|
|
calculate_config_file = CalculateConfigFile()
|
|
|
|
|
|
|
|
|
|
_protected_is_set = False
|
|
|
|
|
_protected_set = {'/etc'}
|
|
|
|
@ -156,6 +157,10 @@ class TemplateWrapper:
|
|
|
|
|
|
|
|
|
|
self.target_package_name = None
|
|
|
|
|
|
|
|
|
|
# Вспомогательный флаг, включается, если по целевому пути лежит файл,
|
|
|
|
|
# для которого не определился никакой пакет.
|
|
|
|
|
self.target_without_package = False
|
|
|
|
|
|
|
|
|
|
self.parameters = parameters
|
|
|
|
|
|
|
|
|
|
self.output_path = self.target_path
|
|
|
|
@ -168,18 +173,8 @@ class TemplateWrapper:
|
|
|
|
|
# применением шаблона.
|
|
|
|
|
self.remove_original = False
|
|
|
|
|
|
|
|
|
|
# Флаг, разрешающий изменение хэш-суммы в contents после отработки
|
|
|
|
|
# шаблона.
|
|
|
|
|
self.update_contents = False
|
|
|
|
|
self.update_config = False
|
|
|
|
|
self.update_archive = False
|
|
|
|
|
|
|
|
|
|
# Флаг, указывающий, что нужно удалить все имеющиеся ._cfg????_filename
|
|
|
|
|
# файлы.
|
|
|
|
|
self.clean_cfg = False
|
|
|
|
|
self.clean_config = False
|
|
|
|
|
|
|
|
|
|
self.check_config = False
|
|
|
|
|
# Временный флаг для определения того, является ли шаблон userspace.
|
|
|
|
|
self.is_userspace = False
|
|
|
|
|
|
|
|
|
|
# Получаем класс соответствующего формата файла.
|
|
|
|
|
if self.parameters.format:
|
|
|
|
@ -271,109 +266,90 @@ class TemplateWrapper:
|
|
|
|
|
'''Проверка на предмет коллизии, то есть конфликта пакета шаблона и
|
|
|
|
|
целевого файла.'''
|
|
|
|
|
if self.parameters.package:
|
|
|
|
|
self.target_package_name = self.parameters.package
|
|
|
|
|
|
|
|
|
|
if self.target_type is None:
|
|
|
|
|
return
|
|
|
|
|
parameter_package = self.parameters.package
|
|
|
|
|
else:
|
|
|
|
|
parameter_package = None
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
file_package = self.package_atom_parser.get_file_package(
|
|
|
|
|
if self.target_type is not None:
|
|
|
|
|
try:
|
|
|
|
|
file_package = self.package_atom_parser.get_file_package(
|
|
|
|
|
self.target_path)
|
|
|
|
|
except PackageNotFound:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if self.target_package_name is None:
|
|
|
|
|
except PackageNotFound:
|
|
|
|
|
file_package = None
|
|
|
|
|
self.target_without_package = True
|
|
|
|
|
else:
|
|
|
|
|
file_package = None
|
|
|
|
|
|
|
|
|
|
# Если для шаблона и целевого файла никаким образом не удается
|
|
|
|
|
# определить пакет и есть параметр append -- шаблон пропускаем.
|
|
|
|
|
if parameter_package is None and file_package is None:
|
|
|
|
|
if self.parameters.append:
|
|
|
|
|
raise TemplateCollisionError(
|
|
|
|
|
"'package' parameter is not defined for"
|
|
|
|
|
" template with 'append' parameter.")
|
|
|
|
|
if parameter_package is None:
|
|
|
|
|
self.target_package_name = file_package
|
|
|
|
|
elif file_package != self.target_package_name:
|
|
|
|
|
|
|
|
|
|
if file_package is None:
|
|
|
|
|
self.target_package_name = parameter_package
|
|
|
|
|
|
|
|
|
|
if file_package != parameter_package:
|
|
|
|
|
raise TemplateCollisionError(
|
|
|
|
|
"The template package is {0} while target"
|
|
|
|
|
" file package is {1}").format(
|
|
|
|
|
self.target_package_name.atom,
|
|
|
|
|
file_package.atom
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
self.target_package_name = parameter_package
|
|
|
|
|
|
|
|
|
|
self.target_package = Package(self.target_package_name,
|
|
|
|
|
chroot_path=self.chroot_path)
|
|
|
|
|
|
|
|
|
|
def check_user_changes(self):
|
|
|
|
|
if (self.template_type is None or
|
|
|
|
|
if self.target_type is None:
|
|
|
|
|
self.md5_matching = True
|
|
|
|
|
elif self.target_without_package:
|
|
|
|
|
if self.parameters.autoupdate:
|
|
|
|
|
self.md5_matching = True
|
|
|
|
|
self.remove_original = True
|
|
|
|
|
else:
|
|
|
|
|
self.md5_matching = False
|
|
|
|
|
|
|
|
|
|
if (self.target_type is None or
|
|
|
|
|
self.target_package is None or
|
|
|
|
|
self.target_type != FILE):
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# Собираем список имеющихся ._cfg файлов.
|
|
|
|
|
cfg_pattern = os.path.join(os.path.dirname(self.target_path),
|
|
|
|
|
"._cfg????_{}".format(
|
|
|
|
|
os.path.basename(self.target_path)))
|
|
|
|
|
self.cfg_list = glob.glob(cfg_pattern)
|
|
|
|
|
|
|
|
|
|
target_md5 = self.target_package.get_md5(self.target_path)
|
|
|
|
|
md5_comparision_result = self.target_package.is_md5_equal(
|
|
|
|
|
self.md5_matching = self.target_package.is_md5_equal(
|
|
|
|
|
self.target_path,
|
|
|
|
|
file_md5=target_md5)
|
|
|
|
|
self.md5_matching = self.md5_matching or self.parameters.autoupdate
|
|
|
|
|
self.archive_path = self._get_archive_path(self.target_path)
|
|
|
|
|
|
|
|
|
|
if (self.parameters.autoupdate or md5_comparision_result):
|
|
|
|
|
if not self.cfg_list:
|
|
|
|
|
# Приоритет отдаем пути из параметра source.
|
|
|
|
|
if self.parameters.source:
|
|
|
|
|
self.input_path = self.parameters.source
|
|
|
|
|
else:
|
|
|
|
|
self.input_path = self.target_path
|
|
|
|
|
self.output_path = self.target_path
|
|
|
|
|
|
|
|
|
|
# Чем обновляем CONTENTS
|
|
|
|
|
self.update_contents = self.target_path
|
|
|
|
|
|
|
|
|
|
# Обновляем CA
|
|
|
|
|
# Должна быть какая-то проверка на предмет userspace.
|
|
|
|
|
self.update_archive = self._get_archive_path(self.target_path)
|
|
|
|
|
|
|
|
|
|
# Очищаем CL
|
|
|
|
|
self.clean_config = True
|
|
|
|
|
if self.md5_matching:
|
|
|
|
|
# Приоритет отдаем пути из параметра source.
|
|
|
|
|
if self.parameters.source:
|
|
|
|
|
self.input_path = self.parameters.source
|
|
|
|
|
else:
|
|
|
|
|
# Приоритет отдаем пути из параметра source.
|
|
|
|
|
if self.parameters.source:
|
|
|
|
|
self.input_path = self.parameters.source
|
|
|
|
|
else:
|
|
|
|
|
self.input_path = self.target_path
|
|
|
|
|
self.output_path = self.target_path
|
|
|
|
|
|
|
|
|
|
# Чем обновляем CONTENTS
|
|
|
|
|
self.update_contents = self.target_path
|
|
|
|
|
self.input_path = self.target_path
|
|
|
|
|
|
|
|
|
|
# Обновляем CA
|
|
|
|
|
# Должна быть какая-то проверка на предмет userspace.
|
|
|
|
|
self.update_archive = self._get_archive_path(self.target_path)
|
|
|
|
|
|
|
|
|
|
# Очищаем CL
|
|
|
|
|
self.clean_config = True
|
|
|
|
|
|
|
|
|
|
# Убираем имеющиеся ._cfg????_filename
|
|
|
|
|
self.clean_cfg = True
|
|
|
|
|
self.output_path = self.target_path
|
|
|
|
|
else:
|
|
|
|
|
if not self.cfg_list:
|
|
|
|
|
# Приоритет отдаем пути из параметра source.
|
|
|
|
|
if self.parameters.source:
|
|
|
|
|
self.input_path = self.parameters.source
|
|
|
|
|
else:
|
|
|
|
|
self.input_path = self._get_archive_path(self.target_path)
|
|
|
|
|
self.output_path = self._get_cfg_path(self.target_path)
|
|
|
|
|
|
|
|
|
|
# Чем обновляем CONTENTS
|
|
|
|
|
self.update_contents = self.output_path
|
|
|
|
|
|
|
|
|
|
# Oбновляем хэш-сумму в CL
|
|
|
|
|
self.update_config = self.output_path
|
|
|
|
|
|
|
|
|
|
self.check_config = True
|
|
|
|
|
# Приоритет отдаем пути из параметра source.
|
|
|
|
|
if self.parameters.source:
|
|
|
|
|
self.input_path = self.parameters.source
|
|
|
|
|
else:
|
|
|
|
|
# Приоритет отдаем пути из параметра source.
|
|
|
|
|
if self.parameters.source:
|
|
|
|
|
self.input_path = self.parameters.source
|
|
|
|
|
else:
|
|
|
|
|
self.input_path = self._get_archive_path(self.target_path)
|
|
|
|
|
self.output_path = self._get_cfg_path(self.target_path)
|
|
|
|
|
|
|
|
|
|
# Чем обновляем CONTENTS
|
|
|
|
|
self.update_contents = self.output_path
|
|
|
|
|
|
|
|
|
|
# Обновляем хэш-сумму в CL
|
|
|
|
|
self.update_config = self.output_path
|
|
|
|
|
self.input_path = self.archive_path
|
|
|
|
|
|
|
|
|
|
self.check_config = True
|
|
|
|
|
self.output_path = self._get_cfg_path(self.target_path)
|
|
|
|
|
|
|
|
|
|
def _get_archive_path(self, file_path):
|
|
|
|
|
if self.chroot_path != "/" and file_path.startswith(self.chroot_path):
|
|
|
|
@ -399,32 +375,16 @@ class TemplateWrapper:
|
|
|
|
|
|
|
|
|
|
return new_cfg_path
|
|
|
|
|
|
|
|
|
|
def _update_contents(self):
|
|
|
|
|
def remove_from_contents(self):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def use_format(self):
|
|
|
|
|
if self.format_class.EXECUTABLE:
|
|
|
|
|
# Для исполняемых форматов.
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if self.target_type is None:
|
|
|
|
|
original_file_text = ''
|
|
|
|
|
else:
|
|
|
|
|
original_file = open(target_path, 'r')
|
|
|
|
|
original_file_text = original_file.read()
|
|
|
|
|
original_file.close()
|
|
|
|
|
|
|
|
|
|
original_file = open(target_path, 'w')
|
|
|
|
|
|
|
|
|
|
original_object = self.format_class(original_file_text)
|
|
|
|
|
template_object = self.format_class(self.template_text)
|
|
|
|
|
original_object.join_template(template_object)
|
|
|
|
|
|
|
|
|
|
original_file.write(original_object.document_text)
|
|
|
|
|
original_file.close()
|
|
|
|
|
|
|
|
|
|
def accept_changes(self):
|
|
|
|
|
pass
|
|
|
|
|
def add_to_contents(self, file_md5=None):
|
|
|
|
|
if self.parameters.append == 'link':
|
|
|
|
|
self.target_package.add_sym(target_path, self.parameters.source)
|
|
|
|
|
elif self.template_type == DIR:
|
|
|
|
|
self.target_package.add_dir(target_path)
|
|
|
|
|
elif self.template_type == FILE:
|
|
|
|
|
self.target_package.add_obj(target_path, file_md5)
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def _set_protected(cls):
|
|
|
|
@ -464,12 +424,12 @@ class TemplateExecutor:
|
|
|
|
|
self.file_appends = {'join': self._append_join_file}
|
|
|
|
|
|
|
|
|
|
self.formats_classes = ParametersProcessor.available_formats
|
|
|
|
|
self.calculate_config_file = CalculateConfigFile(
|
|
|
|
|
cl_config_path=cl_config_path,
|
|
|
|
|
cl_chroot_path=chroot_path)
|
|
|
|
|
|
|
|
|
|
TemplateWrapper.chroot_path = self.chroot_path
|
|
|
|
|
TemplateWrapper.cl_config_archive = cl_config_archive
|
|
|
|
|
TemplateWrapper.calculate_config_file = CalculateConfigFile(
|
|
|
|
|
cl_config_path=cl_config_path,
|
|
|
|
|
cl_chroot_path=chroot_path)
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def available_appends(self):
|
|
|
|
@ -483,64 +443,119 @@ class TemplateExecutor:
|
|
|
|
|
print('Template parameters:')
|
|
|
|
|
parameters.print_parameters_for_debug()
|
|
|
|
|
|
|
|
|
|
# try:
|
|
|
|
|
template_object = TemplateWrapper(target_path, parameters,
|
|
|
|
|
template_type,
|
|
|
|
|
template_text=template_text)
|
|
|
|
|
# except TemplateTypeConflict as error:
|
|
|
|
|
# pass
|
|
|
|
|
try:
|
|
|
|
|
template_object = TemplateWrapper(target_path, parameters,
|
|
|
|
|
template_type,
|
|
|
|
|
template_text=template_text)
|
|
|
|
|
except TemplateTypeConflict as error:
|
|
|
|
|
print('type conflict: {}'.format(str(error)))
|
|
|
|
|
except TemplateCollisionError as error:
|
|
|
|
|
print('collision: {}'.format(str(error)))
|
|
|
|
|
|
|
|
|
|
if template_object.remove_original:
|
|
|
|
|
if template_object.target_type == DIR:
|
|
|
|
|
self._remove_directory(template_object.target_path)
|
|
|
|
|
else:
|
|
|
|
|
self._remove_file(template_object.target_path)
|
|
|
|
|
template_object.target_type = None
|
|
|
|
|
|
|
|
|
|
# Добавить поддержку run, excute и т.д.
|
|
|
|
|
self.directory_appends[template_object.parameters.append](
|
|
|
|
|
if template_object.template_type == DIR:
|
|
|
|
|
self.directory_appends[template_object.parameters.append](
|
|
|
|
|
template_object)
|
|
|
|
|
elif template_object.template_type == FILE:
|
|
|
|
|
self.file_appends[template_object.parameters.append](
|
|
|
|
|
template_object)
|
|
|
|
|
|
|
|
|
|
def _append_join_directory(self, template_object: TemplateWrapper):
|
|
|
|
|
pass
|
|
|
|
|
if template_object.target_type is None:
|
|
|
|
|
self._create_directory(template_object)
|
|
|
|
|
template_object.add_to_contents()
|
|
|
|
|
else:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def _append_remove_directory(self, template_object: TemplateWrapper):
|
|
|
|
|
pass
|
|
|
|
|
if template_object.target_type is not None:
|
|
|
|
|
self._remove_directory(template_object.target_path)
|
|
|
|
|
template_object.remove_from_contents()
|
|
|
|
|
else:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def _append_clear_directory(self, template_object: TemplateWrapper):
|
|
|
|
|
pass
|
|
|
|
|
if template_object.target_type is not None:
|
|
|
|
|
# Подумать об организации очистки CONTENTS для этого append.
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def _append_join_file(self, template_object: TemplateWrapper):
|
|
|
|
|
'''Метод описывающий действия при append = "join".'''
|
|
|
|
|
input_path = template_object.input_path
|
|
|
|
|
output_path = template_object.output_path
|
|
|
|
|
|
|
|
|
|
template_format = template_object.format_class
|
|
|
|
|
|
|
|
|
|
with open(input_path, 'r') as input_file:
|
|
|
|
|
input_text = input_file.read()
|
|
|
|
|
if template_object.md5_matching:
|
|
|
|
|
output_paths = [output_path]
|
|
|
|
|
# Проверка на предмет userspace.
|
|
|
|
|
if template_object.is_userspace:
|
|
|
|
|
output_paths.append(template_object.archive_path)
|
|
|
|
|
|
|
|
|
|
if template_object.target_type is not None:
|
|
|
|
|
with open(input_path, 'r') as input_file:
|
|
|
|
|
input_text = input_file.read()
|
|
|
|
|
else:
|
|
|
|
|
input_text = ''
|
|
|
|
|
parsed_input = template_format(input_text)
|
|
|
|
|
|
|
|
|
|
parsed_template = template_format(template_object.template_text)
|
|
|
|
|
parsed_input.join_template(parsed_template)
|
|
|
|
|
parsed_template = template_format(template_object.template_text)
|
|
|
|
|
|
|
|
|
|
parsed_input.join_template(parsed_template)
|
|
|
|
|
|
|
|
|
|
output_text = parsed_input.document_text
|
|
|
|
|
changed_file_md5 = hashlib.md5(output_text.encode()).hexdigest()
|
|
|
|
|
# Результат наложения шаблона.
|
|
|
|
|
output_text = parsed_input.document_text
|
|
|
|
|
# Удаляем форматный объект входного файла.
|
|
|
|
|
del(parsed_input)
|
|
|
|
|
output_text_md5 = hashlib.md5(output_text.encode()).hexdigest()
|
|
|
|
|
|
|
|
|
|
with open(output_path, 'w') as output_file:
|
|
|
|
|
output_file.write(parsed_input.document_text)
|
|
|
|
|
for save_path in output_paths:
|
|
|
|
|
with open(save_path, 'w') as output_file:
|
|
|
|
|
output_file.write(output_text)
|
|
|
|
|
|
|
|
|
|
if template_object.clean_cfg:
|
|
|
|
|
for cfg_file_path in template_object.cfg_list:
|
|
|
|
|
self._remove_file(cfg_file_path)
|
|
|
|
|
# Убираем все ._cfg файлы.
|
|
|
|
|
if template_object.cfg_list:
|
|
|
|
|
for cfg_file_path in template_object.cfg_list:
|
|
|
|
|
self._remove_file(cfg_file_path)
|
|
|
|
|
|
|
|
|
|
if template_object.update_archive:
|
|
|
|
|
with open(template_object.update_archive, 'r') as ca_file:
|
|
|
|
|
ca_text = ca_file.read()
|
|
|
|
|
parsed_ca = template_format(ca_text)
|
|
|
|
|
# Убираем целевой файл из CL.
|
|
|
|
|
self.calculate_config_file.remove_file(template_object.target_path)
|
|
|
|
|
|
|
|
|
|
parsed_ca.join_template(parsed_template)
|
|
|
|
|
ca_text = parsed_ca.document_text
|
|
|
|
|
# Обновляем CONTENTS.
|
|
|
|
|
template_object.add_to_contents(file_md5=output_text_md5)
|
|
|
|
|
else:
|
|
|
|
|
with open(input_path, 'r') as input_file:
|
|
|
|
|
input_text = input_file.read()
|
|
|
|
|
parsed_input = template_format(input_text)
|
|
|
|
|
|
|
|
|
|
parsed_template = template_format(template_object.template_text)
|
|
|
|
|
parsed_input.join_template(parsed_template)
|
|
|
|
|
|
|
|
|
|
# Результат наложения шаблона.
|
|
|
|
|
output_text = parsed_input.document_text
|
|
|
|
|
# Удаляем форматный объект входного файла.
|
|
|
|
|
del(parsed_input)
|
|
|
|
|
output_text_md5 = hashlib.md5(output_text.encode()).hexdigest()
|
|
|
|
|
|
|
|
|
|
if not self.calculate_config_file.compare_md5(target_path,
|
|
|
|
|
output_text_md5):
|
|
|
|
|
with open(output_path, 'w') as output_file:
|
|
|
|
|
output_file.write(output_text)
|
|
|
|
|
self.calculate_config_file.set_files_md5(template_object,
|
|
|
|
|
output_text_md5)
|
|
|
|
|
else:
|
|
|
|
|
# Действия если CL совпало. Пока ничего не делаем.
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
template_object._update_contents()
|
|
|
|
|
# Обновляем CONTENTS.
|
|
|
|
|
template_object.add_to_contents(file_md5=output_text_md5)
|
|
|
|
|
|
|
|
|
|
def _create_directory(self, template_object: TemplateWrapper):
|
|
|
|
|
target_path = template_object.target_path
|
|
|
|
|