2016-11-16 47 views
0

我们为由一个节点组成的节点设置一个厨师运行列表,例如配方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)。我不知道这是否是一个优雅的解决方案,但它对我有效。

+0

即使配方不可编辑,它的资源可以是“rewind”,例如为'execute'资源添加'env'参数。没有关于配方B的细节,不可能给出正确的建议,也许你可以尝试修改chef ruby​​的'ENV ['PATH']'来添加你的jvm路径,这样子进程就会继承它,但是这味道很脆弱代码结束。 – Tensibai

+0

[相关](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

回答

1

执行启动script.sh的命令资源,该脚本资源使用自定义路径在目标计算机上导出 $ PATH变量。

这个出口只有execute资源内可用,所以您的脚本和任何调用,它是尽快结束资源丢弃。

你的描述听起来像是你一开始做错了,但没有更多细节,很难为你的用例提供正确的建议。

+0

是的,我认为出口范围限于资源或最多配方A.因此,假设我们不能编辑配方B,我认为无法导出该JVM目录以便让配方B正确执行该目录中的任何java可执行文件(查看$ PATH),对吧? – giglio91

+0

@ giglio91有很多方法,这就是为什么我说如果没有更多的洞察你的真实用例/你如何使用它,很难给出正确的建议。展示你的食谱,也许我们将能够提供一个更好的方式来实现目标。 – Tensibai

0

当进程分叉时,环境变量会从父项继承到子项,但它们不能从子项到父项。当Chef运行你的外部命令时,任何env var变化都将被限制到该进程。您可以使用script资源在单个进程中运行更长的一段shell代码,以便共享env变量。