only_if / not_if command guard with lazy behavior
Describe the Enhancement:
When using only_if / not_if with a String, i.e. passing in a command instead of Ruby code, it does not appear easily possible to lazily evaluate node attributes.
For example, the following code will evaluate the value of node['some-attribute'] at compile-time:
file "foo" do
content "bar"
only_if "some-command #{node['some-attribute']}"
end
It'd be nice to have something like the following, but I realize that implementing this literally may be confusing since only_if already lazily evaluates Ruby code (see also https://github.com/chef/chef/issues/10243).
file "foo" do
content "bar"
only_if lazy { "some-command #{node['some-attribute']}" }
end
Describe the Need:
I don't know exactly how common this need is, but it seems like there's an opportunity for syntactic sugar here that would make writing these kinds of things more pleasant.
Current Alternative
It is possible for a user to define a custom resource, or do something like only_if { shell_out("some-command #{node['some-attribute']}").status.success? }.
Can We Help You Implement This?:
Sure, I think the relevant code is here: https://github.com/chef/chef/blob/4ce99c419028c169aeb3e68ec954b79f20e654c5/lib/chef/resource/conditional.rb#L56-L77
The tough part would be deciding what the syntax should be, because lazy might not be a good fit since it could be confusing. I imagine one way might be to have the user pass an Array, and have the guard_interpreter first de-lazy any array elements that are lazy, for example:
file "foo" do
content "bar"
only_if ['some-command', lazy { node['some-attribute'] }]
end