我试图解决的最初问题是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'"
好好阅读这个链接。