Guillaume Rousse
2011-Jun-09 15:20 UTC
[Puppet Users] using command execution result as conditional
Hello. I''d like to enhance the classical package/configuration/service pattern with an additional stage: configuration syntax checking. The goal is to ensure a service won''t be restarted with an invalid configuration first, but also to ensure this configuration error will get explicitly notified, not just buried in logs (we use nagios for this). In CFengine, it was quite easy to use the result of an external command execution to position a class in case of success: srv_dhcp.dhcpd_restart:: "/usr/sbin/dhcpd -t /etc/dhcpd.conf" define=dhcpd_config_ok srv_dhcp.dhcpd_restart.dhcpd_config_ok:: "$(service) dhcpd restart" srv_dhcp.dhcpd_restart.!dhcpd_config_ok:: "$(notify) dhcp-config 2 ''invalid dhcp configuration''" In Puppet documentation, I couldn''t find how to use the result of an ''exec'' resource to do something similar. There is an ''returns'' parameter, defining expected returns code, and the documentation mentions triggering an error when the result differs, but I couldn''t find documentation about how to use this behavior to trigger different actions. -- BOFH excuse #258: That''s easy to fix, but I can''t be bothered. -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
jcbollinger
2011-Jun-10 14:20 UTC
[Puppet Users] Re: using command execution result as conditional
On Jun 9, 10:20 am, Guillaume Rousse <guillomovi...@gmail.com> wrote:> Hello. > > I''d like to enhance the classical package/configuration/service pattern > with an additional stage: configuration syntax checking. The goal is to > ensure a service won''t be restarted with an invalid configuration first, > but also to ensure this configuration error will get explicitly > notified, not just buried in logs (we use nagios for this). > > In CFengine, it was quite easy to use the result of an external command > execution to position a class in case of success: > > srv_dhcp.dhcpd_restart:: > "/usr/sbin/dhcpd -t /etc/dhcpd.conf" define=dhcpd_config_ok > > srv_dhcp.dhcpd_restart.dhcpd_config_ok:: > "$(service) dhcpd restart" > > srv_dhcp.dhcpd_restart.!dhcpd_config_ok:: > "$(notify) dhcp-config 2 ''invalid dhcp configuration''" > > In Puppet documentation, I couldn''t find how to use the result of an > ''exec'' resource to do something similar. There is an ''returns'' > parameter, defining expected returns code, and the documentation > mentions triggering an error when the result differs, but I couldn''t > find documentation about how to use this behavior to trigger different > actions.If you want to trigger more than one action that is not simply a Puppet result message in your log, then your options are: 1) Make a custom fact out of your command (it''s not hard), and use a Puppet conditional based on that fact to control which resources are included in the node''s catlog. This works well, but (a) the command will be run before every Puppet run; (b) it captures the command result *before* the Puppet run. 2) Make a custom function to perform the command. This is a bit more complicated and a bit more flexible, but it has some significant limitations, most importantly: (a) the command is run on the *master*. 3) Put it all in an Exec. The "onlyif" and "unless" parameters can help (for instance, put the real command in an "unless" and the notify command in "command"), or you can script the whole thing and exec that. This is ugly. 4) Use Puppet resource dependencies, perhaps in combination with one or more of the above. If resource A has a declared dependency on resource B, and resource B fails, then resource A will not be applied. 5) If your Ruby-fu is strong, then write a custom type and provider that do whatever you want. I don''t read CFengine, but the following Puppet example might do something similar to your CFE code: file { "/etc/dhcpd.conf": # appropriate properties ... } exec { "check_dhcpd_conf": command => "/usr/sbin/dhcpd -t /etc/dhcpd.conf", refreshonly => true, subscribe => File[ "/etc/dhcpd.conf" ] } service { "dhcpd'': ensure => "running", # other parameters as appropriate ... require => Exec[ "check_dhcpd_conf" ], subscribe => File[ "/etc/dhcpd.conf" ] } John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Guillaume Rousse
2011-Jun-15 07:39 UTC
Re: [Puppet Users] Re: using command execution result as conditional
Hello Jones, thanks for your answer. Le 10/06/2011 16:20, jcbollinger a écrit :> If you want to trigger more than one action that is not simply a > Puppet result message in your log, then your options are: > > 1) Make a custom fact out of your command (it''s not hard), and use a > Puppet conditional based on that fact to control which resources are > included in the node''s catlog. This works well, but (a) the command > will be run before every Puppet run; (b) it captures the command > result *before* the Puppet run.making it unappropriate: I need to test the new configuration file.> 2) Make a custom function to perform the command. This is a bit more > complicated and a bit more flexible, but it has some significant > limitations, most importantly: (a) the command is run on the *master*.same issue.> 3) Put it all in an Exec. The "onlyif" and "unless" parameters can > help (for instance, put the real command in an "unless" and the notify > command in "command"), or you can script the whole thing and exec > that. This is ugly.Indeed :)> 4) Use Puppet resource dependencies, perhaps in combination with one > or more of the above. If resource A has a declared dependency on > resource B, and resource B fails, then resource A will not be applied.That''s the one below.> 5) If your Ruby-fu is strong, then write a custom type and provider > that do whatever you want.That''s a potential future choice.> I don''t read CFengine, but the following Puppet example might do > something similar to your CFE code: > > file { "/etc/dhcpd.conf": > # appropriate properties ... > } > > exec { "check_dhcpd_conf": > command => "/usr/sbin/dhcpd -t /etc/dhcpd.conf", > refreshonly => true, > subscribe => File[ "/etc/dhcpd.conf" ] > } > > service { "dhcpd'': > ensure => "running", > # other parameters as appropriate ... > require => Exec[ "check_dhcpd_conf" ], > subscribe => File[ "/etc/dhcpd.conf" ] > }Yes, that''s I finally opted for, without having the time to test. The documentation wasn''t very clear about impact of failures on dependencies, but I assumed they were preventing depended resources to run (http://docs.puppetlabs.com/learning/ordering.html merely speaks about ordering). However, the limitation of this pattern is that it doesn''t trigger any alert in case of failure. I still can parse execution logs, or pay attention to dashboard results for errors, but that''s not pushing error notifications anymore. -- BOFH excuse #368: Failure to adjust for daylight savings time. -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.