Ответ 1
Здесь вы должны использовать шеф-повара. Гвардейцы определяют условное выполнение, но все же вставляют ресурс в коллекцию ресурсов. В вашем примере и ответе jtblin ресурс никогда не добавляется в коллекцию (что я объясню чуть позже).
Вот какой рабочий код, чтобы вы начали:
windows_batch "Backup IIS Config" do
code %Q|#{node['iis']['home']}"\\appcmd add backup BkpB4Chef|
not_if { ::File.directory?("#{node['iis']['home']}\\backup\\BkpB4Chef") }
end
Используя creates
Многие не-идемпотентные ресурсы Chef также поддерживают параметр creates
, который объясняет, что делает ресурс. Другими словами, что создает windows_batch
. Это может быть файл, каталог или исполняемый файл. Таким образом, следующий код эквивалентен первому ответу.
windows_batch "Backup IIS Config" do
code %Q|#{node['iis']['home']}"\\appcmd add backup BkpB4Chef|
creates"#{node['iis']['home']}\\backup\\BkpB4Chef"
end
Почему not_if
против условной оболочки
Шеф-повар выполняет в два этапа - фазу компиляции и фазу сходимости. На этапе компиляции рецепты обнуляются и ресурсы добавляются в сбор ресурсов. На этапе конвергенции ресурсы в сборке ресурсов выполняются и оцениваются по целевой системе. Итак, рассмотрим следующий пример:
if false
service 'foo' do
action :start
end
end
Это довольно простой рецепт, который запускает сервис, основанный на некоторых условных. Однако в конце этапа компиляции ресурс service
не добавляется в сборку ресурсов. Поскольку рецепт DSL instance_eval
ed, обертывание if false
условно предотвращает чтение кода с помощью Ruby VM. Другими словами, он вроде этого никогда не существует.
Это довольно часто, чтобы уведомлять ресурсы. Позже в рецепте вам может понадобиться перезапустить apache из-за изменения конфигурации. "Правильный" способ сделать это - использовать уведомления:
template '/var/www/conf.d/my.conf.file' do
# ...
notifies :restart, 'service[apache2]'
end
Этот template
не может адекватно уведомлять ресурс службы, потому что он не существует в коллекции ресурсов. Таким образом, этот рецепт не удастся. Это кажется тривиальным примером, но если вы измените условный if false
на тест атрибута node:
if node['cookbook']['use_apache']
service 'apache2' do
action :start
end
end
вы создали дихотомию в своей кулинарной книге, где она будет работать в 50% случаев. К сожалению, большинство кулинарных книг намного сложнее, чем два ресурса, поэтому количество крайних случаев, когда ресурс может уведомить несуществующий ресурс, резко возрастает со сложностью. Это все разрешимо (и демонстрирует правильное поведение) с использованием защитников ресурсов:
service 'apache2' do
action :start
only_if { node['cookbook']['use_apache'] }
end