cfengine3 有没有一种简单的方法可以根据其运行的操作系统复制不同的文件

Mlo*_*ove 1 configuration cfengine

我有两个不同版本的 linux/unix,每个版本都运行 cfengine3。是否可以在两台机器上放置一个 Promise.cf 文件,该文件将根据客户端上的操作系统复制不同的文件?我已经在互联网上搜索了几个小时,但还没有找到任何有用的东西。

zza*_*oni 5

有几种方法可以做到这一点。最简单的是,您可以简单地拥有不同的文件:根据操作系统的 Promise,例如:

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");
Run Code Online (Sandbox Code Playgroud)

通过认识到内置 CFEngine 变量 $(sys.flavor) 包含操作系统的类型和版本,可以轻松简化此示例,因此我们可以按如下方式重写此示例:

"/etc/hosts"
    copy_from => mycopy("$(repository)/etc.$(sys.flavor)");
Run Code Online (Sandbox Code Playgroud)

实现此任务的更灵活的方法在 CFEngine 术语中称为“分层复制”。在此模式中,您可以指定想要区分文件的任意变量列表,以及应考虑它们的顺序(从最具体到最一般)。当执行复制承诺时,将复制找到的最具体的文件。

这种模式的实现非常简单:

# 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)");
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我们定义了一个名为 $(suffixes) 的列表变量,其中包含我们想要区分文件的标准。尽管您可以使用任意 CFEngine 变量,但此列表中包含的所有变量均由 CFEngine 自动定义。然后我们只需将该变量作为标量包含在我们的 copy_from 参数中。因为 CFEngine 会自动扩展列表,所以它将依次尝试每个变量,多次执行复制承诺(列表中的每个值执行一次)并复制存在的第一个文件。例如,对于名为 superman.justiceleague.com 的 Linux SuSE 11 计算机,@(suffixes) 变量将包含以下值:

{ ".superman.justiceleague.com", ".superman", ".justiceleague.com", ".suse_11",
  ".linux", "" }
Run Code Online (Sandbox Code Playgroud)

当执行文件复制承诺时,隐式循环将导致这些字符串按顺序附加到“$(repository)/etc/hosts”,因此将按顺序尝试以下文件名:hosts.superman.justiceleague.com, Hosts.justiceleague.com、hosts.suse_11、hosts.linux 和主机。第一个存在的将被复制到客户端中的 /etc/hosts 上,其余的将被跳过。

为了使这种技术发挥作用,我们必须对要处理的所有文件启用“单一副本”。这是一个配置参数,告诉 CFEngine 最多复制每个文件一次,忽略对同一目标文件的连续复制操作。代理控制正文中的 files_single_copy 参数指定正则表达式列表,以匹配应应用单一副本的文件名。通过将其设置为".*"我们匹配所有文件名。

对于与任何现有文件都不匹配的主机,列表中的最后一项(空字符串)将导致复制通用主机文件。请注意,除了最后一个元素之外,每个文件名的点都包含在 $(suffixes) 中。

我希望这有帮助。

(ps和无耻插件:这摘自我即将出版的书《学习CFEngine 3》,由O'Reilly出版)