Bug: 'notifies' ran even when bash script didn't run when 'creates' presents


#1

We found that it started to happen recently (but we are not 100% sure if it
happened before) that when using the ‘bash’ resource, ‘notifies’ gets
executed even when the script didn’t run because of what’s specified in
"creates" already exists.

For example, for this block in the nginx::source recipe:

bash “compile_nginx_source” do
cwd Chef::Config[:file_cache_path]
code <<-EOH
tar zxf nginx-#{nginx_version}.tar.gz
cd nginx-#{nginx_version} && ./configure #{configure_flags}
make && make install
EOH
creates node[:nginx][:src_binary]
notifies :restart, "service[nginx]"
end

If the file referred in node[:nginx][:src_binary] exists, it doesn’t run
the script to compile nginx, which is right, but it still executes the
notification which restarts nginx, which is not cool.

We worked around this easily by putting a not_if block in it, but we think
this is a chef bug that should be fixed (we are on 10.16.0 and 10.16.2). We
think whether or not “notifies” get triggered should be consistent with
whether the code(script) ran. If ‘creates’ presents and the code may not
run in some conditions, then in those conditions ‘notifies’ shouldn’t get
triggered by default. This nginx example is an example of the use case, if
it’s already compiled, there is no reason to restart it. I try to think
about other use cases and it seems to me that in very rare cases you want
’notifies’ to trigger even when anything else is not executed. As the
result I think at least the default should be the common case, where
"notifies" doesn’t trigger if “creates” presents and when the code did not
run because of being protected by “creates.”

Let me know what you think.

Thanks,
Nuo


#2

Yeah, we should fix it. Not for nothing, but I feel bad about creates
existing at all - we added it to the API before we added meta not_if and
only_if, and it mimics the puppet file API. I would be +1 on deprecating a
special cased not_if.

On 12/7/12 2:36 PM, “Nuo Yan” yan.nuo@gmail.com wrote:

We found that it started to happen recently (but we are not 100% sure if
it happened before) that when using the ‘bash’ resource, ‘notifies’ gets
executed even when the script didn’t run because of what’s specified in
"creates" already exists.

For example, for this block in the nginx::source recipe:

bash “compile_nginx_source” do
cwd Chef::Config[:file_cache_path]
code <<-EOH
tar zxf nginx-#{nginx_version}.tar.gz
cd nginx-#{nginx_version} && ./configure #{configure_flags}
make && make install
EOH
creates node[:nginx][:src_binary]
notifies :restart, "service[nginx]"
end

If the file referred in node[:nginx][:src_binary] exists, it doesn’t run
the script to compile nginx, which is right, but it still executes the
notification which restarts nginx, which is not cool.

We worked around this easily by putting a not_if block in it, but we
think this is a chef bug that should be fixed (we are on 10.16.0 and
10.16.2). We think whether or not “notifies” get triggered should be
consistent with whether the code(script) ran.
If ‘creates’ presents and the code may not run in some conditions, then
in those conditions ‘notifies’ shouldn’t get triggered by default. This
nginx example is an example of the use case, if it’s already compiled,
there is no reason to restart it. I try to
think about other use cases and it seems to me that in very rare cases
you want ‘notifies’ to trigger even when anything else is not executed.
As the result I think at least the default should be the common case,
where “notifies” doesn’t trigger if “creates"
presents and when the code did not run because of being protected by
"creates.”

Let me know what you think.

Thanks,
Nuo


#3

That sounds good to me. Should I create a ticket for this?

On Dec 7, 2012, at 2:39 PM, Adam Jacob adam@opscode.com wrote:

Yeah, we should fix it. Not for nothing, but I feel bad about creates
existing at all - we added it to the API before we added meta not_if and
only_if, and it mimics the puppet file API. I would be +1 on deprecating a
special cased not_if.

On 12/7/12 2:36 PM, “Nuo Yan” yan.nuo@gmail.com wrote:

We found that it started to happen recently (but we are not 100% sure if
it happened before) that when using the ‘bash’ resource, ‘notifies’ gets
executed even when the script didn’t run because of what’s specified in
"creates" already exists.

For example, for this block in the nginx::source recipe:

bash “compile_nginx_source” do
cwd Chef::Config[:file_cache_path]
code <<-EOH
tar zxf nginx-#{nginx_version}.tar.gz
cd nginx-#{nginx_version} && ./configure #{configure_flags}
make && make install
EOH
creates node[:nginx][:src_binary]
notifies :restart, "service[nginx]"
end

If the file referred in node[:nginx][:src_binary] exists, it doesn’t run
the script to compile nginx, which is right, but it still executes the
notification which restarts nginx, which is not cool.

We worked around this easily by putting a not_if block in it, but we
think this is a chef bug that should be fixed (we are on 10.16.0 and
10.16.2). We think whether or not “notifies” get triggered should be
consistent with whether the code(script) ran.
If ‘creates’ presents and the code may not run in some conditions, then
in those conditions ‘notifies’ shouldn’t get triggered by default. This
nginx example is an example of the use case, if it’s already compiled,
there is no reason to restart it. I try to
think about other use cases and it seems to me that in very rare cases
you want ‘notifies’ to trigger even when anything else is not executed.
As the result I think at least the default should be the common case,
where “notifies” doesn’t trigger if “creates"
presents and when the code did not run because of being protected by
"creates.”

Let me know what you think.

Thanks,
Nuo