Uzix | микроблог

Применение m4 для генерации конфигурации

В данной заметке я хочу рассказать о существовании замечательной утилиты - макропроцессора m4. Заметка носит ознакомительный характер и не ставит целью описание нюансов m4 (RTFM!).

Любой *nix-системный администратор сталкивался с проблемой громоздкости и избыточности конфигурационных файлов. Так, некоторое ПО (php-fpm) не поддерживает наследование секций конфигурации (хотите новый пул в php-fpm, отличающийся лишь директорией и пользователем? будьте добры скопипасьте и все остальные 9000 параметров для нового пула). Другое же ПО (nagios) - несмотря на мощные возможности наследования - имеет довольно громоздкий формат конфигурационных файлов.

Обычно подобные проблемы решают двумя путями: скрипты-генераторы конфигов и системы управления конфигурацией (ansible, puppet). Первый подход мне не нравится своей… неэлегантностью что-ли. О втором же подходе (до некоторой поры) можно сказать - “из пушки по воробьям”.

Чем же может помочь m4? m4 - ПО, предназначенное для преобразования входных текстовых данных согласно некоторому набору правил (макросов). Сами макросы могут быть как предопределёнными в m4, так и определяемыми во входных данных (файле конфигурации).

К слову, количество “мусорных” строк в конфигурации Nagios вгоняло меня в уныние с первых дней знакомства с системой. Поэтому, узнав о существовании m4, я решил опробовать этот инструмент именно на Nagios. И результат превзошёл все мои ожидания. Вот пример старой конфигурации:

define host {
    use                 generic-server
    host_name           my-server-1234
    address             1.2.3.4
}

define service {
    use                 service-ping
    host_name           my-server-1234
}

define service {
    use                 service-ssh
    host_name           my-server-1234
    _port               2222
}

define service {
    use                 service-tcp
    host_name           my-server-1234
    service_description SSH honeypot
    _port               22
}

define service {
    use                 service-users
    host_name           my-server-1234
}

... и ещё около сотни строк в таком же духе

А вот новая:

add( my-server-1234, 1.2.3.4, (), (
    ( ping ),
    ( ssh, _port 2222 ),
    ( tcp, service_description SSH honeypot, _port 22 ),
    ( users ),
    ( procs ),
    ( mem ),
    ( load ),
    ( conns ),
    ( disk ),
    ( proc, service_description App servers, _warn 1:1, _crit 1:1, _proc java ),
    ( filelines, service_description App users, _file /var/db/app/usersdump.txt, _pattern Nobody online, _args -v ),
))

Выгода, как мне кажется, очевидна. На минимальное изучение m4, составление макросов, и переписывание конфигурации Nagios (~100 сервисов) ушло менее одного дня. Более объёмные конфигурации можно переписывать небольшими порциями - весь текст в файле, не являющийся макросами m4, будет скопирован на выход без изменений.

Помимо очевидного плюса (сокращение писанины и копипасты), данный подход имеет парочку неприятных минусов:- После редактирования конфигурации необходимо не забывать запускать m4;

  • Некоторые символы и слова требуют специального внимания т.к. могут быть интерпретированы в m4.

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

Комментарии