本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
範例 4:新增流程控制
重要
所以此 AWS OpsWorks Stacks 服務於 2024 年 5 月 26 日終止使用壽命,並已針對新客戶和現有客戶停用。我們強烈建議客戶盡快將其工作負載移轉至其他解決方案。如果您對移轉有任何疑問,請聯絡 AWS Support 團隊上 AWS Re: 郵寄
有些配方只是一系列的 Chef 資源。在這種情況下,當您執行配方時,它僅會依序執行每個資源提供者。不過,有更精密的執行路徑通常會很有幫助。下列是兩個常見情況:
-
您想要某個配方以不同的屬性設定多次執行相同的資源。
-
您想要在不同的作業系統上使用不同的屬性設定。
您可以將 Ruby 控制結構併入配方以處理類似的情況。本節示範如何修改範例 3:建立目錄中的配方來處理這兩種情況。
重複
範例 3:建立目錄示範如何使用 directory
資源來建立目錄或目錄鏈。不過,假設您要建立兩個不同的目錄 /srv/www/config
和 /srv/www/shared
。您可以分別為每個目錄實作目錄資源,但如果您想要建立非常多的目錄,這種方法太過繁瑣。下列配方示範處理此任務的較簡單方式。
[ "/srv/www/config", "/srv/www/shared" ].each do |path| directory path do mode 0755 owner 'root' group 'root' recursive true action :create end end
配方使用包含子目錄路徑的字串集合,而不是為每個子目錄分別使用目錄資源。Ruby each
方法從第一個元素開始,為每個集合元素執行一次資源。資源中以 path
變數表示元素,在本例中表示目錄路徑。您可以輕鬆地調整此範例建立任意數目的子目錄。
執行配方
-
留在
createdir
目錄中,接下來數個範例都會使用該技術指南。 -
若尚未完成,請執行
kitchen destroy
以從乾淨的執行個體開始。 -
以範例取代
default.rb
中的程式碼並執行kitchen converge
。 -
登入執行個體,您會在
/srv
下看到新建立的目錄。
您可以使用雜湊表為每次重複指定兩個值。下列配方建立 /srv/www/config
和 /srv/www/shared
,每個都有不同的模式。
{ "/srv/www/config" => 0644, "/srv/www/shared" => 0755 }.each do |path, mode_value| directory path do mode mode_value owner 'root' group 'root' recursive true action :create end end
執行配方
-
若尚未完成,請執行
kitchen destroy
以從乾淨的執行個體開始。 -
以範例取代
default.rb
中的程式碼並執行kitchen converge
。 -
登入執行個體,您會在指定模式的
/srv
下看到新建立的目錄。
條件式邏輯
您也可以使用 Ruby 條件式邏輯來建立多個執行分支。下列配方使用 if-elsif-else
邏輯來擴展前一個範例,以便建立名為 /srv/www/shared
的子目錄,但只限於 Debian 和 Ubuntu 系統。針對所有其他系統,其會記錄顯示在 Test Kitchen 輸出中的錯誤訊息。
if platform?("debian", "ubuntu") directory "/srv/www/shared" do mode 0755 owner 'root' group 'root' recursive true action :create end else log "Unsupported system" end
執行範例配方
-
如果您的執行個體仍在執行中,請執行
kitchen destroy
關閉它。 -
以範例程式碼取代
default.rb
中的程式碼。 -
編輯
.kitchen.yml
將 CentOS 6.4 系統新增到平台清單。檔案的platforms
區段看起來應該如下:... platforms: - name: ubuntu-12.04 - name: centos-6.4 ...
-
執行
kitchen converge
,這會建立執行個體,並依序為.kitchen.yml
中的每個平台執行配方。注意
如果您想收歛成僅只一個執行個體,請將執行個體名稱新增為參數。例如,若要將配方收歛成僅在 Ubuntu 平台,請執行
kitchen converge default-ubuntu-1204
。如果您忘記了平台名稱,只要執行kitchen list
即可。
您應該會在 Test Kitchen 的 CentOS 部分看到您的日誌訊息,它看起來類似如下:
... Converging 1 resources Recipe: createdir::default * log[Unsupported system] action write[2014-06-23T19:10:30+00:00] INFO: Processing log[Unsupported system] action write (createdir::default line 12) [2014-06-23T19:10:30+00:00] INFO: Unsupported system [2014-06-23T19:10:30+00:00] INFO: Chef Run complete in 0.004972162 seconds
您現在可以登入執行個體並驗證是否已建立目錄。不過,現在無法僅執行 kitchen login
。您必須透過附加平台名稱來指定執行個體,例如 kitchen
login default-ubuntu-1204
。
注意
如果 Test Kitchen 命令接受執行個體名稱,您就不需要輸入完整的名稱。Test Kitchen 會將執行個體名稱視為 Ruby 規則表達式,因此您只需要可提供唯一相符的足夠字元即可。例如,您可以透過執行 kitchen
converge ub
收歛成僅 Ubuntu 執行個體,或透過執行 kitchen
login 64
登入 CentOS 執行個體。
此時可能有的疑問,是配方如何知道它在哪個平台上執行。Chef 為收集系統資料 (包括平台) 的每個回合都執行名為 Ohaiplatform?
方法使用括號來比較系統和 Ohai 平台值,如果其中一項符合即傳回 true。
您可以使用 node['
直接參考您程式碼中的節點屬性值。例如,平台值以 attribute_name
']node['platform']
表示。例如,您可能將前述範例撰寫如下。
if node[:platform] == 'debian' or node[:platform] == 'ubuntu' directory "/srv/www/shared" do mode 0755 owner 'root' group 'root' recursive true action :create end else log "Unsupported system" end
在配方中包含條件邏輯的常見原因,是為了因應不同的 Linux 系列有時使用不同的套件名稱、目錄等等。例如,Apache 套件名稱在 CentOS 系統為 httpd
,在 Ubuntu 系統為 apache2
。
如果只是因為不同的系統需要不同的字串,Chef value_for_platform
if-elsif-else
更簡單的解決方案。下列配方在 CentOS 系統中建立 /srv/www/shared
目錄,在 Ubuntu 系統中建立 /srv/www/data
目錄,在所有其他系統中建立 /srv/www/config
。
data_dir = value_for_platform( "centos" => { "default" => "/srv/www/shared" }, "ubuntu" => { "default" => "/srv/www/data" }, "default" => "/srv/www/config" ) directory data_dir do mode 0755 owner 'root' group 'root' recursive true action :create end
value_for_platform
將適當的路徑指派給 data_dir
,而 directory
資源則使用該值建立目錄。
執行範例配方
-
如果您的執行個體仍在執行中,請執行
kitchen destroy
關閉它。 -
以範例程式碼取代
default.rb
中的程式碼。 -
執行
kitchen converge
,然後登入每個執行個體,以驗證是否有適當的目錄。