Although I know the immediate solution to a problem I was facing yesterday (thanks to the folks over at IRC #puppet), I still don't understand how it solved the problem, or rather what's the fundamental difference between classes and defines in this particular scenario:
The original define, which was incorrect:
define srv($name,$enable="true",$ensure="running",$provider="runit",$hasstatus="true",$hasrestart="true"){
exec {"sleep 5": path=>"/usr/bin:/usr/sbin:/bin:/sbin", before=>Service["$name"],}
service{"$name":
enable=>$enable,
ensure=>$ensure,
provider=>$provider,
hasstatus=>$hasstatus,
hasrestart=>$hasrestart,
}
}
err: Could not retrieve catalog from remote server: Error 400 on SERVER: Duplicate definition: Exec[sleep 5] is already defined in file /etc/puppet/modules/common/manifests/defines/srv.pp at line 4; cannot redefine at /etc/puppet/modules/common/manifests/defines/srv.pp:4 on node testing.abc.def.com
The correct define:
define srv($enable="true",$ensure="running",$provider="runit",$hasstatus="true",$hasrestart="true"){
exec {"sleep 5 for $name": command=>"sleep 5", path=>"/usr/bin:/usr/sbin:/bin:/sbin", before=>Service["$name"],}
service{"$name":
enable=>$enable,
ensure=>$ensure,
provider=>$provider,
hasstatus=>$hasstatus,
hasrestart=>$hasrestart,
}
}
So, why the error in the first case ? How am I duplicating a definition or in other words, if there was a single module using this define then would have the first define worked ? Maybe its the puppet terminology in the docs that has left me confused, but having written a ton of (working) modules and not understanding this sounds dangerous to me, hope I can get some clear answers.
Resources in Puppet have to be unique, i. e. have to have a unique name.
In the described case, you had the resource
Exec["sleep 5"]
in your definition and every time you callsrv
(it's basically the same as including a parameterized class), the resourceExec["sleep 5"]
will also be included and thus the parser finds two or more resources with the same name.By appending the
$name
of the definition to the name of yourExec
resource, you make it unique. Well, at least most likely unique since when you have another resource with the same name (Exec["sleep 5 for foo"
) somewhere else in your manifests, you'll run into this error again.