Как проверить, существует ли папка в Chef?

Это мой код:

if !::File.exist?("#{node['iis']['home']}\\backup\\BkpB4Chef")
 windows_batch "Backup IIS Config" do
  code <<-EOH
   "#{node['iis']['home']}"\\appcmd add backup BkpB4Chef
  EOH
 end
end

Он всегда говорит, что файл существует и выполняет цикл.

Ответ 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

Ответ 2

Используйте Dir.exists?. Вы также можете заменить if ! condition на unless condition, который читается немного лучше.

unless Dir.exist? "#{node['iis']['home']}\\backup\\BkpB4Chef"
 windows_batch "Backup IIS Config" do
  code <<-EOH
   "#{node['iis']['home']}"\\appcmd add backup BkpB4Chef
  EOH
 end
end