added a comment - - edited
Adding myself to this ticket after things like this ticket:
With the push towards lib/application/wrapper style cookbook writing, cloning has become an unpredictable and sometimes dangerous affair. Let me try to offer some more cases:
1. Resources in providers.
Like the ticket above, people can create resources in providers, like a package resource to ensure a required package is installed prior to doing request work. As the provider action is called multiple times, the more times packages resource are cloned, the more warnings you get. This seems somewhat silly in that you're only going to install the package. Maybe the anti pattern here is to leave the package install up to a recipe to include before you call the provider. In either case: lots of clone warnings in your output for no good reason. It's safe if we could ignore them from being outputed.
2. Duplicate effort across cookbooks
This is related to #1. It's not uncommon for two cookbooks to need the same subset of packages. There's no reason for either package to have to rename the name of the resource (and use package_name) just to avoid clone warnings. For that matter, there's no reason to clone the package resource to begin with. The warning in this case is complete noise with no resolution.
3. Customizing templates in wrapper cookbooks.
It's not uncommon in the wrapper/application cookbook to change a template resource from using the upstream template to the application books template source. This will cause a clone by default, which means possibly two templates are rendered; first the originals, then the clone. If you are notifying a service to restart, and that service (maybe in an upstream cookbook like mysql/postgres) is declared as :immediate, you now have two service restarts. If the latter template is not really changing, that's two restarts when there would've been none.
Even worse, if you want to prevent the clone, you have to load an existing resource using #resource() "the resource pattern". If the lib cookbook defines resources using if/else logic instead of using only_if/not_if (like the /etc/memcached.conf template in memcached cookbook), if have to either use that same logic the upstream book is using, or wrap your resources() call in a begin/rescue Chef::Exceptions::ResourceNotfound like Julians example above.
Having that everywhere is also just as non ideal was all the clone warnings and unexpected after effects. After all, the chef-rewind and chef-edit gems exist because of these issues.
People also resort to just changing the name of the resource to match some unique naming covention within loops (like the users examples above). Now we have resources with unique names that do the same thing just to escape clone warnings in output.
4. Service Notifications
As mentioned in previous comments, when a resource like a template, notifies a service to restart, there's no way in a wrapper/application cookbook to undo that decision without maintaining your own fork of the upstream book or copying that recipe locally and changing it.
So, to sum it up. Cloning is causing problems yet doesn't seem to provide many benefits IF our community cookbook practices are changing towards lib/app/wrapper patterns. I'm in favor if just ditching the warning entirely so people (and I) stop having to squash them by the only 2 means available (resource() + begin/rescue) or (rename resource names and move the name into path/package_name/service_name, etc).
Looking for un necessary service restarts and such are a matter of protocol for the user imho. Just because your chef-client succeeded, doesn't mean it's good, or correct. Aka, always inspect the output and look for unexpected things...which ironically is why getting rid of these clone warnings is important.
Taking the possible solutions given in previous comments:
- chef-edit gem ensure you're always create-or-editing resource.
- this leaves no way to change notifications/subscriptions
- chef-edit still uses the begin/rescue exception pattern. ResourceCollection could really use an #exists?() method for inspection purposes.
- in providers, the resources() pattern isn't available like it is in recipes. You have to resort to resource_collection.find. Maybe ensure #resources() is available to providers as well.
I'm all for doing whatever is necessary to make these problems go away as a contributor, but imho, you all need to maybe hash this out in reviews and make a direction decision so we can code towards that direction.
Thanks for the time, and all the fish.