The Puppet::Face class does not define a useful text representation for use in some error messages — I.E. NoMethodError. This makes errors involving missing methods on Puppet Faces especially difficult to track down. Puppet Faces allow multiple versions, so these errors are easy to create by third-party modules defining a new Face version that other Puppet components don't expect.
Reproduction Case.
- Install the latest puppet-agent 4.10.x on CentOS 7:
rpm -Uvh http://yum.puppetlabs.com/puppetlabs-release-pc1-el-7.noarch.rpm
|
yum install -y puppet-agent
|
- Create a module containing a Puppet Face that can fail due to multiple versions:
mkdir -p /etc/puppetlabs/code/environments/production/modules/test_face/lib/puppet/application
|
cat <<EOF > /etc/puppetlabs/code/environments/production/modules/test_face/lib/puppet/application/foo.rb
|
require 'puppet/application/face_base'
|
|
class Puppet::Application::Foo < Puppet::Application::FaceBase
|
end
|
EOF
|
|
mkdir -p /etc/puppetlabs/code/environments/production/modules/test_face/lib/puppet/face
|
cat <<EOF > /etc/puppetlabs/code/environments/production/modules/test_face/lib/puppet/face/foo.rb
|
Puppet::Face.define(:foo, '0.0.1') do
|
action :bar do
|
when_invoked do |*args|
|
puts "Bar action called!"
|
end
|
end
|
|
action :baz do
|
when_invoked do |*args|
|
puts "Baz action called!"
|
Puppet::Face[:foo, :current].bar
|
end
|
end
|
end
|
|
Puppet::Face.define(:foo, '0.0.2') do
|
action :bim do
|
when_invoked do |*args|
|
puts "Bim action called!"
|
end
|
end
|
end
|
EOF
|
- Run the face to generate a failure: /opt/puppetlabs/puppet/bin/puppet foo baz
Outcome
The error message indicates no baz method is avaiailble, but provides no clue that Face versions are coming into play:
# /opt/puppetlabs/puppet/bin/puppet foo baz
|
Baz action called!
|
Error: undefined method `bar' for #<Puppet::Interface:0x00000004668948>
|
Error: Try 'puppet help foo baz' for usage
|
Expected Outcome
The error message should include the face name and version number, as provided by the to_s method of the Puppet::Interface class:
# /opt/puppetlabs/puppet/bin/puppet foo baz
|
Baz action called!
|
Error: undefined method `bar' for Puppet::Face[:foo, v0.0.2]:Puppet::Interface
|
Error: Try 'puppet help foo baz' for usage
|