Как обновить шаблон ERB со вставленным файлом за один запуск Puppet? - PullRequest
0 голосов
/ 21 октября 2018

Я пытаюсь создать файл в Puppet 5, используя шаблон ERB.Этот файл ERB использует переменные класса обычным образом, но также создается путем вставки другого локального файла, управляемого Puppet.Однако я обнаружил, что всякий раз, когда я обновляю вставленный файл, требуется два запуска Puppet для обновления файла, созданного ERB.Я хочу, чтобы обновление происходило при одном запуске Puppet.

Проще всего это увидеть на примере:

# test/manifests/init.pp
class test {
  # This file will be inserted inside the next file:
  file { '/tmp/partial.txt':
    source => 'puppet:///modules/test/partial.txt',
    before => File['/tmp/layers.txt'],
  }

  $inserted_file = file('/tmp/partial.txt')
  # This file uses a template and has the above file inserted into it.
  file { '/tmp/layers.txt':
    content => template('test/layers.txt.erb')
  }
}

Вот файл шаблона:

# test/templates/layers.txt.erb
This is a file
<%= @inserted_file %>

Если я внесу изменение в файл test/files/partial.txt, потребуется два Выполнение Puppet для изменения, чтобы распространиться на /tmp/layers.txt.По эксплуатационным причинам важно, чтобы обновление происходило только за один запуск Puppet.

Я пытался использовать различные зависимости (before, require и т. Д.) И даже этапы Puppet, но все, что я пытался до сих портребуется два запуска Puppet.

Хотя можно достичь того же результата, используя ресурс exec с sed (или что-то подобное), я бы предпочел использовать «чистый» подход Puppet.Это возможно?

1 Ответ

0 голосов
/ 21 октября 2018

Я пытаюсь создать файл в Puppet 5, используя шаблон ERB.Этот файл ERB использует переменные класса обычным способом, но также создается путем вставки другого локального файла, управляемого Puppet.

Запуск Puppet выполняется в три основных этапа:

  1. Сбор фактов
  2. Создание каталога
  3. Приложение каталога

Манифесты марионеток полностью оцениваются на этапе создания каталога, включая оценку всех шаблонов и вызовов функций.Более того, при настройке master / agent сборка каталога происходит на master, так что это «локальная система» на этом этапе.Все изменения целевой системы происходят на этапе применения каталога.

Таким образом, ваш

  $inserted_file = file('/tmp/partial.txt')

выполняется во время построения каталога до применения File[/tmp/partial.txt].Поскольку вы указываете абсолютный путь к функции file(), она пытается использовать версию, уже имеющуюся в системе построения каталога, которая не обязательно является даже машиной, для которой создается манифест.

Мне непонятно, почему вы хотите установить и управлять частичным результатом в дополнение к полному шаблонному файлу, но если это действительно так, то мне кажется, что лучший способ сделать это - прокормить обаиз того же источника вместо того, чтобы пытаться накормить одного из другого.Для этого вы можете использовать возможность функции file загружать данные из файла в каталог (10) * (любого) модуля, аналогично тому, как это делает File.source.

Например,

# test/manifests/init.pp
class test {
  # Reads the contents of a module file:
  $inserted_file = file('test/tmp/partial.txt')

  file { '/tmp/partial.txt':
    content => $inserted_file,
    # resource relationship not necessary
  }

  file { '/tmp/layers.txt':
    # interpolates $inserted_file:
    content => template('test/layers.txt.erb')
  }
}

Обратите внимание, что комментарии в вашем примере манифеста вводят в заблуждение.Ни предоставленный вами файловый ресурс, ни содержимое файла, которым он управляет, не интерполируются в ваш шаблон, если это не случайно.Что интерполируется, так это значение переменной $inserted_file класса, который оценивает шаблон.

...