Pass array to a define

479 views
Skip to first unread message

Douglas Garstang

unread,
Aug 10, 2012, 8:10:20 PM8/10/12
to Puppet Users
How can I pass an array to a define? It's not documented in the puppet
language guide.

I've got:

define lvm::create_vg ( $pvdisks ) {
exec {
'pvcreate':
command => "/sbin/pvcreate -yf $pvdisks",
unless => "/sbin/pvdisplay $pvdisks",
...
}
}

class someclass {
lvm::create_vg {
'bcvg01':
pvdisks => ['/dev/xvdb1', '/dev/xvdc1'];
}
}

Inside the define, $pvdisks gets expanded to '/dev/xvdb1/dev/xvdc1'

Doug.

Stefan Schulte

unread,
Aug 11, 2012, 8:21:05 AM8/11/12
to Puppet Users
Inside your define $pvdisks is whatever you passed as the pvdisks
parameter, so in your case $pvdisks *is* an array. But in the unless
parameter you use the array in a string context so all your items are
concatenated. Unfortunately puppet does not have a join function to
convert an array to a string.

On the other hand it may not be desired to destroy every disk you pass
as in the pvdisks array if only one of the disks is not a LVM disk (as
pvdisplay returns with a non-zero exitcode as soon as one disk is not
recognized to be a LVM disk)

So the best approach is probably to get the LVM puppet plugin and
replace your exec with

physical_volume { $pvdisks:
ensure => present,
}

The physical_volume is a new type that comes with the LVM plugin.

[1] http://forge.puppetlabs.com/puppetlabs/lvm

-Stefan

Mark Roggenkamp

unread,
Aug 11, 2012, 9:02:39 AM8/11/12
to puppet...@googlegroups.com

James A. Peltier

unread,
Aug 11, 2012, 4:46:57 PM8/11/12
to puppet...@googlegroups.com
Great! But what happens if you want to specify multiple physical volumes be a member of a single data volume during creation. Is the expectation that you'd always specify a lvm:vg with the initial disk and then lvm:vg extend that volume?

--
James A. Peltier
Manager, IT Services - Research Computing Group
Simon Fraser University - Burnaby Campus
Phone : 778-782-6573
Fax : 778-782-3045
E-Mail : jpel...@sfu.ca
Website : http://www.sfu.ca/itservices
http://blogs.sfu.ca/people/jpeltier

Success is to be measured not so much by the position that one has reached
in life but as by the obstacles they have overcome. - Booker T. Washington

James A. Peltier

unread,
Aug 11, 2012, 5:02:51 PM8/11/12
to puppet...@googlegroups.com
It appears that split is a method for doing this. I found this online.

$ifs = split($interfaces,",")

define do_this {
$mule = "ipaddress_${name}"
$donkey = inline_template("<%= scope.lookupvar(mule) %>")

notify { "Found interface $donkey":; }
}

do_this { $ifs:; }

Douglas Garstang

unread,
Aug 11, 2012, 7:53:29 PM8/11/12
to puppet...@googlegroups.com
Thanks. What am I looking at when I extract this? I was expecting to
see a couple of .pp files. Installation documentation!?

Doug.

Stefan Schulte

unread,
Aug 11, 2012, 10:48:36 PM8/11/12
to puppet...@googlegroups.com
Do you mean something like sda1 and sda2 beeing two physical volumes in
the volume group vg? This should work:


physical_volume { [ '/dev/sda1', '/dev/sda2']:
ensure => present.
}

volume_group { 'vg':
ensure => present,
physical_volumes => [ '/dev/sda1', '/dev/sda2' ],
require => [
Physical_volume['/dev/sda1'],
Physical_volume['/dev/sda2'],
],
}

-Stefan

Douglas Garstang

unread,
Aug 14, 2012, 5:23:37 PM8/14/12
to puppet...@googlegroups.com
Yeah, well I tried the puppet labs lvm module. After I fixed the
syntax errors, which included a missing '}' in the code (wtf!??!), it
seems that custom types don't work with environments...

http://projects.puppetlabs.com/issues/4409

Doug.

Stefan Schulte

unread,
Aug 14, 2012, 6:28:16 PM8/14/12
to puppet...@googlegroups.com
On Tue, Aug 14, 2012 at 02:23:37PM -0700, Douglas Garstang wrote:
> Yeah, well I tried the puppet labs lvm module. After I fixed the
> syntax errors, which included a missing '}' in the code (wtf!??!), it
> seems that custom types don't work with environments...
>
> http://projects.puppetlabs.com/issues/4409
>
> Doug.
>

You can use custom types even if you use environments. The problem is that
type and parameter validation happens on the master side so the puppetmaster
process needs to be aware of the custom type.

So on your master you need to have at least these files:

/var/lib/puppet/lib/puppet/type/filesystem.rb
/var/lib/puppet/lib/puppet/type/logical_volume.rb
/var/lib/puppet/lib/puppet/type/physical_volume.rb
/var/lib/puppet/lib/puppet/type/volume_group.rb

On your agent you need to have the type/* and provider/*/* files but
this is already handled if you use `pluginsync = true` in your
`/etc/puppet/puppet.conf`.

On your puppet master you can either copy the files by hand or run a puppet
agent process on the master with pluginsync enabled. If the files are in
place make sure to restart your puppetmaster (maybe the master will pick
them up automatically but I am not sure about that).

The thing about environments is: You may want to add a parameter to the
`volume_group� type so you modify the volume_group.rb file in your "dev"
environment. While a puppet node with environment "dev" will get the new
version of the plugin now, the puppetmaster will still see its version
in /var/lib/puppet/type/volume_group.rb which does not have the new
parameter. If you run puppet agent on your masternode in the environment
"prod" you are forced to push your changes to volume_group.rb into prod.

I hope this helps and you get the lvm type to work.

-Stefan

Reply all
Reply to author
Forward
0 new messages