Puppet вызывает один и тот же сервис в нескольких модулях? - PullRequest
1 голос
/ 20 июня 2019

У меня есть кукольный модуль А. В этом модуле у меня есть перезапуск службы для изменения файла.

class A::test1 { 
  include ::corednsclient
  service { 'sshd':
    ensure => running,
    enable => true,
  }
}

Теперь у меня есть другой кукольный модуль B. В этом модуле я также должен перезапустить ту же службу для изменения в другом файле.

Теперь проблема в том, что я получаю следующее:

Duplicate declaration error

когда я делаю / opt / puppetlabs / bin / puppet apply --modulepath = / abc xyz / site.pp

Если я запускаю каждый модуль независимо как puppet, примените -e 'include moduleA' а также puppet apply -e 'include moduleB' , оба будут работать нормально. Но применение кукол во всем мире, похоже, терпит неудачу.

Любая помощь будет принята с благодарностью!

Error: Evaluation Error: Error while evaluating a Resource Statement,
 Duplicate declaration: Service[sshd] is already declared in file 
 /export/content/ucm/puppet/modules/coresshd/manifests/configure.pp:28; cannot
 redeclare at 
 /export/content/ucm/puppet/modules/corednsclient/manifests/daemon_reload.pp:10 at 
 /export/content/ucm/puppet/modules/corednsclient/manifests/daemon_reload.pp:10:3 on 
 node lor1-0002276.int.xxx.com .

1 Ответ

2 голосов
/ 20 июня 2019

Да, это нормально. Puppet позволяет объявлять ресурсы только один раз. В общем, если у вас есть код вроде:

class aaa {
  notify { 'xxx': message => 'yyy' }
}

class bbb {
  notify { 'xxx': message => 'yyy' }
}

include aaa
include bbb

Puppet примените это, и вы увидите ошибку, подобную этой:

Error: Evaluation Error: Error while evaluating a Resource Statement,
 Duplicate declaration: Notify[xxx] is already declared at (file: ...test.pp, 
 line: 2); cannot redeclare (file: ...test.pp, line: 6) (file: ...test.pp, line: 6,
 column: 3) on node ...

Обходные

Решение 1 Рефакторинг, чтобы оба класса наследовали третий класс

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

class ccc {
  notify { 'xxx': message => 'yyy' }
}

class aaa {
  include ccc
}

class bbb {
  include ccc
}

include aaa
include bbb

Это отлично работает.

Обратите внимание, что это работает только потому, что функцию include можно вызывать любое количество раз, в отличие от объявления ресурсов - также в отличие от объявлений классов, подобных ресурсам.

Вы можете узнать больше о «включении-объявлении v-подобных ресурсных объявлений класса» здесь .

Решение 2 Использование виртуальных ресурсов

Вы также можете использовать виртуальных ресурсов . Рефакторинг так:

class ccc {
  @notify { 'xxx': message => 'yyy' }
}

class aaa {
  include ccc
  realize Notify['xxx']
}

class bbb {
  include ccc
  realize Notify['xxx']
}

include aaa
include bbb

Дополнительным преимуществом этого является то, что вы можете использовать сборщиков ресурсов и выбирать только определенные ресурсы из набора виртуальных ресурсов, например:

class ccc {
  @notify { 'ppp': message => 'xxx' }
  @notify { 'qqq': message => 'yyy' }
  @notify { 'rrr': message => 'zzz' }
}

class aaa {
  include ccc
  Notify <| message == 'xxx' |>
}

class bbb {
  include ccc
  Notify <| message == 'xxx' or message == 'yyy' |>
}

include aaa
include bbb

Если вам здесь не нужна эта функциональность, как это выглядит, вам, вероятно, следует использовать первое предложение.

Решение 3 Используйте гарантированный ресурс

Другая опция - это функция ensure_resources в stdlib:

class aaa {
  ensure_resources('notify', {'xxx' => {'message' => 'yyy'}})
}

class bbb {
  ensure_resources('notify', {'xxx' => {'message' => 'yyy'}})
}

include aaa
include bbb

Решение 4 Использование определено

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

class aaa {
  if ! defined(Notify['xxx']) {
    notify { 'xxx': message => 'yyy' }
  }
}

class bbb {
  if ! defined(Notify['xxx']) {
    notify { 'xxx': message => 'yyy' }
  }
}

include aaa
include bbb

Таким образом, ресурс добавляется в каталог, только если его там еще нет.

...