Этот вопрос очень похож на Как я могу использовать вывод команды в cfengine3 но я полагаю, что ответ неприменим в моем случае.
Я хочу обновить репозиторий git с помощью «git pull» и в зависимости от того, приведет ли это к изменениям, вызывающим некоторые последующие действия.
Упрощено, если через какое-то тело было что-то вроде «сопоставить вывод и установить класс» 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)";
}
Итак, можно ли использовать вывод - возможно, дорогостоящей команды - и принять на этом основании какое-то решение?
В execresult
для меня функция не является хорошим выбором, так как а) извлечение может стать дорогим время от времени (не рекомендуется, следуя ссылке cfengine3) и б) не позволяет указывать пользователя, группу, рабочий каталог - что важно в моем случае. Репозиторий находится в пространстве пользователя и не принадлежит пользователю root.
Один из способов добиться этого - использовать протокол модуля, поддерживаемый CFEngine. При этом вы можете устанавливать произвольные классы и переменные из самого скрипта. Например, такой сценарий (непроверенный):
#!/bin/bash
if git pull | grep -q 'Already up-to-date.'; then
echo "+no_update"
fi
Сохраните его в / var / cfengine / modules / update_git, а затем вы можете сделать что-то вроде этого:
commands:
"update_git"
contain => setuidgiddir_sh("$(globals.user)","$(globals.group)","$(target)"),
module => "true";
А затем действовать no_update
как и раньше.
Вероятно, вы могли бы добиться чего-то подобного с телом классов, используя сохраненные / отремонтированные / failed_returncodes атрибуты, но модуль кажется чище и выразительнее.