Como usar o diretório atual do modelo de livro de receitas para copiar todos os modelos de forma recursiva em um loop com o chef

4

Estou tentando descobrir como posso construir o caminho para a pasta templates (ou arquivos, já que funciona da mesma maneira), então eu poderia ler e usar o recurso de modelo no loop, para que cada arquivo de modelo pudesse disparar notificação sobre mudança.

Não consigo usar o remote_directory porque quero notificar os serviços somente se o modelo for alterado.

Eu também gostaria de evitar a especificação manual do modelo, já que pode haver muitos arquivos dentro desses diretórios. Além disso, nos permite alterar apenas as configurações na pasta de modelos sem tocar na receita.

O principal problema são os subdiretórios como padrão, host, host-version e o chef lógico passa para determinar a pasta correta dos templates. Eu estava pensando que talvez houvesse um método em uma das aulas de chef que eu poderia chamar do meu livro de receitas personalizado para chegar ao ponto de partida para a minha lógica (loop).

Deve ser algo assim, eu acho:

entry_point = CHEF::...getEntryPointDir

entry_point.glob..
.each do

    template fname do
    ...
    end

end

Eu gostaria de receber ajuda!

    
por gansbrest 11.07.2013 / 21:34

4 respostas

7

AVISO: Esta solução usa uma interface privada que pode ser alterada ou removida sem aviso. No momento, o Chef (13.x) não fornece uma maneira suportada de resolver esse problema - considere uma abordagem alternativa para resolver sua necessidade.

Agora que você foi avisado, veja como você faria isso em uma receita:

# Get the Chef::CookbookVersion for the current cookbook
cb = run_context.cookbook_collection[cookbook_name]

# Loop over the array of files.
# 'templates' will also work.
cb.manifest['files'].each do |cookbookfile|
  Chef::Log("found: " + cookbookfile['name'])
end

Eu compartilhei uma receita de exemplo para mostrar isso no contexto.

Na prática, isso precisa ser mais complicado - por exemplo, você pode querer apenas um subconjunto dos arquivos / modelos no livro de receitas, ou precisa transformar os caminhos de alguma forma. Considere escrever uma função de biblioteca que faça uma lista dos arquivos de seu interesse e chame isso da sua receita.

    
por 27.07.2013 / 22:49
3

Obrigado "zts". Eu criei um para criar um diretório de templates com todos os arquivos .erb dentro dele.

cb = run_context.cookbook_collection[cookbook_name]
# you may get 'files' OR 'templates' from manifest
cb.manifest['templates'].each do |tmpl_manifest|
  filepath = tmpl_manifest['path']
  next if not filepath =~ /#{cmk_colo}\/server\/checks\/.*erb/
  filename = tmpl_manifest['name'].split(".erb")[0]
  fileshortpath=filepath.split("/",3)[2]
  template "/opt/omd/sites/prod/etc/check_mk/conf.d/checks/#{filename}" do
    source  fileshortpath
    mode '0644'
    owner 'prod'
    group 'prod'
  end
end

este obtém o caminho completo / longo para todos os arquivos .erb nos templates dir. Se o caminho corresponder ao nome do diretório que você deseja fazer um loop, ele será criado por meio da receita de modelo padrão.

    
por 15.09.2015 / 21:12
3

Obrigado ao @zts & @Zaur Eu pensei em postar minha resposta completa que acabou combinando ambas. A coisa mais importante a se notar é que o nome do seu livro de receitas deve estar entre aspas. Isso não era óbvio para mim e foi um pouco bloqueador no meu caso.

Em segundo lugar, em vez de usar a pesquisa RegEx do Zaur para filtrar caminhos de arquivo, estou usando uma maneira mais "ruby" de fazer uma comparação de string para ver se o caminho contém um diretório específico:

# Get the Chef::CookbookVersion for this cookbook
cb = run_context.cookbook_collection['cookbook_name']

# Loop over the array of files
cb.manifest['files'].each do |cbf|
  # cbf['path'] is relative to the cookbook root, eg
  #   'files/default/foo.txt'
  # cbf['name'] strips the first two directories, eg
  #   'foo.txt'
  filepath = cbf['path']
  filename = cbf['name']

  next if not filepath.include? "directory-to-filter-for/"

  cookbook_file "/etc/service/conf.d/#{filename}" do
    source "directory-to-filter-for/#{filename}"
    mode 0600
    owner "root"
    group "root"
  end
end

Estou usando isso para arquivos, mas você também pode usar modelos. Basta substituir o bloco "modelo" em vez do bloco "arquivo" na linha 14. Em seguida, altere a linha 5 para usar modelos em vez de arquivos:

cb.manifest['templates'].each do |cbf|
    
por 09.04.2016 / 05:22
0

Em Chef > 12.19 há uma mudança de quebra (RFC 67) no manifesto que combina todos os arquivos em um livro de receitas em :all_files

Veja o link

Para retornar uma lista de todos os modelos, você agora usa:

run_context.cookbook_collection[:examplecookbook].files_for('templates')

    
por 08.10.2018 / 17:01