![Puppet 类继承混乱](https://linux22.com/image/529084/Puppet%20%E7%B1%BB%E7%BB%A7%E6%89%BF%E6%B7%B7%E4%B9%B1.png)
我已经阅读了有关范围的文档,但我仍然无法解决这个问题。我有两个非常相似的环境 - 所以我得到了:
模块/django-env/manifests/init.pp
class django-env {
package { "python26":
ensure => installed
}
# etc ...
}
import "er.pp"
模块/django-env/manifests/er.pp
$venvname = "er"
$venvpath = "/home/django/virtualenvs"
class er {
file { "$venvpath/$venvname" :
ensure => directory
}
# etc ...
}
class er-dev {
include er
}
class er-bce-dev {
$venvname = "er-bce"
include er
}
清单/模块.pp
import "django-env"
清单/节点.pp
node default {
# etc ...
}
node 'centos-dev' imports default {
include django-env
include er-bce-dev
include er-dev
}
这里的结果是“继承”起作用了 - 但只有“centos-dev”节点下的第一个“er-”项被执行,我要么得到 er-bce-dev 或 er-dev,但不能同时得到两者。这里肯定有一些我误解的基本内容。
这是进口和包括?(不确定我是否理解)
答案1
Puppet 不支持这种配置,但这种限制很容易被绕过。原因在于两个基本的 puppet“规则”:
- 一个类只能被包含一次(后续的包含语句将不执行任何操作)
- 执行顺序没有严格定义,甚至可以是随机的
er-dev
和er-bce-dev
都包含类er
。但是 类 不能包含两次,因此er
类 只与 default$venvname = "er"
或 overridden一起执行$venvname = "er-dev"
,而不能同时执行。
解决方案:将er
类更改为定义(请参阅 Puppet 语言教程中的“定义”)http://docs.puppetlabs.com/guides/language_tutorial.html)):
模块/django-env/manifests/er.pp
# Create new er resource definition
define django-env::er($vpath="/home/django/virtualenvs", $vname="er") {
file { "$vpath/$vname" :
ensure => directory
}
# etc ...
}
我们不需要$venvname
和$venvpath
变量,它们在定义中被指定为默认值。名称django-env::er
将定义添加到django-env
命名空间并允许自动导入(见下文)。
导入和包含
import
和语句之间的区别include
是:
import
处理文件,不执行类include
执行类- 必须先导入文件,然后才能包含类
注意:最后一条规则有一个非常强烈的例外:Puppet 模块查找.include
语句在很多情况下都会自动导入。以下是其中一些:
include foo
尝试导入文件module_dir/foo/manifests/init.pp
include foo::bar
进口module_dir/foo/manifests/bar.pp
通过这些自动导入和资源定义,您可以非常轻松地定义多个虚拟环境。更改node 'centos-dev'
:
node 'centos-dev' imports default {
include django-env
# The er resource with default values:
django-env::er { 'er-bce': }
# Another er resource with different environment name:
django-env::er { 'er-bce-dev': vname => 'bce-dev'}
}
并且您可以删除基本上所有import
考虑模块的语句django-env
。
快乐玩木偶!
答案2
Puppet 语法不断发展,自 Puppet 3.7 以来,您会收到很多弃用警告。关键字import
和inherits
已弃用。不要使用如下布局:
/etc/puppet
/manifests
/nodes
site.pp
/modules
puppet.conf
你应该使用:
/etc/puppet
/environments
/production
/manifests
01_base_node.pp
/modules
environment.conf
puppet.conf
不要使用传统的site.pp
配置:
import 'nodes/*.pp'
node default {
classs{'ntp': }
}
你应该使用标准class
(但你不能class default
称它为保留字), 一份文件manifets/01_common.pp
:
class common {
classs{'ntp': }
}
文件按照字母顺序加载,因此您应该确保首先加载“基类”(编号可能是一个好主意)。
然后,不要定义如下节点:
node /^web\d+/ inherits default {
}
而是使用(解决了经典的多重继承问题,所谓的钻石问题),例如定义在manifests/web.pp
node /^web\d+/ {
include common
# include something_else
}