我们为由一个节点组成的节点设置一个厨师运行列表,例如配方A和配方B. 在配方A中,我们执行启动script.sh的命令资源,它使用自定义路径在目标机器上导出$ PATH变量。
接下来,当执行配方B时,它会查找要启动的可执行文件,我们希望它可以执行它,查看包含在$ PATH中的路径。不幸的是,配方B期间的$ PATH变量丢失了配方A期间所做的修改。
上下文是:在一台机器上,我们有一个特定路径中的JVM(不在$ PATH中)。通过配方A,我们启动一个script.sh,将JVM bin路径导出到$ PATH中。然后在配方B中我们使用一个java可执行文件(比方说,jar),所以我们希望它正在执行查看我们之前在$ PATH中导出的路径。但它不起作用。
为了让配方B执行,我们希望将JVM路径临时设置到$ PATH中。我想我们不能使用任何Chef环境变量来实现这一点,因为在分布式场景中,JVM路径可能因机器而异。
非常感谢。
UPDATE:
配方A
mydir = "/path/to/jvm"
script_name = "script.sh"
sh = File.join(mydir,script_name).gsub("/","\/")
script_str = ". " + sh
# Launch script.sh in order to export Java to PATH
execute "ExecuteScript" do
command script_str
user "myuser"
group "mygroup"
only_if {File.exists?(File.join(mydir,script_name))}
end
可惜我不能公布配方B,但请记住,这是不可编辑的,它只是执行的“java”或“罐子”(找他们在$ PATH中)。
更新2
我解决了这个问题,在配方中的设置如下:
javapath = "/path/to/jvm/bin"
ENV['PATH'] = "#{ENV['PATH']}:" + javapath
这样一来我设置为Ruby执行期间的环境变量$ PATH。这使得配方B能够看到该变量,并执行所需的bin(在我的情况下为jar)。我不知道这是否是一个优雅的解决方案,但它对我有效。
即使配方不可编辑,它的资源可以是“rewind”,例如为'execute'资源添加'env'参数。没有关于配方B的细节,不可能给出正确的建议,也许你可以尝试修改chef ruby的'ENV ['PATH']'来添加你的jvm路径,这样子进程就会继承它,但是这味道很脆弱代码结束。 – Tensibai
[相关](http://stackoverflow.com/questions/25295439/reload-environment-variables-path-from-chef-recipes-client?rq=1)和[也相关](http://stackoverflow.com/questions/6284517/how-can-you-use-a-chef-recipe-to-set-an-environment-variable?rq = 1)附带有关于magic_shell食谱的信息。 – Tensibai