puppet運(yùn)維自動化之Exec資源管理
【導(dǎo)讀】
運(yùn)維人員,經(jīng)常要編譯源碼包,這個時候就可以讓puppet執(zhí)行外部命令。其實(shí)就是直接調(diào)用shell來完成。這里為大家介紹運(yùn)維自動化之exec資源管理。
【基礎(chǔ)】
作為運(yùn)維人員,肯定是對一門語言熟練掌握,因?yàn)榇速Y源是通過shell來完成相關(guān)操作,需要對shell有一定的基礎(chǔ)。
【puppet exec介紹】
puppet執(zhí)行外部命令,多次反復(fù)用這個方式執(zhí)行命令是有威脅性的,因此建議對執(zhí)行的命令進(jìn)行加鎖或者類似的處理.你也可以讓exec只有在收到一個其他資源的事件的時候才執(zhí)行.因?yàn)閑xec資源是一種揮發(fā)性資源,命令執(zhí)行完了,這個資源可以說就處理完了.因此在不同的類里面,exec資源的名字可以是相同的,注意下面的例子紅色字體,這是exec資源特殊的地方。
exec { "make": cwd => "/prod/build/dir", path => "/usr/bin:/usr/sbin:/bin" } exec { "make": cwd => "/test/build/dir", path => "/usr/bin:/usr/sbin:/bin" }
注意:在不同的類定義相同名字的exec資源,如果是其他類型的資源,在執(zhí)行puppet的時候得到一個錯誤,但是在exec資源里面,這卻是正確的. 不過為了方便起見,建議每個exec資源的名字***是唯一的。
【puppet exec 參數(shù)介紹】
command:將會被執(zhí)行的命令,必須為被執(zhí)行命令的絕對路徑,或者得提供該命令的搜索路徑。如果命令被成功執(zhí)行,所有的輸出會被記錄在實(shí)例的正常(normal)日志里,但是如果命令執(zhí)行失敗(既返回值與我們所指定的不同),那么所有的輸出會在錯誤(err)日志中被記錄。
這個是exec資源類型的名變量(namevar)。
creates:指定命令所生成的文件。如果提供了這個參數(shù),那么命令只會在所指定的文件不存在的情況的被執(zhí)行:
cwd:指定命令執(zhí)行的目錄。如果目錄不存在,則命令執(zhí)行失敗。
env:我們不建議使用這個參數(shù),請使用‘environment’。這一部分還未完成。
environment:
為命令設(shè)定額外的環(huán)境變量。要注意的是如果你用這個來設(shè)定PATH,那么PATH的屬性會被覆蓋。多個環(huán)境變量應(yīng)該以數(shù)組的形式來設(shè)定。
group:定義運(yùn)行命令的用戶組。在不同的平臺下的運(yùn)行的結(jié)果無法確定,由于不同用戶運(yùn)行命令的時候,變量是不變的,所以這是平臺的問題,而不是Ruby或Puppet的問題。
logoutput:是否記錄輸出。默認(rèn)會根據(jù)exec資源的日志等級(loglevel)來記錄輸出。若定義為on_failure,則僅在命令返回錯誤的時候記錄輸出。可取的值為:true,false和其他合法的日志等級。
onlyif:如果這個參數(shù)被設(shè)定了,則exec只會在onlyif設(shè)定的命令返回0時才執(zhí)行。例如:
exec { "logrotate": path => "/usr/bin:/usr/sbin:/bin", onlyif => "test `du /var/log/messages | cut -f1` -gt 100000"
只有在test返回true的時候logrotate才會被運(yùn)行。
需要注意的是onlyif定義的命令跟主命令遵循同樣的規(guī)則,也就是說如果path沒有被設(shè)置的話,需要使用絕對路徑。
除此之外,onlyif還可以接受數(shù)組做為其值,例如:
onlyif => ["test -f /tmp/file1", "test -f /tmp/file2"]
上面的代碼限定了只有在所有數(shù)組中的條件返回true時exec才會被執(zhí)行。
path:命令執(zhí)行的搜索路徑。如果path沒有被定義,命令需要使用絕對路徑。路徑可以以數(shù)組或以冒號分隔的形式來定義。
refresh:定義如何更新命令。當(dāng)exec收到一個來自其他資源的事件時,默認(rèn)只會重新執(zhí)行一次命令。不過這個參數(shù)允許你定義更新時執(zhí)行不同的命令。
refreshonly:該屬性可以使命令變成僅刷新觸發(fā)的,也就是說只有在一個依賴的對象被改變時,命令才會被執(zhí)行。僅當(dāng)命令與其他對象有依賴關(guān)系時,這個參數(shù)才有意義。當(dāng)你要觸發(fā)某個行為時,會顯得很有用:
# Pull down the main aliases file file { "/etc/aliases": source => "puppet://server/module/aliases" } # Rebuild the database, but only when the file changes exec { newaliases: path => ["/usr/bin", "/usr/sbin"], subscribe => File["/etc/aliases"], refreshonly => true }
要注意的是只有subscribe和notify可以促發(fā)行為,而不是require,所以在使用refreshonly時,只有同時使用subscribe或notify才有意義。有效的值為true, false。
eturns:指定返回的代碼。如果被執(zhí)行的命令返回了其他的代碼,一個錯誤(error)會被返回。默認(rèn)值是0,可以定義為一個由可以接受的返回代碼組成的數(shù)組或單值。
timeout:命令運(yùn)行的最長時間。如果命令運(yùn)行的時間超過了timeout定義的時間,那么這個命令就會被終止,并作為運(yùn)行失敗處理。當(dāng)定義為負(fù)值時就會取消運(yùn)行時間的限制。timeout的值是以秒為單位的。
unless:如果這個變量被指定了,那么exec會執(zhí)行,除非unless所設(shè)定的命令返回0。例如:
exec { "/bin/echo root >> /usr/lib/cron/cron.allow": path => "/usr/bin:/usr/sbin:/bin", unless => "grep root /usr/lib/cron/cron.allow 2>/dev/null" }
上面這段代碼先用grep在cron.allow文件(Solaris系統(tǒng)中)中找root,如果沒有找到,就寫入root。
要注意的是這個參數(shù)里的命令跟主命令遵循同樣的規(guī)則,也就是說如果path沒有被設(shè)置的話,需要使用絕對路徑
user:定義運(yùn)行命令的用戶。注意如果你使用了這個參數(shù),那么任何的錯誤輸出不會在當(dāng)下被捕捉,這是Ruby的一個bug。
If you are using Puppet to create this user, the exec will automatically require the user, as long as it is specified by name.
【puppet exec示例】
1. 比如編譯某個軟件,執(zhí)行 make命令
file { “/var/nagios/configuration”: source => “puppet://$pupptserver/nagios/”, recurse => true, before => Exec["nagios-rebuid"] } exec { “nagios-rebuild”: command => “/usr/bin/make”, cwd => “/var/nagios/configuration” }
2.設(shè)置一個默認(rèn)的PATH路徑,這樣我們不用每次都寫path路徑。
Exec { path => [ "/bin/", "/sbin/" , "/usr/bin/", "/usr/sbin/" ] }
3.如上例,我有個命令是在/usr/local/sbin路徑下,不在默認(rèn)的PATH里。
exec { "squid": command => "/usr/local/sbin/squid", path => "/usr/local/sbin/", }
注意:這里設(shè)置了path值,會覆蓋掉默認(rèn)的PATH值 。
4. 如果某個文件已存在就不執(zhí)行exec.
exec { "/var/lib/puppet/report": command => "/bin/mkdir -p /var/lib/puppet/report", creates => "/var/lib/puppet/report" }
上例中如果/var/lib/puppet/report存在,puppet就不執(zhí)行exec.
5.有時候我們需要滿足某個條件的時候,才執(zhí)行exec命令。
exec { "logrotate": path => "/usr/bin:/usr/sbin:/bin", onlyif => "test `du /var/log/messages | cut -f1` -gt 100000" }
注意:設(shè)置only只有在命令結(jié)果返回為0的時候才執(zhí)行。
onlyif也可以接受數(shù)組做為其值,例如:
onlyif => ["test -f /tmp/file1", "test -f /tmp/file2"]
上面的代碼限定了只有在所有數(shù)組中的條件返回true時exec才會被執(zhí)行。
6. 當(dāng)兩個資源有依賴關(guān)系,如當(dāng)某個配置文件有改動時,exec執(zhí)行相應(yīng)的命令
file { "/etc/aliases": source => "puppet://server/module/aliases", } exec { newaliases: path => ["/usr/bin", "/usr/sbin"], subscribe => File["/etc/aliases"], refreshonly => true, }
7.記錄puppet 執(zhí)行失敗后的log日志。
exec { "delete_str_tmp": path => "/usr/local/bin/:/bin:/usr/sbin", command => 'find /tmp/ -name "*.str" -type f | xargs -n 1 rm', logoutput => "on_failure", }
【puppet exec 總結(jié)】
puppet管理exec資源主要是調(diào)用shell來完成,有一定的風(fēng)險(xiǎn)性。只要熟悉使用shell,可以很方便的寫出屬與自己的類,或者模塊等。下章會為大家介紹puppet運(yùn)維自動化管理 cron資源。