Troubleshoot Foreman's interaction with Puppet's directory environments

I am having an odd issue with Foreman and Puppet directory environments no
longer working as expected. It worked when I first setup Foreman on this
host, but now it seems to behaving differently. I have exhausted my
troubleshooting skills with Foreman and RTFM on the manual as well as
looking at logs have made me hit a wall. I am reaching out to the community
now to see if I can get some additional assistance figuring out what I
broke, how to find details on how I broke it and what to do to fix it so
that I can document it in my Team's Wiki. I prefer now to just kickstart
the box and start over as that takes the fun out of kicking myself for not
being able to figure it out :slight_smile:

Here is the scenario:

  1. I have /etc/puppet/environments/test setup where I have modules and
    manifests directories.

  2. Under the …/test/modules I have a users module
    (…/test/modules/users) that has the class "rootbashprofile".

  3. Forman sees the rootbashprofile when I scan for classes and it allows me
    to map it as a puppet class to my test host hostA.

  4. When I run puppet agent --debug --verbose --test on hostA or puppet
    master --debug --verbose --trace --compile hostA it fails with the
    puppet error messages

Error: Could not find class rootbashprofile for hostA on node hostA
Error: Failed to compile catalog for node hostA: Could not find class
rootbashprofile for hostA on node hostA.

When I have this setup on a Puppet master without foreman, I have a
modules.pp file under /etc/puppet/environments/test/manifests that does an include
"rootbashprofile"
and there is no problems. If I put that include line in
a file on the Foreman server, it works as well.

  1. If I move the users directory to rootbashprofile, Puppet finds it fine.

So what I am trying to analyze / figure out is why Foreman sees the class
for the module in any directory, but when it configures the hostA to use
the module, Puppet can't seem to find it unless under the specific
directory name.

Or course am I just missing something from my RTFM of the Foreman docs
about this behavior?

I know when I created a test module user-helloworld, Foreman found the
helloworld class with no problems. When I setup the host to use it, the
catalog compile failed until I moved it from the user-helloworld to
helloworld. under …/test/modules.

Thanks!

Thanks!

I am migrating over and I am trying to keep from using the old import call
to get the classes in from the old Puppet master.

At least I am not going crazy! I have been pulling my hair out trying to
figure why I could not get some test classes working!

··· On Monday, April 27, 2015 at 11:15:53 AM UTC-4, James Perry wrote: > > I am having an odd issue with Foreman and Puppet directory environments no > longer working as expected. It worked when I first setup Foreman on this > host, but now it seems to behaving differently. I have exhausted my > troubleshooting skills with Foreman and RTFM on the manual as well as > looking at logs have made me hit a wall. I am reaching out to the community > now to see if I can get some additional assistance figuring out what I > broke, how to find details on how I broke it and what to do to fix it so > that I can document it in my Team's Wiki. I prefer now to just kickstart > the box and start over as that takes the fun out of kicking myself for not > being able to figure it out :) > > Here is the scenario: > > 1. I have /etc/puppet/environments/test setup where I have modules and > manifests directories. > > 2. Under the .../test/modules I have a users module > (.../test/modules/users) that has the class "rootbashprofile". > > 3. Forman sees the rootbashprofile when I scan for classes and it allows > me to map it as a puppet class to my test host *hostA.* > > 4. When I run puppet agent --debug --verbose --test on *hostA* or puppet > master --debug --verbose --trace --compile *hostA* it fails with the > puppet error messages > > Error: Could not find class rootbashprofile for *hostA* on node *hostA* > Error: Failed to compile catalog for node *hostA*: Could not find class > rootbashprofile for *hostA* on node *hostA*. > > When I have this setup on a Puppet master without foreman, I have a > modules.pp file under /etc/puppet/environments/test/manifests that does an *include > "rootbashprofile"* and there is no problems. If I put that include line > in a file on the Foreman server, it works as well. > > 5. If I move the users directory to rootbashprofile, Puppet finds it fine. > > So what I am trying to analyze / figure out is why Foreman sees the class > for the module in any directory, but when it configures the *hostA* to > use the module, Puppet can't seem to find it unless under the specific > directory name. > > Or course am I just missing something from my RTFM of the Foreman docs > about this behavior? > > I know when I created a test module user-helloworld, Foreman found the > helloworld class with no problems. When I setup the host to use it, the > catalog compile failed until I moved it from the user-helloworld to > helloworld. under .../test/modules. > > Thanks! > > >

> 2. Under the …/test/modules I have a users module
> (…/test/modules/users) that has the class "rootbashprofile".
>
[snip]
>
> 5. If I move the users directory to rootbashprofile, Puppet finds it fine.
>
> So what I am trying to analyze / figure out is why Foreman sees the
> class for the module in any directory, but when it configures the
> /hostA/ to use the module, Puppet can't seem to find it unless under the
> specific directory name.
>
> Or course am I just missing something from my RTFM of the Foreman docs
> about this behavior?

It's a difference between Foreman being lazy, and Puppet being precise.

Foreman's smart proxy recursively scans the modulepath directories for
.pp files, parses them one by one (using Puppet as a library) and builds
up a list of the classes it finds. It doesn't consider which class is
in which file at all.

Puppet, mostly since 3.x, has been strict about following the module
layout specification
(https://docs.puppetlabs.com/puppet/3/reference/modules_fundamentals.html#module-layout).
There are lots of benefits to Puppet doing this, primarily performance,
as when asked for class foo, it knows this will be in foo/manifests/init.pp.

> I know when I created a test module user-helloworld, Foreman found the
> helloworld class with no problems. When I setup the host to use it, the
> catalog compile failed until I moved it from the user-helloworld to
> helloworld. under …/test/modules.

Yeah, this is correct behaviour from Puppet.

Arguably we could parse the manifests in a more precise manner too,
ensuring we only load class foo from foo/manifests/init.pp and ignore
classes that are in the wrong place, which might hide this
implementation difference.

··· On 27/04/15 16:07, James Perry wrote:


Dominic Cleal
Red Hat Engineering

I found that adding in an "include <class>" inside the monolithic modules
manifests coming from the old environment provides a good workaround now
that I am aware of the interactions between Foreman and Puppet.

Thanks again Dominic for your insights.