puppet運(yùn)維自動(dòng)化之Exec資源管理
【導(dǎo)讀】
運(yùn)維人員,經(jīng)常要編譯源碼包,這個(gè)時(shí)候就可以讓puppet執(zhí)行外部命令。其實(shí)就是直接調(diào)用shell來(lái)完成。這里為大家介紹運(yùn)維自動(dòng)化之exec資源管理。
【基礎(chǔ)】
作為運(yùn)維人員,肯定是對(duì)一門(mén)語(yǔ)言熟練掌握,因?yàn)榇速Y源是通過(guò)shell來(lái)完成相關(guān)操作,需要對(duì)shell有一定的基礎(chǔ)。
【puppet exec介紹】
puppet執(zhí)行外部命令,多次反復(fù)用這個(gè)方式執(zhí)行命令是有威脅性的,因此建議對(duì)執(zhí)行的命令進(jìn)行加鎖或者類(lèi)似的處理.你也可以讓exec只有在收到一個(gè)其他資源的事件的時(shí)候才執(zhí)行.因?yàn)閑xec資源是一種揮發(fā)性資源,命令執(zhí)行完了,這個(gè)資源可以說(shuō)就處理完了.因此在不同的類(lèi)里面,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" }
注意:在不同的類(lèi)定義相同名字的exec資源,如果是其他類(lèi)型的資源,在執(zhí)行puppet的時(shí)候得到一個(gè)錯(cuò)誤,但是在exec資源里面,這卻是正確的. 不過(guò)為了方便起見(jiàn),建議每個(gè)exec資源的名字***是唯一的。
【puppet exec 參數(shù)介紹】
command:將會(huì)被執(zhí)行的命令,必須為被執(zhí)行命令的絕對(duì)路徑,或者得提供該命令的搜索路徑。如果命令被成功執(zhí)行,所有的輸出會(huì)被記錄在實(shí)例的正常(normal)日志里,但是如果命令執(zhí)行失?。确祷刂蹬c我們所指定的不同),那么所有的輸出會(huì)在錯(cuò)誤(err)日志中被記錄。
這個(gè)是exec資源類(lèi)型的名變量(namevar)。
creates:指定命令所生成的文件。如果提供了這個(gè)參數(shù),那么命令只會(huì)在所指定的文件不存在的情況的被執(zhí)行:
cwd:指定命令執(zhí)行的目錄。如果目錄不存在,則命令執(zhí)行失敗。
env:我們不建議使用這個(gè)參數(shù),請(qǐng)使用‘environment’。這一部分還未完成。
environment:
為命令設(shè)定額外的環(huán)境變量。要注意的是如果你用這個(gè)來(lái)設(shè)定PATH,那么PATH的屬性會(huì)被覆蓋。多個(gè)環(huán)境變量應(yīng)該以數(shù)組的形式來(lái)設(shè)定。
group:定義運(yùn)行命令的用戶(hù)組。在不同的平臺(tái)下的運(yùn)行的結(jié)果無(wú)法確定,由于不同用戶(hù)運(yùn)行命令的時(shí)候,變量是不變的,所以這是平臺(tái)的問(wèn)題,而不是Ruby或Puppet的問(wèn)題。
logoutput:是否記錄輸出。默認(rèn)會(huì)根據(jù)exec資源的日志等級(jí)(loglevel)來(lái)記錄輸出。若定義為on_failure,則僅在命令返回錯(cuò)誤的時(shí)候記錄輸出??扇〉闹禐椋簍rue,false和其他合法的日志等級(jí)。
onlyif:如果這個(gè)參數(shù)被設(shè)定了,則exec只會(huì)在onlyif設(shè)定的命令返回0時(shí)才執(zhí)行。例如:
exec { "logrotate": path => "/usr/bin:/usr/sbin:/bin", onlyif => "test `du /var/log/messages | cut -f1` -gt 100000"
只有在test返回true的時(shí)候logrotate才會(huì)被運(yùn)行。
需要注意的是onlyif定義的命令跟主命令遵循同樣的規(guī)則,也就是說(shuō)如果path沒(méi)有被設(shè)置的話(huà),需要使用絕對(duì)路徑。
除此之外,onlyif還可以接受數(shù)組做為其值,例如:
onlyif => ["test -f /tmp/file1", "test -f /tmp/file2"]
上面的代碼限定了只有在所有數(shù)組中的條件返回true時(shí)exec才會(huì)被執(zhí)行。
path:命令執(zhí)行的搜索路徑。如果path沒(méi)有被定義,命令需要使用絕對(duì)路徑。路徑可以以數(shù)組或以冒號(hào)分隔的形式來(lái)定義。
refresh:定義如何更新命令。當(dāng)exec收到一個(gè)來(lái)自其他資源的事件時(shí),默認(rèn)只會(huì)重新執(zhí)行一次命令。不過(guò)這個(gè)參數(shù)允許你定義更新時(shí)執(zhí)行不同的命令。
refreshonly:該屬性可以使命令變成僅刷新觸發(fā)的,也就是說(shuō)只有在一個(gè)依賴(lài)的對(duì)象被改變時(shí),命令才會(huì)被執(zhí)行。僅當(dāng)命令與其他對(duì)象有依賴(lài)關(guān)系時(shí),這個(gè)參數(shù)才有意義。當(dāng)你要觸發(fā)某個(gè)行為時(shí),會(huì)顯得很有用:
# 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時(shí),只有同時(shí)使用subscribe或notify才有意義。有效的值為true, false。
eturns:指定返回的代碼。如果被執(zhí)行的命令返回了其他的代碼,一個(gè)錯(cuò)誤(error)會(huì)被返回。默認(rèn)值是0,可以定義為一個(gè)由可以接受的返回代碼組成的數(shù)組或單值。
timeout:命令運(yùn)行的最長(zhǎng)時(shí)間。如果命令運(yùn)行的時(shí)間超過(guò)了timeout定義的時(shí)間,那么這個(gè)命令就會(huì)被終止,并作為運(yùn)行失敗處理。當(dāng)定義為負(fù)值時(shí)就會(huì)取消運(yùn)行時(shí)間的限制。timeout的值是以秒為單位的。
unless:如果這個(gè)變量被指定了,那么exec會(huì)執(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,如果沒(méi)有找到,就寫(xiě)入root。
要注意的是這個(gè)參數(shù)里的命令跟主命令遵循同樣的規(guī)則,也就是說(shuō)如果path沒(méi)有被設(shè)置的話(huà),需要使用絕對(duì)路徑
user:定義運(yùn)行命令的用戶(hù)。注意如果你使用了這個(gè)參數(shù),那么任何的錯(cuò)誤輸出不會(huì)在當(dāng)下被捕捉,這是Ruby的一個(gè)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. 比如編譯某個(gè)軟件,執(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è)置一個(gè)默認(rèn)的PATH路徑,這樣我們不用每次都寫(xiě)path路徑。
Exec { path => [ "/bin/", "/sbin/" , "/usr/bin/", "/usr/sbin/" ] }
3.如上例,我有個(gè)命令是在/usr/local/sbin路徑下,不在默認(rèn)的PATH里。
exec { "squid": command => "/usr/local/sbin/squid", path => "/usr/local/sbin/", }
注意:這里設(shè)置了path值,會(huì)覆蓋掉默認(rèn)的PATH值 。
4. 如果某個(gè)文件已存在就不執(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.有時(shí)候我們需要滿(mǎn)足某個(gè)條件的時(shí)候,才執(zhí)行exec命令。
exec { "logrotate": path => "/usr/bin:/usr/sbin:/bin", onlyif => "test `du /var/log/messages | cut -f1` -gt 100000" }
注意:設(shè)置only只有在命令結(jié)果返回為0的時(shí)候才執(zhí)行。
onlyif也可以接受數(shù)組做為其值,例如:
onlyif => ["test -f /tmp/file1", "test -f /tmp/file2"]
上面的代碼限定了只有在所有數(shù)組中的條件返回true時(shí)exec才會(huì)被執(zhí)行。
6. 當(dāng)兩個(gè)資源有依賴(lài)關(guān)系,如當(dāng)某個(gè)配置文件有改動(dòng)時(shí),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來(lái)完成,有一定的風(fēng)險(xiǎn)性。只要熟悉使用shell,可以很方便的寫(xiě)出屬與自己的類(lèi),或者模塊等。下章會(huì)為大家介紹puppet運(yùn)維自動(dòng)化管理 cron資源。