summaryrefslogtreecommitdiffstats
path: root/manifests
diff options
context:
space:
mode:
authorJames Shubin <james@shubin.ca>2014-01-21 05:02:58 -0500
committerJames Shubin <james@shubin.ca>2014-01-21 10:46:34 -0500
commit51fea724f4b606326489636a0ffb7e9673600f9b (patch)
tree5d9fc128b49fc08316b72416c6b36fc7d8e9ab98 /manifests
parentbee4993d4304730da27424dbdc73819b99d8ab5b (diff)
downloadpuppet-gluster-51fea724f4b606326489636a0ffb7e9673600f9b.tar.gz
puppet-gluster-51fea724f4b606326489636a0ffb7e9673600f9b.tar.xz
puppet-gluster-51fea724f4b606326489636a0ffb7e9673600f9b.zip
Add client mounting and associated magic.
* Rename gluster::client to gluster::mount * Add support to gluster::mount * Add client machines and mounts to vagrant setup * Fixed version interface for gluster::mount and gluster::server * Improved firewall support for gluster::mount * Update examples to use gluster::mount instead of gluster::client * Update documentation * Other small fixes
Diffstat (limited to 'manifests')
-rw-r--r--manifests/client.pp79
-rw-r--r--manifests/mount.pp171
-rw-r--r--manifests/mount/base.pp (renamed from manifests/client/base.pp)32
-rw-r--r--manifests/repo.pp4
-rw-r--r--manifests/rulewrapper.pp47
-rw-r--r--manifests/server.pp35
-rw-r--r--manifests/volume.pp7
7 files changed, 267 insertions, 108 deletions
diff --git a/manifests/client.pp b/manifests/client.pp
deleted file mode 100644
index 5ffe054..0000000
--- a/manifests/client.pp
+++ /dev/null
@@ -1,79 +0,0 @@
-# GlusterFS 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/>.
-
-# XXX: try mounting with: glusterfs --volfile-server=<server-address> --volfile-id=<volume-name> <mount-point> --xlator-option='*dht*.assert-no-child-down=yes' # TODO: quotes or not?
-define gluster::client(
- $server, # NOTE: use a vip as server hostname
- $rw = false, # mount read only (true) or rw (false)
-# $suid = false, # mount with suid (true) or nosuid (false) # TODO: will this work with gluster ?
- $mounted = true # useful if we want to pull in the group
- # defs, but not actually mount (testing)
-) {
- #mount -t glusterfs brick1.example.com:/test /test
- include gluster::client::base
-
- $rw_bool = $rw ? {
- true => 'rw',
- default => 'ro',
- }
-
- # TODO: will this work with gluster ?
- #$suid_bool = $suid ? {
- # true => 'suid',
- # default => 'nosuid',
- #}
-
- $mounted_bool = $mounted ? {
- true => mounted,
- default => unmounted,
- }
-
- # make an empty directory for the mount point
- file { "${name}":
- 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
- }
-
- # Mount Options:
- # * backupvolfile-server=server-name
- # * fetch-attempts=N (where N is number of attempts)
- # * log-level=loglevel
- # * log-file=logfile
- # * direct-io-mode=[enable|disable]
- # * ro (for readonly mounts)
- # * acl (for enabling posix-ACLs)
- # * worm (making the mount WORM - Write Once, Read Many type)
- # * selinux (enable selinux on GlusterFS mount
- mount { "${name}":
- atboot => true,
- ensure => $mounted_bool,
- device => "${server}",
- fstype => 'glusterfs',
- options => "defaults,_netdev,${rw_bool}", # TODO: will $suid_bool work with gluster ?
- dump => '0', # fs_freq: 0 to skip file system dumps
- pass => '0', # fs_passno: 0 to skip fsck on boot
- require => [
- Package[['glusterfs', 'glusterfs-fuse']],
- File["${name}"], # the mountpoint
- Exec['gluster-fuse'], # ensure fuse is loaded
- ],
- }
-}
-
-# vim: ts=8
diff --git a/manifests/mount.pp b/manifests/mount.pp
new file mode 100644
index 0000000..27b6baa
--- /dev/null
+++ b/manifests/mount.pp
@@ -0,0 +1,171 @@
+# GlusterFS 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/>.
+
+# XXX: try mounting with: glusterfs --volfile-server=<server-address> --volfile-id=<volume-name> <mount-point> --xlator-option='*dht*.assert-no-child-down=yes' # TODO: quotes or not?
+define gluster::mount(
+ $server, # NOTE: use a vip as server hostname
+ $rw = false, # mount read only (true) or rw (false)
+# $suid = false, # mount with suid (true) or nosuid (false) # TODO: will this work with gluster ?
+ $mounted = true, # useful if we want to pull in the group
+ # defs, but not actually mount (testing)
+ $repo = true, # add a repo automatically? true or false
+ $version = '', # pick a specific version (defaults to latest)
+ $ip = '', # you can specify which ip address to use (if multiple)
+ $shorewall = false
+) {
+ #mount -t glusterfs brick1.example.com:/test /test
+ #include gluster::mount::base
+ #class { '::gluster::mount::base':
+ # repo => $repo,
+ # version => $version,
+ #}
+ $params = {
+ 'repo' => $repo,
+ 'version' => $version,
+ }
+ # because multiple gluster::mount types are allowed on the same server,
+ # we include with the ensure_resource function to avoid identical calls
+ ensure_resource('class', '::gluster::mount::base', $params)
+
+ # eg: vip:/volume
+ $split = split($server, ':') # do some $server parsing
+ $host = $split[0] # host fqdn or ip (eg: vip)
+ # NOTE: technically $path should be everything BUT split[0]. This
+ # lets our $path include colons if for some reason they're needed.
+ #$path = $split[1] # volume
+ # TODO: create substring function
+ $path = inline_template("<%= '${server}'.slice('${host}'.length+1, '${server}'.length-'${host}'.length-1) %>")
+ $short_path = sprintf("%s", regsubst($path, '\/$', '')) # no trailing
+ #$valid_path = sprintf("%s/", regsubst($path, '\/$', ''))
+ $volume = sprintf("%s", regsubst($short_path, '^\/', '')) # no leading
+
+ if ! ( "${host}:${path}" == "${server}" ) {
+ fail('The $server must match a $host:$path pattern.')
+ }
+
+ if ! ( "${host}:/${volume}" == "${server}" ) {
+ fail('The $server must match a $host:/$volume pattern.')
+ }
+
+ $short_name = sprintf("%s", regsubst("${name}", '\/$', '')) # no trailing
+ $long_name = sprintf("%s/", regsubst("${name}", '\/$', '')) # trailing...
+
+ $valid_ip = "${ip}" ? {
+ '' => "${::gluster_host_ip}" ? { # smart fact...
+ '' => "${::ipaddress}", # puppet picks!
+ default => "${::gluster_host_ip}", # smart
+ },
+ default => "${ip}", # user selected
+ }
+ if "${valid_ip}" == '' {
+ fail('No valid IP exists!')
+ }
+
+ if $shorewall {
+ $safename = regsubst("${name}", '/', '_', 'G') # make /'s safe
+ @@shorewall::rule { "glusterd-management-${fqdn}-${safename}":
+ #@@shorewall::rule { "glusterd-management-${volume}-${fqdn}":
+ action => 'ACCEPT',
+ source => '', # override this on collect...
+ source_ips => ["${valid_ip}"],
+ dest => '$FW',
+ proto => 'tcp',
+ port => '24007',
+ comment => 'Allow incoming tcp:24007 from each glusterd.',
+ tag => 'gluster_firewall_management',
+ ensure => present,
+ }
+
+ # wrap shorewall::rule in a fake type so that we can add $match
+ #@@shorewall::rule { "gluster-volume-${fqdn}-${safename}":
+ @@gluster::rulewrapper { "gluster-volume-${fqdn}-${safename}":
+ action => 'ACCEPT',
+ source => '', # override this on collect...
+ source_ips => ["${valid_ip}"],
+ dest => '$FW',
+ proto => 'tcp',
+ port => '', # override this on collect...
+ #comment => "${fqdn}",
+ comment => 'Allow incoming tcp port from glusterfsds.',
+ tag => 'gluster_firewall_volume',
+ match => "${volume}", # used for collection
+ ensure => present,
+ }
+ }
+
+ $rw_bool = $rw ? {
+ true => 'rw',
+ default => 'ro',
+ }
+
+ # TODO: will this work with gluster ?
+ #$suid_bool = $suid ? {
+ # true => 'suid',
+ # default => 'nosuid',
+ #}
+
+ $mounted_bool = $mounted ? {
+ false => unmounted,
+ default => mounted,
+ }
+
+ # ensure parent directories exist
+ exec { "gluster-mount-mkdir-${name}":
+ command => "/bin/mkdir -p '${long_name}'",
+ creates => "${long_name}",
+ logoutput => on_failure,
+ before => File["${long_name}"],
+ }
+
+ # make an empty directory for the mount point
+ file { "${long_name}": # ensure a trailing slash
+ 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
+ alias => "${short_name}", # don't allow duplicates name's
+ }
+
+ # Mount Options:
+ # * backupvolfile-server=server-name
+ # * fetch-attempts=N (where N is number of attempts)
+ # * log-level=loglevel
+ # * log-file=logfile
+ # * direct-io-mode=[enable|disable]
+ # * ro (for readonly mounts)
+ # * acl (for enabling posix-ACLs)
+ # * worm (making the mount WORM - Write Once, Read Many type)
+ # * selinux (enable selinux on GlusterFS mount)
+ # XXX: consider mounting only if some exported resource, collected and turned into a fact shows that the volume is available...
+ # XXX: or something... consider adding the notify => Poke[] functionality
+ mount { "${short_name}":
+ atboot => true,
+ ensure => $mounted_bool,
+ device => "${server}",
+ fstype => 'glusterfs',
+ options => "defaults,_netdev,${rw_bool}", # TODO: will $suid_bool work with gluster ?
+ dump => '0', # fs_freq: 0 to skip file system dumps
+ pass => '0', # fs_passno: 0 to skip fsck on boot
+ require => [
+ Package[['glusterfs', 'glusterfs-fuse']],
+ File["${long_name}"], # the mountpoint
+ Exec['gluster-fuse'], # ensure fuse is loaded!
+ ],
+ }
+}
+
+# vim: ts=8
diff --git a/manifests/client/base.pp b/manifests/mount/base.pp
index 9ec232b..441ebe5 100644
--- a/manifests/client/base.pp
+++ b/manifests/mount/base.pp
@@ -15,10 +15,36 @@
# 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/>.
-class gluster::client::base {
- # TODO: ensure these are from our 'gluster' repo
+class gluster::mount::base(
+ $repo = true, # add a repo automatically? true or false
+ $version = '' # pick a specific version (defaults to latest)
+) {
+ include gluster::vardir
+ #$vardir = $::gluster::vardir::module_vardir # with trailing slash
+ $vardir = regsubst($::gluster::vardir::module_vardir, '\/$', '')
+
+ # if we use ::mount and ::server on the same machine, this could clash,
+ # so we use the ensure_resource function to allow identical duplicates!
+ $rname = "${version}" ? {
+ '' => 'gluster',
+ default => "gluster-${version}",
+ }
+ if $repo {
+ $params = {
+ 'version' => "${version}",
+ }
+ ensure_resource('gluster::repo', "${rname}", $params)
+ }
+
package { ['glusterfs', 'glusterfs-fuse']:
- ensure => present,
+ ensure => "${version}" ? {
+ '' => present,
+ default => "${version}",
+ },
+ require => $repo ? {
+ false => undef,
+ default => Gluster::Repo["${rname}"],
+ },
}
# FIXME: choose a reliable and correct way to ensure fuse is loaded
diff --git a/manifests/repo.pp b/manifests/repo.pp
index ca5cecf..3c45ee0 100644
--- a/manifests/repo.pp
+++ b/manifests/repo.pp
@@ -15,7 +15,7 @@
# 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/>.
-class gluster::repo(
+define gluster::repo(
# if you specify 'x.y', it will find the latest x.y.*
# if you specify 'x.y.z', it will stick to that version
# anything omitted is taken to mean "latest"
@@ -96,7 +96,7 @@ class gluster::repo(
include ::yum
#yum::repos::repo { "gluster-${arch}":
- yum::repos::repo { 'gluster':
+ yum::repos::repo { "${name}":
baseurl => "${base_arch}${arch}/",
enabled => true,
gpgcheck => true,
diff --git a/manifests/rulewrapper.pp b/manifests/rulewrapper.pp
new file mode 100644
index 0000000..4ac6419
--- /dev/null
+++ b/manifests/rulewrapper.pp
@@ -0,0 +1,47 @@
+# GlusterFS module by James
+# Copyright (C) 2012-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/>.
+
+# NOTE: this wraps shorewall::rule so that we can add on additional fake 'tags'
+define gluster::rulewrapper(
+ $action = '',
+ $source = '',
+ $source_ips = [],
+ $dest = '',
+ $dest_ips = [],
+ $proto = '',
+ $port = [],
+ $sport = [],
+ $original = [],
+ $comment = '',
+ $ensure = present,
+ $match = '' # additional tag parameter
+) {
+ shorewall::rule { "${name}":
+ action => "${action}",
+ source => "${source}",
+ source_ips => $source_ips,
+ dest => "${dest}",
+ dest_ips => $dest_ips,
+ proto => "${proto}",
+ port => $port,
+ sport => $sport,
+ comment => "${comment}",
+ ensure => $ensure,
+ }
+}
+
+# vim: ts=8
diff --git a/manifests/server.pp b/manifests/server.pp
index 158f873..247f4d4 100644
--- a/manifests/server.pp
+++ b/manifests/server.pp
@@ -29,30 +29,17 @@ class gluster::server(
) {
$FW = '$FW' # make using $FW in shorewall easier
- # $gluster_package_version is a fact; commonly set by vagrant
- if "${version}" == '' and "${gluster_package_version}" == '' {
- $valid_version = ''
- } else {
- if "${version}" != '' and "${gluster_package_version}" != '' {
- warning('Requested GlusterFS version specified twice!')
- if "${version}" != "${gluster_package_version}" {
- fail('Requested GlusterFS version mismatch!')
- }
- $valid_version = "${version}"
- } elsif "${version}" != '' {
- $valid_version = "${version}"
- } elsif "${gluster_package_version}" != '' {
- $valid_version = "${gluster_package_version}"
- } else {
- fail('Programming error!')
- }
+ # if we use ::mount and ::server on the same machine, this could clash,
+ # so we use the ensure_resource function to allow identical duplicates!
+ $rname = "${version}" ? {
+ '' => 'gluster',
+ default => "gluster-${version}",
}
-
- # ensure these are from a gluster repo
if $repo {
- class { '::gluster::repo':
- version => "${valid_version}",
+ $params = {
+ 'version' => "${version}",
}
+ ensure_resource('gluster::repo', "${rname}", $params)
}
package { 'moreutils': # for scripts needing: 'sponge'
@@ -61,13 +48,13 @@ class gluster::server(
}
package { 'glusterfs-server':
- ensure => "${valid_version}" ? {
+ ensure => "${version}" ? {
'' => present,
- default => "${valid_version}",
+ default => "${version}",
},
require => $repo ? {
false => undef,
- default => Class['::gluster::repo'],
+ default => Gluster::Repo["${rname}"],
},
}
diff --git a/manifests/volume.pp b/manifests/volume.pp
index 01ef8c5..513a431 100644
--- a/manifests/volume.pp
+++ b/manifests/volume.pp
@@ -346,6 +346,13 @@ define gluster::volume(
source => "${zone}", # use our source zone
before => Service['glusterd'],
}
+
+ Gluster::Rulewrapper <<| tag == 'gluster_firewall_volume' and match == "${name}" |>> {
+ #Shorewall::Rule <<| tag == 'gluster_firewall_volume' and match == "${name}" |>> {
+ source => "${zone}", # use our source zone
+ port => "${port}", # comma separated string or list
+ before => Service['glusterd'],
+ }
}
# fsm variables and boilerplate