Reputation: 143
Hopefully a simple question, is there a way I can put variables inside other variables? In my particular use case, I am trying to get tricky to have puppet install a whole bunch of binaries (ant, maven, jdk's etc)
Let's say I have the following manifest:
$package_name = [ 'ant', 'maven' ]
$package_ant_versions = [ '1.7.1', '1.8.4', '1.9.4' ]
$package_ant_prefix = 'apache-ant-'
$package_ant_suffix = '-src.tar.gz'
$package_maven_versions = [ '3.0.4' ]
$package_maven_prefix = 'apache-maven-'
$package_maven_suffix = '.tgz'
$path = 'repo.domain.com/software'
So there are my variables. Now I am trying to write an exec statement that will iterate through all packages and variables and download them locally, so I may install them.
Here is my attempt at the command:
exec { 'download-packages':
command => "/usr/bin/aws s3 cp ${path}/${package_name}/${package_${package_name}_prefix}/{package_${package_name}_versions}/${package_${package_name}_suffix} /tmp"
}
The way I had hoped it would work was that it would iterate through all variables. For example, with the defined variables the commands that would be run are:
/usr/bin/aws s3 cp repo.domain.com/software/ant/apache-ant-1.7.1-src.tar.gz /tmp
/usr/bin/aws s3 cp repo.domain.com/software/ant/apache-ant-1.8.4-src.tar.gz /tmp
/usr/bin/aws s3 cp repo.domain.com/software/ant/apache-ant-1.9.4-src.tar.gz /tmp
/usr/bin/aws s3 cp repo.domain.com/software/maven/apache-maven-3.0.4.tgz /tmp
The end result is that I simply want to add/change versions in the manifest (e.g. I could go in and add ant version 1.9.3 simply by changing:
$package_ant_versions = [ '1.7.1', '1.8.4', '1.9.4' ]
to
$package_ant_versions = [ '1.7.1', '1.8.4', '1.9.3', '1.9.4' ]
And have puppet do the rest (assuming the file is available in the location it is trying to download from).
I am sure I am doing this all wrong, but I hope the end result I am trying to get to is clear. It seems to break when I try and put variables inside variables:
${package_${package_name}_prefix}
${package_${package_name}_versions}
${package_${package_name}_suffix}
Any help to get this working or achieve something similar would be really helpful.
Thanks!
Upvotes: 0
Views: 1367
Reputation: 8223
First, as was noted, use a structure like the following.
$packages = {
'ant' => {
'versions' => [ '1.7.1', '1.8.4', '1.9.4', ],
'prefix' => 'apache-ant-',
'suffix' => '-src.tar.gz',
},
'maven' => {
'versions' => [ '3.0.4', ],
'prefix' => 'apache-maven-',
'suffix' => '-bin.tar.gz',
}
}
Note that the array of versions cannot be sensibly used in a single exec resource. I think you want this:
define software_download($versions, $prefix, $suffix) {
software_version_download { $versions:
software => $name,
prefix => $prefix,
suffix => $suffix,
}
}
define software_version_download($software, $prefix, $suffix) {
$version = $name
exec { "download-$software-$version":
command => "/usr/bin/aws s3 cp ${path}/${software}/${prefix}${version}${suffix} /tmp",
}
}
The define software_download
accepts your data and multiplexes it to the software_version_download
define, passing each distinct version as the resource $name
. From that, the final command is constructed.
If your data is in the hash, you can create_resources('software_download', $packages)
, or less magically via manifest code:
software_download {
'ant':
'versions' => [ '1.7.1', '1.8.4', '1.9.4', ],
'prefix' => 'apache-ant-',
'suffix' => '-src.tar.gz';
'maven':
'versions' => [ '3.0.4', ],
'prefix' => 'apache-maven-',
'suffix' => '-bin.tar.gz';
}
Upvotes: 3
Reputation: 3806
You could do this using inline_template:
exec { 'download-packages':
command => inline_template("/usr/bin/aws s3 cp ${path}/${package_name}/<%=package_${package_name}_prefix%>/<%=package_${package_name}_versions%>/<%=package_${package_name}_suffix%> /tmp")
}
But, as @FelixFrank says, maybe is preferrible a structured way.
That solves the problem of variables inside variables. For the array problem, you could emulate a foreach statement:
$package_name= [ "ant", "maven" ]
define download-packages() {
exec { 'download-packages-$name':
command => "/usr/bin/aws s3 cp ${path}/${name}/${package_${name}_prefix}/{package_${name}_versions}/${package_${name}_suffix} /tmp"
}
}
download-packages{ $package_name:}
Upvotes: 1