Issue #9237 has been updated by Tim Alexander.
Lemme preface this with "I have pretty near 0 experience with Ruby, though I
can generally feel my way around a language without making a complete fool of
myself."
Here's the offending method in current git, identical to my 2.7.1 installation.
def refresh
if self.check_all_attributes(true)
if cmd = self[:refresh]
provider.run(cmd)
else
self.property(:returns).sync
end
end
end
It looks like on line 501 of
https://github.com/puppetlabs/puppet/blob/master/lib/puppet/type/exec.rb
there's this line
provider.run(cmd)
which isn't actually capturing the output and failing the refresh command. So
changing that whole method (refresh) to this (in 2.7.1, which has no changes to
this method from git):
# Run the command, or optionally run a separately-specified command.
def refresh
if self.check_all_attributes(true)
if cmd = self[:refresh]
@output, @status = provider.run(cmd)
unless ( 0 == @status.exitstatus.to_s )
self.fail("#{cmd} returned #{@status.exitstatus}")
end
else
self.property(:returns).sync
end
end
fails it properly. This fixes both this bug, and Bug #6922. I'm going to throw
together a quick patch to take into account the other stuff (cwd, valid return
codes, etc.) unless there's something I'm missing? I still have yet to verify
that this fixes my issues with Service, but that might be a different bug if
not. (does service wrap exec under the covers?)
----------------------------------------
Bug #9237: Failed refresh events do not get logged, or reported as errors.
https://projects.puppetlabs.com/issues/9237
Author: Tim Alexander
Status: Investigating
Priority: High
Assignee: Ben Hughes
Category: metaparameters
Target version:
Affected Puppet version: 2.7.1
Keywords:
Branch:
Similar to Bug #5670 and Bug #6922 (especially Bug #6922)
refresh calls on all types are not registering a failure. If an exec does not
have a refresh defined, this does work properly (see Bug #6922).
Taken directly from the cheatsheet PDF, below is one example. An easily
executable example is included later. The result of this bug is if sshd_config
(below) is changed and causes Service['sshd'] to fail restart (returning other
than return code 0), the failure won't be reported or even visible until the
next puppet run that checks to make sure the service is running (and when it
sees the service is stopped, it attempts to start it). Depending on your
schedule/configuration this could be quite some time.
<pre>
package { 'openssh-server':
ensure => installed,
}
file { '/etc/ssh/sshd_config':
source => 'puppet:///modules/sshd/sshd_config',
owner => 'root',
group => 'root',
mode => '640',
notify => Service['sshd'], # sshd will restart whenever you edit this file.
require => Package['openssh-server'],
}
service { 'sshd':
ensure => running,
enable => true,
hasstatus => true,
hasrestart => true,
}
</pre>
Here's an example using only exec statements (keeps it pretty self contained):
<pre>
root@puppettest:/etc/puppet/manifests# cat test.pp
exec { 'first':
command => '/bin/echo first',
refreshonly => true,
refresh => '/bin/false',
}
exec { 'second':
command => '/bin/echo second',
notify => Exec['first'],
}
</pre>
<pre>
root@puppettest:/etc/puppet/manifests# puppet apply test.pp --verbose --debug
--trace
debug: Creating default schedules
debug: Failed to load library 'selinux' for feature 'selinux'
[SNIP]
debug: Finishing transaction 70246236951700
debug: Loaded state in 0.01 seconds
debug: Loaded state in 0.01 seconds
info: Applying configuration version '1314637523'
debug: /Stage[main]//Exec[second]/notify: subscribes to Exec[first]
debug: /Schedule[never]: Skipping device resources because running on a host
debug: /Schedule[daily]: Skipping device resources because running on a host
debug: /Schedule[monthly]: Skipping device resources because running on a host
debug: /Schedule[puppet]: Skipping device resources because running on a host
debug: /Schedule[hourly]: Skipping device resources because running on a host
debug: /Schedule[weekly]: Skipping device resources because running on a host
debug: Exec[second](provider=posix): Executing '/bin/echo second'
debug: Executing '/bin/echo second'
notice: /Stage[main]//Exec[second]/returns: executed successfully
debug: /Stage[main]//Exec[second]: The container Class[Main] will propagate my
refresh event
info: /Stage[main]//Exec[second]: Scheduling refresh of Exec[first]
debug: Exec[first](provider=posix): Executing '/bin/false'
debug: Executing '/bin/false'
notice: /Stage[main]//Exec[first]: Triggered 'refresh' from 1 events
debug: /Stage[main]//Exec[first]: The container Class[Main] will propagate my
refresh event
debug: Class[Main]: The container Stage[main] will propagate my refresh event
debug: Finishing transaction 70246236019520
debug: Storing state
debug: Stored state in 0.05 seconds
notice: Finished catalog run in 0.24 seconds
debug: Finishing transaction 70246235520580
</pre>
NOTE: This fails properly if I set the initial command to '/bin/false' however,
so it looks like there's a workaround for exec so long as no refresh is defined
(not possible in some circumstances).
<pre>
root@puppettest:/etc/puppet/manifests# cat test.pp
exec { 'first':
command => '/bin/false',
refreshonly => true,
#refresh => '/bin/false',
}
exec { 'second':
command => '/bin/echo second',
notify => Exec['first'],
}
</pre>
<pre>
root@puppettest:/etc/puppet/manifests# puppet apply test.pp --verbose --debug
--trace
debug: Creating default schedules
debug: Failed to load library 'selinux' for feature 'selinux'
[SNIP]
debug: /File[/var/lib/puppet/facts]: Autorequiring File[/var/lib/puppet]
debug: Finishing transaction 69917314836460
debug: Loaded state in 0.01 seconds
debug: Loaded state in 0.01 seconds
info: Applying configuration version '1314638357'
debug: /Stage[main]//Exec[second]/notify: subscribes to Exec[first]
debug: /Schedule[never]: Skipping device resources because running on a host
debug: /Schedule[daily]: Skipping device resources because running on a host
debug: /Schedule[monthly]: Skipping device resources because running on a host
debug: /Schedule[puppet]: Skipping device resources because running on a host
debug: /Schedule[hourly]: Skipping device resources because running on a host
debug: /Schedule[weekly]: Skipping device resources because running on a host
debug: Exec[second](provider=posix): Executing '/bin/echo second'
debug: Executing '/bin/echo second'
notice: /Stage[main]//Exec[second]/returns: executed successfully
info: /Stage[main]//Exec[second]: Scheduling refresh of Exec[first]
debug: /Stage[main]//Exec[second]: The container Class[Main] will propagate my
refresh event
debug: Exec[first](provider=posix): Executing '/bin/false'
debug: Executing '/bin/false'
err: /Stage[main]//Exec[first]: Failed to call refresh: /bin/false returned 1
instead of one of [0] at /etc/puppet/manifests/test.pp:5
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/parameter.rb:171:in `fail'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/type/exec.rb:122:in `sync'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/type/exec.rb:500:in
`refresh'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/transaction/event_manager.rb:94:in
`send'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/transaction/event_manager.rb:94:in
`process_callback'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/transaction/event_manager.rb:20:in
`process_events'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/transaction/event_manager.rb:86:in
`queued_events'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/transaction/event_manager.rb:85:in
`each'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/transaction/event_manager.rb:85:in
`queued_events'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/transaction/event_manager.rb:19:in
`process_events'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/transaction.rb:88:in
`eval_resource'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/transaction.rb:107:in
`evaluate'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/util.rb:430:in `thinmark'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/util.rb:429:in `thinmark'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/transaction.rb:107:in
`evaluate'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/transaction.rb:319:in
`traverse'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/transaction.rb:103:in
`evaluate'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/resource/catalog.rb:141:in
`apply'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/configurer.rb:150:in `run'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/util.rb:194:in `benchmark'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/util.rb:193:in `benchmark'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/configurer.rb:149:in `run'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/application/apply.rb:209:in
`main'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/application/apply.rb:134:in
`run_command'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/application.rb:307:in `run'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/application.rb:411:in `hook'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/application.rb:307:in `run'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/application.rb:402:in
`exit_on_fail'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/application.rb:307:in `run'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/lib/puppet/util/command_line.rb:69:in
`execute'
/usr/lib/ruby/gems/1.8/gems/puppet-2.7.1/bin/puppet:4
/usr/bin/puppet:19:in `load'
/usr/bin/puppet:19
debug: Class[Main]: The container Stage[main] will propagate my refresh event
debug: Finishing transaction 69917313903120
debug: Storing state
debug: Stored state in 0.05 seconds
notice: Finished catalog run in 0.24 seconds
debug: Finishing transaction 69917313411980
</pre>
--
You have received this notification because you have either subscribed to it,
or are involved in it.
To change your notification preferences, please click here:
http://projects.puppetlabs.com/my/account
--
You received this message because you are subscribed to the Google Groups
"Puppet Bugs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/puppet-bugs?hl=en.