Как использовать текущий каталог шаблонов поваренной книги для рекурсивного копирования всех шаблонов с помощью chef

Я пытаюсь выяснить, как я могу построить путь к папке шаблонов (или файлов, поскольку она работает так же), затем я мог бы прочитать ее и использовать ресурс шаблона в цикле, чтобы каждый файл шаблона мог вызывать уведомление об изменении,

Я не могу использовать remote_directory, потому что хочу уведомлять сервисы только в случае изменения шаблона.

Я также хотел бы избежать ручной спецификации шаблона, поскольку внутри этих каталогов может быть много файлов. Плюс это позволило бы нам изменять только конфиги в папке с шаблонами, не трогая рецепт.

Основная проблема заключается в таких подкаталогах, как default, host, host-version, и шеф-повар логики определяет правильную папку шаблонов. Я подумал, может быть, есть метод в одном из классов Chef, который я мог бы вызвать из своей пользовательской кулинарной книги, чтобы добраться до начальной точки для моей логики (цикла).

Это должно быть что-то вроде этого, я думаю:

entry_point = CHEF::...getEntryPointDir

entry_point.glob..
.each do

    template fname do
    ...
    end

end

Буду признателен за любую помощь!

4 ответа

Решение

ПРЕДУПРЕЖДЕНИЕ. В этом решении используется закрытый интерфейс, который может быть изменен или удален без предупреждения. В настоящее время шеф-повар (13.x) не предоставляет поддерживаемый способ решения этой проблемы - рассмотрите альтернативный подход к решению ваших требований.

Теперь, когда вы были предупреждены, вот как вы это сделаете в рецепте:

# 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

Я поделился примером рецепта, чтобы показать это в контексте.

На практике это должно быть более сложным - например, вам может потребоваться только подмножество файлов / шаблонов в кулинарной книге или вам нужно каким-то образом преобразовывать пути. Попробуйте написать библиотечную функцию, которая составляет список интересующих вас файлов, и вызвать ее по своему рецепту.

Спасибо "зтс". Я создал один, чтобы создать каталог шаблонов со всеми файлами.erb внутри него.

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

этот получает полный / длинный путь ко всем файлам.erb в шаблонах dir. Если путь совпадает с именем каталога, который вы хотите зациклить, он создает его по стандартному шаблону рецепта.

Благодаря @zts & @Zaur. Я думал, что выложу свой полный ответ, который в конечном итоге сочетал оба. Самое важное, на что стоит обратить внимание, это то, что название вашей поваренной книги должно быть в кавычках. Это не было очевидно для меня и было немного блокирующим в моем случае.

Во-вторых, вместо того, чтобы использовать поиск RegEx @ Zaur для фильтрации путей к файлам, я использую более "рубиновый" способ сравнения строк, чтобы увидеть, содержит ли путь конкретный каталог:

# 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

Я использую это для файлов, но вы также можете использовать шаблоны. Просто замените блок 'template' вместо блока 'file' в строке 14. Затем измените строку 5, чтобы использовать шаблоны вместо файлов:

cb.manifest['templates'].each do |cbf|

В Chef > 12.19 есть явное изменение (RFC 67) в манифесте, который объединяет все файлы в кулинарной книге под :all_files

См. https://chef.github.io/chef-rfc/rfc067-cookbook-segment-deprecation.html

Чтобы вернуть список всех шаблонов, вы теперь используете:

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

Другие вопросы по тегам