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

Puppet генерирует ошибки каждый раз при изменении модуля

У меня есть тривиальная установка марионетки 2.7.18 следующим образом:

=== manifests/site.pp ===
node build-1 {
  include mod1
  include mod2
  include mod3
}

=== modules/mod1/manifests/init.pp ===
import "*"

=== modules/mod1/manifests/mod1.pp ===
class mod1 {
  file { "/tmp/mod1.file": ensure => present }
}

=== modules/mod2/manifests/init.pp ===
import "*"

=== modules/mod2/manifests/mod2.pp ===
class mod2 {
  file { "/tmp/mod2.file": ensure => present }
}

=== modules/mod3/manifests/init.pp ===
import "*"

=== modules/mod3/manifests/mod3.pp ===
class mod3 {
  file { "/tmp/mod3.file": ensure => present }
}

Когда я пытаюсь запустить агент марионетки на хосте build-1, я получаю следующее сообщение:

: 0 build-1; sudo puppet agent --noop --test
err: Could not retrieve catalog from remote server: Error 400 on SERVER: Could not find class mod1 for build-1 at /etc/puppet/manifests/site.pp:2 on node build-1
warning: Not using cache on failed catalog
err: Could not retrieve catalog; skipping run

Если я запущу его снова, я получу то же сообщение, но для класса mod2. Запуск в третий раз дает мне сообщение для класса mod3. Наконец, четвертый запуск работает. Но если я ничего не сделаю, кроме как прикоснусь к одному из файлов модуля (например, mod1.pp), мне придется пройти через все это снова; запуск марионеточного агента, пока каждый модуль не перекомпилируется должным образом. Это явно не устойчиво.

Еще кое-что я заметил:

  1. Это похоже на https://stackoverflow.com/questions/15289988/puppet-could-not-find-class-hiccups-often-once-after-manifest-module-change, за исключением того, что одна, похоже, предназначена для версии 3.0, и в сообщении об ошибке, на которое она ссылается, конкретно указано, что она не влияет на 2.7. В любом случае переход на пассажирскую установку не помог.
  2. Если я изменю компоновку модуля, чтобы просто поместить все определение модуля в init.pp вместо импорта реального определения модуля, я не пойму проблемы. Но это плохо масштабируется для сложных модулей.

Есть ли причина, по которой вы не можете определить основной класс в init.pp файл?

Мое понимание обнаружения классов рудиментарно, но файл modules/mod1/mod1.pp будет автоматически проверяться на mod1::mod1 класс, а не mod1 класс.

Насколько мне известно, mod1 класс всегда должен быть определен в init.pp, но это не значит, что там должна быть вся конфигурация вашего модуля - подклассы полезны!

Дизайн модуля, который я считаю рекомендуемым в наши дни, выглядит следующим образом:

mod1/init.pp:

class mod1 {
  include mod1::install
  include mod1::config
  include mod1::service
}

mod1/install.pp:

class mod1::install {
  package { "somepackage":
    ensure => installed,
  }
}

mod1/config.pp:

class mod1::config {
  file { "/etc/someapp.conf":
    content => "foo",
    require => Class["mod1::install"],
    notify  => Class["mod1::service"],
  }
}

mod1/service.pp:

class mod1::service {
  service { "someapp":
    ensure => running,
  }
}

Редактировать: далее, вы не должны использовать import внутри модулей:

http://docs.puppetlabs.com/puppet/2.7/reference/lang_import.html

Поведение импорта в автоматически загружаемых манифестах не определено и может варьироваться случайным образом между второстепенными версиями Puppet. Вы никогда не должны помещать операторы импорта в модули; они должны существовать только в site.pp.