diff options
Diffstat (limited to '')
-rwxr-xr-x | heartbeat/smb-share.in | 494 |
1 files changed, 494 insertions, 0 deletions
diff --git a/heartbeat/smb-share.in b/heartbeat/smb-share.in new file mode 100755 index 0000000..8a1a0a8 --- /dev/null +++ b/heartbeat/smb-share.in @@ -0,0 +1,494 @@ +#!@BASH_SHELL@ +# +# OCF Resource Agent for create samba config snippets. +# +# +# +# Copyright (c) 2021 B1 Systems GmbH <info@b1-systems.de> +# Author: +# Tobias D. Oestreicher <oestreicher@b1-systems.de> +# All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# +# +# OCF parameters are as below: +# OCF_RESKEY_outfile +# OCF_RESKEY_includesfile +# OCF_RESKEY_confd +# OCF_RESKEY_share +# OCF_RESKEY_path +# OCF_RESKEY_hosts_allow +# OCF_RESKEY_browseable +# OCF_RESKEY_writeable +# OCF_RESKEY_read_only +# OCF_RESKEY_guest_ok +# OCF_RESKEY_directory_mask +# OCF_RESKEY_create_mask +# OCF_RESKEY_printable +# OCF_RESKEY_valid_users +# OCF_RESKEY_force_user +# OCF_RESKEY_force_group +# OCF_RESKEY_extraopt +# OCF_RESKEY_extraopt_list +# +####################################################################### + +####################################################################### +# +# Purpose: +# -------- +# This RA is used to control samba shares on the fly. +# For adding and removing samba shares no restart of the samba daemon +# is needed. This is the equivalent of the exportfs RA which is used +# for nfs shares. +# +# How to use: +# ----------- +# For this RA to work as expected you need a cloned samba daemon which +# have to be startet before. +# After this RA manages config snippets placed in the filesystem and +# after a fence of that node these snippets will still located there +# you will have to use a tmpfs mount for this. +# Also you need a basic smb.conf file in which all global parameters an +# permanent shares should be placed. +# Within this smb.conf also you must put a line in the global section +# like this: +# +# include = /etc/samba/conf.d/pacemaker-includes.conf +# +# The filename can be changed by setting the parameter "includesfile". +# Every share created by this RA will create a new file located in: +# +# /etc/samba/conf.d/ +# +# This directory also can be changed by setting the RA parameter "confd". +# +####################################################################### + +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} +. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs + +# Defaults + +OCF_RESKEY_outfile_default="" +OCF_RESKEY_includesfile_default="/etc/samba/conf.d/pacemaker-includes.conf" +OCF_RESKEY_confd_default="/etc/samba/conf.d" +OCF_RESKEY_share_default="" +OCF_RESKEY_path_default="" +OCF_RESKEY_hosts_allow_default="" +OCF_RESKEY_browseable_default="" +OCF_RESKEY_writeable_default="" +OCF_RESKEY_read_only_default="" +OCF_RESKEY_guest_ok_default="" +OCF_RESKEY_directory_mask_default="" +OCF_RESKEY_create_mask_default="" +OCF_RESKEY_printable_default="" +OCF_RESKEY_valid_users_default="" +OCF_RESKEY_force_user_default="" +OCF_RESKEY_force_group_default="" +OCF_RESKEY_extraopt_default="" +OCF_RESKEY_extraopt_list_default="" + + +: ${OCF_RESKEY_outfile=${OCF_RESKEY_outfile_default}} +: ${OCF_RESKEY_includesfile=${OCF_RESKEY_includesfile_default}} +: ${OCF_RESKEY_confd=${OCF_RESKEY_confd_default}} +: ${OCF_RESKEY_share=${OCF_RESKEY_share_default}} +: ${OCF_RESKEY_path=${OCF_RESKEY_path_default}} +: ${OCF_RESKEY_hosts_allow=${OCF_RESKEY_hosts_allow_default}} +: ${OCF_RESKEY_browseable=${OCF_RESKEY_browseable_default}} +: ${OCF_RESKEY_writeable=${OCF_RESKEY_writeable_default}} +: ${OCF_RESKEY_read_only=${OCF_RESKEY_read_only_default}} +: ${OCF_RESKEY_guest_ok=${OCF_RESKEY_guest_ok_default}} +: ${OCF_RESKEY_directory_mask=${OCF_RESKEY_directory_mask_default}} +: ${OCF_RESKEY_create_mask=${OCF_RESKEY_create_mask_default}} +: ${OCF_RESKEY_printable=${OCF_RESKEY_printable_default}} +: ${OCF_RESKEY_valid_users=${OCF_RESKEY_valid_users_default}} +: ${OCF_RESKEY_force_user=${OCF_RESKEY_force_user_default}} +: ${OCF_RESKEY_force_group=${OCF_RESKEY_force_group_default}} +: ${OCF_RESKEY_extraopt=${OCF_RESKEY_extraopt_default}} +: ${OCF_RESKEY_extraopt_list=${OCF_RESKEY_extraopt_list_default}} + +####################################################################### + +####################################################################### + +meta_data() { + cat <<END +<?xml version="1.0"?> +<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd"> +<resource-agent name="smb-share" version="1.0"> + <version>1.0</version> + <longdesc lang="en"> +This RA is used to control samba shares on the fly. +For adding and removing samba shares no restart of the samba daemon +is needed. This is the equivalent of the exportfs RA which is used +for nfs shares. + +For this RA to work as expected you need a cloned samba daemon which +have to be startet before. +After this RA manages config snippets placed in the filesystem and +after a fence of that node these snippets will still located there +you will have to use a tmpfs mount for this. +Also you need a basic smb.conf file in which all global parameters an +permanent shares should be placed. +Within this smb.conf also you must put a line in the global section +like this: + + include = /etc/samba/conf.d/pacemaker-includes.conf + +The filename can be changed by setting the parameter includesfile. +Every share created by this RA will create a new file located in: + + /etc/samba/conf.d/ + +This directory also can be changed by setting the RA parameter confd. + </longdesc> + <shortdesc lang="en">Manages samba shares on the fly</shortdesc> + + <parameters> + + <parameter name="share" unique="1" required="1"> + <longdesc lang="en"> + Set the name of a windows share which should be added to Samba + example name "myshare" resulting in [myshare]. + </longdesc> + <shortdesc lang="en">sharename</shortdesc> + <content type="string" default="${OCF_RESKEY_share_default}" /> + </parameter> + + <parameter name="path" unique="1" required="0"> + <longdesc lang="en"> + Set the path to share for cifs clients. + example path "/srv/data/myshare". + </longdesc> + <shortdesc lang="en">path to share</shortdesc> + <content type="string" default="${OCF_RESKEY_path_default}" /> + </parameter> + + <parameter name="hosts_allow" unique="0" required="0"> + <longdesc lang="en"> + This parameter is a comma, space, or tab delimited set of hosts which are permitted to access a service. + </longdesc> + <shortdesc lang="en">hosts allow parameter</shortdesc> + <content type="string" default="${OCF_RESKEY_hosts_allow_default}" /> + </parameter> + + <parameter name="browseable" unique="0" required="0"> + <longdesc lang="en"> + This controls whether this share is seen in the list of available shares in a net view and in the browse list. + </longdesc> + <shortdesc lang="en">browseable parameter</shortdesc> + <content type="string" default="${OCF_RESKEY_browseable_default}" /> + </parameter> + + <parameter name="writeable" unique="0" required="0"> + <longdesc lang="en"> + Inverted synonym for read only. + </longdesc> + <shortdesc lang="en">writeable parameter</shortdesc> + <content type="string" default="${OCF_RESKEY_writeable_default}" /> + </parameter> + + <parameter name="read_only" unique="0" required="0"> + <longdesc lang="en"> + This option can be used to turn the writing backends tdb, tdb2, and ldap into read only mode. + This can be useful e.g. in cases where a pre-filled database exists that should not be extended automatically. + </longdesc> + <shortdesc lang="en">read only parameter</shortdesc> + <content type="string" default="${OCF_RESKEY_read_only_default}" /> + </parameter> + + <parameter name="guest_ok" unique="0" required="0"> + <longdesc lang="en"> + If this parameter is yes for a service, then no password is required to connect to the service. Privileges will be those of the guest account. + </longdesc> + <shortdesc lang="en">guest ok parameter</shortdesc> + <content type="string" default="${OCF_RESKEY_guest_ok_default}" /> + </parameter> + + <parameter name="directory_mask" unique="0" required="0"> + <longdesc lang="en"> + This parameter is the octal modes which are used when converting DOS modes to UNIX modes when creating UNIX directories. + </longdesc> + <shortdesc lang="en">directory mask parameter</shortdesc> + <content type="string" default="${OCF_RESKEY_directory_mask_default}" /> + </parameter> + + <parameter name="create_mask" unique="0" required="0"> + <longdesc lang="en"> + When a file is created, the necessary permissions are calculated according to the mapping from DOS modes to UNIX permissions, + and the resulting UNIX mode is then bit-wise ANDed with this parameter. This parameter may be thought of as a bit-wise MASK for the UNIX modes of a file. + </longdesc> + <shortdesc lang="en">create mask parameter</shortdesc> + <content type="string" default="${OCF_RESKEY_create_mask_default}" /> + </parameter> + + <parameter name="printable" unique="0" required="0"> + <longdesc lang="en"> + If this parameter is yes, then clients may open, write to and submit spool files on the directory specified for the service. + </longdesc> + <shortdesc lang="en">printable parameter</shortdesc> + <content type="string" default="${OCF_RESKEY_printable_default}" /> + </parameter> + + <parameter name="valid_users" unique="0" required="0"> + <longdesc lang="en"> + This is a list of users that should be allowed to login to this service. Names starting with @, + and & are interpreted + using the same rules as described in the invalid users parameter. + </longdesc> + <shortdesc lang="en">valid users parameter</shortdesc> + <content type="string" default="${OCF_RESKEY_valid_users_default}" /> + </parameter> + + <parameter name="force_user" unique="0" required="0"> + <longdesc lang="en"> + This specifies a UNIX user name that will be assigned as the default user for all users connecting to this service. This is useful for sharing files. + </longdesc> + <shortdesc lang="en">force user parameter</shortdesc> + <content type="string" default="${OCF_RESKEY_force_user_default}" /> + </parameter> + + <parameter name="force_group" unique="0" required="0"> + <longdesc lang="en"> + This specifies a UNIX group name that will be assigned as the default primary group for all users connecting to this service. + This is useful for sharing files by ensuring that all access to files on service will use the named group for their permissions checking. + </longdesc> + <shortdesc lang="en">force group parameter</shortdesc> + <content type="string" default="${OCF_RESKEY_force_group_default}" /> + </parameter> + + <parameter name="extraopt" unique="0" required="0"> + <longdesc lang="en"> + This option can be used to define an additional key = value pair. + In this parameter also a semicolon could be placed. + Need to set e.g somthinspecial = value + </longdesc> + <shortdesc lang="en">additional key value pair</shortdesc> + <content type="string" default="${OCF_RESKEY_extraopt_default}" /> + </parameter> + + <parameter name="extraopt_list" unique="0" required="0"> + <longdesc lang="en"> + This option can be used to define multiple additional key = value pairs. + Define the list of element semicolon separated. + e.g somethingspecial = value;one more = value2 + </longdesc> + <shortdesc lang="en">additional key value pairs as semicolon separated list</shortdesc> + <content type="string" default="${OCF_RESKEY_extraopt_list_default}" /> + </parameter> + + <parameter name="outfile" unique="1" required="1"> + <longdesc lang="en"> + Set the path and filename where the snipped should be written. + example "/etc/samba/conf.d/myshare.inc". + </longdesc> + <shortdesc lang="en">outputfile</shortdesc> + <content type="string" default="${OCF_RESKEY_outfile_default}" /> + </parameter> + + <parameter name="confd" unique="0" required="0"> + <longdesc lang="en"> + Set the path where the includes will be written. This folder have to be a tmpfs mount + This defaults to "/etc/samba/conf.d". + </longdesc> + <shortdesc lang="en">confd directory</shortdesc> + <content type="string" default="${OCF_RESKEY_confd_default}" /> + </parameter> + + <parameter name="includesfile" unique="0" required="0"> + <longdesc lang="en"> + Set the path and filename in which the include should be placed. + example includesfile "/etc/samba/conf.d/pacemaker-includes.conf". + This option manages the include= parameter within this file + </longdesc> + <shortdesc lang="en">includesfile for smb.conf</shortdesc> + <content type="string" default="${OCF_RESKEY_includesfile_default}" /> + </parameter> + + </parameters> + + <actions> + <action name="start" timeout="20s" /> + <action name="stop" timeout="20s" /> + <action name="status" depth="0" timeout="20s" interval="10s" /> + <action name="monitor" depth="0" timeout="20s" interval="10s" /> + <action name="meta-data" timeout="5s" /> + <action name="validate-all" timeout="20s" /> + </actions> +</resource-agent> +END + + exit $OCF_SUCCESS +} + +smb_share_addinclude() { + if [ ! -e ${OCF_RESKEY_includesfile} ];then + echo '[global]' > ${OCF_RESKEY_includesfile} + fi + if [ $(grep -c "include = $OCF_RESKEY_outfile" ${OCF_RESKEY_includesfile}) -eq 0 ];then + echo "include = $OCF_RESKEY_outfile" >> ${OCF_RESKEY_includesfile} + fi +} + +smb_share_delinclude() { + ESCAPED=$(echo $OCF_RESKEY_outfile|sed 's,/,\\/,g') + sed -i /include.=.$ESCAPED/d ${OCF_RESKEY_includesfile} +} + +smb_share_create() { + + echo "[${OCF_RESKEY_share}]" > $OCF_RESKEY_outfile + if [ ! -z "$OCF_RESKEY_path" ];then echo " path = $OCF_RESKEY_path" >> $OCF_RESKEY_outfile; fi + if [ ! -z "$OCF_RESKEY_hosts_allow" ];then echo " hosts allow = $OCF_RESKEY_hosts_allow" >> $OCF_RESKEY_outfile; fi + if [ ! -z "$OCF_RESKEY_browseable" ];then echo " browseable = $OCF_RESKEY_browseable" >> $OCF_RESKEY_outfile; fi + if [ ! -z "$OCF_RESKEY_writeable" ];then echo " writeable = $OCF_RESKEY_writeable" >> $OCF_RESKEY_outfile; fi + if [ ! -z "$OCF_RESKEY_read_only" ];then echo " read only = $OCF_RESKEY_read_only" >> $OCF_RESKEY_outfile; fi + if [ ! -z "$OCF_RESKEY_guest_ok" ];then echo " guest ok = $OCF_RESKEY_guest_ok" >> $OCF_RESKEY_outfile; fi + if [ ! -z "$OCF_RESKEY_directory_mask" ];then echo " directory mask = $OCF_RESKEY_directory_mask" >> $OCF_RESKEY_outfile; fi + if [ ! -z "$OCF_RESKEY_create_mask" ];then echo " create mask = $OCF_RESKEY_create_mask" >> $OCF_RESKEY_outfile; fi + if [ ! -z "$OCF_RESKEY_printable" ];then echo " printable = $OCF_RESKEY_printable" >> $OCF_RESKEY_outfile; fi + if [ ! -z "$OCF_RESKEY_valid_users" ];then echo " valid users = $OCF_RESKEY_valid_users" >> $OCF_RESKEY_outfile; fi + if [ ! -z "$OCF_RESKEY_force_user" ];then echo " force user = $OCF_RESKEY_force_user" >> $OCF_RESKEY_outfile; fi + if [ ! -z "$OCF_RESKEY_force_group" ];then echo " force group = $OCF_RESKEY_force_group" >> $OCF_RESKEY_outfile; fi + if [ ! -z "$OCF_RESKEY_extraopt" ];then echo " $OCF_RESKEY_extraopt" >> $OCF_RESKEY_outfile; fi + if [ ! -z "$OCF_RESKEY_extraopt_list" ];then + IFS=';' read -r -a array <<< "$OCF_RESKEY_extraopt_list" + for i in "${array[@]}";do + echo " $i" >> $OCF_RESKEY_outfile; + done + fi + smb_share_addinclude +} + +smb_share_delete() { + if [ -e $OCF_RESKEY_outfile ];then + rm -f $OCF_RESKEY_outfile 2>/dev/null + smb_share_delinclude + exit $OCF_SUCCESS + fi +} + +smb_share_reloadconfig() { + smbcontrol smbd reload-config 2>/dev/null + if [ $? -eq 0 ];then + exit $OCF_SUCCESS + else + ocf_log err "Seems you have an error in your samba configuration" + exit $OCF_ERR_CONFIGURED + fi +} + +smb_share_checktmpmount() { + + ISMOUNT=$(grep $OCF_RESKEY_confd /proc/mounts|grep -c tmpfs) + if [ $ISMOUNT -eq 0 ];then + ocf_log err "The directoy /etc/samba/conf.d need to be a tmpfs mount" + exit $OCF_ERR_CONFIGURED + fi +} + + +###################################################################### + +smb_share_usage() { + cat <<END +usage: $0 {start|stop|status|monitor|validate-all|meta-data} + +Expects to have a fully populated OCF RA-compliant environment set. +END + return $OCF_SUCCESS +} + +smb_share_start() { + smb_share_create + smb_share_reloadconfig +} + +smb_share_stop() { + smbcontrol smbd close-share $OCF_RESKEY_share > /dev/null 2>&1 + smb_share_delete + smb_share_reloadconfig +} + +smb_share_monitor() { + RES=$(smbcontrol smbd ping > /dev/null 2>&1) + if [ $? -eq 0 ];then + if [ $(testparm -s 2>/dev/null| egrep -c \\[$OCF_RESKEY_share\\]) -eq 1 ];then + return $OCF_SUCCESS + else + return $OCF_NOT_RUNNING + fi + else + return $OCF_NOT_RUNNING + fi +} + +smb_share_state() { + smb_share_checktmpmount + RES=$(smbcontrol smbd ping > /dev/null 2>&1) + if [ $? -eq 0 ];then + if [ $(testparm -s 2>/dev/null| egrep -c \\[$OCF_RESKEY_share\\]) -eq 1 ];then + ocf_log info "Samba share $OCF_RESKEY_share is active" + return $OCF_SUCCESS + else + ocf_log info "Samba share $OCF_RESKEY_share is not active" + return $OCF_NOT_RUNNING + fi + else + ocf_log info "Samba share $OCF_RESKEY_share is not active" + return $OCF_NOT_RUNNING + fi +} + +smb_share_validate() { + return $OCF_SUCCESS +} + + +case $__OCF_ACTION in +meta-data) meta_data + ;; +usage|help) smb_share_usage + ;; +esac + + +case $__OCF_ACTION in +start) smb_share_start + ;; +stop) smb_share_stop + ;; +status) smb_share_state + ;; +monitor) smb_share_monitor + ;; +validate-all) smb_share_validate + ;; +*) smb_share_usage + exit $OCF_ERR_UNIMPLEMENTED + ;; +esac +exit $? +# vi:sw=4:ts=8: |