Permalink
Browse files

This patch adds fact magic to make specifying host uuid's optional.

If you would like to be ultra lazy and not specify any uuid's manually,
the puppet module can now generate them on your behalf. This will take
at least two puppet runs because of the distributed nature of gluster
and because the uuid facts must be exported to all the nodes for
peering.

Please note that if you rebuild a node from scratch, you probably won't
get the same UUID. You can either set it manually, or paste one in the
/var/lib/puppet/tmp/gluster/uuid/uuid file. Watch the formatting!
  • Loading branch information...
purpleidea committed Sep 8, 2013
1 parent 7c2dc0c commit 24844a892c07001bb50eeb443005d3c2fe5d4025
@@ -23,7 +23,8 @@
gluster::host { 'annex1.example.com':
# use uuidgen to make these
uuid => '1f660ca2-2c78-4aa0-8f4d-21608218c69c',
# NOTE: specifying a host uuid is optional and can be automatic
#uuid => '1f660ca2-2c78-4aa0-8f4d-21608218c69c',
}
gluster::brick { 'annex1.example.com:/mnt/storage1a':
@@ -25,7 +25,9 @@
}
gluster::host { 'annex2.example.com':
uuid => '2fbe6e2f-f6bc-4c2d-a301-62fa90c459f8',
# NOTE: specifying a host uuid is now optional!
# if you don't choose one, one will be assigned
#uuid => '2fbe6e2f-f6bc-4c2d-a301-62fa90c459f8',
}
gluster::brick { 'annex2.example.com:/data/gluster-storage2':
View
@@ -0,0 +1,122 @@
# Simple? gluster module by James
# Copyright (C) 2010-2013+ James Shubin
# Written by James Shubin <james@shubin.ca>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
require 'facter'
# TODO: the ruby uuid method can be used when newer ruby versions are used here
# require 'securerandom'
# SecureRandom.uuid
# uuid regexp
regexp = /^[a-f0-9]{8}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{4}\-[a-f0-9]{12}$/
# find the module_vardir
dir = Facter.value('puppet_vardirtmp') # nil if missing
if dir.nil? # let puppet decide if present!
dir = Facter.value('puppet_vardir')
if dir.nil?
var = nil
else
var = dir.gsub(/\/$/, '')+'/'+'tmp/' # ensure trailing slash
end
else
var = dir.gsub(/\/$/, '')+'/'
end
if var.nil?
# if we can't get a valid vardirtmp, then we can't continue
uuidfile = nil
else
module_vardir = var+'gluster/'
uuiddir = module_vardir+'uuid/' # safe dir that won't get purged...
uuidfile = uuiddir+'uuid'
end
# NOTE: module specific mkdirs, needed to ensure there is no blocking/deadlock!
if not File.directory?(var)
Dir::mkdir(var)
end
if not File.directory?(module_vardir)
Dir::mkdir(module_vardir)
end
if not File.directory?(uuiddir)
Dir::mkdir(uuiddir)
end
# generate uuid and parent directory if they don't already exist...
if not(uuidfile.nil?) and File.directory?(module_vardir)
if not File.directory?(uuiddir)
Dir::mkdir(uuiddir)
end
# create a uuid and store it in our vardir if it doesn't already exist!
if File.directory?(uuiddir) and (not File.exist?(uuidfile))
result = system("/usr/bin/uuidgen > '" + uuidfile + "'")
if not(result):
# TODO: print warning
end
end
end
# create the fact if the uuid file contains a valid uuid
if File.exist?(uuidfile)
uuid = File.open(uuidfile, 'r').read.strip.downcase # read into str
# skip over uuid's of the wrong length or that don't match (security!!)
if uuid.length == 36 and regexp.match(uuid)
Facter.add('gluster_uuid') do
#confine :operatingsystem => %w{CentOS, RedHat, Fedora}
setcode {
# don't reuse uuid variable to avoid bug #:
# http://projects.puppetlabs.com/issues/22455
uuid
}
end
# TODO: print warning on else...
end
end
# create facts from externally collected uuid files
_uuid = ''
found = {}
prefix = 'uuid_'
if File.directory?(uuiddir)
Dir.glob(uuiddir+prefix+'*').each do |f|
b = File.basename(f)
# strip off leading prefix
fqdn = b[prefix.length, b.length-prefix.length]
_uuid = File.open(f, 'r').read.strip.downcase # read into str
if _uuid.length == 36 and regexp.match(_uuid)
# avoid: http://projects.puppetlabs.com/issues/22455
found[fqdn] = _uuid
# TODO: print warning on else...
end
end
end
found.keys.each do |x|
Facter.add('gluster_uuid_'+x) do
#confine :operatingsystem => %w{CentOS, RedHat, Fedora}
setcode {
found[x]
}
end
end
View
@@ -20,69 +20,115 @@
# only the host holding the vip is allowed to execute cluster peer operations.
define gluster::host(
$uuid
$uuid = '' # if empty, puppet will attempt to use the gluster fact
) {
include gluster::vardir
#$vardir = $::gluster::vardir::module_vardir # with trailing slash
$vardir = regsubst($::gluster::vardir::module_vardir, '\/$', '')
# if we're on itself
if ( "${fqdn}" == "${name}" ) {
# set a unique uuid per host
file { '/var/lib/glusterd/glusterd.info':
content => template('gluster/glusterd.info.erb'),
owner => root,
group => root,
mode => 600, # u=rw,go=r
seltype => 'glusterd_var_lib_t',
seluser => 'unconfined_u',
ensure => present,
require => File['/var/lib/glusterd/'],
# don't purge the uuid file generated within
file { "${vardir}/uuid/":
ensure => directory, # make sure this is a directory
recurse => false, # don't recurse into directory
purge => false, # don't purge unmanaged files
force => false, # don't purge subdirs and links
require => File["${vardir}/"],
}
} else {
# set uuid=
exec { "/bin/echo 'uuid=${uuid}' >> '/var/lib/glusterd/peers/${uuid}'":
logoutput => on_failure,
unless => "/bin/grep -qF 'uuid=' '/var/lib/glusterd/peers/${uuid}'",
notify => File['/var/lib/glusterd/peers/'], # propagate the notify up
before => File["/var/lib/glusterd/peers/${uuid}"],
alias => "gluster-host-uuid-${name}",
# FIXME: doing this causes a dependency cycle! adding
# the Package[] require doesn't. It would be most
# correct to require the peers/ folder, but since it's
# not working, requiring the Package[] will still give
# us the same result. (Package creates peers/ folder).
# NOTE: it's possible the cycle is a bug in puppet or a
# bug in the dependencies somewhere else in this module.
#require => File['/var/lib/glusterd/peers/'],
require => Package['glusterfs-server'],
$valid_uuid = "${uuid}" ? {
# fact from the data generated in: ${vardir}/uuid/uuid
'' => "${::gluster_uuid}",
default => "${uuid}",
}
if "${valid_uuid}" == '' {
fail('No valid UUID exists yet!')
} else {
# set a unique uuid per host
file { '/var/lib/glusterd/glusterd.info':
content => template('gluster/glusterd.info.erb'),
owner => root,
group => root,
mode => 600, # u=rw,go=r
seltype => 'glusterd_var_lib_t',
seluser => 'unconfined_u',
ensure => present,
require => File['/var/lib/glusterd/'],
}
# set state=
exec { "/bin/echo 'state=3' >> '/var/lib/glusterd/peers/${uuid}'":
logoutput => on_failure,
unless => "/bin/grep -qF 'state=' '/var/lib/glusterd/peers/${uuid}'",
notify => File['/var/lib/glusterd/peers/'], # propagate the notify up
before => File["/var/lib/glusterd/peers/${uuid}"],
require => Exec["gluster-host-uuid-${name}"],
alias => "gluster-host-state-${name}",
# NOTE: $name here should probably be the fqdn...
@@file { "${vardir}/uuid/uuid_${name}":
content => "${valid_uuid}\n",
tag => 'gluster_uuid',
owner => root,
group => root,
mode => 600,
ensure => present,
}
}
# set hostname1=...
exec { "/bin/echo 'hostname1=${name}' >> '/var/lib/glusterd/peers/${uuid}'":
logoutput => on_failure,
unless => "/bin/grep -qF 'hostname1=' '/var/lib/glusterd/peers/${uuid}'",
notify => File['/var/lib/glusterd/peers/'], # propagate the notify up
before => File["/var/lib/glusterd/peers/${uuid}"],
require => Exec["gluster-host-state-${name}"],
File <<| tag == 'gluster_uuid' |>> { # collect to make facts
}
# tag the file so it doesn't get removed by purge
file { "/var/lib/glusterd/peers/${uuid}":
ensure => present,
notify => File['/var/lib/glusterd/peers/'], # propagate the notify up
owner => root,
group => root,
# NOTE: this mode was found by inspecting the process
mode => 600, # u=rw,go=r
seltype => 'glusterd_var_lib_t',
seluser => 'unconfined_u',
} else {
$valid_uuid = "${uuid}" ? {
# fact from the data generated in: ${vardir}/uuid/uuid
'' => getvar("gluster_uuid_${name}"), # fact !
default => "${uuid}",
}
if "${valid_uuid}" == '' {
notice('No valid UUID exists yet.') # different msg
} else {
# set uuid=
exec { "/bin/echo 'uuid=${valid_uuid}' >> '/var/lib/glusterd/peers/${valid_uuid}'":
logoutput => on_failure,
unless => "/bin/grep -qF 'uuid=' '/var/lib/glusterd/peers/${valid_uuid}'",
notify => File['/var/lib/glusterd/peers/'], # propagate the notify up
before => File["/var/lib/glusterd/peers/${valid_uuid}"],
alias => "gluster-host-uuid-${name}",
# FIXME: doing this causes a dependency cycle! adding
# the Package[] require doesn't. It would be most
# correct to require the peers/ folder, but since it's
# not working, requiring the Package[] will still give
# us the same result. (Package creates peers/ folder).
# NOTE: it's possible the cycle is a bug in puppet or a
# bug in the dependencies somewhere else in this module.
#require => File['/var/lib/glusterd/peers/'],
require => Package['glusterfs-server'],
}
# set state=
exec { "/bin/echo 'state=3' >> '/var/lib/glusterd/peers/${valid_uuid}'":
logoutput => on_failure,
unless => "/bin/grep -qF 'state=' '/var/lib/glusterd/peers/${valid_uuid}'",
notify => File['/var/lib/glusterd/peers/'], # propagate the notify up
before => File["/var/lib/glusterd/peers/${valid_uuid}"],
require => Exec["gluster-host-uuid-${name}"],
alias => "gluster-host-state-${name}",
}
# set hostname1=...
exec { "/bin/echo 'hostname1=${name}' >> '/var/lib/glusterd/peers/${valid_uuid}'":
logoutput => on_failure,
unless => "/bin/grep -qF 'hostname1=' '/var/lib/glusterd/peers/${valid_uuid}'",
notify => File['/var/lib/glusterd/peers/'], # propagate the notify up
before => File["/var/lib/glusterd/peers/${valid_uuid}"],
require => Exec["gluster-host-state-${name}"],
}
# tag the file so it doesn't get removed by purge
file { "/var/lib/glusterd/peers/${valid_uuid}":
ensure => present,
notify => File['/var/lib/glusterd/peers/'], # propagate the notify up
owner => root,
group => root,
# NOTE: this mode was found by inspecting the process
mode => 600, # u=rw,go=r
seltype => 'glusterd_var_lib_t',
seluser => 'unconfined_u',
}
}
}
}
@@ -1 +1 @@
UUID=<%= uuid %>
UUID=<%= valid_uuid %>

0 comments on commit 24844a8

Please sign in to comment.