1. Шаблоны Calculate

Введение

Традиционно в ОС Linux настройки приложений хранятся в текстовых файлах, как правило в директории /etc, реже в /var. Форматы таких конфигурационных файлов различаются от простых "переменная=значение", до более сложных C-подобных конструкций, либо составленных в XML.

Простой на первый взгляд подход обеспечивает исключительную стабильность в работе приложений, так как за сохранность настроек отвечает исключительно файловая система.

Различные дистрибутивы Linux, как правило, предлагают свои программы настройки приложений. К сожалению, такой подход, имея неоспоримое преимущество в удобстве, имеет также ряд недостатков:
  • пользователь привязывается к определенной программе настройки (дистрибутиву);
  • количество настроек, как правило, ограничено интерфейсом программы;
  • прямое редактирование настроек становится затруднительным, т.к. программа переписывает файл при внесении изменений.

Особенности работы с шаблонами в Calculate 2

Calculate 2 существенно переработан и обладает рядом отличий от первой версии программы:
  • Основной метод переноса шаблонов - объединение с конфигурационными файлами системы. При этом поддерживаются все популярные форматы файлов.
  • Объединение шаблона с конфигурационным файлом производится посредством конвертации в XML формат. При этом формат файла шаблона может отличаться от конфигурационного файла.
  • Файл шаблона может содержать заголовок, описывающий методы объединения.
  • Имена встроенных переменных переименованы согласно типу.

Шаблоны установки

Программа Calculate заменяет прямое редактирование файлов настроек на создание шаблонов.

Форматы файлов

Согласно методу хранения данных, файлы шаблонов могут иметь один из перечисленных форматов:
  • apache, kde, bind, postfix, proftpd, samba, procmail, ldap, dovecot, xml_xfce, xml_xfcepanel, xml_gconf, xml_gconf_tree, compiz, plasma, squid, dhcp, openrc - форматы файлов настроек распространенных приложений
  • bin - двоичный формат файлов
  • raw - сырой текст
  • patch - шаблон для применения регулярных выражений. (Использует специальный вид объединения patch)

Для формата kde не обрабатываются параметры '-','+' для элементов внутри области.

Названия параметров в openrc-формате нечувствительны к регистру букв.

Управляющие элементы

Помимо настроек сервисов, записанных в оригинальном формате программы, файлы шаблонов содержат служебные записи, которые условно можно разделить на несколько типов.

Переменная

Переменная - текстовый элемент в шаблоне, имеющий имя, который заменяется в соответствующем конфигурационном файле значением.

Переменная имеет имя, значение, область действия.
  • имя - латинские буквы и цифры
  • значение - текст для замены (создается в программе)
  • область действия - действует глобально для всех шаблонов или локально для одного

Переменные подразделяются на переменные шаблонов и переменные функций.

У переменных шаблонов глобальная область действия, то есть любая переменная шаблона, доступная программе, может быть использована в любом шаблоне. Значение переменной нельзя изменить в шаблоне.

Переменные функций могут быть созданы в шаблоне; также можно изменить значение переменной в шаблоне. Область действия переменной функции - текущий шаблон.

Для передачи значений переменных функций из текущего шаблона в другой шаблон используется стек переменных функций шаблонов (LIFO), в который при помощи функции шаблонов push() записывается значение из текущего шаблона, а функцией шаблона pop() получаем значение в другом шаблоне.

Стек переменных функций шаблонов.

Стек (LIFO - последним пришел, первым вышел) для хранения значений переменных функций. Доступен глобально для всех шаблонов, для работы используются функции шаблонов, push() - запись, pop() - чтение. Запись и чтение возможны как в одном шаблоне, так и в разных.

Заголовок

Заголовок - управляющая запись шаблона, определяющая методы переноса шаблона в систему. Заголовок шаблона записывается первой строкой файла и имеет следующий вид:

# Calculate параметр1=значение1 параметр2 [параметр3=значение3 ...]

Содержимое заголовка может быть разбито на строки. В этом случае в конце каждой строки заголовка, кроме последней, должен стоять знак "\" (обратная косая черта).

Если заголовок отсутствует, настройки файла шаблона определяются исходя из принятых значений по умолчанию.

Допустимые параметры:
Формат
  • format=[...] - формат файла шаблона (см. форматы файлов). По умолчанию формат файла шаблона определяется как "raw", или "bin" для файлов, содержащих двоичные данные.
  • comment=[.] - обозначение начала строкового комментария (пример: "#").
