Issue #18490 has been updated by David  Lutterkort.

It's hard for me to see how ensure_resource  satisfies anybody; I would say 
it's just punting the issue to the user, but seeing how its behavior adds 
another place where order matters in a way that is hard to understand for the 
user, I think it's even less than that.
Here's how I look at the issue: if there are two duplicate resources B and B' 
in the manifest that are compatible (if they are compatible, there's nothing 
else to do but complain), there are three ways Puppet could react:

1. complain
1. remove B or B' from the catalog
1. merge B and B' into the same resource

This assumes that we have solid definitions of 'duplicate resource' and 
'compatible'; I assume that's not that hard to arrive at. To me, 'duplicate 
resource' means that B and B' would be realized as the same entity on the 
client (same user, same package, ...), and 'compatible' means that B and B' can 
be realized simultaneously on the client (e.g., B says "user 'foo' must have 
uid 1000" while B' says "user 'foo' must have '/bin/bash' as their shell")

What 'ensure_resource' does is implement strategy (2): one of B or B' will not 
appear in the catalog. IOW, we could have the same effect if we just made 
Puppet implement strategy (2) The language design issue is that it's entirely 
unclear to the user whether B or B' will be removed because it depends on the 
order in which they are processed, and that order is in general hard to predict 
for the user.

Comment 10 cites two reasons why strategy (3) is not desirable:

* backtracking from the merged resource can't be done correctly (I assume this 
is about containment and error reporting)
* something about loops and both resources existing in different parts of the 
graph that I don't fully understand; I do understand how having both B and B' 
in the graph when it is checked for cycles might hide an actual loop

I think we can address both concerns and implement strategy (3) with the 
following setup: assume we have A1 -> B -> C1 and A2 -> B' -> C2 (where '->' 
means 'requires') To merge B and B' we create a new resource Bm which combines 
them (from the example above "user 'foo' must have uid 1000 and shell 
'/bin/bash') and replace B and B' with 'proxy' resources Bp and Bp'; replacing 
here means that they take their places in any sort of containment or 
relationship that B and B' might be in. Overall, we then get a graph like this 
(ASCII art alert):


                    A1   ->     Bp               > C1
                                        \      /
                                        >  Bm
                                        >      \         
                                      /         > C2
                    A2    ->    Bp'

If the resource duplication hid a loop (e.g., because C2 == A1), that loop is 
now detected by the modified graph. Backtracking/containment is still there 
since we put Bp and Bp' as markers into the same place as B and B'.

When the catalog is executed, the proxy resources are simply a noop. When error 
messages involving Bp or Bp' are generated, they are shown to the user as if 
they originated from Bm. Errors involving Bm lead to two error messages: one as 
if Bm were Bp, and one as if Bm was Bp' (e.g., "trouble with user['foo'] 
required by A1 and A2")

With that, we have a way to allow duplicate, compatible resources, without 
troubling the user about the finer points behind the scenes, and without 
introducing any ordering issues.


----------------------------------------
Feature #18490: Duplicate resources can make re-usable Forge modules difficult
https://projects.puppetlabs.com/issues/18490#change-100123

* Author: Ryan Coleman
* Status: Investigating
* Priority: Normal
* Assignee: Ryan Coleman
* Category: modules
* Target version: 3.x
* Affected Puppet version: 
* Keywords: 
* Branch: 
----------------------------------------
[EDIT] Re-working this description based on feedback in comment #7. 

User installs module A to provide a web application. 

User installs module B to provide a database server.

Both module A and module B declare a package resource for foo. 

User declares classes from both module A and B on the same node.

User receives duplicate resource declaration error, Puppet run fails. 


I wish to prevent customers of Forge and Puppet from experiencing this 
frustration, when both classes really do need that package for their 
functionality but cannot be used together as-is. I'd love direct questions if 
you need to understand this better from my perspective.



-- 
You have received this notification because you have either subscribed to it, 
or are involved in it.
To change your notification preferences, please click here: 
http://projects.puppetlabs.com/my/account

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Bugs" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/puppet-bugs.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to