On 24 December 2010 11:11, Daniel Piddock <dgp-g...@corefiling.co.uk> wrote:

> Hey all,
>
> I'm not sure if I've made a fundamental misunderstanding of Puppet
> namespacing and include resolution or whether there's a bug.
>
> Background:
> I have a modules, called kerberos, that configures a client for working
> on my kerberos domain. I then have a module called ssh that sets up a
> basic sshd. I wanted to create a ssh::kerberos class in the ssh module
> that extends my ssh setup with kerberos support. I wanted to put a
> dependency on the kerberos module. However things fell apart and there
> was lots of hair tearing thinking I'd done something stupid (e.g. a
> typo.) I now believe it's not that simple...
>
> ..
>
> Is this by design? If so, how do I specify module, not subclass, in the
> include/require?
> Is there a bug?
>

It's a bug, IMO. One which seems to be cropping up more frequently.

I think it's quite a common use case to have sub-classes of the same name as
top-level classes. For instance, I have a number of classes like
'php::mysql', 'python::mysql' and 'exim::mysql' which all 'include mysql' in
order to pull in common MySQL client functionality.

The trouble is that the resolution of a class name always begins relative to
the current class. If it's able to satisfy the include from within the
current class namespace, including the current class itself, then it won't
check the top-level. It can be demonstrated with a simplified example:

"""
d...@dan-macpro:~$ puppet apply
class bar {
    notify { "bar": }
}

class foo::bar {
    include bar
    notify { "foo": }
}

include foo::bar
^D
notice: foo
notice: /Stage[main]/Foo::Bar/Notify[foo]/message: defined 'message' as
'foo'
"""

You can see that Class["bar"] and Notify["bar"] have both been ignored. I
suspect that in a lot of cases this behaviour will go unnoticed by people.
It's not until you add a require to the resource that the loop is then
exposed with a failure:

"""
d...@dan-macpro:~$ puppet apply
class bar {
    notify { "bar": }
}

class foo::bar {
    include bar
    notify { "foo":
        require => Class["bar"],
    }
}

include foo::bar
^D
err: Could not apply complete catalog: Found dependency cycles in the
following relationships: Notify[foo] => Notify[foo]
"""

There are some hack-ish ways to work around it. You can specify that all of
your includes come from the top scope by prefixing them with ::, such as
'include ::mysql'. But this makes for some pretty long winded manifest
writing if you want to be sure 100% of the time. There isn't
an equivalent syntax for require meta-parameters. You can achieve
something vaguely similar with 'require ::mysql' which will create
dependencies from all resources in the current class. It's certainly not the
same effect though.

I spoke to James Turnbull and some others on IRC about this a couple of
weeks ago. I believe he was going to see whether it fitted in with an
existing ticket. If there isn't one, then something new needs to be
raised. What I'd really like to see is that all class naming becomes
absolute. That would leave much less scope for this kind of confusion and
erratic behaviour.

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Users" group.
To post to this group, send email to puppet-us...@googlegroups.com.
To unsubscribe from this group, send email to 
puppet-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/puppet-users?hl=en.

Reply via email to