chef中的powershell脚本不断被识别为ruby代码



我试图解决的最初问题是chefDK版本的ruby没有出现,因为它位于PATH环境变量的末尾,所以我创建了一个代码块来检查,如果找不到就添加。

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

除了当berk-shelf运行时(将厨师食谱发布到我们的厨师服务器),它会抛出以下错误:

**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 -- : ...gerEnvironment' -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).**

这开始让我很沮丧,我之所以这么做,首先是因为chefDK没有被用作默认的ruby(这会把很多其他东西搞砸)。

还有一个次要的问题,如果我看一下路径,我可以清楚地看到最后的C:opscodechefdkembeddedbin,那么为什么:

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

是否注册为false?

编辑:

我试过@acro444说的话,但我仍然会出错:

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_MACHINESystemCurrentControlSetControlSess...
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 -- : ...HINESystemCurrentControlSetControlSession ManagerEnviro...
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_MACHINESystemCurrentControlSetControlSess...
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 -- : ...HINESystemCurrentControlSetControlSession ManagerEnviro...
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 

我做了四反斜杠转义,就像你对所有反斜杠所做的那样,这将错误减少到:

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

我删除了所有尾随的空白,但这并没有解决它,目前我的herdoc看起来像:

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

如果你愿意,你可以跳过保护块,把一些操作移到ruby上,如下所示:

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

这将每次进行检查,删除任何现有条目(如果它在路径中的错误位置),并将所需条目添加到开头。没有重复,不用担心逃跑!

尝试按如下方式构建块:

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

您的only_if防护有几个问题。首先,powershell本身需要对路径进行转义-\,因此您需要在ruby命令中进行双重转义。

其次,这个条件永远不会被满足,因为powershell命令还在字符串的末尾包含换行符,而您不匹配。因此,将strip添加到命令的末尾。你可以使用irb:进行测试

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

你甚至可以在编写完整的防护程序时将其换掉,并使用内置的解释器:

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

好好阅读这个链接。

最新更新