Summary
Puppet::Util#execute may block indefinitely trying to read the pipe connected to the child process it spawns.
Impact Data
Fails consistently trying to manage /usr/sbin/automount on Mac OS X.
Related to #410 (Puppet::Util#execute should support a timeout)
Expected Behavior
The parent puppet process should detect the child's death and proceed.
Actual Behavior
The parent seems to block indefinitely at f.read in this section of code:
source:trunk/lib/puppet/util.rb
IO.popen("-") do |f|
if f
output = f.read
else
begin
$stdin.reopen("/dev/null")
$stderr.close
$stderr = $stdout.dup
if gid
Process.egid = gid
Process.gid = gid unless @@os == "Darwin"
end
if uid
Process.euid = uid
Process.uid = uid unless @@os == "Darwin"
end
if command.is_a?(Array)
Kernel.exec(*command)
else
Kernel.exec(command)
end
rescue => detail
puts detail.to_s
exit!(1)
end
end
end
Regression
Problem exists through 0.22.2.
Steps to Reproduce
On Mac OS X, run puppet as root with the following manifest:
file { "/tmp/auto_home": ensure => exists }
exec {"automount":
command => "/usr/sbin/automount -tcp -m /tmp/home /tmp/auto_home -mnt /private/var/automount/tmp_home",
require => File["/tmp/auto_home"]
}
Other Notes
I'm currently working on a patch. Test new code with:
cd trunk/test/util
./utiltest.rb
Expect 1 failure on Mac OS X and Redhat when attempting to change the UID for a process.
3) Failure:
test_get_provider_value(TestPuppetUtil) [./utiltest.rb:342]:
got invalid uid for root.
<0> expected but was
<nil>.