用 Puppet 來安裝套件一般是用 Package 來裝,但 Package 只能用來跑 apt/yum 或是 deb/rpm 等類型,如果遇到必須要用 script 執行的話就會需要使用 exec 來跑
最近在寫 puppet_aws-agent 這個 module 的時候就遇到了必須用 exec 跑 script 的狀況,為了避免每次 deploy 都會執行 exec 的狀況,exec 有提供 creates、onlyif、unless 參數使用
用 creates 判斷檔案
在執行 exec 的時候會先檢查 creates 這個值的檔案位置是否存在,如果不存在才會執行 exec
而用 exec 來跑 install package 同理也可以用這個方式來判別是否已經安裝
在下載 install script 的 exec 我會將下載的檔案和 creates 指定同一個位置,避免每次 deploy 都會重新下載 install script
exec { 'download_aws-agent': command => "/usr/bin/curl -o /var/tmp/install_awsagent --connect-timeout 60 -O $aws_agent::aws_agent_download_url", path => '/bin:/usr/bin:/usr/local/bin:/usr/sbin', creates => '/var/tmp/install_awsagent' }
然後在安裝的 exec 也是同理,creates 偵測安裝成功會出現的 awsagent bin 位置,用這樣的方式來避免 exec 重複執行
exec { 'install_aws-agent': command => "/bin/bash /var/tmp/install_awsagent", path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', subscribe => Exec['download_aws-agent'], creates => '/opt/aws/awsagent/bin/awsagent', }
用 onlyif、unless 判斷 return 的值
- onlyif:如果回傳的值為 0 或是 true 則 “執行” exec
- unless:如果回傳的值為 0 或是 true 則 “不執行” exec
拿 unbound 舉例,已經存在安裝好的 unbound:
exec { 'apt-get_update': command => 'apt-get update', onlyif => 'dpkg -l | grep -c unbound', }
用 onlyif 會執行 apt-get update,但同樣的指令用 unless 則不會執行。
Linux 小常識:/tmp 和 /var/tmp 的區別
/tmp 是存放在記憶體內,所以每次 reboot 都會把 /tmp 內的資料清掉,而 /var/tmp 是寫在物理硬碟上,不會被清除,在兩者的定義上 /tmp 屬於短時間儲存,而 /var/tmp 屬於較長時間保存,但必須保持一個良好的觀念就是 /var/tmp 僅做臨時保存,只是比 /tmp 能夠存放更久的時間!