Объединение
  • append=[join|before|after|replace|remove|skip|patch|clear] - способ объединения. По умолчанию способ объединения устанавливается в соответствии с форматом файла. Если append=skip - шаблон пропускается. Если append=clear, в случае шаблона файла конфигурационный файл будет очищен - длина файла 0, а в случае шаблона директории все файлы и директории внутри конфигурационной директории будут удалены.
  • force - удалять существующие файлы перед записью конфигурационного файла. Правило действует по умолчанию, если указан параметр "symbolic".
  • link=путь - путь к конфигурационному файлу, с которым объединяется файл шаблона. По умолчанию путь совпадает.
    Пример: "link=/etc/conf.d/net.example"
  • path=путь - путь к директории, в которой будет находиться конфигурационный файл
  • name=имя - имя конфигурационного файла
  • mirror - выполнять объединение только в случае существования конфигурационного файла. Если конфигурационный файл задан параметром "link" и он не существует, файл назначения удаляется.
  • symbolic - создать символическую ссылку на файл, указанный параметром "link".
  • autoupdate - при установке любого пакета запускается специальный скрипт cl-update-config, который применяет шаблоны для устанавливаемого пакета. Конфигурационные файлы устанавливаемого пакета защищены. Иными словами, при установке пакета, если такой же файл существует в системе и изменен, он не будет заменен. Замена конфигурационных файлов установленных пакетов производится командой dispatch-conf. Если в заголовке шаблона есть параметр autoupdate то после применения шаблона конфигурационный файл будет скопирован в систему. Если параметр отсутствует то для переноса измененного конфигурационного файла необходимо использовать dispatch-conf.
  • exec - оболочка для выполнения конфигурационного файла, полученного из шаблона.
    Пример: "exec=/bin/bash"
Права доступа
  • chmod=XXX - права доступа к конечному файлу (пример: "644"). По умолчанию права соответствуют оригинальному файлу. Если его нет, права соответствуют файлу шаблона.
  • chown=user:group - владелец и/или группа конечного файла (пример: "root:root").
Условия
  • переменная[>|<|==|!=|>=|<=]значение ... - условия переноса файла шаблона в систему. Арифметические операции могут объединяться условием "И" (&) (для версии calculate-lib>=2.2 условие "И" (&&)) и "ИЛИ" (||). Приоритет в данном случае будет отдаваться условию И. Несколько условий, разделённых пробелом будут объединяться условием "И".

Метки

Вы можете настроить систему исходя из аппаратных требований компьютера, сетевых установок и прочих условий. Для этого в файле шаблона вы можете вместо постоянных значений устанавливать метки переменных.

Пример файла /etc/conf.d/hostname:

HOSTNAME="#-os_net_hostname-#" 

Условные блоки

Файл шаблона может содержать условные блоки.

Условные блоки - выделенный текст шаблона, подставляемый в случае соответствия регулярного выражения.

Регулярное выражение - метод проверки значений выражений. В качестве значений могут применяться следующие типы данных:

  • переменные - встроенные переменные Calculate.
  • числа - целые и дробные числа, в качестве разделителя дробной части выступает точка ".".
  • строки - буквы, цифры, специальные символы.
  • номера версий - числа и одна или две точки, разделяющих номер версии (например 8.5.1).

Методом проверки выступает арифметическая операция >, <, ==, !=, >=, <= (больше, меньше, равно, не равно, больше либо равно, меньше либо равно). Тип данных определяется перед операцией сравнения.

Арифметические операции могут объединяться условием "И" (&) и "ИЛИ" (||). Приоритет в данном случае будет отдаваться условию "И".

Условный блок должен начинаться с метки "#?переменная1==значение1(...)#" и заканчивается "#переменная1#", записанными в начале строки.

Пример условного блока файла /etc/make.conf:

#?os_arch_march==i686&os_linux_shortname==CLD#
   CFLAGS="-O2 -march=i686 -pipe" 
   CHOST="i686-pc-linux-gnu" 
#os_arch_march#

В приведенном примере сравниваются переменные "setup_march" и "setup_sys_shortname" со строковыми значениями "i686" и "CLD" соответственно. В случае, если значения обоих переменных совпадают, текст блока будет подставлен в результирующий файл.

Функции

Для формирования сложных файлов, требующих вычисления во время обработки, служат функции. Подобно переменным, функции вставляются в текст шаблона при помощи конструкции "#функция()#".

Функции, использующие в аргументах путь к файлу (path), могут использовать в качестве домашней директории пользователя '~'

Доступные функции:

belong(pkg_name) - проверка имени устанавливаемого пакета, если выполняется установка пакета. В остальных случаях функция будет возвращать положительный результат.

pkg_name - имя пакета, необязательный аргумент. Если у функции нет аргумента, то аргументом является имя директории, в которой находится шаблон с функцией belong().

