As someone new to puppet I'm trying to work out the best way to manage
different filesystems and logical volumes on different servers. Specifically
I would like to be able to define on a series of nodes different LVM logical
volumes to create and mount.
I'm trying to do this at the moment with a define of the following type:
# Manage a partition and create if needed.
define lv_partition(
$name = "partition",
$location = "/tmp",
$lvsize = "1G",
$fstype = "ext3",
$vgname = "vg00",
$lvname = $name,
$owner = "root",
$group = "root",
$mode = "755" ) {
file { "$location/$name":
ensure => directory,
owner => $owner,
group => $group,
mode => $mode,
notify => Exec["create lv /dev/$vgname/$lvname"],
}
exec { "create lv /dev/$vgname/$lvname":
command => "lvcreate -n $lvname -L $lvsize /dev/$vgname && mkfs.$fstype /dev/$vgname/$lvname",
unless => "lvs | grep -q "$lvname.*$vgname",
notify => Exec["mount lv $location/$name"],
}
exec { "mount lv $location/$name":
command => "mount -t $fstype /dev/$vgname/$lvname $location/$instance"
unless => "mount | grep -q '/dev/$vgname/$lvname' ",
}
}
which is defined for the node as follows:
node "ams03.wl0.org" {
...
lv_partition { "/tmp/puppet":
name => "puppet",
location => "/tmp",
lvsize => "1M",
fstype => "ext3",
vgname => "vg01",
}
}
Is this the right way to approach the problem in puppet (even if the
syntax is slightly wrong) or should I be trying this another way?
Thanks for any ideas.
Regards,
Simon
On Tue, May 27, 2008 at 12:59:11PM +0200, Simon J Mudd wrote:
> As someone new to puppet I'm trying to work out the best way to manage
> different filesystems and logical volumes on different servers. Specifically
> I would like to be able to define on a series of nodes different LVM logical
> volumes to create and mount.
>
> I'm trying to do this at the moment with a define of the following type:
>
[adjusted for previous errors]
# site.pp
#
# Manage a partition and create if needed.
define lv_partition(
$name = "partition",
$location = "/tmp",
$lvsize = "1G",
$fstype = "ext3",
$vgname = "vg00",
$lvname = "$name",
$owner = "root",
$group = "root",
$mode = "755" ) {
file { "$location/$name":
ensure => directory,
owner => $owner,
group => $group,
mode => $mode,
}
exec { "create lv /dev/$vgname/$lvname":
path => [ "/sbin", "/bin", "/usr/sbin", "/usr/bin" ],
logoutput => true,
command => "lvcreate -n $lvname -L $lvsize /dev/$vgname && mkfs.$fstype /dev/$vgname/$lvname",
unless => "/usr/sbin/lvs | grep -q "$lvname.*$vgname",
subscribe => File[ "$location/$name"],
refreshonly => true,
}
exec { "mount lv $location/$name":
path => [ "/bin", "/usr/bin" ],
logoutput => true,
command => "mount -t $fstype /dev/$vgname/$lvname $location/$name"
unless => "mount | grep -q '/dev/$vgname/$lvname' ",
subscribe => Exec["create lv /dev/$vgname/$lvname"],
refreshonly => true,
}
}
...
node "master.wl0.org" {
lv_partition { "/tmp/puppet":
name => "puppet",
location => "/tmp",
lvname => "lvpuppet", # for the moment you MUST include the lvname, it doesn't take $name by default
lvsize => "1M",
fstype => "ext3",
vgname => "vg00",
}
}
The logging shows:
[root@master puppet]# puppetd -o --debug --test
debug: Creating default schedules
debug: Failed to load library 'shadow' for feature 'libshadow'
debug: /Settings[/etc/puppet/puppet.conf]/Settings[ssl]/File[/var/lib/puppet/ssl/public_keys/master.wl0.org.pem]: Autorequiring File[/var/lib/puppet/ssl/public_keys]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[ssl]/File[/var/lib/puppet/ssl/private_keys]: Autorequiring File[/var/lib/puppet/ssl]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[puppetd]/File[/var/lib/puppet/state/state.yaml]: Autorequiring File[/var/lib/puppet/state]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[main]/File[/var/lib/puppet/lib]: Autorequiring File[/var/lib/puppet]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[ssl]/File[/var/lib/puppet/ssl/certs]: Autorequiring File[/var/lib/puppet/ssl]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[ssl]/File[/var/lib/puppet/ssl/certs/master.wl0.org.pem]: Autorequiring File[/var/lib/puppet/ssl/certs]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[main]/File[/var/lib/puppet/state]: Autorequiring File[/var/lib/puppet]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[ssl]/File[/var/lib/puppet/ssl/certs/ca.pem]: Autorequiring File[/var/lib/puppet/ssl/certs]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[ssl]/File[/var/lib/puppet/ssl/public_keys]: Autorequiring File[/var/lib/puppet/ssl]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[ssl]/File[/var/lib/puppet/ssl/private]: Autorequiring File[/var/lib/puppet/ssl]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[ssl]/File[/var/lib/puppet/ssl/private_keys/master.wl0.org.pem]: Autorequiring File[/var/lib/puppet/ssl/private_keys]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[ssl]/File[/var/lib/puppet/ssl/csr_master.wl0.org.pem]: Autorequiring File[/var/lib/puppet/ssl]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[puppetd]/File[/var/lib/puppet/classes.txt]: Autorequiring File[/var/lib/puppet]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[main]/File[/var/lib/puppet/ssl]: Autorequiring File[/var/lib/puppet]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[puppetd]/File[/etc/puppet/puppet.conf]: Autorequiring File[/etc/puppet]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[puppetd]/File[/var/lib/puppet/state/state.yaml]: Changing mode
debug: /Settings[/etc/puppet/puppet.conf]/Settings[puppetd]/File[/var/lib/puppet/state/state.yaml]: 1 change(s)
debug: /Settings[/etc/puppet/puppet.conf]/Settings[puppetd]/File[/var/lib/puppet/state/state.yaml]/mode: mode changed '640' to '660'
debug: Finishing transaction -604907756 with 1 changes
debug: Loaded state in 0.00 seconds
debug: Retrieved facts in 0.96 seconds
notice: Ignoring cache
debug: Retrieving catalog
debug: Calling puppetmaster.getconfig
debug: Retrieved catalog in 0.47 seconds
debug: Creating default schedules
debug: Finishing transaction -605630670 with 0 changes
info: Caching catalog at /var/lib/puppet/localconfig.yaml
notice: Starting catalog run
debug: Loaded state in 0.01 seconds
debug: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/File[/tmp/puppet]/notify: subscribes to Exec[create lv /dev/vg00/lvpuppet]
debug: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/File[/tmp/puppet]: File does not exist
debug: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/File[/tmp/puppet]: Changing ensure
debug: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/File[/tmp/puppet]: 1 change(s)
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/File[/tmp/puppet]/ensure: created
info: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/File[/tmp/puppet]: Scheduling refresh of Exec[create lv /dev/vg00/lvpuppet]
debug: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]: Changing returns
debug: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]: 1 change(s)
debug: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]: Executing 'lvcreate -n lvpuppet -L 1M /dev/vg00 && mkfs.ext3 /dev/vg00/lvpuppet'
debug: Executing 'lvcreate -n lvpuppet -L 1M /dev/vg00 && mkfs.ext3 /dev/vg00/lvpuppet'
/usr/lib/site_ruby/1.8/puppet/util.rb:312: warning: fork terminates thread at /usr/lib/ruby/1.8/timeout.rb:41
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: File descriptor 7 left open
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: /dev/cdrom: open failed: No medium found
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: Rounding up size to full physical extent 32.00 MB
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: Logical volume "lvpuppet" created
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: mke2fs 1.35 (28-Feb-2004)
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: Filesystem label=
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: OS type: Linux
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: Block size=1024 (log=0)
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: Fragment size=1024 (log=0)
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: 8192 inodes, 32768 blocks
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: 1638 blocks (5.00%) reserved for the super user
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: First data block=1
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: Maximum filesystem blocks=33554432
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: 4 block groups
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: 8192 blocks per group, 8192 fragments per group
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: 2048 inodes per group
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: Superblock backups stored on blocks:
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: 8193, 24577
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns:
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: Writing inode tables: done
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: Creating journal (4096 blocks): done
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: Writing superblocks and filesystem accounting information: done
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns:
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: This filesystem will be automatically checked every 34 mounts or
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: 180 days, whichever comes first. Use tune2fs -c or -i to override.
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: executed successfully
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]: Triggering 'refresh' from 1 dependencies
debug: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]: Executing 'lvcreate -n lvpuppet -L 1M /dev/vg00 && mkfs.ext3 /dev/vg00/lvpuppet'
debug: Executing 'lvcreate -n lvpuppet -L 1M /dev/vg00 && mkfs.ext3 /dev/vg00/lvpuppet'
/usr/lib/site_ruby/1.8/puppet/util.rb:312: warning: fork terminates thread at /usr/lib/ruby/1.8/timeout.rb:41
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: File descriptor 7 left open
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: /dev/cdrom: open failed: No medium found
notice: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]/returns: Logical volume "lvpuppet" already exists in volume group "vg00"
err: /:main/Node[master.wl0.org]/Lv_partition[/tmp/puppet]/Exec[create lv /dev/vg00/lvpuppet]: Failed to call refresh on Exec[create lv /dev/vg00/lvpuppet]: lvcreate -n lvpuppet -L 1M /dev/vg00 && mkfs.ext3 /dev/vg00/lvpuppet returned 5 instead of 0 at /etc/puppet/manifests/site.pp:40
debug: Finishing transaction -605658110 with 2 changes
debug: Storing state
debug: Stored state in 0.22 seconds
notice: Finished catalog run in 3.27 seconds
[root@master puppet]#
So I have several questions:
1. Why do I need to define "$lvname" if the default definition is supposed
to use $name? When I've tried lv_partition{ ... } leaving $lvname
blank $lvname does not get assigned to the value of $name as shown
in the define.
2. Running puppet seems to call lvcreate twice thus giving an error, even
though I thought that the 'unless' clause could be used to avoid the
exec {} running if the lv was already created.
3. I see various errors:
/usr/lib/site_ruby/1.8/puppet/util.rb:312: warning: fork terminates thread at /usr/lib/ruby/1.8/timeout.rb:41
Are these normal?
4. Am I allowed to use the shell syntax I'm using above? It seems to work,
but I'm not sure if that's by luck. Having come from a cfEngine environment
where shellcommands were used quite frequently and where a specific option
useshell=yes/no existed the puppet documentation doesn't seem very clear
about exactly how things are executed from "command" nor how complex
it can be.
Thanks for any feedback anyone can give me on this.
Regards,
Simon
> 1. Why do I need to define "$lvname" if the default definition is
> supposed to use $name? When I've tried lv_partition{ ... } leaving
> $lvname blank $lvname does not get assigned to the value of $name as
> shown in the define.
It's not necessary (and possibly detrimental) to have a name parameter
added here in the call to the definition, or in the definition itself.
Normally, the definition would take the `/tmp/puppet' as the name
automatically. I can definitely verify that the following Amanda-related
definition (abridged down to a minimum, taken from
http://preview.tinyurl.com/5dqmp5 ) works for me:
|> define amandaconfig (
|> $confdir = "/etc/amanda",
|> $logdir = "/var/log/amanda",
|> $libdir = "/var/lib/amanda",
|> $user = "backup",
|> $group = "backup",
|> $dumpcycle = 1,
|> $tapecycle = 2,
|> $runtapes = 1,
|> $labelstr = "LABEL"
|> ) {
|>
|> file {
|> "$confdir/$name":
|> ensure => directory,
|> owner => $user,
|> group => $group,
|> mode => 0770;
|> }
|> }
|>
|> amanda::amandaconfig {
|> "holding":
|> labelstr => "HOLDING",
|> dumpcycle => 1,
|> tapecycle => 2,
|> runtapes => 1;
|> }
> 2. Running puppet seems to call lvcreate twice thus giving an error,
> even though I thought that the 'unless' clause could be used to avoid
> the exec {} running if the lv was already created.
I wonder if you really want `require' instead of `subscribe'. Require
exists only to define dependency order. Subscribe does that, and also
refreshes dependent types. Do you really ever want your lvcreate to be
re-run based off the state of $location/$name ? Does lvcreate even
require $location/$name to be present to execute successfully? If not,
then you probably don't need that particular dependency at all.
My LVM experience is pretty shallow, but I wonder if something more
along these lines is what you're looking for:
define lv_partition(
$location = "/tmp",
$lvsize = "1G",
$fstype = "ext3",
$vgname = "vg00",
$owner = "root",
$group = "root",
$mode = "755" ) {
file { "${location}/${name}":
ensure => directory,
owner => $owner,
group => $group,
mode => $mode,
}
exec { "lvcreate-${vgname}-${name}":
path => [ "/sbin", "/bin", "/usr/sbin", "/usr/bin" ],
logoutput => true,
command => "lvcreate -n ${name} -L ${lvsize} /dev/${vgname} &&
mkfs.${fstype} /dev/${vgname}/${name}",
creates => "/dev/${vgname}/${name}",
}
mount { "${location}/${name}":
atboot => true,
device => "/dev/${vgname}/${name}",
ensure => mounted,
fstype => "${fstype}",
options => "defaults",
dump => "0",
pass => "1",
require => [ Exec["lvcreate-${vgname}-${name}"],
File["${location}/${name}"] ];
}
}
node "master.wl0.org" {
lv_partition { "puppet":
lvsize => "1M"
}
}
> 3. I see various errors: /usr/lib/site_ruby/1.8/puppet/util.rb:312:
> warning: fork terminates thread at /usr/lib/ruby/1.8/timeout.rb:41
> Are these normal?
http://reductivelabs.com/trac/puppet/ticket/724 shows "harmless Ruby
warning".
> 4. Am I allowed to use the shell syntax I'm using above? It seems to
> work, but I'm not sure if that's by luck. Having come from a cfEngine
> environment where shellcommands were used quite frequently and where
> a specific option useshell=yes/no existed the puppet documentation
> doesn't seem very clear about exactly how things are executed from
> "command" nor how complex it can be.
The shell syntax should generally work, but I guess there's always a
chance of overdoing it, especially with respect to quoting between Ruby
the shell itself. I have a particularly nasty one for joining an Active
Directory that's:
$net rpc join -U username\%password -S pdcname
because Samba's net command explicitly wants the percent sign to
separate the username and password. I really ought to just make that one
a separate shell script, copy it to the client, and execute it that way.
--
Mike Renfro / R&D Engineer, Center for Manufacturing Research,
931 372-3601 / Tennessee Technological University
On 27 May 2008 17:42:16, Mike Renfro wrote:
> On 5/27/2008 11:08 AM, Simon J Mudd wrote:
>
> > 1. Why do I need to define "$lvname" if the default definition is
> > supposed to use $name? When I've tried lv_partition{ ... } leaving
> > $lvname blank $lvname does not get assigned to the value of $name as
> > shown in the define.
>
> It's not necessary (and possibly detrimental) to have a name parameter
> added here in the call to the definition, or in the definition itself.
Thanks for the hint and the pointer to your amanda recipe.
...
> > 2. Running puppet seems to call lvcreate twice thus giving an error,
> > even though I thought that the 'unless' clause could be used to avoid
> > the exec {} running if the lv was already created.
>
> I wonder if you really want `require' instead of `subscribe'. Require
> exists only to define dependency order. Subscribe does that, and also
> refreshes dependent types. Do you really ever want your lvcreate to be
> re-run based off the state of $location/$name ? Does lvcreate even
> require $location/$name to be present to execute successfully? If not,
> then you probably don't need that particular dependency at all.
Probably a misunderstanding of puppet and the relation between
different events need to be triggered, but also my logic was wrong. There
should probably be a relation between the mount point being created and
the mount itself but the actual logical volume and filesystem creation
should be done IFF the logical volume doesn't already exist. I just thought
it made sense to order this after the mount point is actually created.
> My LVM experience is pretty shallow, but I wonder if something more
> along these lines is what you're looking for:
>
> define lv_partition(
...
> }
I'll take a look. Thanks.
...
> > 4. Am I allowed to use the shell syntax I'm using above? It seems to
> > work, but I'm not sure if that's by luck. Having come from a cfEngine
> > environment where shellcommands were used quite frequently and where
> > a specific option useshell=yes/no existed the puppet documentation
> > doesn't seem very clear about exactly how things are executed from
> > "command" nor how complex it can be.
>
> The shell syntax should generally work, but I guess there's always a
> chance of overdoing it, especially with respect to quoting between Ruby
> the shell itself. I have a particularly nasty one for joining an Active
> Directory that's:
>
> $net rpc join -U username\%password -S pdcname
>
> because Samba's net command explicitly wants the percent sign to
> separate the username and password. I really ought to just make that one
> a separate shell script, copy it to the client, and execute it that way.
Ok. However the documentation doesn't warn that:
- puppet variables get evaluated first, and
- shell escaping may be required (and how best to do this)
- any rules limitations of what can be in the command (size?)
Sometimes it seems easier to write a slightly largish "single-line"
shell script than to write the script elsewhere and copy it to the puppet
client in order to execute it. This requires more maintenance and perhaps
should be avoided as long as the "command" is not too long. This
alternative is not described as a "better" or "alternative" solution and
perhaps it should be.
Thanks for your feedback on this. You've given me some more things
to look at.
Regards,
Simon
# site.pp or whereever
# This is for creating a partitionn of the defined type if it doesn't exit and mounting it.
# usage:
# lvmconfig{ "mount_point":
# $location => "/tmp",
# $lvsize => "20G",
# $fstype => "xfs",
# $mode => "750",
# }
# Manage a partition and create if needed.
define lvmconfig (
$location = "/tmp",
$lvsize = "1G",
$fstype = "ext3",
$vgname = "vg00",
$lvname = "$name",
$owner = "root",
$group = "root",
$mode = "755" ) {
file { "${location}/${name}":
ensure => directory,
owner => $owner,
group => $group,
mode => $mode,
}
exec { "lvcreate-${vgname}-${lvname}":
path => [ "/sbin", "/bin", "/usr/sbin", "/usr/bin" ],
logoutput => false,
command => "lvcreate -n ${lvname} -L ${lvsize} /dev/${vgname} && mkfs -t ${fstype} /dev/${vgname}/${lvname}",
unless => "lvs | grep -q '${lvname}.*${vgname}'",
subscribe => File[ "$location/$name"],
}
mount { "${location}/${name}":
atboot => true,
device => "/dev/$vgname/$lvname",
ensure => mounted,
fstype => "${fstype}",
options => "defaults",
dump => "0",
pass => "1",
require => [ Exec["lvcreate-${vgname}-${lvname}"], File["${location}/${name}"] ],
}
}
...
# for the moment you MUST include the lvname, it doesn't take $name by default
node "client.some.domain" {
lvmconfig { "puppet":
location => "/tmp",
lvname => "lvpuppet",
lvsize => "1M",
fstype => "ext3",
vgname => "vg00",
}
}
On the client it runs as follows:
[root@client puppet]# puppetd -o --debug --test
debug: Creating default schedules
debug: Failed to load library 'shadow' for feature 'libshadow'
debug: /Settings[/etc/puppet/puppet.conf]/Settings[main]/File[/var/lib/puppet/state]: Autorequiring File[/var/lib/puppet]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[ssl]/File[/var/lib/puppet/ssl/certs/ca.pem]: Autorequiring File[/var/lib/puppet/ssl/certs]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[ssl]/File[/var/lib/puppet/ssl/public_keys]: Autorequiring File[/var/lib/puppet/ssl]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[ssl]/File[/var/lib/puppet/ssl/private]: Autorequiring File[/var/lib/puppet/ssl]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[ssl]/File[/var/lib/puppet/ssl/private_keys/client.some.domain.pem]: Autorequiring File[/var/lib/puppet/ssl/private_keys]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[ssl]/File[/var/lib/puppet/ssl/csr_client.some.domain.pem]: Autorequiring File[/var/lib/puppet/ssl]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[puppetd]/File[/var/lib/puppet/classes.txt]: Autorequiring File[/var/lib/puppet]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[main]/File[/var/lib/puppet/ssl]: Autorequiring File[/var/lib/puppet]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[puppetd]/File[/etc/puppet/puppet.conf]: Autorequiring File[/etc/puppet]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[ssl]/File[/var/lib/puppet/ssl/public_keys/client.some.domain.pem]: Autorequiring File[/var/lib/puppet/ssl/public_keys]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[ssl]/File[/var/lib/puppet/ssl/private_keys]: Autorequiring File[/var/lib/puppet/ssl]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[puppetd]/File[/var/lib/puppet/state/state.yaml]: Autorequiring File[/var/lib/puppet/state]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[main]/File[/var/lib/puppet/lib]: Autorequiring File[/var/lib/puppet]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[ssl]/File[/var/lib/puppet/ssl/certs]: Autorequiring File[/var/lib/puppet/ssl]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[ssl]/File[/var/lib/puppet/ssl/certs/client.some.domain.pem]: Autorequiring File[/var/lib/puppet/ssl/certs]
debug: /Settings[/etc/puppet/puppet.conf]/Settings[puppetd]/File[/var/lib/puppet/state/state.yaml]: Changing mode
debug: /Settings[/etc/puppet/puppet.conf]/Settings[puppetd]/File[/var/lib/puppet/state/state.yaml]: 1 change(s)
debug: /Settings[/etc/puppet/puppet.conf]/Settings[puppetd]/File[/var/lib/puppet/state/state.yaml]/mode: mode changed '640' to '660'
debug: Finishing transaction -604799222 with 1 changes
debug: Loaded state in 0.00 seconds
debug: Retrieved facts in 0.51 seconds
notice: Ignoring cache
debug: Retrieving catalog
debug: Calling puppetmaster.getconfig
debug: Retrieved catalog in 0.74 seconds
debug: Creating default schedules
debug: Finishing transaction -605752656 with 0 changes
info: Caching catalog at /var/lib/puppet/localconfig.yaml
notice: Starting catalog run
debug: Loaded state in 0.00 seconds
debug: Prefetching parsed resources for mount
debug: /:main/Node[client.some.domain]/Lvmconfig[puppet]/Exec[lvcreate-vg00-lvpuppet]/subscribe: subscribes to File[/tmp/puppet]
debug: /:main/Node[client.some.domain]/Lvmconfig[puppet]/Mount[/tmp/puppet]/require: requires Exec[lvcreate-vg00-lvpuppet]
debug: /:main/Node[client.some.domain]/Lvmconfig[puppet]/Mount[/tmp/puppet]/require: requires File[/tmp/puppet]
debug: /:main/Node[client.some.domain]/Lvmconfig[puppet]/File[/tmp/puppet]: File does not exist
debug: /:main/Node[client.some.domain]/Lvmconfig[puppet]/File[/tmp/puppet]: Changing ensure
debug: /:main/Node[client.some.domain]/Lvmconfig[puppet]/File[/tmp/puppet]: 1 change(s)
notice: /:main/Node[client.some.domain]/Lvmconfig[puppet]/File[/tmp/puppet]/ensure: created
info: /:main/Node[client.some.domain]/Lvmconfig[puppet]/File[/tmp/puppet]: Scheduling refresh of Exec[lvcreate-vg00-lvpuppet]
debug: /:main/Node[client.some.domain]/Lvmconfig[puppet]/Exec[lvcreate-vg00-lvpuppet]: Executing check 'lvs | grep -q 'lvpuppet.*vg00''
debug: Executing 'lvs | grep -q 'lvpuppet.*vg00''
/usr/lib/site_ruby/1.8/puppet/util.rb:312: warning: fork terminates thread at /usr/lib/ruby/1.8/timeout.rb:41
debug: /:main/Node[client.some.domain]/Lvmconfig[puppet]/Exec[lvcreate-vg00-lvpuppet]: Changing returns
debug: /:main/Node[client.some.domain]/Lvmconfig[puppet]/Exec[lvcreate-vg00-lvpuppet]: 1 change(s)
debug: /:main/Node[client.some.domain]/Lvmconfig[puppet]/Exec[lvcreate-vg00-lvpuppet]: Executing 'lvcreate -n lvpuppet -L 1M /dev/vg00 && mkfs -t ext3 /dev/vg00/lvpuppet'
debug: Executing 'lvcreate -n lvpuppet -L 1M /dev/vg00 && mkfs -t ext3 /dev/vg00/lvpuppet'
/usr/lib/site_ruby/1.8/puppet/util.rb:312: warning: fork terminates thread at /usr/lib/ruby/1.8/timeout.rb:41
notice: /:main/Node[client.some.domain]/Lvmconfig[puppet]/Exec[lvcreate-vg00-lvpuppet]/returns: executed successfully
notice: /:main/Node[client.some.domain]/Lvmconfig[puppet]/Exec[lvcreate-vg00-lvpuppet]: Triggering 'refresh' from 1 dependencies
debug: /:main/Node[client.some.domain]/Lvmconfig[puppet]/Exec[lvcreate-vg00-lvpuppet]: Executing check 'lvs | grep -q 'lvpuppet.*vg00''
debug: Executing 'lvs | grep -q 'lvpuppet.*vg00''
/usr/lib/site_ruby/1.8/puppet/util.rb:312: warning: fork terminates thread at /usr/lib/ruby/1.8/timeout.rb:41
debug: /:main/Node[client.some.domain]/Lvmconfig[puppet]/Mount[/tmp/puppet]: Changing ensure
debug: /:main/Node[client.some.domain]/Lvmconfig[puppet]/Mount[/tmp/puppet]: 1 change(s)
debug: Puppet::Type::Mount::ProviderParsed: Executing '/bin/mount'
debug: Puppet::Type::Mount::ProviderParsed: Executing '/bin/mount'
debug: Flushing mount provider target /etc/fstab
debug: Puppet::Type::Mount::ProviderParsed: Executing '/bin/mount -o defaults /tmp/puppet'
notice: /:main/Node[client.some.domain]/Lvmconfig[puppet]/Mount[/tmp/puppet]/ensure: defined 'ensure' as 'mounted'
notice: /:main/Node[client.some.domain]/Lvmconfig[puppet]/Mount[/tmp/puppet]: Refreshing self
debug: Puppet::Type::Mount::ProviderParsed: Executing '/bin/mount'
info: Mount[/tmp/puppet](provider=parsed): Remounting
debug: Puppet::Type::Mount::ProviderParsed: Executing '/bin/mount -o remount /tmp/puppet'
debug: Finishing transaction -605841046 with 3 changes
debug: Storing state
debug: Stored state in 0.06 seconds
notice: Finished catalog run in 2.14 seconds
This shows that everything has worked as required
[root@client puppet]# grep /tmp/puppet /etc/fstab
/dev/vg00/lvpuppet /tmp/puppet ext3 defaults 0 1
[root@client puppet]# lvs | grep puppet
/dev/cdrom: open failed: No medium found
lvpuppet vg00 -wi-ao 32.00M
[root@client puppet]# mount | grep puppet
/dev/mapper/vg00-lvpuppet on /tmp/puppet type ext3 (rw)
Might this be a useful recipe to put on the wiki?
Simon
> # for the moment you MUST include the lvname, it doesn't take $name by default
I'm still puzzled on this part. If you replace every instance of $lvname
or ${lvname} with ${name}, what part of the definition fails?
--
Mike Renfro / R&D Engineer, Center for Manufacturing Research,
931 372-3601 / Tennessee Technological University -- ren...@tntech.edu
On Thursday 29 May 2008, Mike Renfro wrote:
> Simon J Mudd wrote:
> > # for the moment you MUST include the lvname, it doesn't take $name by
> > default
>
> I'm still puzzled on this part. If you replace every instance of $lvname
> or ${lvname} with ${name}, what part of the definition fails?
I'd guess the problem is the case when you have "/dev/VG0/LV0"
and "/dev/VG1/LV0" which both have $lvname=LV0
I would suggest using the complete device path as $name and split it within
the define into it's components.
Regards, DavidS
- --
The primary freedom of open source is not the freedom from cost, but the free-
dom to shape software to do what you want. This freedom is /never/ exercised
without cost, but is available /at all/ only by accepting the very different
costs associated with open source, costs not in money, but in time and effort.
- -- http://www.schierer.org/~luke/log/20070710-1129/on-forks-and-forking
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFIPsKv/Pp1N6Uzh0URAj5YAJ9qrOe+h0UJf8sUBYuSsEnq51hVEACfW/nS
L40zt6bU6/38FWoYkX1inj8=
=t4uD
-----END PGP SIGNATURE-----
On Thu, 29 May 2008 09:42:55 Mike Renfro wrote:
> > Simon J Mudd wrote:
> > # for the moment you MUST include the lvname, it doesn't take $name by default
> I'm still puzzled on this part. If you replace every instance of $lvname
> or ${lvname} with ${name}, what part of the definition fails?
Possibly a misunderstanding of what I am doing and that initially
as you point out I was probably doing something wrong (defining $name explicitly).
I want to mount a logical volume /dev/<vgname>/<lvname> under /some/<name>.
<lvname> and <name> aren't necessarily the same. I want the freedom to
be able to define the mount point as needed and also the volume group
and logical volume names too, even though I'd like the puppet recipe to
come up with a sane default of the lvname.
That's why the names are different. However it probably true as mentioned
by David Schmitt that to ensure all names are unique it might be better
to make $name == "/some/<mount_point>" (the complete mount point) and
use that instead. I don't actually use what I $location on its own anywhere.
If I do this I'd have something like:
# Manage a partition and create if needed.
# The name given to this resource MUST BE the mount point, such as "/tmp/puppet"
define lvmconfig (
$lvsize = "1G", # Size of the logical volume as understood by lvcreate(8)
$fstype = "ext3", # Filesystem type as understood by mkfs(8)
$vgname = "vg00", # Name of volume group
$lvname = "XXXXX", # Name of logical volume
$owner = "root",
$group = "root",
$mode = "755" ) {
file { "${name}":
ensure => directory,
owner => $owner,
group => $group,
mode => $mode,
}
exec { "lvcreate-${vgname}-${lvname}":
path => [ "/sbin", "/bin", "/usr/sbin", "/usr/bin" ],
logoutput => false,
command => "lvcreate -n ${lvname} -L ${lvsize} /dev/${vgname} && mkfs -t ${fstype} /dev/${vgname}/${lvname}",
unless => "lvs | grep -q '${lvname}.*${vgname}'",
subscribe => File[ "$name" ],
}
mount { "${name}":
atboot => true,
device => "/dev/$vgname/$lvname",
ensure => mounted,
fstype => "${fstype}",
options => "defaults",
dump => "0",
pass => "1",
require => [ Exec["lvcreate-${vgname}-${lvname}"], File["${name}"] ],
}
}
...
node "some.client" {
lvmconfig { "/tmp/puppet":
lvname => "lvpuppet",
lvsize => "1M",
fstype => "ext3",
vgname => "vg00",
}
}
This leaves me with 2 questions:
- Can I ensure that $name (the mount point) starts with "/"?
- Can I prefill $lvname (if not defined) to use a shell equivalent
of $(basename $name)?
Thanks. I think this is close now to a useful recipe, unless you or
David can see other problems.
Simon
A few months ago I created a "filesystem" and "lv" types, together with
"mkfs" and "lvm2" providers for them, respecively. They do the basic
things I need, but I still consider them to be somewhere in the alpha
stage in terms of quality.
I do want to submit them to the main codebase, but no sooner than I get
the unit/integration tests running on my platform, submit another type
that I wrote (aptrepo) and write proper tests for them.
Still, I'm attaching them just in case someone will find them useful
and/or has more time to improve and integrate them properly.
--
Marcin Owsiany <mar...@owsiany.pl> http://marcin.owsiany.pl/
GnuPG: 1024D/60F41216 FE67 DA2D 0ACA FC5E 3F75 D6F6 3A0D 8AA0 60F4 1216
"Every program in development at MIT expands until it can read mail."
-- Unknown