根据命令输出设置 cfengine3 类

gno*_*mie 3 cfengine

这个问题与如何在 cfengine3 中使用命令的输出非常相似,但我认为答案不适用于我的情况。

我想通过“git pull”更新git存储库,并根据是否会导致更改触发一些后续操作。

简化,如果通过某个主体有类似“匹配输出和设置类”的if_output_matches东西,我想使用这样的东西:

bundle agent updateRepo {

commands:
  "/usr/bin/git pull"
    contain => setuidgiddir_sh("$(globals.user)","$(globals.group)","$(target)"),
    classes => if_output_matches("Already up-to-date.","no_update");

reports:
  no_update::
    "nothing updated";
}

body contain setuidgiddir_sh(owner,group,folder) {
  exec_owner => "$(owner)";
  exec_group => "$(group)";
  useshell => "true";
  chdir => "$(folder)";
Run Code Online (Sandbox Code Playgroud)

}

那么,是否可以使用一个可能很昂贵的命令的输出并以此为基础做出一些决定?

execresult功能对我来说不是一个好的选择,因为 a) 拉动有时可能会变得昂贵(不推荐遵循 cfengine3 参考)和 b) 不允许指定用户、组、工作目录 - 这对我来说很重要。存储库位于用户空间中,不属于 root 用户。

小智 6

实现此目的的一种方法是使用CFEngine 支持模块协议。有了这个,您可以从脚本本身设置任意类和变量。例如,这样的脚本(未经测试):

#!/bin/bash
if git pull | grep -q 'Already up-to-date.'; then
  echo "+no_update"
fi
Run Code Online (Sandbox Code Playgroud)

将其存储在 /var/cfengine/modules/update_git 中,然后您可以执行以下操作:

commands:
  "update_git"
    contain => setuidgiddir_sh("$(globals.user)","$(globals.group)","$(target)"),
    module => "true";
Run Code Online (Sandbox Code Playgroud)

然后no_update像以前一样行动。

您可能可以通过使用keep/repaired/failed_returncodes 属性的类主体来实现类似的功能,但模块似乎更清晰、更具表现力。