voxpupuli / puppet-staging

⛔️ Deprecated in favor of puppet-archive
https://forge.puppet.com/puppet/archive
Apache License 2.0
51 stars 109 forks source link

Duplicate resource declaration #109

Closed shaunrampersad closed 8 years ago

shaunrampersad commented 8 years ago

Hi

I've ran into this issue recently

Error: Could not retrieve catalog from remote server: Error 500 on SERVER: {"message":"Server Error: Evaluation Error: Error while evaluating a Resource Statement, Evaluation Error: Error while evaluating a Resource Statement, Duplicate declaration: File[/opt/jboss3/.staging/jboss] is already declared in file /etc/puppetlabs/code/environments/jboss_master/modules/staging/manifests/file.pp:39; cannot redeclare at /etc/puppetlabs/code/environments/jboss_master/modules/staging/manifests/file.pp:39

This code has been working for months on end with no issues.

Affected Puppet, Ruby, OS and module versions/distributions

Duplicate resource declaration

What behaviour did you expect instead

Create the .staging directory.

Output log

Any additional information you'd like to impart

I've checked the code for file.pp and changed it locally on my side from: if ! defined(File[$staging_dir]) { file { $staging_dir: ensure=>directory, } } to: ensure_resource('file', $staging_dir, { ensure => directory } )

Which fixes the issue.

Would it be possible to change the above to use ensure_resource which is part of stdlib?

Thanks Shaun

alexjfisher commented 8 years ago

@shaunrampersad That's quite odd. I can't quite see why if ! defined wouldn't work (and presumably it does for most people??). ensure_resources, on the other hand, can lead to duplicate resources in situations where the resource has been declared previously but with different parameters (probably not common, but some users may have done this in their profiles - perhaps to set group or mode perhaps??)

Can you confirm what version of puppet you're using?

Cinderhaze commented 8 years ago

I have seen a similar issue.. if the 'if ! defined' happens before your other code not wrapped in an if ! defined is executed, there will be conflicts. (I have seen the same behavior with ensure_resources). @shaunrampersad do you have a regular file resource in your catalog for that folder, or is it only created via staging?

alexjfisher commented 8 years ago

@Cinderhaze That does happen, but the error message suggests it's two instances of the same defined type conflicting. That I don't understand...

is already declared in file /etc/puppetlabs/code/environments/jboss_master/modules/staging/manifests/file.pp:39; cannot redeclare at /etc/puppetlabs/code/environments/jboss_master/modules/staging/manifests/file.pp:39

bastelfreak commented 8 years ago

@shaunrampersad can you tell us the value of ::jboss::version and ::jboss::download_url?

alexjfisher commented 8 years ago

I suspect that for some reason two values of $staging_dir aren't the same string, but refer to the same path. ie (/tmp/staging and /tmp/staging/) That would fool defined, but not the type for file which will munge the paths to be the same.

@shaunrampersad Are you using the target parameter too? Is there anymore you can share?

shaunrampersad commented 8 years ago

@alexjfisher

Can you confirm what version of puppet you're using?

Puppet v4.6.2. This problem occurred recently, so it might just be something that's changed from v4.6.1 to v4.6.2. I will try to confirm when we upgraded puppet. We use puppet in Userspace so this process is confined to /opt/${::jboss::user} and runs as the jboss user.

Are you using the target parameter too? Is there anymore you can share?

I'm making use of the staging module within a custom jboss module. We do not manage the $staging_dir in the jboss module and leave this to the staging module.

This is the code where we make use of the staging resources

  class { '::staging':
    path  => "/opt/${::jboss::user}/.staging",
    mode  => '0700',
    owner => $::jboss::user,
    group => $::jboss::group,
  }

  if $jboss::cumulative_patch_version != 'UNSET' {
    staging::file { "jboss-${::jboss::cumulative_patch_version}-patch.zip":
      source => "${::jboss::download_url}/jboss-${::jboss::cumulative_patch_version}-patch.zip",
    }
  }

  staging::file { "jboss-${::jboss::version}.zip":
    source => "${::jboss::download_url}/jboss-${::jboss::version}.zip",
  } ->

  staging::extract { "jboss-${::jboss::version}.zip":
    target  => "/opt/${::jboss::user}",
    creates => "/opt/${::jboss::user}/jboss-${::jboss::version}/version.txt",
    require => Staging::File["jboss-${::jboss::version}.zip"],
  } 

Values for above are as follows:

${::jboss::download_url} = http://x.x.x.x/jboss
${::jboss::cumulative_patch_version} = 'eap-6.4.6'
${::jboss::version} = 'eap-6.3'
${::jboss::user} = 'jboss4'
$::jboss::group = 'jboss4'
alexjfisher commented 8 years ago

It's actually really easy to reproduce something similar (perhaps not exactly the same issue), but I can get a duplicate resource error in a single line...

puppet apply -e 'staging::file { "master.zip": source => "https://github.com/voxpupuli/puppet-staging/archive/master.zip"}'
Notice: Compiled catalog for alex-virtualbox.ordsvy.gov.uk in environment production in 0.30 seconds
Error: Cannot alias File[/opt/staging/] to ["/opt/staging"] at /home/alex/.puppetlabs/etc/code/modules/staging/manifests/file.pp:40; resource ["File", "/opt/staging"] already declared at /home/alex/.puppetlabs/etc/code/modules/staging/manifests/init.pp:23

@shaunrampersad Your code where you call staging from? Is it in a module? If not, $caller_module_name (and $subdir) will be an empty string.

$staging_dir = "${staging::path}/${subdir}" will then result in a directory path that ends with a / and is the same directory as already declared in init.pp. The if !defined won't trigger as the title of the resource in init.pp won't have the trailing /.

This shouldn't be too hard to fix. Meanwhile, if you explicitly set $subdir, I think your problem will go away. You might also consider migrating to puppet-archive. I think this is the preferred module for downloading stuff these days.

shaunrampersad commented 8 years ago

@alexjfisher , I'm calling the staging module from within my jboss module. Will look into migrating to puppet-archive. thanks!