Not sure if this is a bug in puppet, yum, or just something I'm doing wrong.
I'm trying to use puppet to update a package to a particular version and exec
a command when that update is applied.
The problem is, puppet calls yum which successfully updates the package, but
puppet then thinks the update has failed and hence doesn't trigger the exec.
Next cycle the package is already the correct version, so the update isn't
applied, so the exec is never called.
manifest snippet:
package { "test":
ensure => "1.21",
}
exec { "testcmd":
command => "/foo/bar",
refreshonly => true,
subscribe => package["test"]
}
Output from puppetd:
debug: Puppet::Type::Package::ProviderYum: Executing '/usr/bin/yum -d 0 -e 0 -y install test-1.21'
/usr/lib/site_ruby/1.8/puppet/parameter.rb:279:in `fail'
/usr/lib/site_ruby/1.8/puppet/type/package.rb:88
/usr/lib/site_ruby/1.8/puppet/type/package.rb:84:in `instance_eval'
/usr/lib/site_ruby/1.8/puppet/property.rb:181:in `instance_eval'
/usr/lib/site_ruby/1.8/puppet/property.rb:181:in `call_valuemethod'
/usr/lib/site_ruby/1.8/puppet/property.rb:350:in `set'
/usr/lib/site_ruby/1.8/puppet/property.rb:422:in `sync'
/usr/lib/site_ruby/1.8/puppet/propertychange.rb:81:in `go'
/usr/lib/site_ruby/1.8/puppet/propertychange.rb:109:in `forward'
/usr/lib/site_ruby/1.8/puppet/transaction.rb:117:in `apply_changes'
/usr/lib/site_ruby/1.8/puppet/transaction.rb:109:in `collect'
/usr/lib/site_ruby/1.8/puppet/transaction.rb:109:in `apply_changes'
/usr/lib/site_ruby/1.8/puppet/transaction.rb:81:in `apply'
/usr/lib/site_ruby/1.8/puppet/transaction.rb:238:in `eval_resource'
/usr/lib/site_ruby/1.8/puppet/transaction.rb:237:in `thinmark'
/usr/lib/site_ruby/1.8/puppet/util.rb:444:in `measure'
/usr/lib/ruby/1.8/benchmark.rb:342:in `realtime'
/usr/lib/site_ruby/1.8/puppet/util.rb:444:in `thinmark'
/usr/lib/site_ruby/1.8/puppet/transaction.rb:239:in `eval_resource'
/usr/lib/site_ruby/1.8/puppet/transaction.rb:309:in `evaluate'
/usr/lib/site_ruby/1.8/puppet/transaction.rb:308:in `thinmark'
/usr/lib/site_ruby/1.8/puppet/util.rb:444:in `measure'
/usr/lib/ruby/1.8/benchmark.rb:342:in `realtime'
/usr/lib/site_ruby/1.8/puppet/util.rb:444:in `thinmark'
/usr/lib/site_ruby/1.8/puppet/transaction.rb:310:in `evaluate'
/usr/lib/site_ruby/1.8/puppet/transaction.rb:302:in `collect'
/usr/lib/site_ruby/1.8/puppet/transaction.rb:302:in `evaluate'
/usr/lib/site_ruby/1.8/puppet/node/catalog.rb:118:in `apply'
/usr/lib/site_ruby/1.8/puppet/network/client/master.rb:264:in `run'
/usr/lib/site_ruby/1.8/puppet/network/client/master.rb:263:in `benchmark'
/usr/lib/site_ruby/1.8/puppet/util.rb:211:in `measure'
/usr/lib/ruby/1.8/benchmark.rb:342:in `realtime'
/usr/lib/site_ruby/1.8/puppet/util.rb:211:in `benchmark'
/usr/lib/site_ruby/1.8/puppet/network/client/master.rb:263:in `run'
/usr/lib/site_ruby/1.8/puppet/network/client/master.rb:245:in `synchronize'
/usr/lib/site_ruby/1.8/puppet/network/client/master.rb:245:in `run'
/usr/bin/puppetd:439
err: /:main/Node[testnode]/test/Package[test]/ensure: change from 1.20 to 1.21 failed:
Could not update: Failed to update to version1.21, got version 1.20 instead at
/etc/puppet/modules/test/manifests/init.pp:28
notice: /:main/Node[testnode]/test/Exec[testcmd]: Dependency package[test] has 1 failures
warning: /:main/Node[testnode]/test/Exec[testcmd]: Skipping because of failed dependencies
The package is successfully updated to 1.21 though, and the yum command -
'/usr/bin/yum -d 0 -e 0 -y install test-1.21' - also works fine with returncode
0 and no errors when run independently. So I'm not sure why puppet is reporting
'failed to update'.
Any ideas? O/S is Scientific Linux 4 (RHEL4), yum version is 2.4.2,
puppet version is 0.24.4.
Thanks,
Rob
--
Robert Fay f...@hep.ph.liv.ac.uk
System Administrator office: 210
High Energy Physics Division tel (int): 43396
Oliver Lodge Laboratory tel (ext): +44 (0)151 794 3396
University of Liverpool http://hep.ph.liv.ac.uk
> The package is successfully updated to 1.21 though, and the yum
> command -
> '/usr/bin/yum -d 0 -e 0 -y install test-1.21' - also works fine with
> returncode
> 0 and no errors when run independently. So I'm not sure why puppet
> is reporting
> 'failed to update'.
>
> Any ideas? O/S is Scientific Linux 4 (RHEL4), yum version is 2.4.2,
> puppet version is 0.24.4.
This is a result of the following code:
is = self.query
unless is
raise Puppet::Error, "Could not find package %s" %
self.name
end
# FIXME: Should we raise an exception even if should == :latest
# and yum updated us to a version other than
@param_hash[:ensure] ?
if should && should != is[:ensure]
raise Puppet::Error, "Failed to update to version
#{should}, got version #{is[:ensure]} instead"
end
I *think* that code is in place because yum always exits 0, so we need
to do extra checking to see if it actually installed or not.
It looks like the query isn't actually running again, which is your
problem.
Please file this as a bug; it should be relatively straightforward to
fix.
--
Honest criticism is hard to take, particularly from a relative, a
friend, an acquaintance, or a stranger. -- Franklin P. Jones
---------------------------------------------------------------------
Luke Kanies | http://reductivelabs.com | http://madstop.com
Could this be related to the problem I'm seeing where installing an i386 RPM
fails on an x86_64 machine using the yum provider:
package {
"foo.i386": ensure => installed;
}
--
Jos Backus
jos at catnook.com
Can you add the log of a debug run for this ? That would make it a
little clearer if it is the same problem or not.
David
The relevant bits from the `puppetd -tdv' log are:
debug: Puppet::Type::Package::ProviderYum: Not suitable: false value
debug: Puppet::Type::Package::ProviderYum: Executing '/bin/rpm -q libacl.i386
--nosignature --nodigest --qf %{NAME} %|EPOCH?{%{EPOCH}}:{0}| %{VERSION}
%{RELEASE} %{ARCH}
'
debug: Puppet::Type::Package::ProviderYum: Not suitable: false value
debug: Puppet::Type::Package::ProviderYum: Executing '/bin/rpm -q libattr.i386
--nosignature --nodigest --qf %{NAME} %|EPOCH?{%{EPOCH}}:{0}| %{VERSION}
%{RELEASE} %{ARCH}
'
debug: Puppet::Type::Package::ProviderYum: Not suitable: false value
debug: Puppet::Type::Package::ProviderYum: Executing '/bin/rpm -q
glibc-devel.i386 --nosignature --nodigest --qf %{NAME} %|EPOCH?{%{EPOCH}}:{0}|
%{VERSION} %{RELEASE} %{ARCH}
'
Does that help?
What OS/version are you on ? I assume it's one that uses yum. I don't
understand why it prints the line 'Not suitable: false value' - it also
does that on my Fedora machine _after_ running the yumhelper (which
exits with status 0).
There's also some confusion in my head (and the code) as to what the
@property_hash in a provider refers to. In particular, in the query
method in the rpm provider, @property_hash should refer to the
properties prefilled by the 'instances' method of the rpm provider;
instead these seem to be empty. There's something funky going on between
a provider and its parent .. not sure what though.
David
I am seeing this on both CentOS 4.4 and 5.1.
> I don't
> understand why it prints the line 'Not suitable: false value' - it also
> does that on my Fedora machine _after_ running the yumhelper (which
> exits with status 0).
>
> There's also some confusion in my head (and the code) as to what the
> @property_hash in a provider refers to. In particular, in the query
> method in the rpm provider, @property_hash should refer to the
> properties prefilled by the 'instances' method of the rpm provider;
> instead these seem to be empty. There's something funky going on between
> a provider and its parent .. not sure what though.
That code confuses me, too. It's a little unclear to me how this is suposed to
work and what values to expect where. The plan is to dig into this again next
week, time permitting.
This isn't pertinent to your specific problem, but maybe this
description will help with understanding the situation and why the
information you're getting isn't as good as it could be.
Also, note that you can download the 'puppetdoc' executable and run it
with 'puppetdoc -r providers' to get a full report on what providers
exist, which ones are functional, and, to the extent Puppet can tell,
what makes them non-functional. You can see an example report here:
http://reductivelabs.com/trac/puppet/wiki/ProviderSuitabilityReport
The 'confine' system for determining which providers are functional
has had two good but restrictive tests available to it:
* exists: Whether a file exits
* facter: Whether a given facter value is within the specified array
You can see that if these tests fail, then we can easily log what's
wrong. However, they're not sufficient to test for all cases, so
there are two other tests:
* true: Whether a value is true
* false: Whether a value is false
This would be used for things like what the ldap providers now do:
confine :false => (Puppet[:ldapuser] == "")
I.e., this ldap provider is only functional if the ldapuser setting
has been set to something other than its default empty string.
You can see that it would be essentially impossible to usefully log
what the failure is here, without some additional information.
I recognize the pain of this, and I've just entirely refactored the
Confine system, pulling it into separate classes and thus making it
easier to extend.
For instance, I upgraded the facter test so it can now test both facts
and settings (preferring settings, but there's very little overlap):
confine :ldapport => "389"
This still doesn't work for my above test, because I need to test a
negative, but still, it's better.
The next step would be allow for inclusion of a string that describes
the failure, something like:
confine "Missing X file" => { :true => FileTest.exist?("/my/file") }
I don't really know what the right interface is.
If someone's willing to go through the existing confines and play with
some ways of specifying all of them so that they can be logged better,
it should be easy to provide this better interface.
--
Love is the triumph of imagination over intelligence.
-- H. L. Mencken
> Also, note that you can download the 'puppetdoc' executable and run it
> with 'puppetdoc -r providers' to get a full report on what providers
> exist, which ones are functional, and, to the extent Puppet can tell,
> what makes them non-functional. You can see an example report here:
>
> http://reductivelabs.com/trac/puppet/wiki/ProviderSuitabilityReport
Thanks, I'l play with that.
Just so I understand you correctly: the yum provider works but the debug
output is misleading because of the limited provider testing functionality of
the confine system?
Hmm, I don't think so.
That is, that line "Not suitable: false value" indicates that the
provider isn't suitable, it's just not very informative.
I'm pretty confused as to why it says that and then goes on to work,
though. This original problem kinda got lost in my goal of describing
how the 'confine' stuff works. That'd be a good thing to figure out
the cause of.
--
I was an only child... eventually. -- Stephen Wright
The @property_hash hash, which is not required by the general provider
interface but is usually used by the package providers, is basically
how the provider stores its current values.
That is, if the provider has been prefetched, then those prefetched
values will be in that hash, or if the provider supports flushing,
then the values will usually get set in that hash and flushed to disk
at the end.
This is part of the API that has grown up informally and needs to be
made a more official part of the API, since it's getting a bit messy.
Of course, some classes might not ever use it (e.g., users and groups
just directly run commands, so they don't use 'flush', and they might
never use 'prefetch').
--
Talent hits a target no one else can hit; Genius hits a target no one
else can see. -- Arthur Schopenhauer
> That is, that line "Not suitable: false value" indicates that the
> provider isn't suitable, it's just not very informative.
Right.
> I'm pretty confused as to why it says that and then goes on to work,
> though. This original problem kinda got lost in my goal of describing
> how the 'confine' stuff works. That'd be a good thing to figure out
> the cause of.
Yes, that's puzzling as yum _is_ used by Puppet to install/upgrade packages on
CentOS.
Also, PuppetRedHatCentos mentions a related problem:
With RHEL 5.0-5.2, rpm -q misreports a query of package.arch with a blank line
and zero return code, even if it is installed. This means you can't use the
package type to force the install of multiple architectures of packages
because the provider barfs on the faulty input. Installation of the default
architecture still works. Should be fixed in RHEL5.3.
I don't remember offhand seeing this problem on CentOS 5.1 x86_64 but it's
something to verify next week.
My confusion mostly comes from the following specific to the yum/rpm
provider:
* the yum provider is a child of the rpm provider
* the rpm provider has a 'instances' method that returns info
about currently installed packages
* the yum provider overrides 'prefetch', but calls 'super' in the
overridden prefetch
* even though, the @property_hash in yum provider instances for
installed packages is empty
It shouldn't be empty, right ?
David
Based on that, I agree that it shouldn't be empty, so count me into
the confused group.
--
Commit suicide. A hundred thousand lemmings can't be wrong.