If I'm reading this right, you're trying to join two arrays in a
distinct fashion. I'm afraid puppet cannot easily do that.
Your best bet is the create_resources function, if your puppet is recent
enough. Even then you cannot use arrays per se, but have to structure
your data accordingly:
$users = {
"A" => "1.5",
"B" => "2.0",
...
}
Then you can feed this hash to create_resources. With this structure,
your "mything" define would expect the user name to be the resource title.
mything($version) {
exec { "create_mything_for_${name}_with_version_${version}": ... }
}
HTH,
Felix
I'm trying to make a defined type with two parameters and pass an array for each parameter.
My first try was something like this:init.ppdefine mything ($user, $version) {exec {$user_$version:command => something needing both $user and $version}}in the node file:$user = [ "A", "B", "C", "D"]$version = [ "1.5", "2.0", "4.2", "0.01" ]mything { "thing":user => $user,version => $version,}Now of course this didn't do what I want it to do (give all the users in $users all of the versions in $version)
Searching I came across a post that said do something using $title likeinit.ppdefine mything ($version) {exec {$version:command => something using $foo and $title}}and the node file$user = [ "A", "B", "C", "D" ]mything { $user:version => "1.5"}
However this still means I'd have to do one for each version (and figure out how to avoid a Duplicate definition problem.Is there an easy or a right way to do what I'm trying to do?
I think it important to not only come up with a means to your end, but also to understand what you've done once you get there. What you need to know in this case is that Puppet provides a shortcut for declaring multiple resources of the same type and with the same parameters. If you give it an array -- whether a literal one or a variable or function result -- as the title of a resource, then Puppet creates one resource for each element of the array. That can be used similarly to a 'for' loop in a procedural language, though it isn't a loop at all.However this still means I'd have to do one for each version (and figure out how to avoid a Duplicate definition problem.Is there an easy or a right way to do what I'm trying to do?
Depending on the details of what you're trying to do, Felix's suggestion of the create_resources() function might be your best bet. On the other hand, you can also do it by interposing another defined type, and using Puppet's built-in regsubst() and split() functions. That obtains simpler data at the expense of more complex resources:
define mythings_user($versions) {
# $name == $title == the user
mything { regsubst($versions, '^.*$', "$name:\0"): }
}
define mything () {
# $name == $title == the version
$user_and_version = split($name, ':')
$user = $user_and_version[0]
$version = $user_and_version[1]
exec { "mything $name":
command => "echo mything v. $version for $user"
}
}
When the first argument to regsubst() is an array, it performs the specified substitution on each element, and returns an array of the results. Thus, its usage in definition Mythings_user creates an array of strings of the form "user:version", which are suitable distinct titles for all the needed Mything resources. The Mything definition then splits its name/title to get the user and version pieces. Kinda ugly, really.
John
On Tuesday, July 24, 2012 9:31:39 AM UTC-4, jcbollinger wrote:
[...]
define mything () {
# $name == $title == the version
$user_and_version = split($name, ':')
$user = $user_and_version[0]
$version = $user_and_version[1]
exec { "mything $name":
command => "echo mything v. $version for $user"
}
}
[...]
This almost worked, except when it is called the 2nd or 3rd time, puppet complains that it cannot reassign variable user_and_version.
On Wednesday, July 25, 2012 9:29:18 AM UTC-4, jcbollinger wrote:Something is very strange with that. It is routine practice for definition bodies to set local variables, and for such definitions to be instantiated multiple times. Among other things, it is sometimes used to mangle definitions' properties. For that matter, definitions' property variables are defined separately for each instance, too.
To troubleshoot your problem, I will need to see the exact code you tested, including the corresponding manifest file layout, and the exact error message Puppet emitted.
Yes something was very strange. I did something wrong. I've got it working now. The only major problem I had was that puppet didn't like
mything { regsubst($versions, '^.*$', "$name:\0"): }
I had to take out the regsubst function and do $foo = regsubst(...) mything { $foo: } I don't understand why that was necessary.