Результат зависит от значения переменной шаблона cl_belong_pkg
  • значение cl_belong_pkg - ''
    • результат '1', независимо от того, есть или нет аргумент у функции
  • значение cl_belong_pkg - 'имя_пакета'
    • если совпадают значения cl_belong_pkg и аргумента функции, результат - '1' иначе ''
    • если у функции нет аргумента то сравниваются значение cl_belong_pkg и имя директории в которой находится шаблон с функцией belong(), в случае совпадения результат - '1' иначе ''

Пример.
Заголовок шаблона1:

# Calculate belong(nss_ldap)!=

Заголовок шаблона2:

# Calculate belong(kdm)!=

  1. Наложим шаблон для программы nss_ldap: Установим значение переменной cl_belong_pkg равным nss_ldap. Будет применен только шаблон1
  2. Наложим все шаблоны. Значение переменной cl_belong_pkg по умолчанию - ''. Будут применены шаблон1 и шаблон2.
case(type,var) - вывод значения переменной шаблона с изменением регистра символов.
где:
  • type - тип изменения регистра: upper - верхний регистр, lower - нижний регистр, capitalize - первая буква в верхнем регистре.
  • var - название переменной шаблона.

Пример. Выведем название хоста в верхнем регистре:

#-case(upper,os_net_hostname)-#

disk(mount_point,name) - выводит значение параметра жесткого диска при инсталяции системы.
Значение функция получает из переменной ('os_install_disk_' + name, если такой не существует, то 'os_disk_'+ name), для поиска нужного значения используется переменная os_install_disk_mount (точки монтирования при инсталяции).

где:
  • mount_point - точка монтирования при инсталяции.
  • name - последний элемент переменных начинающихся на os_install_disk_/os_disk ('os_instll_disk_'/'os_disk_' + name).

значения переменных

os_install_disk_mount = ['swap', '/', '', '', '/var/calculate']
os_disk_grub ['0,0', '0,1', '0,2', '0,3', '0,4']

функция
disk(/var/calculate,grub)

  • в переменной os_install_disk_mount находим /var/calculate, получаем индекс 4
  • в переменной os_disk_grub по индексу 4 получаем значение '0,4'
    результат функции disk(/var/calculate,grub) '0,4'

функция
disk(/boot,grub)

  • в переменной os_install_disk_mount /boot не найден, индекс отсутствует
  • если индекс отсутствует, в переменной os_disk_install находим /, получаем индекс 1
  • в переменной os_disk_grub по индексу 1 получаем значение '0,1'
    результат функции disk(/boot,grub) '0,1'

Пример.
Выведем диск для загрузчика grub:

#-disk(/boot,grub)-#

получаем значение 0,1

env(service.var_name) - чтение значения записанной переменной шаблона сервиса. Информация получается путем обработки файлов хранения значений переменных шаблонов.

где:
  • service - название сервиса.
  • var_name - переменная сервиса.
    разделитель - '.' точка
Примеры:
  1. прочитаем доменное имя для соединения с jabber сервисом
    #-info(jabber,sr_jabber_host)-#
    

получаем значение jabber.calculate.ru

exists(path,opt) - проверка существования файла или директории.

Если файл или директория существует, выводит '1', иначе ''

path - путь в файловой системе.
opt - необязательная опция.

Возможные значения "opt":
  • root - путь к файлу не будет содержать chroot-пути. (какой путь указан такой будет в действительности вне зависимости от переменных cl_chroot_path и cl_root_path)

Пример. Проверим существование директории /etc:

#-exists(/etc)-#

Результатом будет '1'.

groups(group1,group2,..groupN) - проверка вхождения пользователя в группы group1,group2, ..groupN

Если пользователь входит хотя бы в одну из групп выводит '1', иначе ''

group1 .. groupN - названия групп.

Пример. Проверим входит ли пользователь в группу wheel:

#-group(wheel)-#

Если пользователь входит в группу wheel, результатом будет '1'.

ini(var, value, opt) - запись и чтение переменной из конфигурационного файла пользователя (~/.calculate/ini.env).

Начиная с версии 2.2.20-r4: если функция выполняется для настройки системы, то конфигурационный файл будет находиться в @/etc/calculate/ini.env@

где:
  • var - имя переменной функции. Имя должно начинаться с буквы и может содержать латинские буквы и цифры, а также точку. Точка служит разделителем для раздела и имени переменной для размещения в конфигурационном файле.
  • value - значение переменной функции, значение присваивается переменной функции и записывается в конфигурационный файл. При отсутствии второго аргумента переменная считывается из конфигурационного файла; при отсутствии названия переменной в конфигурационном файле в переменную записывается пустое значение.
    Начиная с версии 2.2.20-r4, если аргумент пустая строка без кавычек, то переменная удаляется. Если аргумент - пустая строка в кавычках, то значение переменной в ini-файле очищается.
  • opt - опция преобразования значения переменной, необязательный параметр; возможные значения url, purl, unicode. При использовании этого аргумента второй аргумент функции должен быть пустым.
