Skip to content

Conversation

@ehelms
Copy link
Member

@ehelms ehelms commented Feb 28, 2025

This only happens a single time, and is key to the execution when supplied. This also allows the before relationship to properly build the correct dependency chain.

Copy link
Member

@ekohl ekohl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really see the benefit of this.

This also allows the before relationship to properly build the correct dependency chain.

There already was a before present so what's different?

@ehelms
Copy link
Member Author

ehelms commented Feb 28, 2025

There already was a before present so what's different?

From what I can tell - the before isn't respected properly when it's a define. These tests don't show it, but I encountered this when I re-factored the code pulling apart some relationships. If we don't want to merge this now, I'll open up my bigger re-factor and can include the change there instead.

@ekohl
Copy link
Member

ekohl commented Feb 28, 2025

From what I can tell - the before isn't respected properly when it's a define. These tests don't show it, but I encountered this when I re-factored the code pulling apart some relationships.

IMHO that implies a bug in Puppet.

If we don't want to merge this now, I'll open up my bigger re-factor and can include the change there instead.

I'd be tempted to go that route.

@ehelms
Copy link
Member Author

ehelms commented Mar 4, 2025

Ok, now I have run into this issue which I knew was coming once I entangled all my changes. The PR is failing with the below output. With this PR applied on top of #488 the tests pass.

        puppet apply --verbose --detailed-exitcodes /tmp/apply_manifest_112904555.fUjeSx.pp
       Last 10 lines of output were:
       	Error: /Stage[main]/Certs::Apache/File[/etc/pki/katello/certs/katello-server-ca.crt]: Could not evaluate: Could not retrieve information from environment production source(s) file:///root/ssl-build/katello-server-ca.crt
       	Notice: /Stage[main]/Certs/Certs::Tar_extract[/root/foreman-proxy.example.com.tar.gz]/Exec[extract /root/foreman-proxy.example.com.tar.gz]/returns: executed successfully
       	Notice: /Stage[main]/Certs::Config::Generate/File[/root/ssl-build]/mode: mode changed '0755' to '0700'
       	Notice: /Stage[main]/Certs::Ca/File[/root/ssl-build/katello-default-ca.pwd]/ensure: defined content as '{sha256}a164445a2ddf8514a49cc33d4a2c7918b9fc391adc3e4f008788691ce6bfa0ed'
       	Notice: /Stage[main]/Certs::Apache/Certs::Keypair[foreman-proxy.example.com-apache]/Private_key[/etc/pki/katello/private/katello-apache.key]/ensure: created
       	Notice: /Stage[main]/Certs::Apache/Certs::Keypair[foreman-proxy.example.com-apache]/File[/etc/pki/katello/private/katello-apache.key]/mode: mode changed '0644' to '0440'
       	Notice: /Stage[main]/Certs::Apache/Certs::Keypair[foreman-proxy.example.com-apache]/File[/etc/pki/katello/certs/katello-apache.crt]/ensure: defined content as '{sha256}6c25135e7afe7e462ff7985bea4b84270796611188972c990f5ed8aa1c4c0837'
        puppet apply --verbose --detailed-exitcodes /tmp/apply_manifest_112904555.fUjeSx.pp
       Last 10 lines of output were:
       	Error: /Stage[main]/Certs::Apache/File[/etc/pki/katello/certs/katello-server-ca.crt]: Could not evaluate: Could not retrieve information from environment production source(s) file:///root/ssl-build/katello-server-ca.crt
       	Notice: /Stage[main]/Certs/Certs::Tar_extract[/root/foreman-proxy.example.com.tar.gz]/Exec[extract /root/foreman-proxy.example.com.tar.gz]/returns: executed successfully
       	Notice: /Stage[main]/Certs::Config::Generate/File[/root/ssl-build]/mode: mode changed '0755' to '0700'
       	Notice: /Stage[main]/Certs::Ca/File[/root/ssl-build/katello-default-ca.pwd]/ensure: defined content as '{sha256}a164445a2ddf8514a49cc33d4a2c7918b9fc391adc3e4f008788691ce6bfa0ed'
       	Notice: /Stage[main]/Certs::Apache/Certs::Keypair[foreman-proxy.example.com-apache]/Private_key[/etc/pki/katello/private/katello-apache.key]/ensure: created
       	Notice: /Stage[main]/Certs::Apache/Certs::Keypair[foreman-proxy.example.com-apache]/File[/etc/pki/katello/private/katello-apache.key]/mode: mode changed '0644' to '0440'
       	Notice: /Stage[main]/Certs::Apache/Certs::Keypair[foreman-proxy.example.com-apache]/File[/etc/pki/katello/certs/katello-apache.crt]/ensure: defined content as '{sha256}6c25135e7afe7e462ff7985bea4b84270796611188972c990f5ed8aa1c4c0837'

@binford2k
Copy link

binford2k commented Mar 4, 2025

metaparameters like require and before are honored wherever they're located -- in a class or define or anything. It's more likely that complex code made the resolved dependencies complex and unexpected.

You can validate which dependencies are actually set by using the graphviz .dot files that Puppet can generate.

  1. Make a minimal test case with a define that declares the relationship you want to test
  2. Run puppet apply manifest.pp --graph
  3. Examine ${puppet config print graphdir}/relationships.dot in a graphviz viewer

@ehelms
Copy link
Member Author

ehelms commented Mar 4, 2025

How will that explain or help me understand why changing from a define to class solves the dependency problem? If class and define work the same with respect to metaparameters, then the type shouldn't matter, yet it appears to.

@binford2k
Copy link

@ehelms it will help understand what relationships are actually being created. Here's a minimal test case for what I think you're trying to validate, a defined type that sets relationships on something from within the type.

define thing ($string) {
  notify { $string:
    before  => Notify['last'],
    require => Notify['first'],
  }
}
notify {'last':}
thing {'a defined type':
  string => 'foobar',
}
notify {'first': }

It generates this relationship graph, demonstrating that the expected relationships are correctly being set.
Screenshot 2025-03-04 at 12 02 52 PM

If you want more gory details, with all the intermediate graph nodes and such, you can use the expanded_relationships.dot file instead.
Screenshot 2025-03-04 at 12 04 03 PM

What I suspect you're running into is the classic containment problem. The summary of that is that if you put a class within another class, then it's not contained like resources are.

In other words this snippet of Puppet does not put any ordering relationship on Class['bar'] at all.

class foo {
  class { 'bar': }
}
notify { 'words':
  before => Class['foo'],
}

I have a fairly long blog post that explains how and why it works that way, if you're interested.

@binford2k
Copy link

Ah, actually, I see the difference. You're setting a relationship on the type itself, not on resources within the type.

define thing ($string) {
  notify { $string:
    require => Notify['first'],
  }
}
notify {'last':}
thing {'a defined type':
  string => 'foobar',
  before => Notify['last'],
}
notify {'first': }

That generates a slightly different expanded_relationships graph. But you can still see the relationships being set properly.
Screenshot 2025-03-04 at 12 21 03 PM

@ehelms
Copy link
Member Author

ehelms commented Mar 4, 2025

Thanks for the lessons @binford2k - I must admit I still think I only understand 25% of what is going on. I have implemented an update using require that seemed appropriate -- over here.

@binford2k
Copy link

with the caveat that I'm not 100% sure what you're solving for, that PR seems reasonable.

fwiw, I'm happy to help review PRs or even do a "weird parts of Puppet" training or some such. We just added training to our services offered (haven't updated the page yet)

@ehelms ehelms closed this Mar 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants