fix issues with duplicated declarations due to ensure_packages()
Ma27 opened this issue · 4 comments
Description
About a year ago I started maintaining this and willdurand/nodejs. Since then I've seen several bug reports because of duplicated declarations because of wrongly used package declarations in puppet in our or in other module's code.
Actual issue.
The issue can be seen when having a simple look at the docs: ensure_resource() docs. The ensure_*
API only avoids crashes due to duplicated resources if the resource definition passed to the ensure_*
API contains the same hash as the already declared resource if declared. So whenever someone uses ensure => installed
for instance and another one uses ensure => present
(which is the default of the ensure_packages()
function) there'll be a crash (we started using ensure => installed
as the docs do that as well).
However this causes a lot of issues for other users and any change in a minor or even a patch release could be a BC break because of this although there's no real API change.
Steps to reproduce
# class1.pp
class class1 {
ensure_packages(['wget'])
}
# class2.pp
class class2 {
ensure_packages(['wget'], {
ensure => installed,
})
}
Execute both of them and you'll get a duplicate resource
failure during the catalog compilation:
Error: Evaluation Error: Error while evaluating a Function Call, Duplicate declaration: Package[wget] is already declared; cannot redeclare at /tmp/vagrant-puppet/environments/dev/manifests/site.pp:9:3 on node localhost.sbde-40936.btopenzone.com
Expected behavior
We need an approach how to avoid such declarations without receiving a bug report all two months.
Notes to this topic
I think that this approach contains several issues because of a simple issue: many puppet modules require extra-packages that they aren't actually responsible for (in this case wget
although this module installs composer, the nodejs
module needs a gcc
compiler and tar
and wget
as well), so it's quite likely that such collisions might happen.
Related issues
#43, #41, willdurand/puppet-nodejs#168, willdurand/puppet-nodejs#39
Possible solutions
do the if !defined(Package['foobar'])
way
I reverted this in willdurand/nodejs
already because I'm not a big fan of these bloated statements that messed up the code in the current oldstable 1.x versions of that module.
revert the changes
I think that this is the best approach (also suggested in several comments last week) although the docs propose the use of ensure => installed
.
However I think that this just fixes the symptom.
Imagine the following case:
class class1 {
if !defined(Package['wget']) {
package { 'wget':
ensure => installed,
}
}
}
class class2 {
ensure_packages(['wget'])
}
class { '::class1': } ->
class { '::class2': }
If a module uses the ensure => installed
approach and our code gets compiled after theirs (as shown in the example) these guys would have a problem as well:
Error: Evaluation Error: Error while evaluating a Function Call, Duplicate declaration: Package[wget] is already declared in file /tmp/vagrant-puppet/environments/dev/manifests/site.pp:6; cannot redeclare at /tmp/vagrant-puppet/environments/dev/manifests/site.pp:12:3 on node localhost.sbde-40936.btopenzone.com
Therefore I suggest to revert these changes regarding ensure => installed
in both modules (as mentioned in some comments), but add another parameter to the init.pp
class for these cases which avoids execution of these module setup if something still causes crashes.
class { '::composer':
# all the other settings
build_deps => false,
}
This would skip the entire package setup if there are any further problems.
Same with willdurand/nodejs
:
class { '::nodejs':
# all the other settings
build_deps => false,
}
So reverting the changes should (hopefully) resolve most of the issues and in the remaining, rare cases you could do all the package setup on your own and tell the module to skip that.
/cc @willdurand @den-is @cdoublev @s12v @tdm4 you submitted bug reports or commented on them, so this might be interesting for you as well/
ok I closed it here since I fixed the actual bug in puppet-composer
.
On the weekend I'll release a 1.9.6
for willdurand/nodejs
and add the fix to the next alpha of willdurand/nodejs@2.0
, then each of the modules maintained by me has the needed fix.
ok, fixed on 1.9
and 2.0-alpha
at puppet-nodejs for now...
fixed and released https://github.com/willdurand/puppet-nodejs/releases/tag/1.9.6