Thermatix
Thermatix

Reputation: 2929

power-shell script in chef keeps being recognized as ruby code

The initial problem I Was trying to solve was that chefDK version of ruby wasn't showing up because it was at the end of the PATH environmental variable, so I have created a block of code to check and then add if it doesn't find it.

powershell_script "add_chefdk_bin_to_shell" do
  code '$oldPath=(Get-ItemProperty -Path \'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment\' -Name PATH).Path
          $newPath= \'C:\opscode\chefdk\embedded\bin;\' + $oldPath
          Set-ItemProperty -Path \'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment\' -Name PATH –Value $newPath
       '
  only_if { `powershell $a = $Env:Path; $a -match 'C:\\opscode\\chefdk\\embedded\\bin'` == "False" }
end

Except when berk shelf runs (to publish the chef cookbook to our chef server) it spits out this error:

**E, [2014-10-24T11:33:55.771484 #2916] ERROR -- : Cookbook file recipes/install.rb has a ruby syntax error:
E, [2014-10-24T11:33:55.771484 #2916] ERROR -- : c:/path/to/cookbook/root/recipes/install.rb:25: invalid multibyte char (US-ASCII)
E, [2014-10-24T11:33:55.771484 #2916] ERROR -- : c:/path/to/cookbook/root/recipes/install.rb:23: invalid multibyte char (US-ASCII)
E, [2014-10-24T11:33:55.771484 #2916] ERROR -- : c:/path/to/cookbook/root/recipes/install.rb:23: syntax error, unexpected $end, expecting keyword_end
E, [2014-10-24T11:33:55.771484 #2916] ERROR -- : ...ger\Environment\' -Name PATH –Value $newPath
E, [2014-10-24T11:33:55.771484 #2916] ERROR -- : ...                               ^
E, [2014-10-24T11:33:55.771484 #2916] ERROR -- : Ridley::Errors::CookbookSyntaxError: Invalid ruby files in cookbook: gg-web-opsboard (1.0.177).**

This is very-much beginning to frustrate me, I'm only doing this in the first place because chefDK isn't being used as the default ruby (which is screwing a bunch of other stuff up).

There is a secondary issue, if I look at the path, I can clearly see C:\opscode\chefdk\embedded\bin at the end, so why does:

powershell $a = $Env:Path; $a -match 'C:\\opscode\\chefdk\\embedded\\bin'

Register as false?

EDIT:

I tried what @acro444 said but I'm still getting errors:

E, [2014-10-24T12:36:15.642147 #1932] ERROR -- : Cookbook file recipes/install.rb has a ruby syntax error:
E, [2014-10-24T12:36:15.642147 #1932] ERROR -- : c:/path/to/cookbook/root/recipes/install.rb:24: Invalid escape character syntax
E, [2014-10-24T12:36:15.642147 #1932] ERROR -- : ...ry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Sess...
E, [2014-10-24T12:36:15.642147 #1932] ERROR -- : ...                               ^
E, [2014-10-24T12:36:15.642147 #1932] ERROR -- : c:/path/to/cookbook/root/recipes/recipes/install.rb:24: Invalid escape character syntax
E, [2014-10-24T12:36:15.642147 #1932] ERROR -- : ...HINE\System\CurrentControlSet\Control\Session Manager\Enviro...
E, [2014-10-24T12:36:15.642147 #1932] ERROR -- : ...                               ^
E, [2014-10-24T12:36:15.642147 #1932] ERROR -- : c:/path/to/cookbook/root/recipes/recipes/install.rb:26: Invalid escape character syntax
E, [2014-10-24T12:36:15.642147 #1932] ERROR -- : ...ry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Sess...
E, [2014-10-24T12:36:15.642147 #1932] ERROR -- : ...                               ^
E, [2014-10-24T12:36:15.642147 #1932] ERROR -- : c:/path/to/cookbook/root/recipes/install.rb:26: Invalid escape character syntax
E, [2014-10-24T12:36:15.642147 #1932] ERROR -- : ...HINE\System\CurrentControlSet\Control\Session Manager\Enviro...
E, [2014-10-24T12:36:15.642147 #1932] ERROR -- : ...                               ^
E, [2014-10-24T12:36:15.642147 #1932] ERROR -- : c:/path/to/cookbook/root/recipes/install.rb:26: invalid multibyte char (US-ASCII)
E, [2014-10-24T12:36:15.642147 #1932] ERROR -- : c:/path/to/cookbook/root/recipes/install.rb:23: syntax error, unexpected $end, expecting tSTRING_CONTENT or tSTRING_DBEG or tSTRING_DVAR or tSTRING_END 

I did the quadruple backslash escapething you did on all the backslashes and that reduced the error to just :

syntax error, unexpected $end, expecting tSTRING_CONTENT or tSTRING_DBEG or tSTRING_DVAR or tSTRING_END

I removed all trailing white space but that didn't fix it, currently my herdoc looks like:

code <<-EOF
$oldPath=(Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\\\\System\\\\CurrentControlSet\\\\Control\\\\Session Manager\\\\Environment' -Name PATH).Path
$newPath='C:\\\\opscode\\\\chefdk\\\\embedded\\\\bin;' + $oldPath
Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\\\\System\\\\CurrentControlSet\\\\Control\\\\Session Manager\\\\Environment' -Name PATH –Value $newPath
EOF

Upvotes: 0

Views: 1621

Answers (2)

mdavids
mdavids

Reputation: 26

If you want, you can skip the guard block, and move some of the operation to ruby like this:

ruby_block "chefdk_path_check" do
  block do
    current_path = ENV['PATH'].split(';')
    chefdk_path = 'C:\\opscode\\chefdk\\embedded\\bin'
    current_path.delete_if { |path| path == chefdk_path }
    new_path = current_path.unshift(chefdk_path)
    `Powershell -Command Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\Environment' -Name PATH –Value '#{new_path}'`
    end
end

This will check every time, remove any existing entry (if it is in the wrong position in the path), and add the desired entry to the beginning. No duplicates and a lot less escaping to worry about!

Upvotes: 1

arco444
arco444

Reputation: 22821

Try structuring the block as follows:

powershell_script "add_chefdk_bin_to_shell" do
  code <<-EOF
$oldPath=(Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).Path
$newPath='C:\opscode\chefdk\embedded\bin;' + $oldPath
Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH –Value $newPath
EOF
  only_if { `powershell -command "$Env:Path -match 'C:\\\\opscode\\\\chefdk\\\\embedded\\\\bin'".strip }` == "False"
end

Your only_if guard has a couple of problems. Firstly, powershell itself requires the paths to be escaped - \\, therefore you need to double escape in the ruby command.

Secondly, the condition will never be met because the powershell command also includes the newline character on the end of the string, and you weren't matching for that. Hence add the strip to the end of the command. You can test that using irb:

irb> `powershell -command "$Env:Path -match 'C:\\\\opscode\\\\chefdk\\\\embedded\\\\bin'"`
=> "True\n"

You may even be able to swap out the guard as it's written altogether and use the built in interpreter:

guard_interpreter :powershell_script
not_if "$Env:Path -match 'C:\\\\opscode\\\\chefdk\\\\embedded\\\\bin'"

Have a good read of this link.

Upvotes: 0

Related Questions