Like... a root canal

14 views
Skip to first unread message

Douglas Garstang

unread,
Nov 7, 2009, 7:16:19 PM11/7/09
to Puppet Users
I have multiple instances of tomcat running on a single system. They
are installed to /opt/tomcat/$x/$y/$version.

I wanted to symlink each instance's version back to a tomcat-current
directory, like this...

/opt/tomcat/$x/$y/tomcat-current -> /opt/tomcat/$x/$y/tomcat-6.0.20-1.tf

So, I had a definition like this...

define tomcat::create_inst($software, $version = "current",
$server_port, $connector_port) {
#
# Create a symlink.
#
"/opt/tomcat/$name/$software/tomcat-current":
require => Package["apache-tomcat-$name-$software"],
ensure => "/opt/tomcat/$name/$software/$tomcat_version";
}

which is called from the node definition like this....

tomcat::create_inst {
tfel0:
software => "starterkit",
server_port => 7119,
connector_port => 7118;
}

However, puppet complains (but of course!)...

Nov 7 16:15:05 gumby puppetd[17245]: Could not retrieve catalog:
Puppet::Parser::AST::Resource failed with error ArgumentError:
Duplicate definition:
File[/opt/tomcat/tfel0/starterkit/tomcat-current] is already defined
in file /etc/puppe
t/modules/tomcat/manifests/init.pp at line 88; cannot redefine at
/etc/puppet/modules/tomcat/manifests/init.pp:88 on node
gumby.fr.xxx.com

Why? I'm only calling the definition once! ARRRGGGHHHHH!!!!!!

Doug

Avi Miller

unread,
Nov 7, 2009, 8:10:52 PM11/7/09
to puppet...@googlegroups.com
Hi,

Douglas Garstang wrote:
> define tomcat::create_inst($software, $version = "current",
> $server_port, $connector_port) {
> #
> # Create a symlink.
> #
> "/opt/tomcat/$name/$software/tomcat-current":
> require => Package["apache-tomcat-$name-$software"],
> ensure => "/opt/tomcat/$name/$software/$tomcat_version";
> }

Is this a direct cut-n-paste? If so, you're missing a type declaration
around that block. It should be something like:

file {"/opt/tomcat/$name/$software/tomcat-current":


require => Package["apache-tomcat-$name-$software"],

ensure => "/opt/tomcat/$name/$software/$tomcat_version",
}

cYa,
Avi

Douglas Garstang

unread,
Nov 7, 2009, 8:53:00 PM11/7/09
to puppet...@googlegroups.com
Yes, effect of cut and paste. Assume the file {} declaration is there.
--
Regards,

Douglas Garstang
http://www.linkedin.com/in/garstang
Email: doug.g...@gmail.com
Cell: +1-805-340-5627

James Turnbull

unread,
Nov 7, 2009, 9:00:37 PM11/7/09
to puppet...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Douglas Garstang wrote:
> Yes, effect of cut and paste. Assume the file {} declaration is there.
>

I don't assume anything - always leads to badness. :)

Can you paste or link to the full code please?

Regards

James Turnbull

