【使用指南】运维人员经常需要编译源码包。这时候puppet就可以执行外部命令了。其实就是直接调用shell完成的。这里介绍一下运维自动化的exec资源管理。【基础】作为运维人员,必须要精通一门语言,因为这个资源是通过shell来完成相关操作的,需要一定的shell基础。【puppetexec介绍】Puppet执行外部命令。以这种方式多次执行命令是有威胁的。因此,建议对执行的命令进行加锁或类似处理。您也可以让exec只接收其他资源。它仅在事件发生时执行。因为exec资源是一个volatile资源,在command执行完之后,这个资源可以说是被处理了。因此,在不同的类中,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资源定义在不同的类中。如果是其他类型的资源,执行puppet时会报错,但是在exec资源中,这是正确的。不过为了方便起见,建议每个exec资源的名称必须是唯一的。【puppeexec参数介绍】command:要执行的命令必须是要执行的命令的绝对路径,或者必须提供命令的搜索路径。如果命令执行成功,所有的输出都会记录在实例的正常(normal)日志中,但是如果命令失败(即返回值与我们指定的不一样),那么所有的输出都会在错误(err)log中记录的,这是exec资源类型的名称变量(namevar)。creates:指定命令生成的文件。如果提供该参数,则只有指定文件不存在时才会执行命令:cwd:指定执行命令的目录。如果该目录不存在,则命令失败。env:我们不推荐使用这个参数,请使用'environment'。这部分还没有完成。环境:为命令设置额外的环境变量。请注意,如果您使用它来设置PATH,那么PATH属性将被覆盖。多个环境变量应该以数组的形式设置。group:定义运行命令的用户组。无法确定在不同平台上运行的结果。由于不同用户运行命令时变量不变,这是一个平台问题,而不是Ruby或Puppet问题。logoutput:是否记录输出。默认情况下,输出将根据exec资源的日志级别(loglevel)进行记录。如果定义为on_failure,则仅当命令返回错误时才记录输出。可能的值:true、false和其他合法的日志级别。onlyif:如果设置了该参数,只有当onlyif设置的命令返回0时才会执行exec。例如:exec{"logrotate":path=>"/usr/bin:/usr/sbin:/bin",onlyif=>"test`du/var/log/messages|cut-f1`-gt100000"onlyintestlogrotate只会在返回true时运行。需要注意的是,onlyif定义的命令与main命令遵循相同的规则,即如果不设置路径,则需要使用绝对路径。另外,onlyif也可以接受数组作为它的值,例如:onlyif=>["test-f/tmp/file1","test-f/tmp/file2"]以上代码限制只有exec才会被执行当条件返回真时。path:命令执行的搜索路径。如果未定义路径,则该命令需要使用绝对路径。路径可以定义为数组或以冒号分隔的形式。refresh:定义如何刷新命令。当exec从另一个资源接收到事件时,它默认只会重新执行一次命令。但是这个参数允许你定义不同的命令在更新时执行。refreshonly:该属性可以使命令refresh-only被触发,也就是说只有当依赖的对象发生改变时才会执行该命令。此参数仅在命令依赖于其他对象时才有意义。当你想触发一个动作时,这很有用:#Pulldownthemainaliasesfile{"/etc/aliases":source=>"puppet://server/module/aliases"}#重建数据库,但仅当文件修改exec{newaliases:path=>["/usr/bin","/usr/sbin"],subscribe=>File["/etc/aliases"],refreshonly=>true}只有subscribe和notify才能提升behavior,notrequire,所以当使用refreshonly时,只有同时使用subscribe或notify才有意义。有效值为真、假。returns:指定返回码。如果执行的命令返回任何其他代码,将返回错误。默认值为0,可以定义为可接受返回码的数组或单个值。超时:命令运行的最长时间。如果命令运行的时间超过timeout定义的时间,命令将被终止并被视为失败。当定义为负值时,运行时间限制将被取消。超时值以秒为单位。unless:如果指定了这个变量,exec就会执行除非unless设置的命令返回0。例如:exec{"/bin/echoroot>>/usr/lib/cron/cron.allow":path=>"/usr/bin:/usr/sbin:/bin",unless=>"greproot/usr/lib/cron/cron.allow2>/dev/null"}上面的代码首先使用grep在cron中找到root。允许文件(在Solaris系统中),如果没有找到,写入root。需要注意的是,该参数中的命令遵循与主命令相同的规则,即如果不设置路径,则需要使用绝对路径user:定义运行该命令的用户。请注意,如果您使用此参数,则此时不会捕获任何错误输出,这是一个Ruby错误。如果您使用Puppet创建此用户,exec将自动要求该用户,只要按名称指定即可。【puppetexec示例】1.比如编译某个软件,执行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.设置默认值PATH路径这样我们就不用每次都写path路径了Exec{path=>["/bin/","/sbin/","/usr/bin/","/usr/sbin/"]}3.如上例,我在/usr/local/sbin路径下的命令不在默认的PATH.exec{"squid":command=>"/usr/local/sbin/squid",path=>"/usr/local/sbin/",}注意:这里设置的是路径值,会覆盖默认的PATH值。4、如果文件已经存在,不执行exec。exec{"/var/lib/puppet/report":command=>"/bin/mkdir-p/var/lib/puppet/report",creates=>"/var/lib/puppet/report"}在上面例如,如果/var/lib/puppet/report存在,puppet将不会执行exec。5、有时候我们需要满足某种条件才可以执行exec命令。exec{"logrotate":path=>"/usr/bin:/usr/sbin:/bin",onlyif=>"test`du/var/log/messages|cut-f1`-gt100000"}注意:设置only只在命令结果返回0时执行。onlyif也可以接受一个数组作为它的值,例如:onlyif=>["test-f/tmp/file1","test-f/tmp/file2"]代码以上限制只有所有数组中的条件返回trueexec才会被执行。6.当两个资源有依赖关系时,比如某个配置文件发生变化时,exec执行相应的命令文件{"/etc/aliases":source=>"puppet://server/module/aliases",}exec{newaliases:path=>["/usr/bin","/usr/sbin"],subscribe=>File["/etc/aliases"],refreshonly=>true,}7.记录puppet执行失败log日志。exec{"delete_str_tmp":path=>"/usr/local/bin/:/bin:/usr/sbin",command=>'find/tmp/-name"*.str"-typef|xargs-n1rm',logoutput=>"on_failure",}【puppeexec总结】Puppet主要通过调用shell来管理exec资源,存在一定的风险。只要熟悉使用shell,就可以轻松编写自己的类或模块。下一章将介绍puppet运维自动化管理cron资源。
