18

Problem: I have a chef statement that should only run if the attribute is "true". But it runs every time.

Expected Behavior: When default[:QuickBase_Legacy_Stack][:dotNetFx4_Install] = "false" dotnet4 should not be installed.

Actual Behavior: No matter what the attribute is set to, it installs dotnet4.

My code:

attribute file:

default[:QuickBase_Legacy_Stack][:dotNetFx4_Install] = "false"

recipe file:

windows_package "dotnet4" do
    only_if node[:QuickBase_Legacy_Stack][:dotNetFx4_Install]=='true'
    source "#{node[:QuickBase_Legacy_Stack][:dotNetFx4_URL]}"
    installer_type :custom
    action :install
    options "/quiet /log C:\\chef\\installLog4.txt /norestart /skipmsuinstall"
end
tbenz9
  • 446
  • 2
  • 5
  • 18
  • 2
    I really like the format of your question. You clearly identified the problem, given outcome, and desired outcome. You must be an engineer :) – sethvargo Jul 15 '14 at 17:13
  • 1
    Yes I am, perhaps you can reward it with an upvote... :) – tbenz9 Jul 15 '14 at 17:36

2 Answers2

20

Guards that run Ruby must be enclosed in a block {} otherwise Chef will try to run the string in the default interpreter (usually bash).

windows_package "dotnet4" do
    only_if        { node[:QuickBase_Legacy_Stack][:dotNetFx4_Install] == 'true' }
    source         node[:QuickBase_Legacy_Stack][:dotNetFx4_URL]
    installer_type :custom
    action         :install
    options        "/quiet /log C:\\chef\\installLog4.txt /norestart /skipmsuinstall"
end

Check if you need boolean true instead of "true"

Also, use the plain variable name (for source) unless you need to interpolate other data with the string quoting.

Matt
  • 68,711
  • 7
  • 155
  • 158
8

That is a Ruby conditional, so you need to use a block for your not_if:

only_if { node[:QuickBase_Legacy_Stack][:dotNetFx4_Install]=='true' }

(Please take note of the added {}). You can also use the do..end syntax for multiline conditions:

only_if do
  node[:QuickBase_Legacy_Stack][:dotNetFx4_Install]=='true'
end

Finally, please make sure your value is the String "true" and not the value true (see the difference). In Ruby, true is a boolean (just like false), but "true" is a string (just like "foo") Checking if true == "true" will return false.

sethvargo
  • 26,739
  • 10
  • 86
  • 156
  • I am having a similar issue.. I have `"sync_db": "true"` in json config and in my chef recipe I cannot get it to work unless I check if `only_if { sub_site['sync_db'] != nil }` and remove it from attributes. `only_if { sub_site['sync_db'] == "true"}` or `true` does not work. Any idea? – awm Mar 30 '17 at 19:40