Назад | Перейти на главную страницу

Проблемы с модулем Puppet, включающим только подкласс, который, похоже, неявно включает родительский класс

Мне сложно понять, как Puppet выполняет наследование и автоматическое включение модулей.

У меня есть класс Puppet, который работает должным образом, когда я тестирую его «локально», но не работает, когда я отправляю его на свои узлы через сервер Puppet.

«Локально» означает проход через puppet apply и отправка правильного пути к локальному модулю.

Вот пример классов и того, что происходит. Я попытался сократить это до минимального количества вещей, которые вызывают эту проблему, однако признаю, что не уверен, что могу пропустить что-то важное.

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

Объявление моего узла выглядит следующим образом:

node /myserver.*/ {
    include myclass::server
}

Манифесты объявлены следующим образом:

# File "myclass/manifests/init.pp"
class myclass {

    file { '/etc/oldconfig.conf':
        ensure => file,
        owner  => root,
        group  => root,
        mode   => '0644',
        source => 'puppet:///files/oldconfig.conf',
    }

}

# File "myclass/manifests/server.pp"
class myclass::server {
    include myclass::next
}

# File "myclass/manifests/next.pp"
class myclass::next {

    # Remove clutter
    file { '/etc/oldconfig.conf':
        ensure => absent
    }

    ... more stuff, not relevant ...
}

Подводя итог, исходный init.pp включает файл "oldconfig.conf". Новый класс модуля "следующий", удаляет этот файл.

Когда я запускаю модуль с помощью команды «puppet apply» (т.е. локально), я не получаю никаких конфликтов, и выполнение заканчивается с нулевым статусом выхода.

Но когда я бегу puppet agent -t на реальном узле, который извлекает манифесты с марионеточного сервера, я получаю следующее:

Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Duplicate declaration: File[/etc/oldconfig.conf] is already declared in file /etc/puppet/environments/common/myclass/manifests/init.pp:48; cannot redeclare at /etc/puppet/environments/common/myclass/manifests/next.pp:4 on node mynode01.example.com

Есть ли какое-то наследование манифеста Puppet и / или автоматическое включение, которое происходит при прогонах от Puppetmaster, которые отличаются от локального? puppet apply работает?

Если я включу просто подкласс - например, include myclass::my_subclass - в объявлении узла манифеста Puppet, следует ли ожидать, что подкласс всегда будет ссылаться на родительский класс? Я не помню, чтобы видел такое поведение до этого примера, и я также не смог найти явной документации, отвечающей на этот вопрос. (Хотя это довольно сложно для Google)

Мне сложно понять, как Puppet выполняет наследование и автоматическое включение модулей.

В вашем примере нет наследования, подклассов или родительских классов, я так не думаю. Именование отличается от наследования, оно не должно означать, что родительский класс включен в каталог.

Есть ли какое-то наследование манифеста Puppet и / или автоматическое включение, которое происходит при прогонах от мастера марионеток, которые отличаются от прогонов применения локальной марионетки?

  1. На вашем Мастере Марионеток могут быть манифесты сайта, которые не используются в вашем локальном apply запустить. Они могут включать в себя класс прямо или косвенно через hiera_include или похожие. Проверьте любые манифесты сайта и использование hiera_include и ваши файлы данных, если применимо.
  2. Классификаторы внешних узлов могут быть настроены на главном устройстве со списком классов для включения в узел.

Попробуйте добавить отладку в myclass класс, чтобы показать, откуда он включен:

notice("myclass included by $caller_module_name")

(https://docs.puppet.com/puppet/latest/reference/lang_facts_and_builtin_vars.html#compiler-variables)

Это может ничего не отображать, если включено из ENC.