diff options
Diffstat (limited to 'extras/hook-scripts')
36 files changed, 1495 insertions, 334 deletions
diff --git a/extras/hook-scripts/Makefile.am b/extras/hook-scripts/Makefile.am index f6bded20cbe..26059d7dbb9 100644 --- a/extras/hook-scripts/Makefile.am +++ b/extras/hook-scripts/Makefile.am @@ -1 +1,7 @@ -EXTRA_DIST = S29CTDBsetup.sh S30samba-start.sh S30samba-stop.sh S30samba-set.sh S56glusterd-geo-rep-create-post.sh +EXTRA_DIST = S40ufo-stop.py S56glusterd-geo-rep-create-post.sh +SUBDIRS = add-brick create delete set start stop reset + +scriptsdir = $(GLUSTERD_WORKDIR)/hooks/1/gsync-create/post/ +if USE_GEOREP +scripts_SCRIPTS = S56glusterd-geo-rep-create-post.sh +endif diff --git a/extras/hook-scripts/S29CTDBsetup.sh b/extras/hook-scripts/S29CTDBsetup.sh deleted file mode 100644 index e256be1f3ea..00000000000 --- a/extras/hook-scripts/S29CTDBsetup.sh +++ /dev/null @@ -1,69 +0,0 @@ -#! /bin/bash -#non-portable - RHS-2.0 only -# - The script mounts the 'meta-vol' on start 'event' on a known -# directory (eg. /gluster/lock) -# - Adds the necessary configuration changes for ctdb in smb.conf and -# restarts smb service. -# - P.S: There are other 'tasks' that need to be done outside this script -# to get CTDB based failover up and running. - -SMB_CONF=/etc/samba/smb.conf - -CTDB_MNT=/gluster/lock -PROGNAME="ctdb" -OPTSPEC="volname:" -VOL= -# $META is the volume that will be used by CTDB as a shared filesystem. -# It is not desirable to use this volume for storing 'data' as well. -# META is set to 'all' (viz. a keyword and hence not a legal volume name) -# to prevent the script from running for volumes it was not intended. -# User needs to set META to the volume that serves CTDB lockfile. -META="all" - -function sighup_samba () { - pid=`cat /var/run/smbd.pid` - if [ $pid != " " ] - then - kill -HUP $pid; - else - /etc/init.d/smb start - fi -} - -function parse_args () { - ARGS=$(getopt -l $OPTSPEC -name $PROGNAME $@) - eval set -- "$ARGS" - - while true; do - case $1 in - --volname) - shift - VOL=$1 - ;; - - *) - shift - break - ;; - - esac - - shift - done -} - -function add_glusterfs_ctdb_options () { - PAT="Share Definitions" - GLUSTER_CTDB_CONFIG="# ctdb config for glusterfs\n\tclustering = yes\n\tidmap backend = tdb2\n\tprivate dir = "$CTDB_MNT"\n" - - sed -i /"$PAT"/i\ "$GLUSTER_CTDB_CONFIG" $SMB_CONF -} - -parse_args $@ -if [ "$META" = "$VOL" ] -then - add_glusterfs_ctdb_options - sighup_samba - mount -t glusterfs `hostname`:$VOL "$CTDB_MNT" & -fi - diff --git a/extras/hook-scripts/S30samba-set.sh b/extras/hook-scripts/S30samba-set.sh deleted file mode 100755 index 33ffca3d741..00000000000 --- a/extras/hook-scripts/S30samba-set.sh +++ /dev/null @@ -1,107 +0,0 @@ -#!/bin/bash - -#Need to be copied to hooks/<HOOKS_VER>/set/post/ - -#TODO: All gluster and samba paths are assumed for fedora like systems. -#Some efforts are required to make it work on other distros. - -#The preferred way of creating a smb share of a gluster volume has changed. -#The old method was to create a fuse mount of the volume and share the mount -#point through samba. -# -#New method eliminates the requirement of fuse mount and changes in fstab. -#glusterfs_vfs plugin for samba makes call to libgfapi to access the volume. -# -#This hook script enables user to enable or disable smb share by volume set -#option. Keys "user.cifs" and "user.smb" both are valid, but user.smb is -#preferred. - - -PROGNAME="Ssamba-set" -OPTSPEC="volname:" -VOL= - -enable_smb="" - -function parse_args () { - ARGS=$(getopt -l $OPTSPEC -o "o" -name $PROGNAME $@) - eval set -- "$ARGS" - - while true; do - case $1 in - --volname) - shift - VOL=$1 - ;; - *) - shift - for pair in $@; do - read key value < <(echo "$pair" | tr "=" " ") - case "$key" in - "user.cifs") - enable_smb=$value - ;; - "user.smb") - enable_smb=$value - ;; - *) - ;; - esac - done - - shift - break - ;; - esac - shift - done -} - -function add_samba_share () { - volname=$1 - STRING="\n[gluster-$volname]\n" - STRING+="comment = For samba share of volume $volname\n" - STRING+="vfs objects = glusterfs\n" - STRING+="glusterfs:volume = $volname\n" - STRING+="path = /\n" - STRING+="read only = no\n" - STRING+="guest ok = yes\n" - printf "$STRING" >> /etc/samba/smb.conf -} - -function sighup_samba () { - pid=`cat /var/run/smbd.pid` - if [ "$pid" != "" ] - then - kill -HUP "$pid"; - else - /etc/init.d/smb start - fi -} - -function del_samba_share () { - volname=$1 - cp /etc/samba/smb.conf /tmp/smb.conf - sed -i "/gluster-$volname/,/^$/d" /tmp/smb.conf &&\ - cp /tmp/smb.conf /etc/samba/smb.conf -} - -function is_volume_started () { - volname=$1 - echo "$(grep status /var/lib/glusterd/vols/"$volname"/info |\ - cut -d"=" -f2)" -} - -parse_args $@ -if [ "0" = $(is_volume_started "$VOL") ]; then - exit 0 -fi - -if [ "$enable_smb" = "enable" ]; then - add_samba_share $VOL - sighup_samba - -elif [ "$enable_smb" = "disable" ]; then - del_samba_share $VOL - sighup_samba -fi diff --git a/extras/hook-scripts/S30samba-start.sh b/extras/hook-scripts/S30samba-start.sh deleted file mode 100755 index 926fe603534..00000000000 --- a/extras/hook-scripts/S30samba-start.sh +++ /dev/null @@ -1,89 +0,0 @@ -#!/bin/bash - -#Need to be copied to hooks/<HOOKS_VER>/start/post - -#TODO: All gluster and samba paths are assumed for fedora like systems. -#Some efforts are required to make it work on other distros. - -#The preferred way of creating a smb share of a gluster volume has changed. -#The old method was to create a fuse mount of the volume and share the mount -#point through samba. -# -#New method eliminates the requirement of fuse mount and changes in fstab. -#glusterfs_vfs plugin for samba makes call to libgfapi to access the volume. -# -#This hook script automagically creates shares for volume on every volume start -#event by adding the entries in smb.conf file and sending SIGHUP to samba. -# -#In smb.conf: -#glusterfs vfs plugin has to be specified as required vfs object. -#Path value is relative to the root of gluster volume;"/" signifies complete -#volume. - -PROGNAME="Ssamba-start" -OPTSPEC="volname:" -VOL= - -function parse_args () { - ARGS=$(getopt -l $OPTSPEC -name $PROGNAME $@) - eval set -- "$ARGS" - - while true; do - case $1 in - --volname) - shift - VOL=$1 - ;; - *) - shift - break - ;; - esac - shift - done -} - -function add_samba_share () { - volname=$1 - STRING="\n[gluster-$volname]\n" - STRING+="comment = For samba share of volume $volname\n" - STRING+="vfs objects = glusterfs\n" - STRING+="glusterfs:volume = $volname\n" - STRING+="path = /\n" - STRING+="read only = no\n" - STRING+="guest ok = yes\n" - printf "$STRING" >> /etc/samba/smb.conf -} - -function sighup_samba () { - pid=`cat /var/run/smbd.pid` - if [ "$pid" != "" ] - then - kill -HUP "$pid"; - else - /etc/init.d/smb condrestart - fi -} - -function get_smb () { - volname=$1 - uservalue= - - usercifsvalue=$(grep user.cifs /var/lib/glusterd/vols/"$volname"/info |\ - cut -d"=" -f2) - usersmbvalue=$(grep user.smb /var/lib/glusterd/vols/"$volname"/info |\ - cut -d"=" -f2) - - if [[ $usercifsvalue = "disable" || $usersmbvalue = "disable" ]]; then - uservalue="disable" - fi - echo "$uservalue" -} - -parse_args $@ -if [ $(get_smb "$VOL") = "disable" ]; then - exit 0 -fi - -add_samba_share $VOL -sighup_samba diff --git a/extras/hook-scripts/S30samba-stop.sh b/extras/hook-scripts/S30samba-stop.sh deleted file mode 100755 index def87e00ed2..00000000000 --- a/extras/hook-scripts/S30samba-stop.sh +++ /dev/null @@ -1,60 +0,0 @@ -#! /bin/bash - -#Need to be copied to hooks/<HOOKS_VER>/stop/pre - -#TODO: All gluster and samba paths are assumed for fedora like systems. -#Some efforts are required to make it work on other distros. - -#The preferred way of creating a smb share of a gluster volume has changed. -#The old method was to create a fuse mount of the volume and share the mount -#point through samba. -# -#New method eliminates the requirement of fuse mount and changes in fstab. -#glusterfs_vfs plugin for samba makes call to libgfapi to access the volume. -# -#This hook script automagically removes shares for volume on every volume stop -#event by removing the volume related entries(if any) in smb.conf file. - -PROGNAME="Ssamba-stop" -OPTSPEC="volname:" -VOL= - -function parse_args () { - ARGS=$(getopt -l $OPTSPEC -name $PROGNAME $@) - eval set -- "$ARGS" - - while true; do - case $1 in - --volname) - shift - VOL=$1 - ;; - *) - shift - break - ;; - esac - shift - done -} - -function del_samba_share () { - volname=$1 - cp /etc/samba/smb.conf /tmp/smb.conf - sed -i "/gluster-$volname/,/^$/d" /tmp/smb.conf &&\ - cp /tmp/smb.conf /etc/samba/smb.conf -} - -function sighup_samba () { - pid=`cat /var/run/smbd.pid` - if [ $pid != "" ] - then - kill -HUP $pid; - else - /etc/init.d/smb condrestart - fi -} - -parse_args $@ -del_samba_share $VOL -sighup_samba diff --git a/extras/hook-scripts/S40ufo-stop.py b/extras/hook-scripts/S40ufo-stop.py index 107f1968355..2c79eb1d54a 100755 --- a/extras/hook-scripts/S40ufo-stop.py +++ b/extras/hook-scripts/S40ufo-stop.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python3 import os from optparse import OptionParser diff --git a/extras/hook-scripts/S56glusterd-geo-rep-create-post.sh b/extras/hook-scripts/S56glusterd-geo-rep-create-post.sh index 71e44b6ed13..7d6052315bb 100755 --- a/extras/hook-scripts/S56glusterd-geo-rep-create-post.sh +++ b/extras/hook-scripts/S56glusterd-geo-rep-create-post.sh @@ -1,8 +1,19 @@ #!/bin/bash -key_val_pair1=`echo $2 | cut -d ' ' -f 1` -key_val_pair2=`echo $2 | cut -d ' ' -f 2` -key_val_pair3=`echo $2 | cut -d ' ' -f 3` +#key_val_pair is the arguments passed to the script in the form of +#key value pair + +key_val_pair1=`echo $2 | cut -d ',' -f 1` +key_val_pair2=`echo $2 | cut -d ',' -f 2` +key_val_pair3=`echo $2 | cut -d ',' -f 3` +key_val_pair4=`echo $2 | cut -d ',' -f 4` +key_val_pair5=`echo $2 | cut -d ',' -f 5` +key_val_pair6=`echo $2 | cut -d ',' -f 6` + +mastervol=`echo $1 | cut -d '=' -f 2` +if [ "$mastervol" == "" ]; then + exit; +fi key=`echo $key_val_pair1 | cut -d '=' -f 1` val=`echo $key_val_pair1 | cut -d '=' -f 2` @@ -21,10 +32,24 @@ fi if [ "$val" == "" ]; then exit; fi + pub_file=`echo $val` +pub_file_bname="$(basename $pub_file)" +pub_file_dname="$(dirname $pub_file)" +pub_file_tmp=`echo $val`_tmp key=`echo $key_val_pair3 | cut -d '=' -f 1` val=`echo $key_val_pair3 | cut -d '=' -f 2` +if [ "$key" != "slave_user" ]; then + exit; +fi +if [ "$val" == "" ]; then + exit; +fi +slave_user=`echo $val` + +key=`echo $key_val_pair4 | cut -d '=' -f 1` +val=`echo $key_val_pair4 | cut -d '=' -f 2` if [ "$key" != "slave_ip" ]; then exit; fi @@ -33,9 +58,47 @@ if [ "$val" == "" ]; then fi slave_ip=`echo $val` +key=`echo $key_val_pair5 | cut -d '=' -f 1` +val=`echo $key_val_pair5 | cut -d '=' -f 2` +if [ "$key" != "slave_vol" ]; then + exit; +fi +if [ "$val" == "" ]; then + exit; +fi +slavevol=`echo $val` + +key=`echo $key_val_pair6 | cut -d '=' -f 1` +val=`echo $key_val_pair6 | cut -d '=' -f 2` +if [ "$key" != "ssh_port" ]; then + exit; +fi +if [ "$val" == "" ]; then + exit; +fi +SSH_PORT=`echo $val` +SSH_OPT="-oPasswordAuthentication=no -oStrictHostKeyChecking=no" + if [ -f $pub_file ]; then - ssh $slave_ip "\rm -rf $pub_file" - scp $pub_file $slave_ip:$pub_file &> /dev/null - ssh $slave_ip "gluster system:: copy file /geo-replication/common_secret.pem.pub > /dev/null" - ssh $slave_ip "gluster system:: execute add_secret_pub > /dev/null" + # For a non-root user copy the pub file to the user's home directory + # For a root user copy the pub files to priv_dir->geo-rep. + if [ "$slave_user" != "root" ]; then + slave_user_home_dir=`ssh -p ${SSH_PORT} ${SSH_OPT} $slave_user@$slave_ip "getent passwd $slave_user | cut -d ':' -f 6"` + scp -P ${SSH_PORT} ${SSH_OPT} $pub_file $slave_user@$slave_ip:$slave_user_home_dir/common_secret.pem.pub_tmp + ssh -p ${SSH_PORT} ${SSH_OPT} $slave_user@$slave_ip "mv $slave_user_home_dir/common_secret.pem.pub_tmp $slave_user_home_dir/${mastervol}_${slavevol}_common_secret.pem.pub" + else + if [[ -z "${GR_SSH_IDENTITY_KEY}" ]]; then + scp -P ${SSH_PORT} ${SSH_OPT} $pub_file $slave_ip:$pub_file_tmp + ssh -p ${SSH_PORT} ${SSH_OPT} $slave_ip "mv $pub_file_tmp ${pub_file_dname}/${mastervol}_${slavevol}_${pub_file_bname}" + ssh -p ${SSH_PORT} ${SSH_OPT} $slave_ip "gluster system:: copy file /geo-replication/${mastervol}_${slavevol}_common_secret.pem.pub > /dev/null" + ssh -p ${SSH_PORT} ${SSH_OPT} $slave_ip "gluster system:: execute add_secret_pub root geo-replication/${mastervol}_${slavevol}_common_secret.pem.pub > /dev/null" + ssh -p ${SSH_PORT} ${SSH_OPT} $slave_ip "gluster vol set ${slavevol} features.read-only on" + else + scp -P ${SSH_PORT} -i ${GR_SSH_IDENTITY_KEY} ${SSH_OPT} $pub_file $slave_ip:$pub_file_tmp + ssh -p ${SSH_PORT} -i ${GR_SSH_IDENTITY_KEY} ${SSH_OPT} $slave_ip "mv $pub_file_tmp ${pub_file_dname}/${mastervol}_${slavevol}_${pub_file_bname}" + ssh -p ${SSH_PORT} -i ${GR_SSH_IDENTITY_KEY} ${SSH_OPT} $slave_ip "gluster system:: copy file /geo-replication/${mastervol}_${slavevol}_common_secret.pem.pub > /dev/null" + ssh -p ${SSH_PORT} -i ${GR_SSH_IDENTITY_KEY} ${SSH_OPT} $slave_ip "gluster system:: execute add_secret_pub root geo-replication/${mastervol}_${slavevol}_common_secret.pem.pub > /dev/null" + ssh -p ${SSH_PORT} -i ${GR_SSH_IDENTITY_KEY} ${SSH_OPT} $slave_ip "gluster vol set ${slavevol} features.read-only on" + fi + fi fi diff --git a/extras/hook-scripts/add-brick/Makefile.am b/extras/hook-scripts/add-brick/Makefile.am new file mode 100644 index 00000000000..6e2701e909e --- /dev/null +++ b/extras/hook-scripts/add-brick/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = post pre +CLEANFILES = diff --git a/extras/hook-scripts/add-brick/post/Makefile.am b/extras/hook-scripts/add-brick/post/Makefile.am new file mode 100644 index 00000000000..9b236df096d --- /dev/null +++ b/extras/hook-scripts/add-brick/post/Makefile.am @@ -0,0 +1,6 @@ +EXTRA_DIST = disabled-quota-root-xattr-heal.sh S10selinux-label-brick.sh S13create-subdir-mounts.sh + +hookdir = $(GLUSTERD_WORKDIR)/hooks/1/add-brick/post/ +if WITH_SERVER +hook_SCRIPTS = disabled-quota-root-xattr-heal.sh S10selinux-label-brick.sh S13create-subdir-mounts.sh +endif diff --git a/extras/hook-scripts/add-brick/post/S10selinux-label-brick.sh b/extras/hook-scripts/add-brick/post/S10selinux-label-brick.sh new file mode 100755 index 00000000000..4a17c993a77 --- /dev/null +++ b/extras/hook-scripts/add-brick/post/S10selinux-label-brick.sh @@ -0,0 +1,100 @@ +#!/bin/bash +# +# Install to hooks/<HOOKS_VER>/add-brick/post +# +# Add an SELinux file context for each brick using the glusterd_brick_t type. +# This ensures that the brick is relabeled correctly on an SELinux restart or +# restore. Subsequently, run a restore on the brick path to set the selinux +# labels. +# +### + +PROGNAME="Sselinux" +OPTSPEC="volname:,version:,gd-workdir:,volume-op:" +VOL= + +parse_args () { + ARGS=$(getopt -o '' -l ${OPTSPEC} -n ${PROGNAME} -- "$@") + eval set -- "${ARGS}" + + while true; do + case ${1} in + --volname) + shift + VOL=${1} + ;; + --gd-workdir) + shift + GLUSTERD_WORKDIR=$1 + ;; + --version) + shift + ;; + --volume-op) + shift + ;; + *) + shift + break + ;; + esac + shift + done +} + +set_brick_labels() +{ + local volname="${1}" + local fctx + local list=() + + fctx="$(semanage fcontext --list -C)" + + # wait for new brick path to be updated under + # ${GLUSTERD_WORKDIR}/vols/${volname}/bricks/ + sleep 5 + + # grab the path for each local brick + brickpath="${GLUSTERD_WORKDIR}/vols/${volname}/bricks/" + brickdirs=$( + find "${brickpath}" -type f -exec grep '^path=' {} \; | \ + cut -d= -f 2 | \ + sort -u + ) + + # create a list of bricks for which custom SELinux + # label doesn't exist + for b in ${brickdirs}; do + pattern="${b}(/.*)?" + echo "${fctx}" | grep "^${pattern}\s" >/dev/null + if [[ $? -ne 0 ]]; then + list+=("${pattern}") + fi + done + + # Add a file context for each brick path in the list and associate with the + # glusterd_brick_t SELinux type. + for p in ${list[@]} + do + semanage fcontext --add -t glusterd_brick_t -r s0 "${p}" + done + + # Set the labels for which SELinux label was added above + for b in ${brickdirs} + do + echo "${list[@]}" | grep "${b}" >/dev/null + if [[ $? -eq 0 ]]; then + restorecon -R "${b}" + fi + done +} + +SELINUX_STATE=$(which getenforce && getenforce) +[ "${SELINUX_STATE}" = 'Disabled' ] && exit 0 + +parse_args "$@" +[ -z "${VOL}" ] && exit 1 + +set_brick_labels "${VOL}" + +exit 0 diff --git a/extras/hook-scripts/add-brick/post/S13create-subdir-mounts.sh b/extras/hook-scripts/add-brick/post/S13create-subdir-mounts.sh new file mode 100755 index 00000000000..1a6923ee7aa --- /dev/null +++ b/extras/hook-scripts/add-brick/post/S13create-subdir-mounts.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +##--------------------------------------------------------------------------- +## This script runs the self-heal of the directories which are expected to +## be present as they are mounted as subdirectory mounts. +##--------------------------------------------------------------------------- + +MOUNT_DIR=`mktemp -d -t ${0##*/}.XXXXXX`; +OPTSPEC="volname:,version:,gd-workdir:,volume-op:" +PROGNAME="add-brick-create-subdir" +VOL_NAME=test +GLUSTERD_WORKDIR="/var/lib/glusterd" + +cleanup_mountpoint () +{ + umount -f $MOUNT_DIR; + if [ 0 -ne $? ] + then + return $? + fi + + rmdir $MOUNT_DIR; + if [ 0 -ne $? ] + then + return $? + fi +} + +##------------------------------------------ +## Parse the arguments +##------------------------------------------ +ARGS=$(getopt -l $OPTSPEC -name $PROGNAME $@) +eval set -- "$ARGS" + +while true; +do + case $1 in + --volname) + shift + VOL_NAME=$1 + ;; + --gd-workdir) + shift + GLUSTERD_WORKDIR=$1 + ;; + --version) + shift + ;; + --volume-op) + shift + ;; + *) + shift + break + ;; + esac + shift +done + +## See if we have any subdirs to be healed before going further +subdirs=$(grep 'auth.allow' ${GLUSTERD_WORKDIR}/vols/${VOL_NAME}/info | cut -f2 -d'=' | tr ',' '\n' | cut -f1 -d'('); + +if [ -z ${subdirs} ]; then + rmdir $MOUNT_DIR; + exit 0; +fi + +##---------------------------------------- +## Mount the volume in temp directory. +## ----------------------------------- +glusterfs -s localhost --volfile-id=$VOL_NAME --client-pid=-50 $MOUNT_DIR; +if [ 0 -ne $? ] +then + exit $?; +fi + +## ----------------------------------- +# Do the 'stat' on all the directory for now. Ideal fix is to look at subdir +# list from 'auth.allow' option and only stat them. +for subdir in ${subdirs} +do + stat ${MOUNT_DIR}/${subdir} > /dev/null; +done + +## Clean up and exit +cleanup_mountpoint; diff --git a/extras/hook-scripts/add-brick/post/disabled-quota-root-xattr-heal.sh b/extras/hook-scripts/add-brick/post/disabled-quota-root-xattr-heal.sh new file mode 100755 index 00000000000..ca17a903549 --- /dev/null +++ b/extras/hook-scripts/add-brick/post/disabled-quota-root-xattr-heal.sh @@ -0,0 +1,145 @@ +#!/bin/sh + +##--------------------------------------------------------------------------- +## This script updates the 'limit-set' xattr on the newly added node. Please +## refer hook-scripts/add-brick/pre/S28Quota-root-xattr-heal.sh for the complete +## description. +## Do the following only if limit configured on root. +## 1. Do an auxiliary mount. +## 2. Get 'limit-set' xattr on root +## 3. Set xattrs with the same value on the root. +## 4. Disable itself +##--------------------------------------------------------------------------- + +QUOTA_LIMIT_XATTR="trusted.glusterfs.quota.limit-set" +QUOTA_OBJECT_LIMIT_XATTR="trusted.glusterfs.quota.limit-objects" +MOUNT_DIR=$(mktemp -d -t "${0##*/}.XXXXXX"); +OPTSPEC="volname:,version:,gd-workdir:,volume-op:" +PROGNAME="Quota-xattr-heal-add-brick" +VOL_NAME= +VERSION= +VOLUME_OP= +GLUSTERD_WORKDIR= +ENABLED_NAME_PREFIX="S28" +ENABLED_NAME="Quota-root-xattr-heal.sh" + +THIS_SCRIPT=$(echo "${0}" | awk -F'/' '{print $NF}') + +cleanup_mountpoint () +{ + + if umount -f "${MOUNT_DIR}"; then + return $? + fi + + if rmdir "${MOUNT_DIR}"; then + return $? + fi +} + +disable_and_exit () +{ + if [ -e "${ENABLED_STATE}" ] + then + unlink "${ENABLED_STATE}"; + exit $? + fi + + exit 0 +} + +get_and_set_xattr () +{ + XATTR=$1 + + VALUE=$(getfattr -n "${XATTR}" -e hex --absolute-names "${MOUNT_DIR}" 2>&1) + RET=$? + if [ 0 -eq ${RET} ]; then + VALUE=$(echo "${VALUE}" | grep "${XATTR}" | awk -F'=' '{print $NF}') + setfattr -n "${XATTR}" -v "${VALUE}" "${MOUNT_DIR}"; + RET=$? + else + if echo "${VALUE}" | grep -iq "No such attribute" ; then + RET=0 + fi + fi + + return ${RET}; +} + +##------------------------------------------ +## Parse the arguments +##------------------------------------------ +ARGS=$(getopt -o '' -l ${OPTSPEC} -n ${PROGNAME} -- "$@") +eval set -- "$ARGS" + +while true; +do + case $1 in + --volname) + shift + VOL_NAME=$1 + ;; + --version) + shift + VERSION=$1 + ;; + --gd-workdir) + shift + GLUSTERD_WORKDIR=$1 + ;; + --volume-op) + shift + VOLUME_OP=$1 + ;; + *) + shift + break + ;; + esac + shift +done +##---------------------------------------- + +# Avoid long lines +ENABLED_STATE_1="${GLUSTERD_WORKDIR}/hooks/${VERSION}/${VOLUME_OP}/" +ENABLED_STATE_2="post/${ENABLED_NAME_PREFIX}${VOL_NAME}-${ENABLED_NAME}" +ENABLED_STATE="${ENABLED_STATE_1}${ENABLED_STATE_2}" + +if [ "${THIS_SCRIPT}" != *"${VOL_NAME}"* ]; then + exit 0 +fi + +## Is quota enabled? +FLAG=$(grep "^features.quota=" "${GLUSTERD_WORKDIR}/vols/${VOL_NAME}/info" \ +| awk -F'=' '{print $NF}'); +if [ "${FLAG}" != "on" ] +then + disable_and_exit +fi + +## ----------------------------------- +## Mount the volume in temp directory. +## ----------------------------------- +# Avoid long lines +CMD_1="glusterfs -s localhost" +CMD_2="--volfile-id=${VOL_NAME} client-pid=-42 ${MOUNT_DIR}" +CMD="${CMD_1}${CMD_2}" + +if ${CMD} +then + exit $?; +fi +## ----------------------------------- + +RET1=$(get_and_set_xattr "${QUOTA_LIMIT_XATTR}") +RET2=$(get_and_set_xattr "${QUOTA_OBJECT_LIMIT_XATTR}") + +## Clean up and exit +cleanup_mountpoint; + +if [ "${RET1}" -ne 0 ] || [ "${RET2}" -ne 0 ]; then + exit 1 +fi + +disable_and_exit; diff --git a/extras/hook-scripts/add-brick/pre/Makefile.am b/extras/hook-scripts/add-brick/pre/Makefile.am new file mode 100644 index 00000000000..3288581aa57 --- /dev/null +++ b/extras/hook-scripts/add-brick/pre/Makefile.am @@ -0,0 +1,6 @@ +EXTRA_DIST = S28Quota-enable-root-xattr-heal.sh + +hookdir = $(GLUSTERD_WORKDIR)/hooks/1/add-brick/pre/ +if WITH_SERVER +hook_SCRIPTS = S28Quota-enable-root-xattr-heal.sh +endif diff --git a/extras/hook-scripts/add-brick/pre/S28Quota-enable-root-xattr-heal.sh b/extras/hook-scripts/add-brick/pre/S28Quota-enable-root-xattr-heal.sh new file mode 100755 index 00000000000..27e85231f45 --- /dev/null +++ b/extras/hook-scripts/add-brick/pre/S28Quota-enable-root-xattr-heal.sh @@ -0,0 +1,101 @@ +#!/bin/sh + +############################################################################### +## ---------------------------------------------------------------------------- +## The scripts +## I. add-brick/pre/S28Quota-root-xattr-heal.sh (itself) +## II. add-brick/post/disabled-root-xattr-heal.sh AND +## collectively archieves the job of healing the 'limit-set' xattr upon +## add-brick to the gluster volume. +## +## This script is the 'controlling' script. Upon add-brick this script enables +## the corresponding script based on the status of the volume. +## If volume is started - enable add-brick/post script +## else - enable start/post script. +## +## The enabling and disabling of a script is based on the glusterd's logic, +## that it only runs the scripts which starts its name with 'S'. So, +## Enable - symlink the file to 'S'*. +## Disable- unlink symlink +## ---------------------------------------------------------------------------- +############################################################################### + +OPTSPEC="volname:,version:,gd-workdir:,volume-op:" +PROGNAME="Quota-xattr-heal-add-brick-pre" +VOL_NAME= +GLUSTERD_WORKDIR= +VOLUME_OP= +VERSION= +ENABLED_NAME_PREFIX="S28" +ENABLED_NAME="Quota-root-xattr-heal.sh" +DISABLED_NAME="disabled-quota-root-xattr-heal.sh" + +activate () +{ + ln -sf $DISABLED_STATE $1; +} + +##------------------------------------------ +## Parse the arguments +##------------------------------------------ +ARGS=$(getopt -o '' -l $OPTSPEC -n $PROGNAME -- "$@") +eval set -- "$ARGS" + +while true; +do + case $1 in + --volname) + shift + VOL_NAME=$1 + ;; + --gd-workdir) + shift + GLUSTERD_WORKDIR=$1 + ;; + --volume-op) + shift + VOLUME_OP=$1 + ;; + --version) + shift + VERSION=$1 + ;; + *) + shift + break + ;; + esac + shift +done +##---------------------------------------- + +DISABLED_STATE="$GLUSTERD_WORKDIR/hooks/$VERSION/add-brick/post/$DISABLED_NAME" +ENABLED_STATE_START="$GLUSTERD_WORKDIR/hooks/$VERSION/start/post/""$ENABLED_NAME_PREFIX$VOL_NAME""-""$ENABLED_NAME" +ENABLED_STATE_ADD_BRICK="$GLUSTERD_WORKDIR/hooks/$VERSION/add-brick/post/""$ENABLED_NAME_PREFIX""$VOL_NAME""-""$ENABLED_NAME"; + +## Why to proceed if the required script itself is not present? +ls $DISABLED_STATE; +if [ 0 -ne $? ] +then + exit $?; +fi + +## Is quota enabled? +FLAG=`cat $GLUSTERD_WORKDIR/vols/$VOL_NAME/info | grep "^features.quota=" \ + | awk -F'=' '{print $NF}'`; +if [ "$FLAG" != "on" ] +then + exit $EXIT_SUCCESS; +fi + +## Is volume started? +FLAG=`cat $GLUSTERD_WORKDIR/vols/$VOL_NAME/info | grep "^status=" \ + | awk -F'=' '{print $NF}'`; +if [ "$FLAG" != "1" ] +then + activate $ENABLED_STATE_START; + exit $? +fi + +activate $ENABLED_STATE_ADD_BRICK; +exit $? diff --git a/extras/hook-scripts/create/Makefile.am b/extras/hook-scripts/create/Makefile.am new file mode 100644 index 00000000000..b083a9145d6 --- /dev/null +++ b/extras/hook-scripts/create/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = post diff --git a/extras/hook-scripts/create/post/Makefile.am b/extras/hook-scripts/create/post/Makefile.am new file mode 100644 index 00000000000..fd1892e9589 --- /dev/null +++ b/extras/hook-scripts/create/post/Makefile.am @@ -0,0 +1,8 @@ +EXTRA_DIST = S10selinux-label-brick.sh + +scriptsdir = $(GLUSTERD_WORKDIR)/hooks/1/create/post/ +if WITH_SERVER +if USE_SELINUX +scripts_SCRIPTS = S10selinux-label-brick.sh +endif +endif diff --git a/extras/hook-scripts/create/post/S10selinux-label-brick.sh b/extras/hook-scripts/create/post/S10selinux-label-brick.sh new file mode 100755 index 00000000000..f9b4b1a57e3 --- /dev/null +++ b/extras/hook-scripts/create/post/S10selinux-label-brick.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# +# Install to hooks/<HOOKS_VER>/create/post +# +# Add an SELinux file context for each brick using the glusterd_brick_t type. +# This ensures that the brick is relabeled correctly on an SELinux restart or +# restore. Subsequently, run a restore on the brick path to set the selinux +# labels. +# +### + +PROGNAME="Sselinux" +OPTSPEC="volname:" +VOL= + +parse_args () { + ARGS=$(getopt -o '' -l ${OPTSPEC} -n ${PROGNAME} -- "$@") + eval set -- "${ARGS}" + + while true; do + case ${1} in + --volname) + shift + VOL=${1} + ;; + *) + shift + break + ;; + esac + shift + done +} + +set_brick_labels() +{ + volname="${1}" + + # grab the path for each local brick + brickpath="/var/lib/glusterd/vols/${volname}/bricks/" + brickdirs=$( + find "${brickpath}" -type f -exec grep '^path=' {} \; | \ + cut -d= -f 2 | \ + sort -u + ) + + for b in ${brickdirs}; do + # Add a file context for each brick path and associate with the + # glusterd_brick_t SELinux type. + pattern="${b}(/.*)?" + semanage fcontext --add -t glusterd_brick_t -r s0 "${pattern}" + # Set the labels on the new brick path. + restorecon -R "${b}" + done +} + +SELINUX_STATE=$(which getenforce && getenforce) +[ "${SELINUX_STATE}" = 'Disabled' ] && exit 0 + +parse_args "$@" +[ -z "${VOL}" ] && exit 1 + +set_brick_labels "${VOL}" + +exit 0 diff --git a/extras/hook-scripts/delete/Makefile.am b/extras/hook-scripts/delete/Makefile.am new file mode 100644 index 00000000000..c98a05d9205 --- /dev/null +++ b/extras/hook-scripts/delete/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = pre diff --git a/extras/hook-scripts/delete/pre/Makefile.am b/extras/hook-scripts/delete/pre/Makefile.am new file mode 100644 index 00000000000..4fbfbe7311f --- /dev/null +++ b/extras/hook-scripts/delete/pre/Makefile.am @@ -0,0 +1,8 @@ +EXTRA_DIST = S10selinux-del-fcontext.sh + +scriptsdir = $(GLUSTERD_WORKDIR)/hooks/1/delete/pre/ +if WITH_SERVER +if USE_SELINUX +scripts_SCRIPTS = S10selinux-del-fcontext.sh +endif +endif diff --git a/extras/hook-scripts/delete/pre/S10selinux-del-fcontext.sh b/extras/hook-scripts/delete/pre/S10selinux-del-fcontext.sh new file mode 100755 index 00000000000..056b52afe76 --- /dev/null +++ b/extras/hook-scripts/delete/pre/S10selinux-del-fcontext.sh @@ -0,0 +1,73 @@ +#!/bin/bash +# +# Install to hooks/<HOOKS_VER>/delete/pre +# +# Delete the file context associated with the brick path on volume deletion. The +# associated file context was added during volume creation. +# +# We do not explicitly relabel the brick, as this could be time consuming and +# unnecessary. +# +### + +PROGNAME="Sselinux" +OPTSPEC="volname:" +VOL= + +function parse_args () { + ARGS=$(getopt -o '' -l ${OPTSPEC} -n ${PROGNAME} -- "$@") + eval set -- "${ARGS}" + + while true; do + case ${1} in + --volname) + shift + VOL=${1} + ;; + *) + shift + break + ;; + esac + shift + done +} + +function delete_brick_fcontext() +{ + local volname=$1 + local fctx + local list=() + + fctx="$(semanage fcontext --list -C)" + # grab the path for each local brick + brickpath="/var/lib/glusterd/vols/${volname}/bricks/" + brickdirs=$(find "${brickpath}" -type f -exec grep '^path=' {} \; | \ + cut -d= -f 2 | sort -u) + for b in ${brickdirs} + do + pattern="${b}(/.*)?" + echo "${fctx}" | grep "^${pattern}\s" >/dev/null + if [[ $? -eq 0 ]]; then + list+=("${pattern}") + fi + done + if [[ ${#list[@]} -gt 0 ]]; then + printf 'fcontext --delete %s\n' "${list[@]}" | semanage -i - + fi + for b in ${brickdirs} + do + restorecon -R "${b}" + done +} + +SELINUX_STATE=$(which getenforce && getenforce) +[ "${SELINUX_STATE}" = 'Disabled' ] && exit 0 + +parse_args "$@" +[ -z "${VOL}" ] && exit 1 + +delete_brick_fcontext "${VOL}" + +# failure to delete the fcontext is not fatal +exit 0 diff --git a/extras/hook-scripts/reset/Makefile.am b/extras/hook-scripts/reset/Makefile.am new file mode 100644 index 00000000000..6e2701e909e --- /dev/null +++ b/extras/hook-scripts/reset/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = post pre +CLEANFILES = diff --git a/extras/hook-scripts/reset/post/Makefile.am b/extras/hook-scripts/reset/post/Makefile.am new file mode 100644 index 00000000000..1b336ac1a85 --- /dev/null +++ b/extras/hook-scripts/reset/post/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST = diff --git a/extras/hook-scripts/reset/pre/Makefile.am b/extras/hook-scripts/reset/pre/Makefile.am new file mode 100644 index 00000000000..1b336ac1a85 --- /dev/null +++ b/extras/hook-scripts/reset/pre/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST = diff --git a/extras/hook-scripts/set/Makefile.am b/extras/hook-scripts/set/Makefile.am new file mode 100644 index 00000000000..1fcade4b07f --- /dev/null +++ b/extras/hook-scripts/set/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = post +CLEANFILES = diff --git a/extras/hook-scripts/set/post/Makefile.am b/extras/hook-scripts/set/post/Makefile.am new file mode 100644 index 00000000000..506a25a8666 --- /dev/null +++ b/extras/hook-scripts/set/post/Makefile.am @@ -0,0 +1,6 @@ +EXTRA_DIST = S30samba-set.sh S32gluster_enable_shared_storage.sh + +hookdir = $(GLUSTERD_WORKDIR)/hooks/1/set/post/ +if WITH_SERVER +hook_SCRIPTS = $(EXTRA_DIST) +endif diff --git a/extras/hook-scripts/set/post/S30samba-set.sh b/extras/hook-scripts/set/post/S30samba-set.sh new file mode 100755 index 00000000000..854f131f6c8 --- /dev/null +++ b/extras/hook-scripts/set/post/S30samba-set.sh @@ -0,0 +1,161 @@ +#!/bin/bash + +#Need to be copied to hooks/<HOOKS_VER>/set/post/ + +#TODO: All gluster and samba paths are assumed for fedora like systems. +#Some efforts are required to make it work on other distros. + +#The preferred way of creating a smb share of a gluster volume has changed. +#The old method was to create a fuse mount of the volume and share the mount +#point through samba. +# +#New method eliminates the requirement of fuse mount and changes in fstab. +#glusterfs_vfs plugin for samba makes call to libgfapi to access the volume. +# +#This hook script enables user to enable or disable smb share by volume set +#option. Keys "user.cifs" and "user.smb" both are valid, but user.smb is +#preferred. + + +PROGNAME="Ssamba-set" +OPTSPEC="volname:,gd-workdir:" +VOL= +CONFIGFILE= +LOGFILEBASE= +PIDDIR= +GLUSTERD_WORKDIR= +USERSMB_SET="" +USERCIFS_SET="" + +function parse_args () { + ARGS=$(getopt -o 'o:' -l $OPTSPEC -n $PROGNAME -- "$@") + eval set -- "$ARGS" + + while true; do + case $1 in + --volname) + shift + VOL=$1 + ;; + --gd-workdir) + shift + GLUSTERD_WORKDIR=$1 + ;; + --) + shift + break + ;; + -o) + shift + read key value < <(echo "$1" | tr "=" " ") + case "$key" in + "user.cifs") + USERCIFS_SET="YES" + ;; + "user.smb") + USERSMB_SET="YES" + ;; + *) + ;; + esac + ;; + *) + shift + break + ;; + esac + shift + done +} + +function find_config_info () { + cmdout=`smbd -b | grep smb.conf` + if [ $? -ne 0 ]; then + echo "Samba is not installed" + exit 1 + fi + CONFIGFILE=`echo $cmdout | awk '{print $2}'` + PIDDIR=`smbd -b | grep PIDDIR | awk '{print $2}'` + LOGFILEBASE=`smbd -b | grep 'LOGFILEBASE' | awk '{print $2}'` +} + +function add_samba_share () { + volname=$1 + STRING="\n[gluster-$volname]\n" + STRING+="comment = For samba share of volume $volname\n" + STRING+="vfs objects = glusterfs\n" + STRING+="glusterfs:volume = $volname\n" + STRING+="glusterfs:logfile = $LOGFILEBASE/glusterfs-$volname.%%M.log\n" + STRING+="glusterfs:loglevel = 7\n" + STRING+="path = /\n" + STRING+="read only = no\n" + STRING+="kernel share modes = no\n" + printf "$STRING" >> ${CONFIGFILE} +} + +function sighup_samba () { + pid=`cat ${PIDDIR}/smbd.pid` + if [ "x$pid" != "x" ] + then + kill -HUP "$pid"; + else + service smb condrestart + fi +} + +function deactivate_samba_share () { + volname=$1 + sed -i -e '/^\[gluster-'"$volname"'\]/{ :a' -e 'n; /available = no/H; /^$/!{$!ba;}; x; /./!{ s/^/available = no/; $!{G;x}; $H; }; s/.*//; x; };' ${CONFIGFILE} +} + +function is_volume_started () { + volname=$1 + echo "$(grep status $GLUSTERD_WORKDIR/vols/"$volname"/info |\ + cut -d"=" -f2)" +} + +function get_smb () { + volname=$1 + uservalue= + + usercifsvalue=$(grep user.cifs $GLUSTERD_WORKDIR/vols/"$volname"/info |\ + cut -d"=" -f2) + usersmbvalue=$(grep user.smb $GLUSTERD_WORKDIR/vols/"$volname"/info |\ + cut -d"=" -f2) + + if [ -n "$usercifsvalue" ]; then + if [ "$usercifsvalue" = "disable" ] || [ "$usercifsvalue" = "off" ]; then + uservalue="disable" + fi + fi + + if [ -n "$usersmbvalue" ]; then + if [ "$usersmbvalue" = "disable" ] || [ "$usersmbvalue" = "off" ]; then + uservalue="disable" + fi + fi + + echo "$uservalue" +} + +parse_args "$@" +if [ "0" = "$(is_volume_started "$VOL")" ]; then + exit 0 +fi + + +if [ "$USERCIFS_SET" = "YES" ] || [ "$USERSMB_SET" = "YES" ]; then + #Find smb.conf, smbd pid directory and smbd logfile path + find_config_info + + if [ "$(get_smb "$VOL")" = "disable" ]; then + deactivate_samba_share $VOL + else + if ! grep --quiet "\[gluster-$VOL\]" ${CONFIGFILE} ; then + add_samba_share $VOL + else + sed -i '/\[gluster-'"$VOL"'\]/,/^$/!b;/available = no/d' ${CONFIGFILE} + fi + fi + sighup_samba +fi diff --git a/extras/hook-scripts/set/post/S32gluster_enable_shared_storage.sh b/extras/hook-scripts/set/post/S32gluster_enable_shared_storage.sh new file mode 100755 index 00000000000..1f2564b44ff --- /dev/null +++ b/extras/hook-scripts/set/post/S32gluster_enable_shared_storage.sh @@ -0,0 +1,136 @@ +#!/bin/bash + +key=`echo $3 | cut -d '=' -f 1` +val=`echo $3 | cut -d '=' -f 2` +if [ "$key" != "cluster.enable-shared-storage" ] && [ "$key" != "enable-shared-storage" ]; then + exit; +fi +if [ "$val" != 'enable' ]; then + if [ "$val" != 'disable' ]; then + exit; + fi +fi + +option=$val + +key_val_pair1=`echo $4 | cut -d ',' -f 1` +key_val_pair2=`echo $4 | cut -d ',' -f 2` + +key=`echo $key_val_pair1 | cut -d '=' -f 1` +val=`echo $key_val_pair1 | cut -d '=' -f 2` +if [ "$key" != "is_originator" ]; then + exit; +fi +is_originator=$val; + +key=`echo $key_val_pair2 | cut -d '=' -f 1` +val=`echo $key_val_pair2 | cut -d '=' -f 2` +if [ "$key" != "local_node_hostname" ]; then + exit; +fi +local_node_hostname=$val; + +# Read gluster peer status to find the peers +# which are in 'Peer in Cluster' mode and +# are connected. + +number_of_connected_peers=0 +while read -r line +do + # Already got two connected peers. Including the current node + # we have 3 peers which is enough to create a shared storage + # with replica 3 + if [ "$number_of_connected_peers" == "2" ]; then + break; + fi + + key=`echo $line | cut -d ':' -f 1` + if [ "$key" == "Hostname" ]; then + hostname=`echo $line | cut -d ':' -f 2 | xargs` + fi + + if [ "$key" == "State" ]; then + peer_state=`echo $line | cut -d ':' -f 2 | cut -d '(' -f 1 | xargs` + conn_state=`echo $line | cut -d '(' -f 2 | cut -d ')' -f 1 | xargs` + + if [ "$peer_state" == "Peer in Cluster" ]; then + if [ "$conn_state" == "Connected" ]; then + ((number_of_connected_peers++)) + connected_peer[$number_of_connected_peers]=$hostname + fi + fi + fi + +done < <(gluster peer status) + +# Include current node in connected peer list +((number_of_connected_peers++)) +connected_peer[$number_of_connected_peers]=$local_node_hostname + +# forming the create vol command +create_cmd="gluster --mode=script --wignore volume create \ + gluster_shared_storage replica $number_of_connected_peers" + +# Adding the brick names in the command +for i in "${connected_peer[@]}" +do + create_cmd=$create_cmd" "$i:"$GLUSTERD_WORKDIR"/ss_brick +done + +if [ "$option" == "disable" ]; then + # Unmount the volume on all the nodes + umount /run/gluster/shared_storage + cat /etc/fstab | grep -v "gluster_shared_storage /run/gluster/shared_storage/" > /run/gluster/fstab.tmp + mv /run/gluster/fstab.tmp /etc/fstab +fi + +if [ "$is_originator" == 1 ]; then + if [ "$option" == "enable" ]; then + # Create and start the volume + $create_cmd + gluster --mode=script --wignore volume start gluster_shared_storage + fi + + if [ "$option" == "disable" ]; then + # Stop and delete the volume + gluster --mode=script --wignore volume stop gluster_shared_storage + gluster --mode=script --wignore volume delete gluster_shared_storage + fi +fi + +function check_volume_status() +{ + status=`gluster volume info gluster_shared_storage | grep Status | cut -d ':' -f 2 | xargs` + echo $status +} + +key=`echo $5 | cut -d '=' -f 1` +val=`echo $5 | cut -d '=' -f 2` +if [ "$key" == "transport.address-family" ]; then + mount_cmd="mount -t glusterfs -o xlator-option=transport.address-family=inet6 \ + $local_node_hostname:/gluster_shared_storage /run/gluster/shared_storage" +else + mount_cmd="mount -t glusterfs $local_node_hostname:/gluster_shared_storage \ + /run/gluster/shared_storage" +fi + +if [ "$option" == "enable" ]; then + retry=0; + # Wait for volume to start before mounting + status=$(check_volume_status) + while [ "$status" != "Started" ]; do + sleep 5; + ((retry++)) + if [ "$retry" == 3 ]; then + break; + fi + status=$(check_volume_status) + done + # Mount the volume on all the nodes + umount /run/gluster/shared_storage + mkdir -p /run/gluster/shared_storage + $mount_cmd + cp /etc/fstab /run/gluster/fstab.tmp + echo "$local_node_hostname:/gluster_shared_storage /run/gluster/shared_storage/ glusterfs defaults 0 0" >> /run/gluster/fstab.tmp + mv /run/gluster/fstab.tmp /etc/fstab +fi diff --git a/extras/hook-scripts/start/Makefile.am b/extras/hook-scripts/start/Makefile.am new file mode 100644 index 00000000000..1fcade4b07f --- /dev/null +++ b/extras/hook-scripts/start/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = post +CLEANFILES = diff --git a/extras/hook-scripts/start/post/Makefile.am b/extras/hook-scripts/start/post/Makefile.am new file mode 100644 index 00000000000..792019d3c9f --- /dev/null +++ b/extras/hook-scripts/start/post/Makefile.am @@ -0,0 +1,6 @@ +EXTRA_DIST = S29CTDBsetup.sh S30samba-start.sh S31ganesha-start.sh + +hookdir = $(GLUSTERD_WORKDIR)/hooks/1/start/post/ +if WITH_SERVER +hook_SCRIPTS = $(EXTRA_DIST) +endif diff --git a/extras/hook-scripts/start/post/S29CTDBsetup.sh b/extras/hook-scripts/start/post/S29CTDBsetup.sh new file mode 100755 index 00000000000..69a0d89a3eb --- /dev/null +++ b/extras/hook-scripts/start/post/S29CTDBsetup.sh @@ -0,0 +1,84 @@ +#! /bin/bash +# +# - The script mounts the 'meta-vol' on start 'event' on a known +# directory (eg. /gluster/lock) +# - P.S: There are other 'tasks' that need to be done outside this script +# to get CTDB based failover up and running. + +CTDB_MNT=/gluster/lock +# Make sure ping-timeout is not default for CTDB volume +PING_TIMEOUT_SECS=10 +PROGNAME="ctdb" +OPTSPEC="volname:,gd-workdir:,version:,volume-op:,first:" +HOSTNAME=`hostname` +MNTOPTS="_netdev,transport=tcp,xlator-option=*client*.ping-timeout=${PING_TIMEOUT_SECS}" +VOL= +GLUSTERD_WORKDIR= +VERSION= +VOLUME_OP= +FIRST= +# $META is the volume that will be used by CTDB as a shared filesystem. +# It is not desirable to use this volume for storing 'data' as well. +# META is set to 'all' (viz. a keyword and hence not a legal volume name) +# to prevent the script from running for volumes it was not intended. +# User needs to set META to the volume that serves CTDB lockfile. +META="all" + +function parse_args () { + ARGS=$(getopt -o '' -l $OPTSPEC -n $PROGNAME -- "$@") + eval set -- "$ARGS" + + while true; do + case $1 in + --volname) + shift + VOL=$1 + ;; + --gd-workdir) + shift + GLUSTERD_WORKDIR=$1 + ;; + --version) + shift + VERSION=$1 + ;; + --volume-op) + shift + VOLUME_OP=$1 + ;; + --first) + shift + FIRST=$1 + ;; + *) + shift + break + ;; + esac + + shift + done +} + +function add_fstab_entry () { + volname=$1 + mntpt=$2 + mntopts="${MNTOPTS}" + + mntent="${HOSTNAME}:/${volname} ${mntpt} glusterfs ${mntopts} 0 0" + exists=`grep "${mntpt}" /etc/fstab` + if [ "$exists" == "" ] + then + echo "${mntent}" >> /etc/fstab + fi +} + +parse_args "$@" +if [ "$META" = "$VOL" ] +then + mkdir -p $CTDB_MNT + sleep 5 + mount -t glusterfs -o${MNTOPTS} ${HOSTNAME}:/$VOL "$CTDB_MNT" && \ + add_fstab_entry $VOL $CTDB_MNT + chkconfig ctdb on +fi diff --git a/extras/hook-scripts/start/post/S30samba-start.sh b/extras/hook-scripts/start/post/S30samba-start.sh new file mode 100755 index 00000000000..cac0cbf1464 --- /dev/null +++ b/extras/hook-scripts/start/post/S30samba-start.sh @@ -0,0 +1,145 @@ +#!/bin/bash + +#Need to be copied to hooks/<HOOKS_VER>/start/post + +#TODO: All gluster and samba paths are assumed for fedora like systems. +#Some efforts are required to make it work on other distros. + +#The preferred way of creating a smb share of a gluster volume has changed. +#The old method was to create a fuse mount of the volume and share the mount +#point through samba. +# +#New method eliminates the requirement of fuse mount and changes in fstab. +#glusterfs_vfs plugin for samba makes call to libgfapi to access the volume. +# +#This hook script automagically creates shares for volume on every volume start +#event by adding the entries in smb.conf file and sending SIGHUP to samba. +# +#In smb.conf: +#glusterfs vfs plugin has to be specified as required vfs object. +#Path value is relative to the root of gluster volume;"/" signifies complete +#volume. + +PROGNAME="Ssamba-start" +OPTSPEC="volname:,gd-workdir:,version:,volume-op:,first:" +VOL= +CONFIGFILE= +LOGFILEBASE= +PIDDIR= +GLUSTERD_WORKDIR= +VERSION= +VOLUME_OP= +FIRST= + +function parse_args () { + ARGS=$(getopt -o '' -l $OPTSPEC -n $PROGNAME -- "$@") + eval set -- "$ARGS" + + while true; do + case $1 in + --volname) + shift + VOL=$1 + ;; + --gd-workdir) + shift + GLUSTERD_WORKDIR=$1 + ;; + --version) + shift + VERSION=$1 + ;; + --volume-op) + shift + VOLUME_OP=$1 + ;; + --first) + shift + FIRST=$1 + ;; + *) + shift + break + ;; + esac + + shift + done +} + +function find_config_info () { + cmdout=$(smbd -b 2> /dev/null) + CONFIGFILE=$(echo "$cmdout" | grep CONFIGFILE | awk '{print $2}') + if [ -z "$CONFIGFILE" ]; then + echo "Samba is not installed" + exit 1 + fi + PIDDIR=$(echo "$cmdout" | grep PIDDIR | awk '{print $2}') + LOGFILEBASE=$(echo "$cmdout" | grep 'LOGFILEBASE' | awk '{print $2}') +} + +function add_samba_share () { + volname=$1 + STRING="\n[gluster-$volname]\n" + STRING+="comment = For samba share of volume $volname\n" + STRING+="vfs objects = glusterfs\n" + STRING+="glusterfs:volume = $volname\n" + STRING+="glusterfs:logfile = $LOGFILEBASE/glusterfs-$volname.%%M.log\n" + STRING+="glusterfs:loglevel = 7\n" + STRING+="path = /\n" + STRING+="read only = no\n" + STRING+="kernel share modes = no\n" + printf "$STRING" >> "${CONFIGFILE}" +} + +function sighup_samba () { + pid=$(cat "${PIDDIR}/smbd.pid" 2> /dev/null) + if [ "x$pid" != "x" ] + then + kill -HUP "$pid"; + else + service smb condrestart + fi +} + +function get_smb () { + volname=$1 + uservalue= + + usercifsvalue=$(grep user.cifs "$GLUSTERD_WORKDIR"/vols/"$volname"/info |\ + cut -d"=" -f2) + usersmbvalue=$(grep user.smb "$GLUSTERD_WORKDIR"/vols/"$volname"/info |\ + cut -d"=" -f2) + + if [ -n "$usercifsvalue" ]; then + if [ "$usercifsvalue" = "enable" ] || [ "$usercifsvalue" = "on" ]; then + uservalue="enable" + fi + fi + + if [ -n "$usersmbvalue" ]; then + if [ "$usersmbvalue" = "enable" ] || [ "$usersmbvalue" = "on" ]; then + uservalue="enable" + fi + fi + + echo "$uservalue" +} + +parse_args "$@" + +value=$(get_smb "$VOL") + +if [ -z "$value" ] || [ "$value" != "enable" ]; then + exit 0 +fi + +#Find smb.conf, smbd pid directory and smbd logfile path +find_config_info + +if ! grep --quiet "\[gluster-$VOL\]" "${CONFIGFILE}" ; then + add_samba_share "$VOL" +else + sed -i '/\[gluster-'"$VOL"'\]/,/^$/!b;/available = no/d' "${CONFIGFILE}" +fi +sighup_samba diff --git a/extras/hook-scripts/start/post/S31ganesha-start.sh b/extras/hook-scripts/start/post/S31ganesha-start.sh new file mode 100755 index 00000000000..7ad6f23ad06 --- /dev/null +++ b/extras/hook-scripts/start/post/S31ganesha-start.sh @@ -0,0 +1,122 @@ +#!/bin/bash +PROGNAME="Sganesha-start" +OPTSPEC="volname:,gd-workdir:" +VOL= +declare -i EXPORT_ID +ganesha_key="ganesha.enable" +GANESHA_DIR="/run/gluster/shared_storage/nfs-ganesha" +CONF1="$GANESHA_DIR/ganesha.conf" +GLUSTERD_WORKDIR= + +function parse_args () +{ + ARGS=$(getopt -l $OPTSPEC -o "o" -name $PROGNAME $@) + eval set -- "$ARGS" + + while true; do + case $1 in + --volname) + shift + VOL=$1 + ;; + --gd-workdir) + shift + GLUSTERD_WORKDIR=$1 + ;; + *) + shift + break + ;; + esac + shift + done +} + + + +#This function generates a new export entry as export.volume_name.conf +function write_conf() +{ +echo -e "# WARNING : Using Gluster CLI will overwrite manual +# changes made to this file. To avoid it, edit the +# file, copy it over to all the NFS-Ganesha nodes +# and run ganesha-ha.sh --refresh-config." + +echo "EXPORT{" +echo " Export_Id = 2;" +echo " Path = \"/$VOL\";" +echo " FSAL {" +echo " name = \"GLUSTER\";" +echo " hostname=\"localhost\";" +echo " volume=\"$VOL\";" +echo " }" +echo " Access_type = RW;" +echo " Disable_ACL = true;" +echo " Squash=\"No_root_squash\";" +echo " Pseudo=\"/$VOL\";" +echo " Protocols = \"3\", \"4\" ;" +echo " Transports = \"UDP\",\"TCP\";" +echo " SecType = \"sys\";" +echo "}" +} + +#It adds the export dynamically by sending dbus signals +function export_add() +{ + dbus-send --print-reply --system --dest=org.ganesha.nfsd \ +/org/ganesha/nfsd/ExportMgr org.ganesha.nfsd.exportmgr.AddExport \ +string:$GANESHA_DIR/exports/export.$VOL.conf string:"EXPORT(Export_Id=$EXPORT_ID)" + +} + +# based on src/scripts/ganeshactl/Ganesha/export_mgr.py +function is_exported() +{ + local volume="${1}" + + dbus-send --type=method_call --print-reply --system \ + --dest=org.ganesha.nfsd /org/ganesha/nfsd/ExportMgr \ + org.ganesha.nfsd.exportmgr.ShowExports \ + | grep -w -q "/${volume}" + + return $? +} + +# Check the info file (contains the volume options) to see if Ganesha is +# enabled for this volume. +function ganesha_enabled() +{ + local volume="${1}" + local info_file="${GLUSTERD_WORKDIR}/vols/${VOL}/info" + local enabled="off" + + enabled=$(grep -w ${ganesha_key} ${info_file} | cut -d"=" -f2) + + [ "${enabled}" == "on" ] + + return $? +} + +parse_args $@ + +if ganesha_enabled ${VOL} && ! is_exported ${VOL} +then + if [ ! -e ${GANESHA_DIR}/exports/export.${VOL}.conf ] + then + #Remove export entry from nfs-ganesha.conf + sed -i /$VOL.conf/d $CONF1 + write_conf ${VOL} > ${GANESHA_DIR}/exports/export.${VOL}.conf + EXPORT_ID=`cat $GANESHA_DIR/.export_added` + EXPORT_ID=EXPORT_ID+1 + echo $EXPORT_ID > $GANESHA_DIR/.export_added + sed -i s/Export_Id.*/"Export_Id=$EXPORT_ID;"/ \ + $GANESHA_DIR/exports/export.$VOL.conf + echo "%include \"$GANESHA_DIR/exports/export.$VOL.conf\"" >> $CONF1 + else + EXPORT_ID=$(grep ^[[:space:]]*Export_Id $GANESHA_DIR/exports/export.$VOL.conf |\ + awk -F"[=,;]" '{print $2}' | tr -d '[[:space:]]') + fi + export_add $VOL +fi + +exit 0 diff --git a/extras/hook-scripts/stop/Makefile.am b/extras/hook-scripts/stop/Makefile.am new file mode 100644 index 00000000000..e2ac8e2740b --- /dev/null +++ b/extras/hook-scripts/stop/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = pre +CLEANFILES = diff --git a/extras/hook-scripts/stop/pre/Makefile.am b/extras/hook-scripts/stop/pre/Makefile.am new file mode 100644 index 00000000000..9e8d1565e93 --- /dev/null +++ b/extras/hook-scripts/stop/pre/Makefile.am @@ -0,0 +1,6 @@ +EXTRA_DIST = S29CTDB-teardown.sh S30samba-stop.sh + +hookdir = $(GLUSTERD_WORKDIR)/hooks/1/stop/pre/ +if WITH_SERVER +hook_SCRIPTS = $(EXTRA_DIST) +endif diff --git a/extras/hook-scripts/stop/pre/S29CTDB-teardown.sh b/extras/hook-scripts/stop/pre/S29CTDB-teardown.sh new file mode 100755 index 00000000000..0975a00f18d --- /dev/null +++ b/extras/hook-scripts/stop/pre/S29CTDB-teardown.sh @@ -0,0 +1,62 @@ +#! /bin/bash + +CTDB_MNT=/gluster/lock +PROGNAME="ctdb" +OPTSPEC="volname:,last:" +VOL= +LAST= +# $META is the volume that will be used by CTDB as a shared filesystem. +# It is not desirable to use this volume for storing 'data' as well. +# META is set to 'all' (viz. a keyword and hence not a legal volume name) +# to prevent the script from running for volumes it was not intended. +# User needs to set META to the volume that serves CTDB lockfile. +META="all" + +function parse_args () { + ARGS=$(getopt -o '' -l $OPTSPEC -n $PROGNAME -- "$@") + eval set -- "$ARGS" + + while true; do + case $1 in + --volname) + shift + VOL=$1 + ;; + --last) + shift + LAST=$1 + ;; + *) + shift + break + ;; + esac + shift + done +} + + +function remove_fstab_entry () { + mntpt=$1 + fstab="/etc/fstab" + exists=`grep "$mntpt" ${fstab}` + esc_mntpt=$(echo -e $mntpt | sed 's/\//\\\//g') + if [ "$exists" != " " ] + then + sed -i /"$esc_mntpt"/d $fstab + exists=`grep "$mntpt" ${fstab}` + if [ "$exists" != " " ] + then + echo "fstab entry cannot be removed for unknown reason" + exit 1 + fi + fi +} + +parse_args "$@" +if [ "$META" = "$VOL" ] +then + umount "$CTDB_MNT" + chkconfig ctdb off + remove_fstab_entry $CTDB_MNT +fi diff --git a/extras/hook-scripts/stop/pre/S30samba-stop.sh b/extras/hook-scripts/stop/pre/S30samba-stop.sh new file mode 100755 index 00000000000..ea799381d62 --- /dev/null +++ b/extras/hook-scripts/stop/pre/S30samba-stop.sh @@ -0,0 +1,77 @@ +#! /bin/bash + +#Need to be copied to hooks/<HOOKS_VER>/stop/pre + +#TODO: All gluster and samba paths are assumed for fedora like systems. +#Some efforts are required to make it work on other distros. + +#The preferred way of creating a smb share of a gluster volume has changed. +#The old method was to create a fuse mount of the volume and share the mount +#point through samba. +# +#New method eliminates the requirement of fuse mount and changes in fstab. +#glusterfs_vfs plugin for samba makes call to libgfapi to access the volume. +# +#This hook script automagically removes shares for volume on every volume stop +#event by removing the volume related entries(if any) in smb.conf file. + +PROGNAME="Ssamba-stop" +OPTSPEC="volname:,last:" +VOL= +CONFIGFILE= +PIDDIR= +LAST= + +function parse_args () { + ARGS=$(getopt -o '' -l $OPTSPEC -n $PROGNAME -- "$@") + eval set -- "$ARGS" + + while true; do + case $1 in + --volname) + shift + VOL=$1 + ;; + --last) + shift + LAST=$1 + ;; + *) + shift + break + ;; + esac + + shift + done +} + +function find_config_info () { + cmdout=`smbd -b | grep smb.conf` + if [ $? -ne 0 ];then + echo "Samba is not installed" + exit 1 + fi + CONFIGFILE=`echo $cmdout | awk '{print $2}'` + PIDDIR=`smbd -b | grep PIDDIR | awk '{print $2}'` +} + +function deactivate_samba_share () { + volname=$1 + sed -i -e '/^\[gluster-'"$volname"'\]/{ :a' -e 'n; /available = no/H; /^$/!{$!ba;}; x; /./!{ s/^/available = no/; $!{G;x}; $H; }; s/.*//; x; };' ${CONFIGFILE} +} + +function sighup_samba () { + pid=`cat ${PIDDIR}/smbd.pid` + if [ "x$pid" != "x" ] + then + kill -HUP $pid; + else + service smb condrestart + fi +} + +parse_args "$@" +find_config_info +deactivate_samba_share $VOL +sighup_samba |
