2016-11-16 49 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變量。