我有两个不同版本的linux / unix,每个版本都运行cfengine3。是否有可能有一个promises.cf文件我可以放在两台机器上,根据客户端上的操作系统复制不同的文件?我一直在互联网上搜索几个小时,但还没有找到任何有用的东西。
答案 0 :(得分:4)
有几种方法可以做到这一点。最简单的是,您可以简单地使用不同的文件:promises取决于操作系统,例如:
files:
ubuntu_10::
"/etc/hosts"
copy_from => mycopy("$(repository)/etc.hosts.ubuntu_10");
suse_9::
"/etc/hosts"
copy_from => mycopy("$(repository)/etc.hosts.suse_9");
redhat_5::
"/etc/hosts"
copy_from => mycopy("$(repository)/etc.hosts.redhat_5");
windows_7::
"/etc/hosts"
copy_from => mycopy("$(repository)/etc.hosts.windows_7");
通过认识到内置的CFEngine变量$(sys.flavor)包含操作系统的类型和版本,可以很容易地简化这个例子,所以我们可以按如下方式重写这个例子:
"/etc/hosts"
copy_from => mycopy("$(repository)/etc.$(sys.flavor)");
实现此任务的更灵活的方法在CFEngine术语中称为" hierarchical copy。"在此模式中,您可以指定要区分文件的任意变量列表,以及从最具体到最常见的应该考虑它们的顺序。执行复制承诺时,将复制找到的最具体的文件。
这种模式实施起来非常简单:
# Use single copy for all files
body agent control
{
files_single_copy => { ".*" };
}
bundle agent test
{
vars:
"suffixes" slist => { ".$(sys.fqhost)", ".$(sys.uqhost)", ".$(sys.domain)",
".$(sys.flavor)", ".$(sys.ostype)", "" };
files:
"/etc/hosts"
copy_from => local_dcp("$(repository)/etc/hosts$(suffixes)");
}
如您所见,我们正在定义一个名为$(后缀)的列表变量,其中包含我们要区分文件的标准。尽管您可以使用任意CFEngine变量,但此列表中包含的所有变量都由CFEngine自动定义。然后我们在copy_from参数中简单地将该变量作为标量包含在内。因为CFEngine执行自动列表扩展,它将依次尝试每个变量,多次执行复制许可(列表中的每个值一个)并复制存在的第一个文件。例如,对于名为superman.justiceleague.com的Linux SuSE 11计算机,@(后缀)变量将包含以下值:
{ ".superman.justiceleague.com", ".superman", ".justiceleague.com", ".suse_11",
".linux", "" }
执行文件复制承诺时,隐式循环将导致这些字符串按顺序附加到" $(repository)/ etc / hosts",因此将按顺序尝试以下文件名: hosts.superman.justiceleague.com,hosts.justiceleague.com,hosts.suse_11,hosts.linux和hosts。存在的第一个将被复制到客户端的/ etc / hosts上,其余的将被跳过。
要使这项技术有效,我们必须启用"单一副本"在您要处理的所有文件上。这是一个配置参数,它告诉CFEngine最多复制一次文件,忽略同一目标文件的连续复制操作。代理程序控制主体中的files_single_copy参数指定正则表达式列表,以匹配应该应用单个副本的文件名。通过将其设置为".*"
,我们匹配所有文件名。
对于不匹配任何现有文件的主机,列表中的最后一项(空字符串)将导致复制通用主机文件。请注意,每个文件名的点都包含在$(后缀)中,但最后一个元素除外。
我希望这会有所帮助。
(p.s。和无耻的插件:这取自我即将出版的书" Learning CFEngine 3",由O' Reilly出版)