有时包之间的交互很复杂。为了避免类接口中出现无数看似不相关的参数,我考虑使用标签、 defined(<resource>)
函数让资源根据其余配置(而非事实)稍微改变其行为。
不幸的是,我无法找到一种方法让 Puppet 首先解析可以生成条件的类,然后再解析其行为隐式(例如通过标签)取决于第一个类的执行方式的类。
假设这里有一个类,它管理特定用户存储其敏感个人数据的地方。该类可以例如创建分区(可能已加密),或者仅维护外部文件夹(例如 /mnt/user)。或者它可以将文件夹保留在默认位置,即 /home/user(spurcetype=>'none')
class userdocs ( $sourcetype) {
case $sourcetype {
'cryptpartition' : {
tag 'dedicated_user_docs_partition'
...
}
'partition' : {
tag 'dedicated_user_docs_partition'
...
}
'none' : {
...
}
}
...
}
除了用户可能想要转发到其分区的相当标准的文件夹集之外,还有一些文件夹的存在取决于正在运行的特定软件,如 thunderbird 或 virtualbox。仅当满足两个条件时,才应为 virtualbox 创建链接(而不是文件夹):a) 用户管理单独的分区(tagged('dedicated_user_docs_partition')
)和用户安装 VirtualBox。
必须有一个地方可以放置额外的代码,用于检查这两个条件。我可以将其放入管理虚拟盒的类中:
class vbox {
if tagged('dedicated_user_docs_partition') {
file { "${userhome}/.VirtualBox": ensure=>link, require=>Class['userdocs'] ...
}
} else {
file { "${userhome}/.VirtualBox": ensure=>directory, require=>Class['userdocs'] ...
}
}
...
}
问题是,尽管我明确要求file
执行资源前类userdocs
,file
资源被评估后而且,puppet 错误地认为用户没有,dedicated_user_docs_partition
因此执行了语句的错误分支if
。
有什么办法可以解决这个问题吗?
我已经在ask.puppet.com。
答案1
这是一个使用虚拟资源的答案,lavaman
建议如此。
我不喜欢这样的事实,它迫使我将带有“VirtualBox”的代码放入类中,而我认为该类在逻辑上应该独立于它。但我认为可以使用委托类(如 userdocs::virtualbox,在其他地方完全定义)来解决这个问题。
class userdocs ( $sourcetype) {
case $sourcetype {
'cryptpartition' : {
@file { "${userhome}/.VirtualBox": ensure=>link, ...
}
...
}
'partition' : {
@file { "${userhome}/.VirtualBox": ensure=>link, ...
}
...
}
'none' : {
@file { "${userhome}/.VirtualBox": ensure=>directory, ...
}
...
}
}
...
}
和
class vbox {
realize File["${userhome}/.VirtualBox"]
...
}
答案2
此答案归功于lavaman
ask.puppetlabs.com 上的用户:
假设您也使用 puppet 管理软件(从您的示例代码来看确实如此),我会在软件模块中使用由处理挂载的模块收集的虚拟资源。
官方文档: https://puppet.com/docs/puppet/latest/lang_virtual.html