summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Shubin <james@shubin.ca>2013-09-08 01:28:39 -0400
committerJames Shubin <james@shubin.ca>2013-09-08 01:28:39 -0400
commit24844a892c07001bb50eeb443005d3c2fe5d4025 (patch)
tree2791e5ff324488afa2cc18860a6c71fefc404765
parent7c2dc0cadc03bc5dd2da3155e5773ad4471563df (diff)
downloadpuppet-gluster-24844a892c07001bb50eeb443005d3c2fe5d4025.tar.gz
puppet-gluster-24844a892c07001bb50eeb443005d3c2fe5d4025.tar.xz
puppet-gluster-24844a892c07001bb50eeb443005d3c2fe5d4025.zip
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!
-rw-r--r--examples/distributed-replicate-example.pp3
-rw-r--r--examples/filesystem-backed-bricks-example.pp4
-rw-r--r--lib/facter/gluster_uuid.rb122
-rw-r--r--manifests/host.pp152
-rw-r--r--templates/glusterd.info.erb2
5 files changed, 227 insertions, 56 deletions
diff --git a/examples/distributed-replicate-example.pp b/examples/distributed-replicate-example.pp
index 8543d7e..20cfb7e 100644
--- a/examples/distributed-replicate-example.pp
+++ b/examples/distributed-replicate-example.pp
@@ -23,7 +23,8 @@ class gluster_base {
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':
diff --git a/examples/filesystem-backed-bricks-example.pp b/examples/filesystem-backed-bricks-example.pp
index 461283c..e87f777 100644
--- a/examples/filesystem-backed-bricks-example.pp
+++ b/examples/filesystem-backed-bricks-example.pp
@@ -25,7 +25,9 @@ class gluster_base {
}
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':
diff --git a/lib/facter/gluster_uuid.rb b/lib/facter/gluster_uuid.rb
new file mode 100644
index 0000000..f163195
--- /dev/null
+++ b/lib/facter/gluster_uuid.rb
@@ -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
+
diff --git a/manifests/host.pp b/manifests/host.pp
index 9a31f97..7bd461d 100644
--- a/manifests/host.pp
+++ b/manifests/host.pp
@@ -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',
+ }
}
}
}
diff --git a/templates/glusterd.info.erb b/templates/glusterd.info.erb
index fe849ba..512f6e1 100644
--- a/templates/glusterd.info.erb
+++ b/templates/glusterd.info.erb
@@ -1 +1 @@
-UUID=<%= uuid %>
+UUID=<%= valid_uuid %>