1、 Puppet exec簡介node
Puppet經過exec來執行外部的命令或者腳本,通常來說是shell腳本 。這裏面就涉及到一個重複執行的問題,由於默認的agent一鏈接上來就會自動執行對應的命令或者腳本。若是腳本重複執行對系統沒影響的還無所謂,若是會對系統形成影響呢?一個有用的方法是使用像creates參數檢查來避免運行命令,除非達到了某個條件纔會指定。好比執行以前判斷文件是否存在等等。你可使用refreshonly參數限制一個exec只有收到某個事件才執行。ios
2、 Puppet exec參數介紹shell
1. commandwindows
指定要執行的命令。若是忽略,這個參數的值默認爲資源的標題。必須填寫命令的完整路徑或者提供這個命令的查找路徑。假如命令執行成功,執行過程的輸出將會記錄到普通(normal)日誌中,可是若是命令執行失敗,任何的輸出都會記錄到錯誤日誌中。數組
2. creates安全
命令建立的一個文件。加入這個參數設置的話,只有這個文件不存在的時候命令纔會執行,好比下面的例子:ruby
exec { "tar -xf /Volumes/nfs02/important.tar":app
cwd => "/var/tmp",less
creates => "/var/tmp/myfile",ide
path => ["/usr/bin", "/usr/sbin"]
}
這例子中,只有/var/tmp/myfile文件不存在的時候,tar -xf /Volumes/nfs02/important.tar命令纔會執行。
3. cwd
命令執行的路徑。假如目錄不存在,命令執行將會失敗。
4. environment
爲命令設置附加的環境變量。加入你用這個參數設置PATH,那麼將會把path參數的值覆蓋。多個環境變量須要使用數組指定。
5. group
執行命令運行的用戶組。這個看起來在各個平臺運行結果不肯定,這是平臺的問題不是ruby或者puppet的問題。
6. logoutput
是否記錄輸出信息。默認會根據exec資源的日誌等級來記錄輸出信息,使用on_failure只有當命令執行出錯的時候纔會記錄輸出信息。值能夠爲true、fales、on_failure和任何合法的日誌等級。
7. onlyif
只有onlyif指定命令執行返回爲0的時候,命令纔會執行。好比下面的例子:
exec { "logrotate":
path => "/usr/bin:/usr/sbin:/bin",
onlyif => "test `du /var/log/messages | cut -f1` -gt 100000"
}
只有當test `du /var/log/messages | cut -f1` -gt 100000執行的結果返回爲0,也就是執行成功才與執行logrotate命令。Onlyif中指定的命令加入沒有設置path的話要指定完整路徑。Onlyif也能夠將數組做爲他的值,好比:
onlyif => ["test -f /tmp/file1", "test -f /tmp/file2"]
只有當數組中的全部命令都返回true的時候纔會執行命令。
8. path
命令執行搜索的路徑。若是沒有指定path,命令須要填寫完整的路徑。路徑能夠指定爲一個數組並經過冒號分隔。
9. provider
exec資源的特定後臺。通常不多須要指定這個,puppet通常會自動爲你的平臺發現合適的provider,可用的provider以下:
posix ---- 不經過shell解釋或者執行如何插值,直接執行外部的二進制文件,這是一個執行大多數命令都更安全更肯定的方式。可是阻止通配符和shell內置插件的使用(包括像for這樣的控制邏輯和if語句)
shell ---- 經過/bin/sh來解釋提供的命令,只在POSIX系統中可用。致個模式容許使用通配符和shell內置插件,而且不須要爲命令的路徑指定完整的路徑。雖然shell比posix更方便,可是同時也意味着在轉譯方面更當心。這個shell的exec類型在puppet 0.25.x.版本提供。
windows ---- 在windows系統上執行外部的二進制文件。和posix模式同樣,這個模式經過給定的參數直接調用命令,不經過shell解釋或者執行如何插值。
10. refresh
如何更新命令。默認的當exec收到其餘的資源的一個事件時會從新執行。可是這個參數容許你定義更新不一樣的命令。
11. refreshonly
做爲一個更新機制當一個依賴的對象改變的時候命令纔會執行。當這個命令依賴其餘對象的時候這個選項纔會有意義。當須要出發某個行爲的時候會很是有用。好比下面的例子:
# 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
}
只有當/etc/aliases文件改變的時候纔會觸發從master中獲取aliases文件到/etc/ aliases。
備註:只有subscribe和notify才能夠觸發行爲,而不是require,因此只有使用refreshonly和subscribe或notify一塊兒使用的時候有意義。可用的值爲true或false。
12. returns
指定預期的返回代碼。假如執行的命令返回其餘的代碼那麼將會出現錯誤。默認是0,能夠指定一個單一的值也能夠指定一個包含多個值的數組。
13. timeout
指定命令運行的最長時間。假如命令執行的時間查過timeout設定的時間,那麼就會認爲命令執行失敗了而且會中止該命令。設置爲0表示沒有執行時間限制。時間以秒爲單位。
14. tries
命令執行重試次數,默認爲1。設置這個參數命令將會重試你設置的次數直到合理的代碼返回。
15. try_sleep
設置命令重試的間隔時間,單位是秒。
16. unless
加入這個參數設置的話,而後exec會執行,除非unless的命令返回爲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"
}
這段代碼將會將root添加到/usr/lib/cron/cron.allow文件中,除非grep發現root已經在那個文件裏了。
17. user
指定執行命令的用戶。
備註:加入你使用這個參數,任何錯誤輸出不會在當下撲捉。這是源自ruby內部的一個bug。
3、 Puppet exec實戰
1. 若是不存在就建立一個空文件,代碼以下:
exec { "/tmp/test1":
command => "touch /tmp/test1",
creates => "/tmp/test1"
}
這裏沒有指定path,命令又沒有寫完整路徑,所以報以下錯誤,解決辦法是加上path或者爲touch寫完整路徑。
err: Failed to apply catalog: 'touch /tmp/test1' is not qualified and no path was specified. Please qualify the command or specify a path.
更改後代碼爲:
exec { "/tmp/test1":
command => "/bin/touch /tmp/test1",
creates => "/tmp/test1"
}
或者:
exec { "/tmp/test1":
command => "touch /tmp/test1",
path => "/usr/bin:/usr/sbin:/bin:/sbin",
creates => "/tmp/test1"
}
爲了方即可以設置一個默認的path,這樣就不會每次都要寫path了。
exec { path => [ "/bin/", "/sbin/" , "/usr/bin/", "/usr/sbin/" ] }
2. 自動安裝nagios客戶端的完整示例,代碼以下:
node 'node1.zhang.com'{
#將nagios-plugins和nrpe打包,複製到agent上
file {"/data/software/install_nrpe.tar.gz":
source => "puppet://puppet.zhang.com/files/install_nrpe.tar.gz";
}
#解壓源碼包
exec { "unzip package":
command => "tar xzvf /data/software/install_nrpe.tar.gz",
path => "/usr/bin:/usr/sbin:/bin:/sbin",
creates => "/data/software/install_nrpe/nrpe.cfg";
}
#執行安裝腳本
exec { "install package":
command => "/data/software/install_nrpe/install_nrpe.sh",
path => "/usr/bin:/usr/sbin:/bin:/sbin",
logoutput => "true",
creates => "/usr/local/nagios";
}
}
3. 知足某個條件的時候執行exec,代碼以下:
#當result.log超過1K的就刪除該文件
exec { "clear comment":
command => "rm -f /tmp/result.log",
path => "/usr/bin:/usr/sbin:/bin:/sbin",
onlyif => "test `du /tmp/result.log | cut -f1 ` -gt 1024"
}
奇怪的是我將cut換成awk的時候及時達到條件也不會刪除該文件,並且沒有任何報錯:
exec { "clear comment":
command => "rm -f /tmp/result.log",
path => "/usr/bin:/usr/sbin:/bin:/sbin",
onlyif => "test `du /tmp/result.log |awk '{print $1}' ` -gt 1024"
}
4. 當資源有依賴的時候,若是某個文件發生變動,exec就執行對應的命令,下面是一個ftp虛擬賬號管理的觸發條件,代碼以下:
#設置一個公共的path
Exec { path => [ "/bin/", "/sbin/" , "/usr/bin/", "/usr/sbin/" ] }
#設置vftpuser.txt資源
file {"/etc/vsftpd/vftpuser.txt":
source => "puppet://puppet.zhang.com/files/vftpuser.txt",
backup => ".bak_$uptime_seconds",
}
#當vftpuser.txt發生變動的時候進行更ftp的帳戶信息
exec { "new vftpuser.db":
command => "db_load -T -t hash -f /etc/vsftpd/vftpuser.txt /etc/vsftpd/vftpuser.db",
subscribe => File["/etc/vsftpd/vftpuser.txt"],
refreshonly => true,
}