|
|
|
@ -1,8 +1,8 @@
|
|
|
|
|
from calculate.templates.template_engine import TemplateEngine, Variables,\
|
|
|
|
|
FILE, DIR, LINK,\
|
|
|
|
|
ParametersProcessor
|
|
|
|
|
FILE, DIR, ParametersProcessor
|
|
|
|
|
from calculate.templates.template_processor import TemplateAction
|
|
|
|
|
from calculate.utils.package import PackageAtomParser
|
|
|
|
|
from calculate.utils.package import PackageAtomParser, Package, PackageNotFound
|
|
|
|
|
import glob
|
|
|
|
|
import shutil
|
|
|
|
|
import os
|
|
|
|
|
|
|
|
|
@ -42,25 +42,40 @@ class TemplateTypeConflict(Exception):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TemplateCollisionError(Exception):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TemplateWrapper:
|
|
|
|
|
type_checks = {DIR: os.path.isdir,
|
|
|
|
|
FILE: os.path.isfile}
|
|
|
|
|
|
|
|
|
|
chroot_path = '/'
|
|
|
|
|
package_atom_parser = PackageAtomParser(chroot_path = chroot_path)
|
|
|
|
|
package_atom_parser = PackageAtomParser(chroot_path=chroot_path)
|
|
|
|
|
|
|
|
|
|
_protected_is_set = False
|
|
|
|
|
_protected_set = {'/etc'}
|
|
|
|
|
_unprotected_set = set()
|
|
|
|
|
|
|
|
|
|
def __init__(self, target_file_path, parameters, template_type,
|
|
|
|
|
template_text=''):
|
|
|
|
|
self._target_path = target_file_path
|
|
|
|
|
self.target_path = target_file_path
|
|
|
|
|
self.target_package_name = None
|
|
|
|
|
|
|
|
|
|
self.parameters = parameters
|
|
|
|
|
|
|
|
|
|
self.template_type = template_type
|
|
|
|
|
|
|
|
|
|
self.template_text = template_text
|
|
|
|
|
|
|
|
|
|
self.remove_original = False
|
|
|
|
|
|
|
|
|
|
if self.parameters.format:
|
|
|
|
|
self.format_class = ParametersProcessor.\
|
|
|
|
|
available_formats[self.parameters.format]
|
|
|
|
|
else:
|
|
|
|
|
# Здесь будет детектор форматов.
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
# Если по этому пути что-то есть -- проверяем конфликты.
|
|
|
|
|
if os.path.exists(target_file_path):
|
|
|
|
|
for file_type, checker in self.type_checks.items():
|
|
|
|
@ -71,7 +86,19 @@ class TemplateWrapper:
|
|
|
|
|
else:
|
|
|
|
|
self.target_type = None
|
|
|
|
|
|
|
|
|
|
self.check_conflicts(self)
|
|
|
|
|
self.check_conflicts()
|
|
|
|
|
|
|
|
|
|
self.check_package_collision()
|
|
|
|
|
|
|
|
|
|
# Если целью является файл -- проверяем наличие ._cfg0000_filename
|
|
|
|
|
# файлов.
|
|
|
|
|
if self.target_type is FILE:
|
|
|
|
|
self._cfg_pattern = os.path.join(
|
|
|
|
|
os.path.dirname(self.target_path),
|
|
|
|
|
"._cfg????_{}".format(
|
|
|
|
|
os.path.basename(self.target_path)))
|
|
|
|
|
|
|
|
|
|
self._cfg_list = glob.glob(self._cfg_pattern)
|
|
|
|
|
|
|
|
|
|
def check_conflicts(self):
|
|
|
|
|
'''Проверка конфликтов типов.'''
|
|
|
|
@ -81,8 +108,8 @@ class TemplateWrapper:
|
|
|
|
|
return
|
|
|
|
|
elif self.target_type == DIR:
|
|
|
|
|
raise TemplateTypeConflict(
|
|
|
|
|
"The target is a directory while the"
|
|
|
|
|
" template has append = 'link'.")
|
|
|
|
|
"The target is a directory while the"
|
|
|
|
|
" template has append = 'link'.")
|
|
|
|
|
else:
|
|
|
|
|
raise TemplateTypeConflict(
|
|
|
|
|
"The target is a file while the"
|
|
|
|
@ -96,7 +123,7 @@ class TemplateWrapper:
|
|
|
|
|
raise TemplateTypeConflict("The target is a file while the"
|
|
|
|
|
" template is a directory.")
|
|
|
|
|
elif self.target_is_link and self.target_type == DIR:
|
|
|
|
|
self._target_path = os.readlink(self._target_path)
|
|
|
|
|
self.target_path = os.readlink(self.target_path)
|
|
|
|
|
return
|
|
|
|
|
else:
|
|
|
|
|
return
|
|
|
|
@ -107,7 +134,7 @@ class TemplateWrapper:
|
|
|
|
|
self.remove_original = True
|
|
|
|
|
return
|
|
|
|
|
elif self.target_is_link and self.target_type == FILE:
|
|
|
|
|
self._target_path = os.readlink(self._target_path)
|
|
|
|
|
self.target_path = os.readlink(self.target_path)
|
|
|
|
|
return
|
|
|
|
|
else:
|
|
|
|
|
return
|
|
|
|
@ -117,25 +144,87 @@ class TemplateWrapper:
|
|
|
|
|
raise TemplateTypeConflict("The target file is a directory"
|
|
|
|
|
" while the template is a file.")
|
|
|
|
|
|
|
|
|
|
def check_original_file(self):
|
|
|
|
|
def check_package_collision(self):
|
|
|
|
|
'''Проверка на предмет коллизии, то есть конфликта пакета шаблона и
|
|
|
|
|
целевого файла.'''
|
|
|
|
|
if self.parameters.package:
|
|
|
|
|
package_atom = self.parameters.package
|
|
|
|
|
self.target_package_name = self.parameters.package
|
|
|
|
|
|
|
|
|
|
if self.target_type is None:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
file_package = self.package_atom_parser.get_file_package(
|
|
|
|
|
self.target_path)
|
|
|
|
|
except PackageNotFound:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if self.target_package_name is None:
|
|
|
|
|
self.target_package_name = file_package
|
|
|
|
|
elif file_package != self.target_package_name:
|
|
|
|
|
raise TemplateCollisionError(
|
|
|
|
|
"The template package is {0} while target"
|
|
|
|
|
" file package is {1}").format(
|
|
|
|
|
self.target_package_name.atom,
|
|
|
|
|
file_package.atom
|
|
|
|
|
)
|
|
|
|
|
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
|
|
|
|
|
self.target_package is None or
|
|
|
|
|
self.target_type != FILE):
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if self.target_package.check_md5(self.target_path):
|
|
|
|
|
pass
|
|
|
|
|
else:
|
|
|
|
|
# пока что определяем значение package для всех файлов.
|
|
|
|
|
package_atom = package_atom_parser.get_file_package()
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def join_template(self):
|
|
|
|
|
if self.template_type is not None:
|
|
|
|
|
original_file_text = ''
|
|
|
|
|
def _update_contents(self):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def use_format(self):
|
|
|
|
|
if self.format_class.EXECUTABLE:
|
|
|
|
|
# Для исполняемых форматов.
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
original_file = open(self._target_path, 'w')
|
|
|
|
|
if self.target_type is None:
|
|
|
|
|
original_file_text = ''
|
|
|
|
|
else:
|
|
|
|
|
original_file = open(self._target_path, 'r')
|
|
|
|
|
original_file = open(target_path, 'r')
|
|
|
|
|
original_file_text = original_file.read()
|
|
|
|
|
original_file.close()
|
|
|
|
|
|
|
|
|
|
original_file = open(self._target_path, 'w')
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def _set_protected(cls):
|
|
|
|
|
if cls._protected_is_set:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
config_protect_env = os.environ.get('CONFIG_PROTECT', False)
|
|
|
|
|
if config_protect_env:
|
|
|
|
|
for protected_path in config_protect_env.split():
|
|
|
|
|
cls._protected_set.add(protected_path.strip())
|
|
|
|
|
|
|
|
|
|
config_protect_mask_env = os.environ.get('CONFIG_PROTECT_MASK', False)
|
|
|
|
|
if config_protect_mask_env:
|
|
|
|
|
for unprotected_path in config_protect_mask_env.split():
|
|
|
|
|
cls._unprotected_set.add(protected_path.strip())
|
|
|
|
|
|
|
|
|
|
cls._protected_is_set = True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TemplateExecutor:
|
|
|
|
@ -157,6 +246,7 @@ class TemplateExecutor:
|
|
|
|
|
self.file_appends = {'join': self._append_join_file}
|
|
|
|
|
|
|
|
|
|
self.formats_classes = ParametersProcessor.available_formats
|
|
|
|
|
TemplateWrapper.chroot_path = self.chroot_path
|
|
|
|
|
|
|
|
|
|
def use_template(self, target_path, parameters, template_type,
|
|
|
|
|
template_text=''):
|
|
|
|
|