Примеры:
  1. Создадим переменную "test" и присвоим ей значение 15, запишем в конфигурационный файл:
    #-ini(test,15)-#
    
  1. Считаем значение ранее записанной в конфигурационный файл переменной test, заменим функцию значением считанной переменной, в нашем случае "15":
    #-ini(test)-#
    
  1. Использование функции ini c тремя аргументами. Предположим что в файле ~/.calculate/ini.env существует секция
    [test]
    param = Тестовый параметр
    

тогда функция

#-ini(test.param,,unicode)-#

вернет

\u0422\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440

а функция

#-ini(test.param,,url)-#

вернет

%d0%a2%d0%b5%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9%20%d0%bf%d0%b0%d1%80%d0%b0%d0%bc%d0%b5%d1%82%d1%80

Опция purl отличается от url тем, что преобразует '/' в код '%2F'

server(service.option,var) - чтение значения параметра сервиса. Информация получается путем обработки файла /var/calculate/remote/server.env,

где:
  • service - название сервиса.
  • option - опция сервиса.
  • var - имя переменной функции(необязательный параметр).
    Разделитель service и option: '.' - точка.
    В случае использования var - имени переменной функции, полученное значение опции сервиса будет записана в переменную функции var.
    Если var не используется, полученное значение опции сервиса будет вставлено в текст конфигурационного файла.
Примеры:
  1. прочитаем значение порта для соединения с jabber-сервисом
    #-server(jabber,port)-#
    
получаем значение 5223
  1. прочитаем значение порта для соединения с jabber-сервисом и поместим в переменную функции jabber_port
    #-server(jabber,port,jabber_port)-#
    

Значение переменной функции jabber_port - 5223.

list(var,index) - вывод значения по индексу из переменной.
где:
  • var - название переменной функции или переменной шаблона (значение переменной должно быть списком).
  • index - индекс для поиска значения в переменной функции или переменной шаблона (первый элемент имеет индекс 0, и т.д.).

Пример.
Значение переменной
os_disk_dev = ['/dev/sda1', '/dev/sda2', '/dev/sda3', '/dev/sda4', '/dev/sda5']

#-list(os_disk_dev,1)-#

Метка функции будет заменена на '/dev/sda2'.

Если запрошен элемент, отсутствующий в списке, наложение шаблонов прерывается с ошибкой. Начиная с версии 2.2.17 - возвращает пустую строку.

load(arg,path,opt) - отображение информации из файла.
где:
arg - тип содержимого файла;
path - путь к файлу;
opt - необязательная опция

Возможные значения "opt":
  • root - путь к файлу не будет содержать chroot-пути (какой путь указан, такой и будет в действительности, вне зависимости от переменных cl_chroot_path и cl_root_path).