- --
Author of:
* Pro Linux System Administration (http://tinyurl.com/linuxadmin)
* Pulling Strings with Puppet (http://tinyurl.com/pupbook)
* Pro Nagios 2.0 (http://tinyurl.com/pronagios)
* Hardening Linux (http://tinyurl.com/hardeninglinux)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEVAwUBSvYmRSFa/lDkFHAyAQKHfAf/cVdKGvt+43gh4eBxAbVUl1s0I3mF+j3P
Rmgn0hLhy1SOx4trrymwNCz/RKC4GaeGeqU2VEaMwF0B03U0QvQhQtEb6TW4A7iI
z4OldJy8g9X3bN9a7uBz/E9ri0ec0hrRoN5lkLohnXwwOs2wnEvCn4e0gLUlYNm9
oNUiSkB5dCY47b4itD4eLyev5cHlwtuqgbHxNHdnurkFjDprDBPQsLnTLZRxYlG5
tjQwzE8bxwCtcKpmrgDNoFd5JRBOFmt9HQX987kmg/fUULl/6B6Xof/0vMblDcfr
hW/SaleP66/r7D0NnJdC+RfEewvU+E13eCmdWvZDka6CE8EnclHiCQ==
=tlRu
-----END PGP SIGNATURE-----

Douglas Garstang

unread,
Nov 7, 2009, 9:17:13 PM11/7/09
to Puppet Users
James.

Link: http://pastebin.com/m418fc08a

Currently getting this error from it...

Nov 7 18:13:09 gumby puppetd[13556]: Could not retrieve catalog:


Puppet::Parser::AST::Resource failed with error ArgumentError:
Duplicate definition:
File[/opt/tomcat/tfel0/starterkit/tomcat-current] is already defined
in file /etc/puppe
t/modules/tomcat/manifests/init.pp at line 88; cannot redefine at
/etc/puppet/modules/tomcat/manifests/init.pp:88 on node

gumby.fr.twofish.com

Now, I know you can't define the same resource twice, but as far as I
can tell, I'm not passing the same parameters to the definition, so
the final version of the resource should not be the same.

Doug.

--

Dan Bode

unread,
Nov 7, 2009, 11:49:45 PM11/7/09
to puppet...@googlegroups.com
Hi Doug,


I had a chance to look at the code, and..

three things that I see here, are


define tomcat::create_inst($software, $version = "current", $server_port, $connector_port) {

#1.  version is set to "current" by default.
  1.         "/opt/tomcat/${name}/${software}/tomcat-current":
  2.             require => Package["apache-tomcat-${name}-${software}"],
  3.             ensure => "/opt/tomcat/${name}/${software}/${tomcat_version}";
  4.  
  5.         #
  6.         # Make sure that the base Tomcat directory for this instance exists.
  7.         #
  8.         "/opt/tomcat/${name}/${software}/tomcat-${version}":
#2. These two file resource will have the same name, if $version=current

 tomcat::create_inst {
        tfel0:
            #version => $tomcat_version,

#3 If you do not set this param when calling the definition, then it will get set to "current" by default, which creates duplicate resources.

Hope this is helpful,

Dan

Douglas Garstang

unread,
Nov 8, 2009, 1:12:00 AM11/8/09
to puppet...@googlegroups.com
Err, well that's not gonna work!

I need to both make sure that the base directory exists AND the
symlink to it exists. Other than defining a file resource that ensures
the base directory exists and another file resource to create the
symlink, how else could this be done?

In fact, they aren't the same resource. One is a file resource called
"/opt/tomcat/${name}/${software}/tomcat-${version}" and the other is a
LINK to a file resource called
"/opt/tomcat/${name}/${software}/tomcat-${version}".

The error messages are pretty confusing. They point to the symlink
line and tell me that's where the duplicate definition is, not where
the other file resource is.

Doug.

Dan Bode

unread,
Nov 8, 2009, 2:07:12 AM11/8/09
to puppet...@googlegroups.com
On Sat, Nov 7, 2009 at 10:12 PM, Douglas Garstang <doug.g...@gmail.com> wrote:

Err, well that's not gonna work!

I need to both make sure that the base directory exists AND the
symlink to it exists. Other than defining a file resource that ensures
the base directory exists and another file resource to create the
symlink, how else could this be done?

In fact, they aren't the same resource. One is a file resource called
"/opt/tomcat/${name}/${software}/tomcat-${version}" and the other is a
LINK to a file resource called
"/opt/tomcat/${name}/${software}/tomcat-${version}".

you are making a link to a file called
   "/opt/tomcat/${name}/${software}/${tomcat_version}";

under the directory comments you use the name:
   "/opt/tomcat/${name}/${software}/tomcat_${version}";
(which is the same name used for the link)


maybe this is the mistake?

 
The error messages are pretty confusing. They point to the symlink
line and tell me that's where the duplicate definition is, not where
the other file resource is.


I agree that its confusing that it shows the same line number for both of the duplicate references. I can see if there is an issue open.
 
Doug.



Here is the code that I think you want

  1.         #
  2.         # Make a symlink for tomcat.
  1.         #
  2.         "/opt/tomcat/${name}/${software}/tomcat-${version}":
  3.             require => Package["apache-tomcat-${name}-${software}"],
  4.             ensure => "/opt/tomcat/${name}/${software}/${tomcat_version}";
  5.  
  6.         #
  7.         # Make sure that the base Tomcat directory for this instance exists.
  8.         #
  1.         "/opt/tomcat/${name}/${software}/${tomcat_version}":
  1.             require => Package["apache-tomcat-${name}-${software}"],
  1.             owner => tomcat, group => tomcat,
  2.             ensure => directory,
 

Jon Stanley

unread,
Nov 8, 2009, 12:17:58 PM11/8/09
to puppet...@googlegroups.com
On Sun, Nov 8, 2009 at 1:12 AM, Douglas Garstang
<doug.g...@gmail.com> wrote:

> I need to both make sure that the base directory exists AND the
> symlink to it exists. Other than defining a file resource that ensures
> the base directory exists and another file resource to create the
> symlink, how else could this be done?

My use case is slightly different from yours, but what I do is use
virtual resources to get around duplicate definition errors. One of
my defines looks like this. In the class resin::files and
sites::files, I have hardcoded every possible site and environment
that could be passed in (you'll know you forgot this part if on a
puppet run you get "Failed to realize virtual resource blah"). This
is far from ideal, and I'm open to ways to do this that wouldn't
require me to do that :).

The actual use case is that for each site (which is a distinct
website), there are multiple JVM's that make various components of
that site (env_alias, which is really misnamed), We can also
vertically scale JVM's on the same machine, in different runtime
directories (the instance variable). For example, we can have
/apps/runtime/site_A/main/resin/host1_main_1,
/apps/runtime/site_A/main/resin/host1_main_2, and
/apps/runtime/site_A/jive/resin/host1_jive_1 all on the same host.
These are completely unrelated (to puppet) other than the fact that
they're all resin instances running on the same box.

So for each one, I need to make sure that /apps/runtime/site_A,
/apps/runtime/site_A/[main, jive], and /apps/runtime/site_A/[main,
jive]/resin all exist (/apps and /apps/runtime are taken care of in
resin::base. which as you see is included). All of that is handled via
virtual resources, defined in sites::files and resin::files like so:

class resin::files {
@file { "/apps/runtime/gq/main/resin":
owner => cnp,
group => cnp-admin,
mode => 0755,
require => File["/apps/runtime/gq/main"],
ensure => directory;
<much snipped.....>

And here's the complete define resin::instance.

define resin::instance(
$site_alias,
$env_alias,
$instance ="1",
$host_alias,
$resin_ver,
$java_ver,
$watchdog_port = "6700"
) {
include resin::base
include resin::files
include "resin::${resin_ver}"
include sites::files
include "java::${java_ver}"
$instance_name="${host_alias}_${env_alias}_${instance}"
$runtime_dir =
"/apps/runtime/$site_alias/$env_alias/resin/${host_alias}_${env_alias}_${instance}"
file { "/apps/runtime/$site_alias/$env_alias/resin/${host_alias}_${env_alias}_${instance}":
owner => cnp,
group => cnp-admin,
#mode => 0755,
require => File["/apps/runtime/$site_alias/$env_alias"],
source => "/media/CNT/common/puppet/resin3-runtime",
recurse => true,
ignore => ".svn",
replace => no;
"/apps/runtime/$site_alias/$env_alias/resin/${host_alias}_${env_alias}_${instance}/conf":
owner => cnp,
group => cnp-admin,
require =>
File["/apps/runtime/$site_alias/$env_alias/resin/${host_alias}_${env_alias}_${instance}"],
ensure => "/media/CNT/$site_alias/apps/$site_alias/$env_alias/resin/conf";
}
# no class names are allowed with dots, so do a lame workaround
case $resin_ver {
"resin318": { $real_resin_ver = "resin-pro-3.1.8" }
"resin316": { $real_resin_ver = "resin-pro-3.1.6" }
}
case $java_ver {
"java1607": { $real_java_ver = "jdk1.6.0_07" }
}

file { "/apps/runtime/$site_alias/$env_alias/resin/${host_alias}_${env_alias}_${instance}/bin/setenv.sh":
owner => cnp,
group => cnp-admin,
require =>
File["/apps/runtime/$site_alias/$env_alias/resin/${host_alias}_${env_alias}_${instance}"],
mode => 0755,
content => template("resin/setenv.sh.erb");
}

# these two are defined in sites::files
realize File["/apps/runtime/$site_alias"]
realize File["/apps/runtime/$site_alias/$env_alias"]
# this is defined in resin::files above
realize File["/apps/runtime/$site_alias/$env_alias/resin"]
}

Reply all
Reply to author
Forward
0 new messages