Chef mangling bash command?


#1

I have an issue with nastly bash command I’m trying to get chef to execute
and it’s not working properly, but if I run the same command from the
command line it works without errors and does what I expect. Here’s
resource:

bash “Set newrelic java options” do
user “root"
group “root"
cwd glassfishconfig
code <<-EOH
awk -v searchterm=”<java-config” -v payload="
-javaagent:#{newrelic_dir}/newrelic-#{node[:newrelic][:version]}/newrelic.jar\n
-Dnewrelic.config.file=#{newrelic_dir}/#{node[:app][:key]}/newrelic.yml\n
-Dnewrelic.config.log_file_path=#{newrelic_dir}/#{node[:app][:key]}/logs"
’{ if ($0 ~ searchterm) print $0 “\n” payload; else print $0 }'
domain.xml.newrelic.bak > domain.xml
EOH
action :nothing
end

and here’s the error:

---- Begin output of “bash” “/tmp/chef-script20120627-8350-r7jiup” ----
STDOUT:
STDERR: awk: { if ($0 ~ searchterm) print $0 "
awk: ^ unterminated string
---- End output of “bash” “/tmp/chef-script20120627-8350-r7jiup” ----

I am not able to use a template in this case (just saying because that was
suggested on IRC).

Unfortunately, when using debug logging the command that is run isn’t shown
and there’s no way I know of to tell chef-client to leave behind the
/tmp/chef-script#### files (though this should be an option or happen
automatically when debug logging is used because without it you can’t
properly troubleshoot this type of issue). I’ve been told in the past chef
passes the command along “as it is in the resource” to the temp script and
just runs it but obviously that isn’t the case.

I’ve tried different variations of the above script including escaping all
double and single quotes but doesn’t help. Does anyone have an additional
insight or suggestions? I could just drop it into a shell script and
include it as a cookbook file but it should work as I have it above. Plus
I’d really like to know what the “gotcha’s” are when using the script
resources (what needs to be escaped, what doesn’t, what won’t work at all,
etc.) but I haven’t found anything in the documentation about it.

Thanks,

Mike G.


#2

Chatting on IRC I think the problems are with the \n in the ruby HERDOC block is causing that to be output as a litteral new line in the /tmp/chef-script it runs. Replacing it with \n should do the trick. (Make ruby output \n so that bash sees it as a newline escape, not a new-line literal.)

($0 could also be a problem but that is in a single-quotes string in the script when bash gets hold of it so should be fine.)

-ash

On 27 Jun 2012, at 21:48, Michael Glenney wrote:

I have an issue with nastly bash command I’m trying to get chef to execute and it’s not working properly, but if I run the same command from the command line it works without errors and does what I expect. Here’s resource:

bash “Set newrelic java options” do
user "root"
group “root”

cwd glassfishconfig
code <<-EOH
awk -v searchterm="<java-config" -v payload=" -javaagent:#{newrelic_dir}/newrelic-#{node[:newrelic][:version]}/newrelic.jar\n -Dnewrelic.config.file=#{newrelic_dir}/#{node[:app][:key]}/newrelic.yml\n -Dnewrelic.config.log_file_path=#{newrelic_dir}/#{node[:app][:key]}/logs" ‘{ if ($0 ~ searchterm) print $0 “\n” payload; else print $0 }’ domain.xml.newrelic.bak > domain.xml

EOH
action :nothing
end
and here’s the error:

---- Begin output of “bash” “/tmp/chef-script20120627-8350-r7jiup” ----

STDOUT:
STDERR: awk: { if ($0 ~ searchterm) print $0 "
awk: ^ unterminated string

---- End output of “bash” “/tmp/chef-script20120627-8350-r7jiup” ----

I am not able to use a template in this case (just saying because that was suggested on IRC).

Unfortunately, when using debug logging the command that is run isn’t shown and there’s no way I know of to tell chef-client to leave behind the /tmp/chef-script#### files (though this should be an option or happen automatically when debug logging is used because without it you can’t properly troubleshoot this type of issue). I’ve been told in the past chef passes the command along “as it is in the resource” to the temp script and just runs it but obviously that isn’t the case.

I’ve tried different variations of the above script including escaping all double and single quotes but doesn’t help. Does anyone have an additional insight or suggestions? I could just drop it into a shell script and include it as a cookbook file but it should work as I have it above. Plus I’d really like to know what the “gotcha’s” are when using the script resources (what needs to be escaped, what doesn’t, what won’t work at all, etc.) but I haven’t found anything in the documentation about it.

Thanks,

Mike G.


#3

Responding for closure.

Ash is right (helped me on IRC after I sent this). Can’t put \n in a bash
(and probably others) script resource without escaping it. I’ll see if I
can update the wiki page with that info. If anyone else knows of any other
stuff that needs to be escaped send them on and I’ll include them in the
update.

On a side note, I’m a little annoyed that Ruby parses heredocs in that
way. In my opinion it should pass it as written except for variable
substitution. But maybe I’m just annoyed because I’ve had to spend so much
time on this silly issue but seems wrong.

Thanks again Ash.

MG

On Wed, Jun 27, 2012 at 2:03 PM, Ash Berlin ash_opscode@firemirror.comwrote:

Chatting on IRC I think the problems are with the \n in the ruby HERDOC
block is causing that to be output as a litteral new line in the
/tmp/chef-script it runs. Replacing it with \n should do the trick. (Make
ruby output \n so that bash sees it as a newline escape, not a new-line
literal.)

($0 could also be a problem but that is in a single-quotes string in the
script when bash gets hold of it so should be fine.)

-ash

On 27 Jun 2012, at 21:48, Michael Glenney wrote:

I have an issue with nastly bash command I’m trying to get chef to
execute and it’s not working properly, but if I run the same command from
the command line it works without errors and does what I expect. Here’s
resource:

bash “Set newrelic java options” do
user "root"
group “root”

cwd glassfishconfig
code <<-EOH
awk -v searchterm="<java-config" -v payload="
-javaagent:#{newrelic_dir}/newrelic-#{node[:newrelic][:version]}/newrelic.jar\n

-Dnewrelic.config.file=#{newrelic_dir}/#{node[:app][:key]}/newrelic.yml\n

-Dnewrelic.config.log_file_path=#{newrelic_dir}/#{node[:app][:key]}/logs"
’{ if ($0 ~ searchterm) print $0 “\n” payload; else print $0 }'
domain.xml.newrelic.bak > domain.xml

EOH
action :nothing
end
and here’s the error:

---- Begin output of “bash” “/tmp/chef-script20120627-8350-r7jiup” ----

STDOUT:
STDERR: awk: { if ($0 ~ searchterm) print $0 "
awk: ^ unterminated string

---- End output of “bash” “/tmp/chef-script20120627-8350-r7jiup” ----

I am not able to use a template in this case (just saying because that
was suggested on IRC).

Unfortunately, when using debug logging the command that is run isn’t
shown and there’s no way I know of to tell chef-client to leave behind the
/tmp/chef-script#### files (though this should be an option or happen
automatically when debug logging is used because without it you can’t
properly troubleshoot this type of issue). I’ve been told in the past chef
passes the command along “as it is in the resource” to the temp script and
just runs it but obviously that isn’t the case.

I’ve tried different variations of the above script including escaping
all double and single quotes but doesn’t help. Does anyone have an
additional insight or suggestions? I could just drop it into a shell
script and include it as a cookbook file but it should work as I have it
above. Plus I’d really like to know what the “gotcha’s” are when using the
script resources (what needs to be escaped, what doesn’t, what won’t work
at all, etc.) but I haven’t found anything in the documentation about it.

Thanks,

Mike G.