Bug #948

err: Could not create root: undefined method `groups' for #<Puppet::Type::User:0xb77e3ef4>

Added by David Schmitt over 2 years ago. Updated over 2 years ago.

Status:Closed Start:
Priority:High Due date:
Assignee:Puppet Community % Done:

0%

Category:-
Target version:0.24.0
Affected version:0.25.4 Branch:
Keywords:
Votes: 0

Description

When testing [8eecbe54c96cec0de492e7ae77211637b65057e8], one of my clients fails with this error message:

err: Could not create root: undefined method @groups' for #
./lib/puppet/type/user.rb:197:in @retrieve'
./lib/puppet/type/user.rb:179:in @should'
./lib/puppet/metatype/closure.rb:36:in @managed?'
./lib/puppet/metatype/closure.rb:35:in @each'
./lib/puppet/metatype/closure.rb:35:in @managed?'
./lib/puppet/type/user.rb:38:in @default'
./lib/puppet/metatype/attributes.rb:635:in @setdefaults'
./lib/puppet/metatype/attributes.rb:118:in @eachattr'
./lib/puppet/metatype/attributes.rb:115:in @each'
./lib/puppet/metatype/attributes.rb:115:in @eachattr'
./lib/puppet/metatype/attributes.rb:625:in @setdefaults'
./lib/puppet/type.rb:272:in @initialize'
./lib/puppet/metatype/instances.rb:151:in @new'
./lib/puppet/metatype/instances.rb:151:in @create'
./lib/puppet/transportable.rb:88:in @to_type'
./lib/puppet/transportable.rb:193:in @to_configuration'
./lib/puppet/transportable.rb:125:in @each'
./lib/puppet/transportable.rb:125:in @each'
./lib/puppet/transportable.rb:190:in @to_configuration'
./lib/puppet/transportable.rb:198:in @call'
./lib/puppet/transportable.rb:198:in @to_configuration'
./lib/puppet/transportable.rb:125:in @each'
./lib/puppet/transportable.rb:125:in @each'
./lib/puppet/transportable.rb:190:in @to_configuration'
./lib/puppet/transportable.rb:198:in @call'
./lib/puppet/transportable.rb:198:in @to_configuration'
./lib/puppet/transportable.rb:125:in @each'
./lib/puppet/transportable.rb:125:in @each'
./lib/puppet/transportable.rb:190:in @to_configuration'
./lib/puppet/transportable.rb:203:in @call'
./lib/puppet/transportable.rb:203:in @to_configuration'
./lib/puppet/node/configuration.rb:286:in @initialize'
./lib/puppet/transportable.rb:183:in @new'
./lib/puppet/transportable.rb:183:in @to_configuration'
./lib/puppet/network/client/master.rb:177:in @getconfig'
./lib/puppet/network/client/master.rb:260:in @run'
./lib/puppet/util.rb:444:in @thinmark'
/usr/lib/ruby/1.8/benchmark.rb:293:in @measure'
/usr/lib/ruby/1.8/benchmark.rb:307:in @realtime'
./lib/puppet/util.rb:443:in @thinmark'
./lib/puppet/network/client/master.rb:259:in @run'
/usr/lib/ruby/1.8/sync.rb:229:in @synchronize'
./lib/puppet/network/client/master.rb:252:in @run'
./bin/puppetd:427

Using the minimal user testing manifest (

user { “bin”: uid => 2 } 
) the error looks like this:

root@git-test:~/trunk# RUBYLIB=./lib/ PATH=./bin/:$PATH ./bin/puppet --verbose --debug --trace /home/david/tmp/users.pp
./lib/puppet/type/user.rb:46:in @retrieve'
./lib/puppet/type/user.rb:332:in @retrieve'
./lib/puppet/external/gratr/search.rb:325:in @inject'
./lib/puppet/type/user.rb:326:in @each'
./lib/puppet/type/user.rb:326:in @inject'
./lib/puppet/type/user.rb:326:in @retrieve'
./lib/puppet/metatype/evaluation.rb:23:in @evaluate'
...

I added a bit of debugging to

lib/puppet/type.rb:ensure:retrieve
:

Puppet.err "%s has class %s" % [provider.to_s, provider.class.to_s]

which prints

err: User[bin] has class Puppet::Type::User

Running the same modification against 0.23.2 yields:

err: User[bin](provider=useradd) has class user provider useradd

user.rb (1.4 KB) David Schmitt, 12/06/2007 10:02 am

History

Updated by David Schmitt over 2 years ago

Very strange things happen here: I can’t reproduce it on my sid development machine, which has ruby 1.8.6, but it happens on all etch installations i tried it on. The latter have ruby 1.8.5

Also I coded up a few specs (attached) for the provider parameter, which work on every(!) installation i tested.

Updated by David Schmitt over 2 years ago

Yes! I could now pinpoint the cause of this bug, although I’m still not sure of the background details.

I have a custom user and group provider for smbldap, which gets loaded via pluginsync. for some weird reason puppet realizes that there should be such a provider, but fails to load it. Observe:

There is no config referencing

/var/puppet
:

root@backuppc:~/trunk# RUBYLIB=./lib/ PATH=./bin/:$PATH ./bin/puppet --genconfig | grep /var/puppet
    # The default value is '/var/puppet'.
root@backuppc:~/trunk# 

Especially vardir and libdir are set correctly:

root@backuppc:~/trunk# RUBYLIB=./lib/ PATH=./bin/:$PATH ./bin/puppet --configprint vardir
/var/lib/puppet
root@backuppc:~/trunk# RUBYLIB=./lib/ PATH=./bin/:$PATH ./bin/puppet --configprint libdir
/var/lib/puppet/lib
root@backuppc:~/trunk# ls -la /var/lib/puppet/lib/puppet/provider/*/smbldap.rb
-rw-r--r-- 1 root root  376 2007-10-09 11:19 /var/lib/puppet/lib/puppet/provider/group/smbldap.rb
-rw-r--r-- 1 root root 1086 2007-10-09 11:19 /var/lib/puppet/lib/puppet/provider/user/smbldap.rb
root@backuppc:~/trunk# 

But(!) if I try to run puppet on the user_test.pp this happens:

root@backuppc:~/trunk# RUBYLIB=./lib/ PATH=./bin/:$PATH strace -f -o ~/tmp/user_test.trace ./bin/puppet --debug ~/tmp/user_test.pp 
err: //User[bin]: Failed to retrieve current state of resource: undefined method @exists?' for #
debug: Finishing transaction -607094328 with 0 changes
root@backuppc:~/trunk# grep '/var.*puppet.*smbldap' ~/tmp/user_test.trace 
2872  stat64("/var/puppet/lib/puppet/provider/user/smbldap.rb", 0xbfc4563c) = -1 ENOENT (No such file or directory)
2872  stat64("/var/puppet/lib/puppet/provider/user/smbldap.so", 0xbfc4563c) = -1 ENOENT (No such file or directory)
2872  stat64("/var/puppet/lib/puppet/provider/group/smbldap.rb", 0xbfc4977c) = -1 ENOENT (No such file or directory)
2872  stat64("/var/puppet/lib/puppet/provider/group/smbldap.so", 0xbfc4977c) = -1 ENOENT (No such file or directory)
root@backuppc:~/trunk# 

As you can see, puppet is very confused about where to look for the plugins.

Setting the “—libdir /var/lib/puppet”(!!) on the command line allows puppet to find the providers and get on with it:

root@backuppc:~/trunk# RUBYLIB=./lib/ PATH=./bin/:$PATH ./bin/puppet --debug --libdir /var/lib/puppet ~/tmp/user_test.pp 
debug: Puppet::Type::User::ProviderPw: Not suitable: missing pw
debug: Puppet::Type::User::ProviderDirectoryservice: Not suitable: operatingsystem not in darwin
debug: Puppet::Type::User::ProviderNetinfo: Not suitable: missing nireport
Setting provider for User[bin] to useradd
debug: Finishing transaction -607381908 with 0 changes
root@backuppc:~/trunk#

h3. Summary

There are several problems here:

  1. when libdir is set to “/var/lib/puppet/lib”, puppet becomes confused about where to look for plugins: it tries
    /var/puppet/lib
    instead
  2. when —libdir is set to “/var/lib/puppet”, puppet again becomes confused about where to look for plugins: it tries
    /var/lib/puppet/lib
    instead, which is conicidentally the right path on my system
  3. last but not least: when puppet believes a provider to be there, but fails to find it, it dies a horrible but silent death

Sorry that I didn’t split this up into new bugs, but I’m heading for my flight now.

Updated by Luke Kanies over 2 years ago

I’ve figured out the problem here — I’m not calling hooks for values set in the configuration file.

This is a reasonable oversight, because values can shadow each other (e.g., conflicting values can be set in ‘puppetmasterd’ and ‘main’), but it’s really a design flaw.

I’ll figure out how to fix it.

Updated by Luke Kanies over 2 years ago

  • Status changed from 1 to Closed
  • 7 set to fixed

Fixed in [3790ce1c6463e0d44ae0151fdc24000b9d5ede27] and [7a4ae082c216d68092f140ed1f5cca40ffb1a09e].

Also available in: Atom PDF