|
|
@ -471,14 +471,30 @@ class TemplateWrapper:
|
|
|
|
if self.template_type == DIR:
|
|
|
|
if self.template_type == DIR:
|
|
|
|
self.target_package.clear_dir(self.target_path)
|
|
|
|
self.target_package.clear_dir(self.target_path)
|
|
|
|
|
|
|
|
|
|
|
|
def add_to_contents(self, file_md5=None):
|
|
|
|
def add_to_contents(self, file_md5=None, file_path=None):
|
|
|
|
'''Метод для добавления целевого файла в CONTENTS.'''
|
|
|
|
'''Метод для добавления целевого файла в CONTENTS.'''
|
|
|
|
if self.parameters.append == 'link':
|
|
|
|
if self.parameters.append == 'link':
|
|
|
|
self.target_package.add_sym(target_path, self.parameters.source)
|
|
|
|
self.target_package.add_sym(self.target_path,
|
|
|
|
|
|
|
|
self.parameters.source)
|
|
|
|
elif self.template_type == DIR:
|
|
|
|
elif self.template_type == DIR:
|
|
|
|
self.target_package.add_dir(target_path)
|
|
|
|
self.target_package.add_dir(self.target_path)
|
|
|
|
elif self.template_type == FILE:
|
|
|
|
elif self.template_type == FILE:
|
|
|
|
self.target_package.add_obj(target_path, file_md5)
|
|
|
|
self.target_package.add_obj(self.target_path, file_md5)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def update_contents_from_list(self, changed_list: dict):
|
|
|
|
|
|
|
|
for file_path, mode in changed_list.items():
|
|
|
|
|
|
|
|
if mode == "modify":
|
|
|
|
|
|
|
|
if os.path.islink(file_path):
|
|
|
|
|
|
|
|
self.target_package.add_sym(file_path)
|
|
|
|
|
|
|
|
elif os.path.isdir(file_path):
|
|
|
|
|
|
|
|
self.target_package.add_dir(file_path)
|
|
|
|
|
|
|
|
elif os.path.isfile(file_path):
|
|
|
|
|
|
|
|
self.target_package.add_obj(file_path)
|
|
|
|
|
|
|
|
elif mode == "remove":
|
|
|
|
|
|
|
|
if os.path.islink(file_path) or os.path.isfile(file_path):
|
|
|
|
|
|
|
|
self.target_package.remove_obj(file_path)
|
|
|
|
|
|
|
|
elif os.path.isdir(file_path):
|
|
|
|
|
|
|
|
self.target_package.add_dir(file_path)
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
@classmethod
|
|
|
|
def _set_protected(cls):
|
|
|
|
def _set_protected(cls):
|
|
|
@ -658,14 +674,32 @@ class TemplateExecutor:
|
|
|
|
if template_object.target_type is not None:
|
|
|
|
if template_object.target_type is not None:
|
|
|
|
self._clear_directory(template_object.target_path)
|
|
|
|
self._clear_directory(template_object.target_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Меняем права и владельца очищенной директории, если это
|
|
|
|
|
|
|
|
# необходимо.
|
|
|
|
|
|
|
|
if template_object.parameters.chmod:
|
|
|
|
|
|
|
|
self._chmod_directory(target_path,
|
|
|
|
|
|
|
|
template_object.parameters.chmod)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if template_object.parameters.chown:
|
|
|
|
|
|
|
|
self._chown_directory(target_path,
|
|
|
|
|
|
|
|
template_object.parameters.chown)
|
|
|
|
|
|
|
|
|
|
|
|
template_object.clear_dir_contents()
|
|
|
|
template_object.clear_dir_contents()
|
|
|
|
|
|
|
|
|
|
|
|
def _append_link_directory(self, template_object: TemplateWrapper):
|
|
|
|
def _append_link_directory(self, template_object: TemplateWrapper):
|
|
|
|
'''Метод описывающий действия для append = "link", если шаблон --
|
|
|
|
'''Метод описывающий действия для append = "link", если шаблон --
|
|
|
|
директория. Создает ссылку на директорию, если она есть.'''
|
|
|
|
директория. Создает ссылку на директорию, если она есть.'''
|
|
|
|
target = template_object.parameters.source
|
|
|
|
self._link_directory(template_object.parameters.source,
|
|
|
|
link_path = template_object.target_path
|
|
|
|
template_object.target_path)
|
|
|
|
self._link_directory(link_path, target)
|
|
|
|
|
|
|
|
|
|
|
|
# Меняем права и владельца файла, на который указывает ссылка.
|
|
|
|
|
|
|
|
if template_object.parameters.chmod:
|
|
|
|
|
|
|
|
self._chmod_directory(template_object.parameters.source,
|
|
|
|
|
|
|
|
template_object.parameters.chmod)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if template_object.parameters.chown:
|
|
|
|
|
|
|
|
self._chmod_directory(template_object.parameters.source,
|
|
|
|
|
|
|
|
template_object.parameters.chown)
|
|
|
|
|
|
|
|
|
|
|
|
template_object.add_to_contents()
|
|
|
|
template_object.add_to_contents()
|
|
|
|
|
|
|
|
|
|
|
@ -687,8 +721,33 @@ class TemplateExecutor:
|
|
|
|
output_path = template_object.output_path
|
|
|
|
output_path = template_object.output_path
|
|
|
|
|
|
|
|
|
|
|
|
template_format = template_object.format_class
|
|
|
|
template_format = template_object.format_class
|
|
|
|
|
|
|
|
print('target_path: ', template_object.target_path)
|
|
|
|
|
|
|
|
print('output_path: ', output_path)
|
|
|
|
|
|
|
|
|
|
|
|
if template_object.md5_matching:
|
|
|
|
# Задаемся значениями chmod и chown в зависимости от наличия или
|
|
|
|
|
|
|
|
# отсутствия файла.
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
chmod = template_parameters.chmod
|
|
|
|
|
|
|
|
if not chmod:
|
|
|
|
|
|
|
|
chmod = self._get_file_mode(template_object.target_path)
|
|
|
|
|
|
|
|
elif template_object.target_type is not None:
|
|
|
|
|
|
|
|
chmod = self.directory_default_parameters.get('chmod',
|
|
|
|
|
|
|
|
False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
chown = template_parameters.chown
|
|
|
|
|
|
|
|
if not chown:
|
|
|
|
|
|
|
|
chown = self._get_file_owner(template_object.target_path)
|
|
|
|
|
|
|
|
elif template_object.target_type is not None:
|
|
|
|
|
|
|
|
chown = self.directory_default_parameters.get('chown',
|
|
|
|
|
|
|
|
False)
|
|
|
|
|
|
|
|
except OSError:
|
|
|
|
|
|
|
|
raise TemplateExecutorError('No access to the directory: {}'.
|
|
|
|
|
|
|
|
format(template_object.target_path))
|
|
|
|
|
|
|
|
print('chmod: ', chmod)
|
|
|
|
|
|
|
|
print('chown: ', chown)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if template_object.format_class.EXECUTABLE or\
|
|
|
|
|
|
|
|
template_object.md5_matching:
|
|
|
|
# Действия при совпадении md5 из CONTENTS и md5 целевого файла.
|
|
|
|
# Действия при совпадении md5 из CONTENTS и md5 целевого файла.
|
|
|
|
output_paths = [output_path]
|
|
|
|
output_paths = [output_path]
|
|
|
|
|
|
|
|
|
|
|
@ -719,14 +778,14 @@ class TemplateExecutor:
|
|
|
|
with open(save_path, 'w') as output_file:
|
|
|
|
with open(save_path, 'w') as output_file:
|
|
|
|
output_file.write(output_text)
|
|
|
|
output_file.write(output_text)
|
|
|
|
|
|
|
|
|
|
|
|
if template_object.parameters.chown:
|
|
|
|
# Меняем права доступа и владельца всех сохраняемых файлов,
|
|
|
|
self.chown_file(save_path,
|
|
|
|
# если это необходимо.
|
|
|
|
template_object.parameters.chown,
|
|
|
|
if chown:
|
|
|
|
|
|
|
|
self.chown_file(save_path, chown,
|
|
|
|
check_existation=False)
|
|
|
|
check_existation=False)
|
|
|
|
|
|
|
|
|
|
|
|
if template_object.parameters.chmod:
|
|
|
|
if chmod:
|
|
|
|
self.chmod_file(save_path,
|
|
|
|
self.chmod_file(save_path, chmod,
|
|
|
|
template_object.parameters.chmod,
|
|
|
|
|
|
|
|
check_existation=False)
|
|
|
|
check_existation=False)
|
|
|
|
|
|
|
|
|
|
|
|
# Убираем все ._cfg файлы.
|
|
|
|
# Убираем все ._cfg файлы.
|
|
|
@ -746,24 +805,30 @@ class TemplateExecutor:
|
|
|
|
template_object.add_to_contents(
|
|
|
|
template_object.add_to_contents(
|
|
|
|
file_md5=output_text_md5)
|
|
|
|
file_md5=output_text_md5)
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
parsed_template.execute_format(
|
|
|
|
changed_files = parsed_template.execute_format(
|
|
|
|
input_text=input_text,
|
|
|
|
input_text=input_text,
|
|
|
|
target_path=template_object.target_path)
|
|
|
|
target_path=template_object.target_path)
|
|
|
|
# Удаляем форматный объект входного файла.
|
|
|
|
# Удаляем форматный объект входного файла.
|
|
|
|
del(parsed_template)
|
|
|
|
del(parsed_template)
|
|
|
|
|
|
|
|
# Если исполняемый формат выдал список измененных файлов для
|
|
|
|
|
|
|
|
# изменения CONTENTS -- обновляем CONTENTS.
|
|
|
|
|
|
|
|
if changed_files:
|
|
|
|
|
|
|
|
template_object.update_contents_from_list(changed_files)
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
if template_object.target_type is not None and not replace:
|
|
|
|
if template_object.target_type is not None and not replace:
|
|
|
|
with open(input_path, 'r') as input_file:
|
|
|
|
with open(input_path, 'r') as input_file:
|
|
|
|
input_text = input_file.read()
|
|
|
|
input_text = input_file.read()
|
|
|
|
parsed_input = template_format(input_text)
|
|
|
|
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
input_text = ''
|
|
|
|
input_text = ''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
parsed_input = template_format(input_text)
|
|
|
|
parsed_template = template_format(template_object.template_text)
|
|
|
|
parsed_template = template_format(template_object.template_text)
|
|
|
|
|
|
|
|
|
|
|
|
parsed_input.join_template(parsed_template)
|
|
|
|
parsed_input.join_template(parsed_template)
|
|
|
|
|
|
|
|
|
|
|
|
# Результат наложения шаблона.
|
|
|
|
# Результат наложения шаблона.
|
|
|
|
output_text = parsed_input.document_text
|
|
|
|
output_text = parsed_input.document_text
|
|
|
|
|
|
|
|
|
|
|
|
# Удаляем форматный объект входного файла.
|
|
|
|
# Удаляем форматный объект входного файла.
|
|
|
|
del(parsed_input)
|
|
|
|
del(parsed_input)
|
|
|
|
output_text_md5 = hashlib.md5(output_text.encode()).hexdigest()
|
|
|
|
output_text_md5 = hashlib.md5(output_text.encode()).hexdigest()
|
|
|
@ -773,16 +838,18 @@ class TemplateExecutor:
|
|
|
|
with open(output_path, 'w') as output_file:
|
|
|
|
with open(output_path, 'w') as output_file:
|
|
|
|
output_file.write(output_text)
|
|
|
|
output_file.write(output_text)
|
|
|
|
|
|
|
|
|
|
|
|
if template_object.parameters.chown:
|
|
|
|
# Меняем права доступа и владельца ._cfg????_ файлов, если
|
|
|
|
self.chown_file(output_path,
|
|
|
|
# это необходимо.
|
|
|
|
template_object.parameters.chown,
|
|
|
|
if chown:
|
|
|
|
|
|
|
|
self.chown_file(output_path, chown,
|
|
|
|
check_existation=False)
|
|
|
|
check_existation=False)
|
|
|
|
|
|
|
|
|
|
|
|
if template_object.parameters.chmod:
|
|
|
|
if chmod:
|
|
|
|
self.chmod_file(output_file,
|
|
|
|
self.chmod_file(output_file,
|
|
|
|
template_object.parameters.chmod,
|
|
|
|
template_object.parameters.chmod,
|
|
|
|
check_existation=False)
|
|
|
|
check_existation=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Обновляем CL.
|
|
|
|
self.calculate_config_file.set_files_md5(
|
|
|
|
self.calculate_config_file.set_files_md5(
|
|
|
|
template_object.target_path,
|
|
|
|
template_object.target_path,
|
|
|
|
output_text_md5)
|
|
|
|
output_text_md5)
|
|
|
@ -794,90 +861,125 @@ class TemplateExecutor:
|
|
|
|
template_object.add_to_contents(file_md5=output_text_md5)
|
|
|
|
template_object.add_to_contents(file_md5=output_text_md5)
|
|
|
|
|
|
|
|
|
|
|
|
def _append_after_file(self, template_object: TemplateWrapper):
|
|
|
|
def _append_after_file(self, template_object: TemplateWrapper):
|
|
|
|
|
|
|
|
'''Метод описывающий действия при append = "after", если шаблон --
|
|
|
|
|
|
|
|
файл. Объединяет шаблон с целевым файлом так, чтобы текст добавлялся
|
|
|
|
|
|
|
|
в конец файла и в конец каждой секции файла.'''
|
|
|
|
self._append_join_file(template_object, join_before=False)
|
|
|
|
self._append_join_file(template_object, join_before=False)
|
|
|
|
|
|
|
|
|
|
|
|
def _append_before_file(self, template_object: TemplateWrapper):
|
|
|
|
def _append_before_file(self, template_object: TemplateWrapper):
|
|
|
|
|
|
|
|
'''Метод описывающий действия при append = "after", если шаблон --
|
|
|
|
|
|
|
|
файл. Объединяет шаблон с целевым файлом так, чтобы текст добавлялся
|
|
|
|
|
|
|
|
в начало файла и в начало каждой секции файла.'''
|
|
|
|
self._append_join_file(template_object, join_before=True)
|
|
|
|
self._append_join_file(template_object, join_before=True)
|
|
|
|
|
|
|
|
|
|
|
|
def _append_skip_file(self, template_object: TemplateWrapper):
|
|
|
|
def _append_skip_file(self, template_object: TemplateWrapper):
|
|
|
|
|
|
|
|
'''Метод описывающий действия при append = "skip". Пока никаких
|
|
|
|
|
|
|
|
действий.'''
|
|
|
|
pass
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
def _append_replace_file(self, template_object: TemplateWrapper):
|
|
|
|
def _append_replace_file(self, template_object: TemplateWrapper):
|
|
|
|
|
|
|
|
'''Метод описывающий действия при append = "replace", если шаблон --
|
|
|
|
|
|
|
|
файл. Очищает файл и затем накладывает на него шаблон.'''
|
|
|
|
self._append_join_file(template_object, replace=True)
|
|
|
|
self._append_join_file(template_object, replace=True)
|
|
|
|
|
|
|
|
|
|
|
|
def _append_remove_file(self, template_object: TemplateWrapper):
|
|
|
|
def _append_remove_file(self, template_object: TemplateWrapper):
|
|
|
|
|
|
|
|
'''Метод описывающий действия при append = "remove", если шаблон --
|
|
|
|
|
|
|
|
файл. Удаляет файл.'''
|
|
|
|
if template_object.target_type is not None:
|
|
|
|
if template_object.target_type is not None:
|
|
|
|
self._remove_file(template_object.target_path)
|
|
|
|
self._remove_file(template_object.target_path)
|
|
|
|
|
|
|
|
|
|
|
|
template_object.remove_from_contents()
|
|
|
|
template_object.remove_from_contents()
|
|
|
|
|
|
|
|
|
|
|
|
def _append_clear_file(self, template_object: TemplateWrapper):
|
|
|
|
def _append_clear_file(self, template_object: TemplateWrapper):
|
|
|
|
|
|
|
|
'''Метод описывающий действия при append = "clear", если шаблон --
|
|
|
|
|
|
|
|
файл. Очищает файл.'''
|
|
|
|
if template_object.target_type is not None:
|
|
|
|
if template_object.target_type is not None:
|
|
|
|
self._clear_file(template_object.target_path)
|
|
|
|
self._clear_file(template_object.target_path)
|
|
|
|
else:
|
|
|
|
|
|
|
|
open(template_object.target_path, 'w').close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template_object.add_to_contents()
|
|
|
|
# Меняем владельца и права доступа к очищенному файлу, если нужно.
|
|
|
|
|
|
|
|
if template_object.chown:
|
|
|
|
|
|
|
|
self.chown_file(template_object.target_path,
|
|
|
|
|
|
|
|
template_object.parameters.chown)
|
|
|
|
|
|
|
|
|
|
|
|
def _append_link_file(self, template_object: TemplateWrapper):
|
|
|
|
if template_object.chmod:
|
|
|
|
if template_object.target_type is not None:
|
|
|
|
self.chmod_file(template_object.target_path,
|
|
|
|
self._link_file(template_object.target_path,
|
|
|
|
template_object.parameters.chown)
|
|
|
|
template_object.parameters.source)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template_object.add_to_contents()
|
|
|
|
template_object.add_to_contents()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _append_link_file(self, template_object: TemplateWrapper):
|
|
|
|
|
|
|
|
'''Метод описывающий действия при append = "link", если шаблон --
|
|
|
|
|
|
|
|
файл. Создает ссылку на файл, указанный в параметре source.'''
|
|
|
|
|
|
|
|
self._link_file(template_object.parameters.source,
|
|
|
|
|
|
|
|
template_object.parameters.target_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Меняем права и владельца файла, на который указывает ссылка.
|
|
|
|
|
|
|
|
if template_object.parameters.chmod:
|
|
|
|
|
|
|
|
self.chmod_file(template_object.parameters.source,
|
|
|
|
|
|
|
|
template_object.parameters.chmod)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if template_object.parameters.chown:
|
|
|
|
|
|
|
|
self.chmod_file(template_object.parameters.source,
|
|
|
|
|
|
|
|
template_object.parameters.chown)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template_object.add_to_contents()
|
|
|
|
|
|
|
|
|
|
|
|
def _create_directory(self, template_object: TemplateWrapper):
|
|
|
|
def _create_directory(self, template_object: TemplateWrapper):
|
|
|
|
'''Метод для создания директории и, при необходимости, изменения
|
|
|
|
'''Метод для создания директории и, при необходимости, изменения
|
|
|
|
владельца и доступа все директорий на пути к целевой.'''
|
|
|
|
владельца и доступа все директорий на пути к целевой.'''
|
|
|
|
target_path = template_object.target_path
|
|
|
|
target_path = template_object.target_path
|
|
|
|
template_parameters = template_object.parameters
|
|
|
|
template_parameters = template_object.parameters
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Если файл есть, но указан chmod или chown -- используем их.
|
|
|
|
if os.access(target_path, os.F_OK):
|
|
|
|
if os.access(target_path, os.F_OK):
|
|
|
|
if template_parameters.chmod:
|
|
|
|
if template_parameters.chmod:
|
|
|
|
self.chmod_directory(target_path)
|
|
|
|
self._chmod_directory(target_path, template_parameters.chmod)
|
|
|
|
|
|
|
|
|
|
|
|
if self.template_parameters.chown:
|
|
|
|
if template_parameters.chown:
|
|
|
|
self.chown_directory(target_path)
|
|
|
|
self._chown_directory(target_path, template_parameters.chown)
|
|
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
directories_to_create = [target_path]
|
|
|
|
directories_to_create = [target_path]
|
|
|
|
directory_path = os.path.dirname(target_path)
|
|
|
|
directory_path = os.path.dirname(target_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Составляем список путей к директориям, которые нужно создать.
|
|
|
|
while not os.access(directory_path, os.F_OK) and directory_path:
|
|
|
|
while not os.access(directory_path, os.F_OK) and directory_path:
|
|
|
|
directories_to_create.append(directory_path)
|
|
|
|
directories_to_create.append(directory_path)
|
|
|
|
directory_path = os.path.dirname(directory_path)
|
|
|
|
directory_path = os.path.dirname(directory_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# получаем информацию о владельце и правах доступа ближайшей
|
|
|
|
|
|
|
|
# существующей директории.
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
current_mod, current_uid, current_gid = self.get_file_info(
|
|
|
|
chmod = template_parameters.chmod
|
|
|
|
directory_path,
|
|
|
|
if not chmod:
|
|
|
|
'all')
|
|
|
|
chmod = self._get_file_mode(directory_path)
|
|
|
|
current_owner = {'uid': current_uid, 'gid': current_gid}
|
|
|
|
else:
|
|
|
|
|
|
|
|
chmod = self.directory_default_parameters.get('chmod', False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
chown = template_parameters.chown
|
|
|
|
|
|
|
|
if not chown:
|
|
|
|
|
|
|
|
chown = self._get_file_owner(directory_path)
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
chown = self.directory_default_parameters.get('chown', False)
|
|
|
|
except OSError:
|
|
|
|
except OSError:
|
|
|
|
raise TemplateExecutorError('No access to the directory: {}'.
|
|
|
|
raise TemplateExecutorError('No access to the directory: {}'.
|
|
|
|
format(directory_path))
|
|
|
|
format(directory_path))
|
|
|
|
|
|
|
|
|
|
|
|
directories_to_create.reverse()
|
|
|
|
directories_to_create.reverse()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# создаем директории.
|
|
|
|
for create_path in directories_to_create:
|
|
|
|
for create_path in directories_to_create:
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
os.mkdir(create_path)
|
|
|
|
os.mkdir(create_path)
|
|
|
|
|
|
|
|
|
|
|
|
if (template_parameters.chmod and
|
|
|
|
# Для каждой созданной директории меняем права и владельца
|
|
|
|
template_parameters.chmod != current_mod):
|
|
|
|
# если это необходимо.
|
|
|
|
self.chmod_directory(create_path)
|
|
|
|
if chmod:
|
|
|
|
elif 'chmod' in self.directory_default_parameters:
|
|
|
|
self._chmod_directory(create_path, chmod)
|
|
|
|
self.chmod_directory(
|
|
|
|
|
|
|
|
create_path,
|
|
|
|
if chown:
|
|
|
|
chmod_value=self.directory_default_parameters['chown'])
|
|
|
|
self._chown_directory(create_path, chown)
|
|
|
|
|
|
|
|
|
|
|
|
if (template_parameters.chown and
|
|
|
|
|
|
|
|
template_parameters.chown != current_owner):
|
|
|
|
|
|
|
|
self.chown_directory(create_path)
|
|
|
|
|
|
|
|
elif 'chown' in self.directory_default_parameters:
|
|
|
|
|
|
|
|
self.chown_directory(
|
|
|
|
|
|
|
|
create_path,
|
|
|
|
|
|
|
|
chown_value=self.directory_default_parameters['chmod'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
except OSError as error:
|
|
|
|
except OSError as error:
|
|
|
|
raise TemplateExecutorError(
|
|
|
|
raise TemplateExecutorError(
|
|
|
@ -911,11 +1013,13 @@ class TemplateExecutor:
|
|
|
|
'''Метод для очистки содержимого целевой директории.'''
|
|
|
|
'''Метод для очистки содержимого целевой директории.'''
|
|
|
|
if os.path.exists(target_path):
|
|
|
|
if os.path.exists(target_path):
|
|
|
|
if os.path.isdir(target_path):
|
|
|
|
if os.path.isdir(target_path):
|
|
|
|
|
|
|
|
# Удаляем все содержимое директории.
|
|
|
|
for node in os.scandir(target_path):
|
|
|
|
for node in os.scandir(target_path):
|
|
|
|
if node.is_dir():
|
|
|
|
if node.is_dir():
|
|
|
|
self._remove_directory(node.path)
|
|
|
|
self._remove_directory(node.path)
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
self._remove_file(node.path)
|
|
|
|
self._remove_file(node.path)
|
|
|
|
|
|
|
|
return
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
error_message = "target file is not directory"
|
|
|
|
error_message = "target file is not directory"
|
|
|
|
else:
|
|
|
|
else:
|
|
|
@ -925,7 +1029,7 @@ class TemplateExecutor:
|
|
|
|
" reason: {}").format(target_path,
|
|
|
|
" reason: {}").format(target_path,
|
|
|
|
error_message))
|
|
|
|
error_message))
|
|
|
|
|
|
|
|
|
|
|
|
def _link_directory(self, target_path, source):
|
|
|
|
def _link_directory(self, source, target_path):
|
|
|
|
'''Метод для создания по целевому пути ссылки на директорию
|
|
|
|
'''Метод для создания по целевому пути ссылки на директорию
|
|
|
|
расположенную на пути, указанному в source.'''
|
|
|
|
расположенную на пути, указанному в source.'''
|
|
|
|
try:
|
|
|
|
try:
|
|
|
@ -958,7 +1062,7 @@ class TemplateExecutor:
|
|
|
|
raise TemplateExecutorError("failed to clear the file: {}".
|
|
|
|
raise TemplateExecutorError("failed to clear the file: {}".
|
|
|
|
format(target_path))
|
|
|
|
format(target_path))
|
|
|
|
|
|
|
|
|
|
|
|
def _link_file(self, target_path, source):
|
|
|
|
def _link_file(self, source, target_path):
|
|
|
|
'''Метод для создания по целевому пути ссылки на файл расположенный на
|
|
|
|
'''Метод для создания по целевому пути ссылки на файл расположенный на
|
|
|
|
пути, указанному в source.'''
|
|
|
|
пути, указанному в source.'''
|
|
|
|
try:
|
|
|
|
try:
|
|
|
@ -968,52 +1072,6 @@ class TemplateExecutor:
|
|
|
|
"Failed to create symlink to the file: {0} -> {1}".
|
|
|
|
"Failed to create symlink to the file: {0} -> {1}".
|
|
|
|
format(target_path, self.source))
|
|
|
|
format(target_path, self.source))
|
|
|
|
|
|
|
|
|
|
|
|
def chown_directory(self, target_path, chown_value={}):
|
|
|
|
|
|
|
|
"""Метод для смены владельца директории."""
|
|
|
|
|
|
|
|
if not chown_value:
|
|
|
|
|
|
|
|
chown_value = self.template_parameters.chown
|
|
|
|
|
|
|
|
print('chown value = {}'.format(chown_value))
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
os.chown(target_path, chown_value['uid'], chown_value['gid'])
|
|
|
|
|
|
|
|
except (OSError, Exception) as error:
|
|
|
|
|
|
|
|
# возможно потребуются дополнительные проверки.
|
|
|
|
|
|
|
|
raise TemplateExecutorError(
|
|
|
|
|
|
|
|
'Can not chown directory: {0}, reason: {1}'.
|
|
|
|
|
|
|
|
format(target_path, str(error)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def chmod_directory(self, target_path, chmod_value=False):
|
|
|
|
|
|
|
|
'''Метод для смены прав доступа к директории.'''
|
|
|
|
|
|
|
|
if not chmod_value:
|
|
|
|
|
|
|
|
chmod_value = self.template_parameters.chmod
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
os.chmod(target_path, chmod_value)
|
|
|
|
|
|
|
|
except (OSError, Exception) as error:
|
|
|
|
|
|
|
|
# возможно потребуются дополнительные проверки.
|
|
|
|
|
|
|
|
self.output.set_error('Can not chmod directory: {0}, reason: {1}'.
|
|
|
|
|
|
|
|
format(target_path, str(error)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def chown_file(self, target_path, chown_value, check_existation=True):
|
|
|
|
|
|
|
|
'''Метод для смены владельца файла.'''
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
if check_existation and not os.path.exists(target_path):
|
|
|
|
|
|
|
|
open(target_path, 'w').close()
|
|
|
|
|
|
|
|
os.lchown(target_path, chown_value['uid'], chown_value['gid'])
|
|
|
|
|
|
|
|
except (OSError, Exception) as error:
|
|
|
|
|
|
|
|
# возможно потребуются дополнительные проверки.
|
|
|
|
|
|
|
|
raise TemplateExecutorError('Can not chown file: {0}, reason: {1}'.
|
|
|
|
|
|
|
|
format(target_path, str(error)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def chmod_file(self, target_path, chmod_value, check_existation=True):
|
|
|
|
|
|
|
|
'''Метод для смены прав доступа к директории.'''
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
if check_existation and not os.path.exists(target_path):
|
|
|
|
|
|
|
|
open(target_path, 'w').close()
|
|
|
|
|
|
|
|
os.chmod(target_path, chmod_value)
|
|
|
|
|
|
|
|
except (OSError, Exception) as error:
|
|
|
|
|
|
|
|
# возможно потребуются дополнительные проверки.
|
|
|
|
|
|
|
|
raise TemplateExecutorError('Can not chmod file: {0}, reason: {1}'.
|
|
|
|
|
|
|
|
format(target_path, str(error)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _run_template(self, template_object: TemplateWrapper):
|
|
|
|
def _run_template(self, template_object: TemplateWrapper):
|
|
|
|
'''Метод для сохранения текста шаблонов, который должен быть исполнен
|
|
|
|
'''Метод для сохранения текста шаблонов, который должен быть исполнен
|
|
|
|
интерпретатором указанным в run прямо во время обработки шаблонов.'''
|
|
|
|
интерпретатором указанным в run прямо во время обработки шаблонов.'''
|
|
|
@ -1045,18 +1103,24 @@ class TemplateExecutor:
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
text_to_run = template_object.template_text
|
|
|
|
text_to_run = template_object.template_text
|
|
|
|
interpreter = template_object.parameters.exec
|
|
|
|
interpreter = template_object.parameters.exec
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Получаем путь к директории для хранения файлов .execute.
|
|
|
|
if (self.chroot_path != '/' and not
|
|
|
|
if (self.chroot_path != '/' and not
|
|
|
|
self.exec_files_directory.startswith(self.chroot_path)):
|
|
|
|
self.exec_files_directory.startswith(self.chroot_path)):
|
|
|
|
exec_files_directory = join_paths(self.chroot_path,
|
|
|
|
exec_files_directory = join_paths(self.chroot_path,
|
|
|
|
'/var/lib/calculate/.execute/')
|
|
|
|
'/var/lib/calculate/.execute/')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Если директория уже существует получаем номер очередного файла для
|
|
|
|
|
|
|
|
# exec по номеру последнего.
|
|
|
|
exec_number = 0
|
|
|
|
exec_number = 0
|
|
|
|
if os.path.exists(exec_files_directory):
|
|
|
|
if os.path.exists(exec_files_directory):
|
|
|
|
exec_files_list = os.listdir(exec_files_directory)
|
|
|
|
exec_files_list = os.listdir(exec_files_directory)
|
|
|
|
if exec_files_list:
|
|
|
|
if exec_files_list:
|
|
|
|
exec_number = int(exec_files_list[-1][-4:])
|
|
|
|
exec_number = int(exec_files_list[-1][-4:])
|
|
|
|
|
|
|
|
|
|
|
|
exec_number = str(exec_number + 1)
|
|
|
|
exec_number = str(exec_number + 1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Получаем название нового exec_???? файла.
|
|
|
|
if len(exec_number) < 4:
|
|
|
|
if len(exec_number) < 4:
|
|
|
|
exec_number = '0' * (4 - len(exec_number)) + exec_number
|
|
|
|
exec_number = '0' * (4 - len(exec_number)) + exec_number
|
|
|
|
exec_file_name = 'exec_{}'.format(exec_number)
|
|
|
|
exec_file_name = 'exec_{}'.format(exec_number)
|
|
|
@ -1067,63 +1131,119 @@ class TemplateExecutor:
|
|
|
|
exec_file.write(text_to_run)
|
|
|
|
exec_file.write(text_to_run)
|
|
|
|
exec_file.close()
|
|
|
|
exec_file.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Добавляем новый файл в словарь файлов для дальнейшего исполнения.
|
|
|
|
self.executor_output['exec_file'] = {interpreter: exec_file_name}
|
|
|
|
self.executor_output['exec_file'] = {interpreter: exec_file_name}
|
|
|
|
|
|
|
|
|
|
|
|
def get_file_info(self, path, info='all'):
|
|
|
|
def _chown_directory(self, target_path, chown_value):
|
|
|
|
file_stat = os.stat(path)
|
|
|
|
"""Метод для смены владельца директории."""
|
|
|
|
if info == 'all':
|
|
|
|
try:
|
|
|
|
return stat.S_IMODE(file_stat.st_mode), file_stat.st_uid,\
|
|
|
|
os.chown(target_path, chown_value['uid'], chown_value['gid'])
|
|
|
|
file_stat.st_gid
|
|
|
|
except (OSError, Exception) as error:
|
|
|
|
if info == 'mode':
|
|
|
|
if not self._check_os_error(error, target_path):
|
|
|
|
return stat.S_IMODE(file_stat.st_mode)
|
|
|
|
raise TemplateExecutorError(
|
|
|
|
if info == 'owner':
|
|
|
|
'Can not chown file: {0} to {1}, reason: {2}'.
|
|
|
|
return file_stat.st_uid, file_stat.st_gid
|
|
|
|
format(target_path, self._translate_uid_gid(
|
|
|
|
|
|
|
|
target_path,
|
|
|
|
def set_uid_gid_error(self, path, uid, gid, template_path=''):
|
|
|
|
chown_value['uid'],
|
|
|
|
|
|
|
|
chown_value['gid']),
|
|
|
|
|
|
|
|
str(error)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _chmod_directory(self, target_path, chmod_value):
|
|
|
|
|
|
|
|
'''Метод для смены прав доступа к директории.'''
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
os.chmod(target_path, chmod_value)
|
|
|
|
|
|
|
|
except (OSError, Exception) as error:
|
|
|
|
|
|
|
|
if not self._check_os_error(error, target_path):
|
|
|
|
|
|
|
|
self.output.set_error(
|
|
|
|
|
|
|
|
'Can not chmod directory: {0}, reason: {1}'.
|
|
|
|
|
|
|
|
format(target_path, str(error)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def chown_file(self, target_path, chown_value, check_existation=True):
|
|
|
|
|
|
|
|
'''Метод для смены владельца файла.'''
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
if check_existation and not os.path.exists(target_path):
|
|
|
|
|
|
|
|
open(target_path, 'w').close()
|
|
|
|
|
|
|
|
os.lchown(target_path, chown_value['uid'], chown_value['gid'])
|
|
|
|
|
|
|
|
except (OSError, Exception) as error:
|
|
|
|
|
|
|
|
if not self._check_os_error(error, target_path):
|
|
|
|
|
|
|
|
raise TemplateExecutorError(
|
|
|
|
|
|
|
|
'Can not chown file: {0} to {1}, reason: {2}'.
|
|
|
|
|
|
|
|
format(target_path, self._translate_uid_gid(
|
|
|
|
|
|
|
|
target_path,
|
|
|
|
|
|
|
|
chown_value['uid'],
|
|
|
|
|
|
|
|
chown_value['gid']),
|
|
|
|
|
|
|
|
str(error)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def chmod_file(self, target_path, chmod_value, check_existation=True):
|
|
|
|
|
|
|
|
'''Метод для смены прав доступа к директории.'''
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
if check_existation and not os.path.exists(target_path):
|
|
|
|
|
|
|
|
open(target_path, 'w').close()
|
|
|
|
|
|
|
|
os.chmod(target_path, chmod_value)
|
|
|
|
|
|
|
|
except (OSError, Exception) as error:
|
|
|
|
|
|
|
|
if not self._check_os_error(error, target_path):
|
|
|
|
|
|
|
|
raise TemplateExecutorError(
|
|
|
|
|
|
|
|
'Can not chmod file: {0}, reason: {1}'.
|
|
|
|
|
|
|
|
format(target_path, str(error)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _get_file_mode(self, file_path):
|
|
|
|
|
|
|
|
'''Метод для получения прав доступа для указанного файла.'''
|
|
|
|
|
|
|
|
file_stat = os.stat(file_path)
|
|
|
|
|
|
|
|
return stat.S_IMODE(file_stat.st_mode)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _get_file_owner(self, file_path):
|
|
|
|
|
|
|
|
'''Метод для получения uid и gid значений для владельца указанного
|
|
|
|
|
|
|
|
файла.'''
|
|
|
|
|
|
|
|
file_stat = os.stat(file_path)
|
|
|
|
|
|
|
|
return {'uid': file_stat.st_uid, 'gid': file_stat.st_gid}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _translate_uid_gid(self, target_path, uid, gid):
|
|
|
|
|
|
|
|
'''Метод для получения из uid и gid имен пользователя и группы при,
|
|
|
|
|
|
|
|
необходимых для выдачи сообщения об ошибке при попытке chown.'''
|
|
|
|
import pwd
|
|
|
|
import pwd
|
|
|
|
import grp
|
|
|
|
import grp
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
user_name = pwd.getpwuid(uid).pw_name
|
|
|
|
if self.chroot_path == '/':
|
|
|
|
|
|
|
|
user_name = pwd.getpwuid(uid).pw_name
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
user_name = str(uid)
|
|
|
|
except (TypeError, KeyError):
|
|
|
|
except (TypeError, KeyError):
|
|
|
|
user_name = str(uid)
|
|
|
|
user_name = str(uid)
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
group_name = grp.getgrgid(gid).gr_name
|
|
|
|
if self.chroot_path == '/':
|
|
|
|
|
|
|
|
group_name = grp.getgrgid(gid).gr_name
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
user_name = str(gid)
|
|
|
|
except (TypeError, KeyError):
|
|
|
|
except (TypeError, KeyError):
|
|
|
|
group_name = str(gid)
|
|
|
|
group_name = str(gid)
|
|
|
|
owner = '{0}:{1}'.format(user_name, group_name)
|
|
|
|
|
|
|
|
if template_path:
|
|
|
|
|
|
|
|
self.output.set_error('Failed to process template file {}'.
|
|
|
|
|
|
|
|
template_path)
|
|
|
|
|
|
|
|
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
|
|
|
# !! описать ошибку !!
|
|
|
|
|
|
|
|
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
|
|
|
self.output.set_error('error with owner: {}'.format(owner))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def check_filesystem(self, target_path):
|
|
|
|
|
|
|
|
'''Метод, который предположительно будет использоваться для проверки
|
|
|
|
|
|
|
|
файловой системы перед применением шаблона.'''
|
|
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def is_vfat(self, path):
|
|
|
|
return '{0}:{1}'.format(user_name, group_name)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _check_os_error(self, error, path_to_check):
|
|
|
|
|
|
|
|
'''Метод для проверки причины, по которой не удалось изменить владельца
|
|
|
|
|
|
|
|
или права доступа файла.'''
|
|
|
|
|
|
|
|
if hasattr(error, 'errno') and error.errno == os.errno.EPERM:
|
|
|
|
|
|
|
|
if self.is_vfat(path_to_check):
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return hasattr(error, 'errno') and error.errno == os.errno.EACCES and\
|
|
|
|
|
|
|
|
'var/calculate/remote' in path_to_check
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _is_vfat(self, path_to_check):
|
|
|
|
'''Метод, проверяющий является ли файловая система vfat. Нужно для того,
|
|
|
|
'''Метод, проверяющий является ли файловая система vfat. Нужно для того,
|
|
|
|
чтобы заранее знать о возможности применения chown, chmod и т.д.'''
|
|
|
|
чтобы знать о возможности применения chown, chmod и т.д.'''
|
|
|
|
|
|
|
|
# Инициализируем объект для проверки примонтированных файловых систем.
|
|
|
|
if self.mounts is None:
|
|
|
|
if self.mounts is None:
|
|
|
|
self.mounts = Mounts()
|
|
|
|
self.mounts = Mounts()
|
|
|
|
if self.mounts.get_from_fstab(what=self.mounts.TYPE,
|
|
|
|
|
|
|
|
where=self.mounts.DIR,
|
|
|
|
# Проверяем файловую систему на пути.
|
|
|
|
is_in=path) in ('vfat', 'ntfs-3g',
|
|
|
|
return self.mounts.get_from_fstab(what=self.mounts.TYPE,
|
|
|
|
'ntfs'):
|
|
|
|
where=self.mounts.DIR,
|
|
|
|
return True
|
|
|
|
is_in=path_to_check) in {'vfat',
|
|
|
|
return False
|
|
|
|
'ntfs-3g',
|
|
|
|
|
|
|
|
'ntfs'}
|
|
|
|
def check_os_error(self, error, path):
|
|
|
|
|
|
|
|
if hasattr(error, 'errno') and error.errno == os.errno.EPERM:
|
|
|
|
|
|
|
|
if self.is_vfat(path):
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
if hasattr(error, 'errno') and error.errno == os.errno.EACCES and\
|
|
|
|
|
|
|
|
'var/calculate/remote' in path:
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Применение основного шаблона:
|
|
|
|
# Применение основного шаблона:
|
|
|
|