Да, это нормально. 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
Таким образом, ресурс добавляется в каталог, только если его там еще нет.