A execução do livro de receitas do chef não funciona passo a passo

1

Minha configuração de receita é assim:

package "scribe" do
  action :install
end

package "supervise-scripts" do
   action :install
end

remote_directory "/var/service/" do
   source "#{node['site-scribe']['cluster']}"
end

Dir.foreach('/var/service') do |dir|
next if dir == '..'|| dir == '.'
  execute "svc_add_#{dir}" do
    command "/usr/bin/svc-add #{dir}"
    not_if { ::Dir.exists?("/var/service/#{dir}/supervise") }
  end

  execute "svc_restart_#{dir}" do
    command "/usr/bin/svc-restart #{dir}"
  end
end

E agora eu tenho um comportamento estranho ... na primeira execução do cliente-chefe no servidor, ele está executando somente o bloco remote_directory e não inicia o Dir.foreach loop. Na segunda execução ele executa Dir.foreach normalmente (sempre quando remote_directory não foi baixado). Por que meu loop Dir.foreach não está iniciando se remote_directory block foi executado?

O mesmo comportamento é quando eu removo esse not_if .

// holosiano

    
por user3069488 27.03.2015 / 15:33

1 resposta

1

O loop Dir.foreach é executado antes que a ação do diretório remoto realmente ocorra. Chef executa em duas fases. Durante o primeiro, todo o seu código de receita é executado e os recursos são colocados em uma matriz para avaliação posterior. Na segunda fase, esses recursos são executados para realmente fazer o trabalho. O que está acontecendo no seu caso, como aludido por StephenKing, é que:

  1. seu bloco remote_directory é executado e coloca um recurso no modelo para desativar esse diretório remoto.
  2. o seu Dir.foreach loop é executado, mas como o recurso para # 1 ainda está na matriz (ainda não foi executado), não há filhos no diretório /var/service . Então, o loop faz um loop sobre 0 elementos e sai.
  3. Na sua segunda execução de chef-client , você tem valores em /var/service , então o loop funciona muito bem.

A menos que você precise fazer uma convergência completa em apenas uma corrida de chef, você realmente não tem nenhum problema. Apenas certifique-se de usar as instruções not_if e only_if para garantir que cada recurso só seja executado quando necessário. No entanto, se você precisa fazer tudo em uma corrida, é necessário hackear uma solução. A opção mais fácil é forçar uma avaliação imediata do seu recurso remote_directory fazendo algo assim:

remote_directory "/var/service/" do
   source "#{node['site-scribe']['cluster']}"
end.run_action(:create)

Isso forçará a ação a ser executada durante a primeira fase da execução do chef e, em seguida, o loop funcionará.

    
por 30.03.2015 / 15:31

Tags