[Devel-conf] Verborum Caterva

Pavel Wolneykien manowar на altlinux.org
Пт Апр 10 14:03:31 MSD 2009


Stanislav Ievlev <stanislav.ievlev на gmail.com> wrote:

> А что такое caterva?

  Всё вместе переводится как "Словоизвержение". :)

  Мне надо генерировать конфигурационный файл для Squid на основе
значений, которые пользователь ввёл через модуль Альтератора. Причём
сам модуль никак не сохраняет эти значения, а передаёт их метабакенду,
который складывает их в сторонке. Такая система возникла в виду
сложности корректного обновления конфигурационного файла: его проще
перезаписать целиком, а значит нужно где-то хранить исходные данные.

  Исходных данных было немного, а конфигурационный файл по умолчанию из
пакета Squid довольно длинный: он содержит много полезных комментариев,
которые хочется сохранить на случай, если администратор решит поправить
что-то в ручную (ну не отсылать же его в этом случае к документации по
Squid, в самом деле?). Самый простой способ решения этой задачи
заключается в помещении статической части конфигурационного файла
непосредственно в генерирующий код. А по умолчанию у нас генератором
является сам бакенд. Идея раздуть бакенд на добрых 4500 строк меня,
честно скажу, не обрадовала (хотя вначале повеселила немного).

  Мысль вынести генератор в отдельную программу постепенно привела к
мысли о создании шаблона: известно, что в тех случаях, когда статическая
часть существенно превышает вычислимую, пишут "программу наоборот" --
шаблон файла с "вкраплениями" вычислительного кода. Тут, естественно,
возникает проблема с выбором escape-символов, которые будут отделять код
от статической части. Но с ними никогда не угадаешь: какой символ лучше?
К тому же придётся выбирать один язык программирования. Для подстановки
значений в шаблон хорошо подходит Shell-scripting, но только до тех пор
пока не нужно что-то _действительно вычислить_. Конструкции получаются
_громоздкие_.

  Размышляя обо всём этом я пришёл к выводу, что задача генерации файлов
может быть решена проще и элегантнее, если использовать несколько языков
программирования: одну часть файла генерировать на одном языке, а другую
часть -- на другом. Но при смешении языков проблема выбора
escape-символов становится практически неразрешимой. То, что для одного
языка служит признаком комментария, для другого может быть ключевым
словом! Поэтому разные фрагменты генератора следовало изолировать друг
от друга более надёжным способом.

  Более радикальным уровнем разделения данных, после синтаксиса языка,
является разделение их на отдельные файлы: тут уж ничего так просто не
перепутается! К тому же очень просто становится отделить статическую
часть от динамической: для этого ведь существует признак исполняемого
файла! И поддержка меток языка интерпретатора тоже уже встроена. В общем
красота. Осталось только написать утилиту под управлением которой
кусочки файлов объединялись бы в один, и всё. Программа verborum-caterva
как раз и является такой утилитой.

Работает она сравнительно просто: входные данные представляются в виде
иерархии директорий и файлов, структура которых во многом повторяет
структуру выходных данных, т.е. целевой иерархии файлов. С одним
исключением: директория в шаблоне может содержать либо только другие
директории, либо только файлы ("это не слишком сильное ограничение"
[inger@]). В первом случае она просто воссоздаётся в целевой иерархии, а
во втором случае отображается в файл. Содержимое файла составляется из
файлов-кусочков, расположенных в директории-шаблоне.

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

  Собственно всё. Но осталось ещё кое-что.

  Кусочки-генераторы, ради которых всё это и строилось, должны откуда-то
брать данные. Поскольку у нас конфигурация системы определяется через
Альтератор, то логично получать данные от него.

  Для получения данных от Альтератора существует, по крайней мере, одна
утилита: alterator-cmdline. Но вот беда: результат её вызова не так-то
просто использовать в коде. Нет, ну конечно это сравнительно просто, но
не настолько, чтобы каждый раз вставлять нужный код прямо в
генератор. Более естественным является объединение требуемых функций в
библиотеку.

  Первым языком, для которого я реализовал такую библиотечку стал
Shell-scripting. Функции содержаться в пакете
caterva-alterator-kit-sh. Функция-то на самом деле всего одна:
on_object. Использовать её можно следующим образом:

  alterator-cmdline /имя_бакенда action "read" | on_object имя_функции

Тогда функция имя_функции будет вызвана столько раз, сколько объектов
вернёт бакенд, а внутри функции будут доступны переменные с именами,
совпадающими с именами атрибутов объекта (правда для Shell символ '-'
будет заменён на '_' -- Shell вообще слишком придирчив к отдельным
символам, на мой взгляд). После вызова функции было бы здорово
автоматически удалять определения этих переменных: собираюсь сегодня
сделать это.

  Есть и ещё одна функция: print_info. Она позволяет выводить на консоль
различные сообщения, если verborum-caterva был запущен с признаком
verbose ("Словоизвержение не только на диск, но и в консоль!").

  Пока это всё.

  Павел.

  P.S. К разработке собирался присоединиться raorn@, и грозился
переписать всё это на некоем libshell. Так что если кто-то ещё захочет
сделать это, просьба сперва связаться с ним.


Подробная информация о списке рассылки devel-conf