chef icon indicating copy to clipboard operation
chef copied to clipboard

only_if / not_if command guard with lazy behavior

Open ericnorris opened this issue 2 years ago • 0 comments

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

ericnorris avatar Nov 03 '23 14:11 ericnorris