Возможные значения "arg":

  • ver - содержимое файла номер версии
  • num - содержимое файла число
  • char - содержимое файла строка
  • empty - результат, содержимое файла без закомментированных (комментарии # или ;) и пустых строк.
Возможные значения "path":
  • path - абсолютный или относительный путь к файлу.

Пример. Выведем содержимое /proc/cpuinfo на место объявления функции:

#-load(char,/proc/cpuinfo)-#

module(name_space) - получение переменных шаблонов пакета или выполнение методов пакета, используя его api-модуль или выполнение определенного метода для всех пакетов, у которых есть api-модуль,
где:

  • name_space - пространство имен api-модуля.

Пространство имен для получения переменных состоит из элементов разделенных точкой.
Первый элемент пространства имен - имя пакета. Имя пакета это название установленного пакета, имеющего api-модуль (тире '-' в названии должно быть заменено на нижнее подчеркивание '_').
Первый элемент пространства имен для всех пакетов - 'all' (зарезервированное название).
Пример первого элемента для пакета calculate-ldap:

calculate_ldap

Второй элемент пространства имен - название метода api или 'var' - зарезервированное название для пространства имен переменных шаблонов пакета.

Пример первого и второго элементов для пакета calculate-ldap для получения доступа к переменным:

calculate_ldap.var

Пример первого и второго элементов для пакета calculate-ldap для получения результата выполнения метода is_setup() api-модуля (проверка, настроен ли пакет).

calculate_ldap.is_setup

Третий элемент пространства - в большинстве случаев это пространство имен для получения значения переменной шаблона.

Пример пространства имен для получения значения переменной шаблонов cl_name пакета calculate-ldap:

calculate_ldap.var.cl_name

Примеры использования функции:
Получим значение переменной шаблонов cl_name (название пакета) пакета calculate-ldap.

#-module(calculate_ldap.var.cl_name)-#

Получаем значение

calculate-ldap

Проверим, настроен ли пакет calculate-ldap для работы:

#-module(calculate_ldap.is_setup)-#

если пакет настроен, получаем значение

1

Проверим, настроены ли для работы все установленные пакеты, имеющие api-модуль:

#-module(all.is_setup)-#

Если все пакеты настроены, получаем значение

1

pkg (category/package) - вывод версии установленного пакета.
где:
  • category - категория пакета
  • package - название пакета

В качестве совместимого режима можно указывать только название пакета; в этом случае скорость обработки шаблона будет ниже.

Пример. Выведем версию установленного пакета (например 4.2.4):

#-pkg(kde-base/kdelibs)-#

Значит, в системе установлен пакет kdelibs-4.2.4.

push(var, value) - помещение значения переменной в стек переменных функций шаблонов.

где:
  • var - имя переменной функции. Имя должно начинаться с буквы и может содержать латинские буквы и цифры. Переменная создается на время обработки конфигурационного файла.
  • value - значение переменной функции, значение присваивается переменной функции и заносится в стек переменных функций шаблонов. При отсутствии второго аргумента, в стек переменных функций шаблонов будет записано значение переменной.
Примеры:
  1. Создадим переменную "test" и присвоим ей значение 15, запишем в стек переменных функций шаблонов.
    #-push(test,15)-#
    
  1. Запишем в стек переменных функций шаблонов значение ранее созданной переменной test:
    #-push(test)-#
    
pop(var) - извлечение значения из стека переменных функций шаблонов и присвоение его переменной.
  • var - имя переменной функции. Имя должно начинаться с буквы и может содержать латинские буквы и цифры. Переменная создается на время обработки конфигурационного файла.
Примеры:
  1. Создадим переменную "test" и присвоим ей значение 15, запишем в стек переменных функций шаблонов.
    #-push(test,15)-#
    
  1. Получим значение из стека переменных функций шаблонов и присвоим его переменной test2:
    #-pop(test2)-#
    

Получить значение из стека переменных функций шаблонов возможно как в текущем шаблоне, так и в любом другом.
После получения значения оно удаляется из стека.

replace(old, new, var) - замена в значении переменной var текста old на new.
где:
  • old - текст, каждое вхождение которого в значении переменной будет заменено на текст new
  • new - текст, на который в значении переменной будет заменен текст old
  • var - название переменной функции или переменной шаблона

Текст old и new должен быть заключен в двойные или одинарные кавычки.

В тексте в двойных кавычках обрабатываются управляющие символы (\', \", \n, \r, \t, \).
В одинарных кавычках текст не обрабатывается.

Пример.
значение переменной шаблона ur_signature

Компания «Калкулэйт»\nРоссия, Санкт-Петербург, пл. Стачек, 4\nhttp://www.calculate.ru\n+7 812 3363632\n+7 495 7727678

при выполении функции

#-replace('\n',"\n",ur_signature)-#

в точку вставки будет вставлен следующий текст (символ "\n" будет заменен на перевод строки)

Компания «Калкулэйт»
Россия, Санкт-Петербург, пл. Стачек, 4
http://www.calculate.ru
+7 812 3363632
+7 495 7727678

rnd(type,len) - вывод случайной комбинации символов.
где:
  • type - используемые символы, возможные значения: num - числа, pas - числа и буквы, uuid - числа и буквы от a-f. (uuid добавлен начиная с версии 2.2.17).
  • len - количество символов (число).

Пример. Выведем три 3 случайных числа (например 372):

#-rnd(num,3)-#

sum(var,sum_print, sum_out) - вычисляемые значения смещений. Функция разрабатывалась для настройки Plasma (KDE).

где:
  • var - имя переменной функции "sum". Имя должно начинаться с буквы и может содержать латинские буквы и цифры. Переменная создается на время обработки конфигурационного файла.
  • sum_print - арифметическое выражение, результат которого будет отображен на месте объявления функции. При отсутствии аргумента значение выводиться не будет. Поддерживаются операции сложения "+" и вычитания "-", деления "/" и умножения "*". В арифметическом выражении могут участвовать другие переменные функции, а также переменные шаблона.
  • sum_out - арифметическое выражение, результат которого будет присвоен переменной "var" (первому аргументу функции). При отсутствии третьего аргумента переменной "var" будет присвоено вычисленное значение второго аргумента.
Примеры:
  1. Создадим переменную "clock" и присвоим ей значение 15, не выводя результат.
    #-sum(clock,,15)-#
    
  1. Создадим переменную "bt", присвоим ей значение переменной "clock" и выведем значение.
    #-sum(bt,clock)-#
    
  1. Разместим кнопку на панели шириной "35" пикселов, оставив отступ в "4" пиксела по краям:
    #-sum(bt,bt+2,bt+35+2)-#
    

Способы объединения

Существуют несколько способов объединения шаблона установки с исходным файлом системы:
  • join - основной способ объединения - методом слияния двух файлов. Подробно описан в "схеме объединения".
  • before - шаблон переписывается в начало оригинального файла
  • after - шаблон переписывается в конец оригинального файла
  • replace - шаблон переписывается заменяя оригинальный файл
  • delete - объединение не происходит, оригинальный файл удаляется
  • remove - вместо объединения происходит удаление оригинального файла
Изменение шаблона перед объединением, для способов объединения "before", "after", "replace":
  • если существуют управляющие элементы, то они обрабатываются
  • если существует заголовок, то он обрабатывается
  • если существует параметр format в заголовке то происходит обработка управляющих символов: "+, -, !"

Правила по умолчанию

По умолчанию способ объединения устанавливается в соответствии с форматом файла.
Для форматов файлов основных приложений "samba", "bind" и т.п. по умолчанию действует объединение "join", для формата "raw" и "bin" - объединение "replace". Для пустого файла по умолчанию действует правило объединения "delete" - конечный файл удаляется из системы.

Правила объединения могут быть изменены установкой параметра "append" заголовка файла шаблона.

Расположение

Правила именования файлов

Имена файлов шаблона могут содержать условные операторы, определяющие правила, при выполнении которых файл шаблона будет перенесен в систему. Подобно ссылке на страницу сайта условия отделяются от имени знаком вопроса (?), после которого могут идти условные операторы, подробно описанные в условных блоках (см. выше).

Арифметические операции могут объединяться условием И (&) и ИЛИ (?). Приоритет в данном случае будет отдаваться условию И.

Пример:

grub.conf?os_linux_shortname==CDS?os_linux_shortname==CLD

В приведенном примере файл шаблона выполнит настройки загрузчика как для систем Calculate Linux Desktop, так и для Calculate Directory Server.

При наличии условных операторов в заголовке файла шаблона для переноса файла шаблона в систему должны выполняться оба условных выражения.

Правила именования директорий

Правила именования директорий схожи с правилами именования файлов. При выполнении условий, заданных условными операторами, директория будет перенесена в систему; в противном случае директория вместе с содержимым будет пропущена.

Права доступа

Права доступа конфигурационного файла после объединения с файлом шаблона устанавливаются по следующим приоритетам:
  • при наличии конфигурационного файла в системе права будут сохранены неизменными;
  • в случае отсутствия оригинального конфигурационного файла, права будут выставлены как 644 для файла и 755 для директории;
  • в случае установки значения переменной "chmod" или "chown" заголовка файла шаблона, права на конфигурационный файл будут изменены согласно установленному значению.

Символические ссылки

Для создания символических ссылок используйте параметры "link + symbolic" заголовка файла шаблона.

Если помимо заголовка файл шаблона будет содержать тело шаблона, оригинальный файл будет модифицирован согласно правилам объединения.

Calculate не будет переносить так называемые "битые ссылки" - ссылки, не ведущие ни на какой файл (директорию), если явно не указан параметр force.

Схема объединения

Объединение - изменение настроек оригинального файла настроек в соответствии с настройками файла шаблона.

В процессе объединения все записи оригинального файла и файла шаблона разбиваются на элементы: области, переменные, списки, разделённые списки, комментарии, управляющие элементы (см. ниже).

Файл шаблона должен быть составлен с применением синтаксиса оригинального файла. Расположение элементов оригинального файла при объединении сохраняется. Во время объединения комментарии из файла шаблона не переносятся.

Правила объединения

Над элементами могут происходит операции Объединение, Замена, Удаление:

Объединение

  • Отсутствующие в оригинальном файле элементы дописываются в конец области. При этом в случае наличия перевода строки перед вставляемым элементом перевод строки добавляется после вставляемого элемента. В противном случае перевод строки добавляется перед вставляемым элементом.
  • В случае объединения разделённого списка, отсутствующие элементы добавляются следом за последним элементом разделённого списка конфигурационного файла.

Замена

  • Значение элементов заменяется на новое. При этом форматирование переносится из файла шаблона.

Удаление

  • Элемент удаляется вместе с переводом строки, стоящим перед элементом.

Правила объединения, действующие по умолчанию

Правила объединения действуют на элементы с одним именем, расположенные в одной области шаблона.

При нахождении различий, по умолчанию действуют следующие правила:
  • Области - содержимое двух областей объединяется (+).
  • Переменные - значения переменных заменяются (-).
  • Списки - содержимое списков заменяется (-).
  • Разделённые списки - аналогично правилу объединения переменных - значения списков заменяются (-).

Изменение правил объединения

Для изменения правил объединения действующих по умолчанию, в начале имени элемента в файле шаблона добавляется управляющие символы:
  • "+" - объединить элементы (для областей и списков); после объединения остаются только уникальные элементы
  • "-" - значение элемента заменяется
  • "!" - элемент удаляется
    В CXmlConf описания файла шаблона эти правила описываются тэгом "<action>".

Формат CXmlConf

CXmlConf - универсальный формат описания конфигурационных файлов. Служит для выборочного изменения настроек большинства распространенных типов конфигурационных файлов ОС Linux/Unix.

XML файл описания настроек разбивает конфигурационный файл на логические структуры - элементы, пригодные для последующего объединения. После объединения файл может быть преобразован в первозданный вид за некоторыми исключениями (см. Схема объединения).

Описания элементов вкладываются в конструкцию:

<cxmlconf>
  <head>
    <ver>версия формата</ver>
    <format>формат конфигурационного файла</format>
  </head>
  <body>
    [<area>...</area>... <field>..</field>]
  </body>
</cxmlconf>

Где:
  • ver - передает номер версии разметки
  • format - формат конфигурационного файла (определяется по распространенным программам).

Все элементы (см. ниже) помещаются внутрь элемента <body/>.

Области

Области конфигурационных файлов разграничивают пространство имен переменных. Области могут содержать логические структуры, в том числе другие области (пример: {{Filename|named.conf}}).

Области помещается в конструкцию:

<area>
  <caption>
    <name>Заголовок области</name>
    <action>join|replace|drop</action>
    <quote>Начальная часть области (заголовок)</quote>
    <quote>Завершающая часть описания области</quote>
  </caption>

  [<field></field>...]

</area>

Переменные

Переменные имеют запись в виде:

<field type="var">
  <name>имя переменной</name>
  <value>значение переменной</value>
  <action>join|replace|drop</action>
  <quote>Оригинальный текст описания</quote>
</field>

В некоторых конфигурационных файлах, например, /etc/openldap/slapd.conf, встречается конструкция:

index   cn              pres,sub,eq
index   sn              pres,sub,eq
index   uid             pres,sub,eq

В этом случае имя переменной состоит из первой и второй части, а значение - из третьей.

Cтрока

index   cn              pres,sub,eq

В XML это будет выглядеть так:

<field type="var">
  <name>indexcn</name>
  <value>pres,sub,eq</value>
  <quote>index   cn              pres,sub,eq</quote>
</field>
<field type="br" \>

Списки

По примеру файла named.conf, блок "listen-on" может содержать одни значения - значения блока, а не переменных.

Для обозначения значений служит конструкция:

<field type="list">
  <name>hostsallow</name>
  <value>192.168.0.0/24</value>
  <value>127.</value>
  <action>join|replace|drop</action>
  <quote>Оригинальный текст списка</quote>
</field>

где внутри блока "<quote>" сохраняется оригинальный текст описания значения, без завершающего перевода строки.

Разделённые списки

Файл настроек веб-сервера Apache может содержать инструкцию "Include", позволяющую делать исходный файл модульным. Подобные случаи описываются в "CXmlConf", как "Разделённые списки".

Разделенные списки описываются следующей конструкцией:

<field type="seplist">
  <name>Include</name>
  <value>/etc/apache2/modules.d/*.conf</value>
  <action>join|replace|drop</action>
  <quote>Оригинальный текст списка</quote>
</field>

Комментарии

При объединении конфигурационных файлов комментарии оригинального файла сохраняются в неизменном виде.

Все типы комментариев помещаются в конструкцию "<comment>". В тексте, помещаемом в "<quote/>", сохраняются символы комментария и перевод строки:

<field type="comment">
  <quote>Оригинальный текст комментария</quote>
</field>

Комментарии не могут быть вложенными (быть описаны в других конструкциях комментариев).

Управляющие элементы

Для обозначения перевода строк служит конструкция:

<field type="br">
  <quote>разделительные элементы (пробелы, табуляция)</quote>
</field>

Где:
  • "quote" содержит элементы форматирования (пробелы, табуляция)

Формат XML

Поддерживаемые форматы XML

В настоящее время реализована поддержка форматов xml_xfce (XML файл для конфигурирования оконного менеджера XFCE), xml_xfcepanel (XML файл для конфигурирования панелей оконного менеджера XFCE), xml_gconf (XML файл для конфигурирования GNOME)

Отличия от формата CXmlConf

  • XML файлы хранятся и обрабатываются без перевода их в другой формат.
  • Все правила, функции, переменные действуют на файл XML-шаблона аналогично обычному шаблону за исключением операций объединения элементов XML

Объединение элементов XML

Для объединения элементов XML в тексте XML шаблона используется атрибут XML-элемента - 'action'

Допустимые значения атрибута
  • action="join" - элементы объединяются (действует по умолчанию)
  • action="replace" - элемент шаблона замещает элемент файла
  • action="drop" - элемент файла удаляется

Формат xml_xfce

Формат состоит из элементов "channel" и "property".

В атрибутах "channel" находится имя и версия файла.

Внутри элемента "channel" находятся элементы "property".

Пример элемента "channel":

<channel name="xfwm4" version="1.0">
  <property name="general" type="empty">
  .....
  </property>
</channel>

Пример элемента "property":

<property name="wrap_workspaces" type="bool" value="false"/>

У каждого элемента "property" есть атрибут type.

Если type="array", то этот элемент и внутренние элементы будут заменены на элементы из шаблона.
Иначе элементы будут объединены.

Пример type="array":

<property name="workspace_names" type="array">
  <value type="string" value="Рабочее место 1"/>
  <value type="string" value="Рабочее место 2"/>
  <value type="string" value="Рабочее место 3"/>
  <value type="string" value="Рабочее место 4"/>
</property>

Формат xml_xfcepanel

Формат состоит из следующих элементов: "panels", "panel", "properties", "property", "items", "item".

Если элемент "items", то этот элемент и внутренние элементы будут заменены на элементы из шаблона.
Иначе элементы будут объединены.

Пример элемента "items":

<items>
  <item name="xfce4-mixer-plugin" id="9"/>
  <item name="clock" id="10"/>
  <item name="separator" id="52"/>
  <item name="actions" id="12"/>
</items>

Формат xml_gconf

Формат состоит из элементов "entry".
Если у элемента "entry" есть атрибут "ltype" (список) или атрибут type="string" то этот элемент и внутренние элементы будут заменены на элементы из шаблона, в ином случае элементы будут объединены.

Атрибут элемента "entry" - "mtime" при изменении элемента "entry" показывает время, когда произошло изменение в секундах.

Пример шаблона xml_gconf:

# Calculate format=xml_gconf
<?xml version="1.0"?>
<gconf>
        <entry name="rgba_order" mtime="1235158855" type="string">
              <stringvalue>rgb</stringvalue>
       </entry>
       <entry name="dpi" mtime="1235162438" type="float" value="86">
       </entry>
       <entry name="hinting" mtime="1235266915" type="string">
               <stringvalue>full</stringvalue>
       </entry>
       <entry name="antialiasing" mtime="1235266915" type="string">
               <stringvalue>rgba</stringvalue>
       </entry>
</gconf>

Формат xml_gconf_tree

Формат состоит из элементов "dir" и "entry" и их атрибутов.

Атрибуты элементов будут объединены в случае 'join'-объединения.

При объединении шаблона и конфигурационного файла элементы "entry" конфигурационного файла будут заменены, соответствующими элементами "entry" шаблона.

Атрибут элемента "entry" - "mtime" при изменении элемента "entry" показывает время когда произошло изменение в секундах.

Пример шаблона xml_gconf:

# Calculate format=xml_gconf_tree
<?xml version="1.0"?>
<gconf>
    <dir name="desktop">
        <dir name="gnome">
            <dir name="volume_manager">
                <entry name="percent_used" mtime="1285580987" schema="/schemas/desktop/gnome/volume_manager/percent_used"/>
                        </dir>
                </dir>
        </dir>
<gconf>

Примеры использования

Файл шаблона:

# Calculate format=xml_xfce
<?xml version="1.0" encoding="UTF-8"?>
<channel name="xfce4-session" version="1.0">
  <property name="general" type="empty" action="drop">
    <property name="FailsafeSessionName" type="empty"/>
    <property name="SessionName" type="string" value="Default"/>
    <property name="SaveOnExit" type="bool" value="true"/>
  </property>   
</channel>

Cтрока <property name="general" type="empty" action="drop"> говорит о том, что этот элемент и все элементы внутри будут удалены.

Получившийся в результате файл имеет следующий вид:

<?xml version="1.0" encoding="UTF-8"?>
<channel name="xfce4-session" version="1.0">
</channel>

Формат patch.

Формат patch используется для обработки конфигурационных файлов при помощи регулярных выражений языка программирования Python.

Особенности.

Формат patch использует обработку конфигурационного файла на основании шаблона (тип объединения patch); при этом не происходит объединения шаблона и конфигурационного файла.

Описание.

Шаблон формата patch:

# Calculate format=patch
<reg>регулярное выражение python 1</reg>
<text>текст 1 для замены регулярного выражения</text>
<reg>регулярное выражение python 2</reg>
<text>текст 2 для замены регулярного выражения</text>
...

Пример:

# Calculate format=patch
<reg>TEXT</reg>
<text>TEXT_CONFIG</text>

Этот шаблон заменит в конфигурационном файле TEXT на TEXT_CONFIG.

Спасибо!