Конфигурации

Со всех сторон нас окружают файлы конфигураций. Иногда, это просто некий набор значений по умолчанию, который читается на старте и пишется при изменениях. Такой тип конфигураций обычно оказывается в более-менее приемлемом и читабельном виде вне зависимости от его формата. Но периодически приходится сталкиваться с довольно странной формой извращения – “программирование на конфигурациях”. Обычно для этих целей берется совершенно не пригодный инструмент, например XML файл или, что еще хуже, база данных и придумывается загадочный псевдоязык для скрещивания логически не совместимых вещей.

О кошмарах

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

Чуть менее ужасное творение с которым мне недавно пришлось повозиться был WIX. По большому счету, это тоже псевдоязык программирования, но уже не поверх базы данных, а на базе XML. Решение чуть менее кривое чем в случае с базами данных, но все же можно было сделать в разы проще и понятнее.

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

Хотя иногда можно найти более чем адекватные решения. Так мне очень понравился подход Эппл к конфигурациям в SandBox. Использование простого скриптового языка для описания конфигурации меняет процесс настройки приложения с ног на голову. Логически не приложение проходит по файлу концигурации и инициализирует значения своих переменных, а файл конфигурации, исполняясь, выставляет значения необходимых переменный.

В принципе, все можно было сделать по старинке, и приведенный мной ранее скрипт для запуска Firefox в песочнице практически наглядный тому пример. Секция “разрешить чтение”, секция “разрешить запуск”, выставления ряда одиночных переменный (“дать доступ к tcp”, “дать доступ к udp”) отлично лягут на классический конфигурационный файл в том же ini или xml формате. Если же посмотреть на файл с правилами внимательно, станет очевидно что в нем имеются повторения, которые можно было бы сгруппировать плюс я для упрощения игнорировал получение ряда переменных окружения, ту же директорию текущего пользователя и т.п. В общем случае это означает то, что размер можно сократить, а читаемость повысить. Небольшой пример (на небольших данных подобный подход большое похож на вредительство, но это просто пример).

(define (shared-preferences-read . domains)
  (for-each (lambda (domain)   
      (begin   
        (allow file-read*  
            (literal (string-append "/Library/Preferences/" domain))   
            (regex (string-append "^/Users/.*/Library/Preferences" domain))
        )  
      )) domains)) 
   
(shared-preferences-read    
  "\.GlobalPreferences\.plist" 
  "com.apple.HIToolbox.plist")

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

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

4 Comments Конфигурации

  1. antoxa

    Неплохой пример в тему – tarantool.org, начиная с версии 1.6 там “конфиги” на lua, при старте сервер читает некоторый “конфиг”, который выполняясь, все настраивает.

    Учитывая, что оно вообще заточено целиком под lua – довольно удобно.

    Reply
    1. Alexander Stavonin

      Да, если конфиг выходит сложнее чем просто чтение переменных из файла, то использование интерпретатора типа Lua или Scheme очень адекватное решение.

      Reply

Leave a Reply