当我和puppet一起工作时,我发现自己想要自动化更复杂的设置,例如X个网站的虚拟主机。 当我的木偶performance变得更加复杂时,我发现很难应用DRY(不要重复自己)的原则。 下面是我之后的简化片段,但是不起作用,因为puppet会根据我使用的类或定义抛出各种错误。 我想从一些经验丰富的傀儡老师那里得到一些关于他们如何接近这个解决scheme的反馈。
# site.pp import 'nodes' # nodes.pp node nodes_dev { $service_env = 'dev' } node nodes_prod { $service_env = 'prod' } import 'nodes/dev' import 'nodes/prod' # nodes/dev.pp node 'service1.ownij.lan' inherits nodes_dev { httpd::vhost::package::site { 'foo': } httpd::vhost::package::site { 'bar': } } # modules/vhost/package.pp class httpd::vhost::package { class manage($port) { # More complex stuff goes here like ensuring that conf paths and uris exist # As well as log files, which is I why I want to do the work once and use many notify { $service_env: } notify { $port: } } define site { case $name { 'foo': { class 'httpd::vhost::package::manage': port => 20000 } } 'bar': { class 'httpd::vhost::package::manage': port => 20001 } } } } }
该代码片段给了我一个Duplicate declaration: Class[Httpd::Vhost::Package::Manage]错误,如果我将manage类切换到一个定义,并尝试访问一个全局或传递一个共同的variablesfoo和酒吧,我得到一个Duplicate declaration: Notify[dev]错误。
有什么build议,我可以如何执行干燥原则,仍然傀儡工作?
– 更新 –
我仍然有一个问题,试图确保我的一些虚拟主机,可能共享父目录,安装正确。 像这样的东西:
node 'service1.ownij.lan' inherits nodes_dev { httpd::vhost::package::site { 'foo_sitea': } httpd::vhost::package::site { 'foo_siteb': } httpd::vhost::package::site { 'bar': } }
我需要发生的是sitea和siteb具有相同的父“foo”文件夹。 我遇到的问题是当我调用一个定义来确保“foo”文件夹存在。 下面是网站的定义,因为我有它,希望这将是有道理的,我正在努力完成。
class httpd::vhost::package { File { owner => root, group => root, mode => 0660 } define site() { $app_parts = split($name, '[_]') $app_primary = $app_parts[0] if ($app_parts[1] == '') { $tpl_path_partial_app = "${app_primary}" $app_sub = '' } else { $tpl_path_partial_app = "${app_primary}/${app_parts[1]}" $app_sub = $app_parts[1] } include httpd::vhost::log::base httpd::vhost::log::app { $name: app_primary => $app_primary, app_sub => $app_sub } } } class httpd::vhost::log { class base { $paths = [ '/tmp', '/tmp/var', '/tmp/var/log', '/tmp/var/log/httpd', "/tmp/var/log/httpd/${service_env}" ] file { $paths: ensure => directory } } define app($app_primary, $app_sub) { $paths = [ "/tmp/var/log/httpd/${service_env}/${app_primary}", "/tmp/var/log/httpd/${service_env}/${app_primary}/${app_sub}" ] file { $paths: ensure => directory } } }
include httpd::vhost::log::base工作正常,因为它是“包含”,这意味着它只实现了一次,即使site被调用多次。 我得到的错误是: Duplicate declaration: File[/tmp/var/log/httpd/dev/foo] 。 我看着使用exec ,但不知道这是正确的路线,当然其他人必须先处理这个问题,任何有识之士的赞赏,因为我一直在努力这几个星期。 谢谢。
首先 – 你一定要使用httpd::vhost::package::manage ,而不是class ,因为它将被定义多次为同一个节点。
notify { $service_env: }将总是吹捧的事情,因为$service_env dev这两个调用的define 。 您不能再次用相同的名称声明相同的资源。
你可以通过切换到notify { "${service_env}-${port}": }解决这个问题,但是如果这个问题没有被正确地构build来处理被设置为一个定义types。
一直到httpd::vhost::package::manage的类结构都是奇怪的 – 我build议真的把事情减less到一个简化的事情,让你只有资源需要。
httpd (init.pp - have it include the install, config, service classes) httpd::install (install.pp - have it define Package[httpd] to install) httpd::service (service.pp - have it define Service[httpd]; the vhost defines can notify this to update) httpd::config (config.pp - any configuration, such as handling of httpd.conf, that won't be per-vhost) httpd::vhost (vhost.pp - the defined type that can be used multiple times. Have it include httpd so that the base classes are handled, and notify httpd::service from your vhost config file resources)
虚拟主机pipe理的一个简单的例子实际上是文档中定义types的例子 – 让我知道如果你需要任何其他的澄清如何设置这是一个很好的可重用的configuration位!
编辑:
更新共享父目录的问题。
从两个不同的地方pipe理一个文件是Puppet的一个难题,也给我带来了麻烦。 尤其令人沮丧的是,当前的两个资源声明之间没有冲突。
你是对的, exec资源可能是你最好的答案。
define app($app_primary, $app_sub) { exec { "mkdir_${service_env}_${app_primary}_${app_sub}": command => "/bin/mkdir -p /tmp/var/log/httpd/${service_env}/${app_primary}/${app_sub}", creates => "/tmp/var/log/httpd/${service_env}/${app_primary}/${app_sub}", require => Class["httpd::vhost::log::base"], } }
这适用于这两种情况(有和没有子目录),因为你设置$app_sub为一个空string,如果它没有被使用。
我认为,只是不共享一个目录树(使用log/httpd/foo_sitea作为日志目录而不是log/httpd/foo/sitea )可能会更log/httpd/foo/sitea ,但是这应该可以做到。 分裂的string和行为不同的基础上,所有这些单独的define当这可以真正活在site类..确保保持简单!