Дано
манифест/site.pp
...
include foo::bar
include baz::alpha
include baz::beta
include baz::gamma
...
Где
foo::bar
создает/etc/puppetlabs/puppet/config_file.yaml
- От
foo::alpha
доfoo::gamma
— это настраиваемые типы, которые используют классыpuppet_x
, для работы которых требуется указанный выше файл, и выдаетPuppet::Error
, если файл недоступен. - Классы с
baz::alpha
поbaz::gamma
используют пользовательские типыfoo:beta`` through
foo:gamma``` для определения ресурсов.
Вопрос
Как я могу гарантировать, что foo::bar
будет выполняться до конца независимо от сбоя любого из классов baz
?
Я открыт для любых предложений о том, как этого добиться. Предпочтительным решением было бы такое, которое не требует массовой перезаписи для foo
пользовательских типов, но если это единственный способ, я это сделаю.
Попытки
- Использование
Class['foo::bar'] -> Class[...] -> ...
(штриховая стрелка) для обеспечения порядка применения. - Использование
Class['foo::bar'] ~> Class[...] -> ...
(тильда-стрелка) для обеспечения порядка применения. - Добавление
autorequire(:file)
ко всем пользовательским типам сfoo::alpha
поfoo::gamma
. - Не оставляя никакой связи между
foo::bar
и любым другим классом. - Попытка
catch Puppet:error do err(message) end
во всехfoo
поставщиках пользовательских типов.
Реальная проблема
Я не знал, что Puppet попытается создать экземпляры всех классов, прежде чем применить изменения, которые должен был выполнить любой из них. Даже когда используется «этап», все классы инициализируются до того, как что-либо будет сделано.
Что на самом деле происходило, так это то, что один из пользовательских типов пытался использовать служебный класс Ruby, который зависел от файла конфигурации, который был бы создан классом foo::bar
в его собственном методе «инициализации».
Этот служебный класс мог бы привести к катастрофическому сбою, если бы файл конфигурации отсутствовал. Что приведет к обратному каскаду к Puppet и приведет к сбою всего запуска.