¿Cómo compruebo si existe una carpeta en Chef?

Este es mi código:

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 

Siempre dice que el archivo existe y ejecuta el bucle.

Deberías usar los guardias del chef aquí. Los guardias especifican la ejecución condicional, pero aún así insertan el recurso en la colección de recursos. En su ejemplo y en la respuesta de jtblin, el recurso nunca se agrega a la colección (que explicaré un poco más en un momento).

Aquí hay algunos códigos de trabajo para comenzar:

 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 

Usando creates

Muchos recursos de Chef que no son idempotentes también admiten un parámetro de creates , que explica qué hace el recurso. En otras palabras, ¿qué “crea” el windows_batch ? Esto puede ser un archivo, directorio o ejecutable. Entonces, el siguiente código es equivalente a la respuesta anterior.

 windows_batch "Backup IIS Config" do code %Q|#{node['iis']['home']}"\\appcmd add backup BkpB4Chef| creates"#{node['iis']['home']}\\backup\\BkpB4Chef" end 

¿Por qué not_if vs la envoltura condicional

Chef ejecuta en dos fases: la fase de comstackción y la fase de convergencia. Durante la fase de comstackción, las recetas se evalúan y los recursos se agregan a la colección de recursos. En la fase de convergencia, los recursos de la colección de recursos se ejecutan y evalúan en relación con el sistema de destino. Entonces, considere el siguiente ejemplo:

 if false service 'foo' do action :start end end 

Esta es una receta bastante sencilla que inicia un servicio basado en algunos condicionales. Sin embargo, al final de la fase de comstackción, el recurso de service no se agrega a la colección de recursos. Dado que la receta DSL es instance_eval ed, el ajuste if false condicional impide que Ruby VM lea ese código. En otras palabras, es como si el servicio nunca existiera.

Es bastante común notificar recursos. Más adelante en la receta, es posible que desee reiniciar Apache debido a un cambio de configuración. La forma “correcta” de hacerlo es mediante el uso de notificaciones:

 template '/var/www/conf.d/my.conf.file' do # ... notifies :restart, 'service[apache2]' end 

Esta template no puede notificar adecuadamente el recurso de servicio, porque no existe en la colección de recursos. Así que esta receta va a fallar. Parece un ejemplo trivial, pero si cambia el condicional if false a una prueba de atributo de nodo:

 if node['cookbook']['use_apache'] service 'apache2' do action :start end end 

ha creado una dicotomía en su libro de cocina donde funcionará el 50% del tiempo. Desafortunadamente, la mayoría de los libros de cocina son mucho más complejos que dos recursos, por lo que la cantidad de casos en los que un recurso puede notificar a un recurso inexistente aumenta drásticamente con la complejidad. Todo esto es solucionable (y muestra el comportamiento correcto) utilizando recursos de protección:

 service 'apache2' do action :start only_if { node['cookbook']['use_apache'] } end 

Usa Dir.exists? . También puede reemplazar if ! condition if ! condition por unless condition que se lee un poco mejor.

 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