This repository has been archived by the owner on Jan 11, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
xrd_mk_config
executable file
·362 lines (291 loc) · 14.7 KB
/
xrd_mk_config
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
#!/usr/bin/env bash
command -v curl &> /dev/null || { echo "curl command not found; do : yum -y install curl.x86_64"; exit 1; }
command -v bzip2 &> /dev/null || { echo "bzip2 command not found (logs compression); do : yum -y install bzip2.x86_64"; exit 1; }
command -v pgrep &> /dev/null || { echo "pgrep command not found; do : yum -y install procps-ng.x86_64"; exit 1; }
command -v awk &> /dev/null || { echo "awk command not found; do : yum -y install awk"; exit 1; }
CURLCMD="/usr/bin/curl --ipv4 -m 1 -fsSLk"
######################################
get_name_extension () {
local filename="${1##*/}"
local extension="${1##*.}"
echo "${filename%.*}" "${extension}"
}
######################################
cfg_set_value () {
local CFGFILE="$1"
local KEY="$2"
local VALUE="$3"
sed --follow-symlinks -i "s#^\($KEY\s*=\s*\).*\$#\1\"$VALUE\"#" "${CFGFILE}"
}
######################################
cfg_set_xrdvalue () {
local CFGFILE="$1"
local KEY="$2"
local VALUE="$3"
sed --follow-symlinks -i "s#^\#@@\($KEY\s*=\s*\).*\$#\#@@\1\"$VALUE\"#" "${CFGFILE}"
}
monalisa_info () {
######################################
## Get all relevant server information from MonaLisa
# links to alimonitor to query about info
local ALIMON_SE_URL ALIMON_IP_URL
ALIMON_SE_URL='"http://alimonitor.cern.ch/services/se.jsp?se='"${SE_NAME}"'&ml_ip=true&resolve=true"' #'
ALIMON_IP_URL="http://alimonitor.cern.ch/services/ip.jsp"
## if SE_NAME not found in system.cnf
[[ -z "${SE_NAME}" ]] && { echo "SE name is not defined in system.cnf!" && exit 1; }
## Get SE info from MonaLisa and check if the SE name is valid; try 3 times before fail and exit
local SE_INFO
SE_INFO=$(eval "${CURLCMD}" "${ALIMON_SE_URL}";)
[[ -z "${SE_INFO}" ]] && { sleep 1; SE_INFO=$(eval "${CURLCMD}" "${ALIMON_SE_URL}";); }
[[ -z "${SE_INFO}" ]] && { sleep 2; SE_INFO=$(eval "${CURLCMD}" "${ALIMON_SE_URL}";); }
[[ "${SE_INFO}" == "null" ]] || [[ -z "${SE_INFO}" ]] && { echo "The stated SE name ${SE_NAME} is not found - either bad conectivity or wrong SE name"; exit 1; }
[[ -n "${XRDCTL_DEBUG}" ]] && echo -e "${SE_INFO}\n\nFound SE_NAME=${SE_NAME}"
## Find information about site from ML
MONALISA_HOST=$(/bin/awk -F": " '/MLSERVICE_/ {print $2}' <<< "${SE_INFO}" | head -n1) #'
## Validate the ip - make sure is a public one and the reverse match the defined hostname
local MYNET MYIP REVERSE
MYNET=$(eval "${CURLCMD}" "${ALIMON_IP_URL}")
[[ -z "${MYNET}" ]] && { sleep 1; MYNET=$(eval "${CURLCMD}" "${ALIMON_IP_URL}"); }
[[ -z "${MYNET}" ]] && { sleep 2; MYNET=$(eval "${CURLCMD}" "${ALIMON_IP_URL}"); }
[[ -z "${MYNET}" ]] && { echo "MYNET not found, maybe bad connectivity to alimonitor?" && exit 1; }
[[ -n "${XRDCTL_DEBUG}" ]] && echo -e "${MYNET}\n"
## Network information and validity checking
MYIP=$(/bin/awk '/IP/ {gsub("IP:","",$1); print $1;}' <<< "${MYNET}") #'
REVERSE=$(/bin/awk '/FQDN/ {gsub("FQDN:","",$1); print $1;}' <<< "${MYNET}" ) #'
## make sure the exit public ip is locally configured
local ip_list
ip_list=$(/sbin/ip addr show scope global up | /bin/awk '/inet/ {split ($2,ip,"/"); print ip[1];}') #'
[[ "${ip_list}" =~ ${MYIP} ]] || { echo "Server without public/rutable ip. No NAT schema supported at this moment"; exit 1; }
## what is my local set hostname
local MYHNAME
MYHNAME=$(/bin/hostname -f)
[[ -z "${MYHNAME}" ]] && MYHNAME=$(/usr/bin/cat /proc/sys/kernel/hostname)
[[ -z "${MYHNAME}" ]] && MYHNAME=$(/usr/bin/hostnamectl | /usr/bin/awk '/hostname/ {print $NF;}')
[[ -z "${MYHNAME}" ]] && { echo "Cannot determine hostname. Aborting."; exit 1; }
## make sure the locally configured hostname is the same with the external one
[[ "${MYHNAME}" != "${REVERSE}" ]] && { echo "detected hostname ${MYHNAME} does not corespond to reverse dns name ${REVERSE}"; exit 1; }
[[ -n "${XRDCTL_DEBUG}" ]] && echo "The FQDN appears to be : ${MYHNAME}"
## XROOTD Manager info
local MANAGER_HOST_PORT
MANAGER_HOST_PORT=$(/usr/bin/awk -F": " '/seioDaemons/ { gsub ("root://","",$2); print $2 }' <<< "${SE_INFO}" ) #'
IFS=':' read -r -a mgr_host_port_arr <<< "${MANAGER_HOST_PORT}"
MANAGERHOST="${mgr_host_port_arr[0]}"
MANAGERPORT="${mgr_host_port_arr[1]}"
LOCALPATHPFX=$(/usr/bin/awk -F": " '/seStoragePath/ {print $2;}' <<< "${SE_INFO}" ) #'
###############################################################################################
## WHAT IS MY ROLE?
# Default assumption
ROLE="server"
# ipv6 logic; we don't use it as storage have to be dual stack
# ipv4 ips recorded to the manager fqdn
local DNS_QUERY_IPv4 MANAGER_IP_LIST MANAGER_IPv4_LIST MANAGER_HOST_LIST
DNS_QUERY_IPv4=$(host -t A "${MANAGERHOST}")
[[ "${DNS_QUERY_IPv4}" =~ no.+record ]] || [[ "${DNS_QUERY_IPv4}" =~ NXDOMAIN ]] && DNS_QUERY_IPv4=""
[[ -n "${DNS_QUERY_IPv4}" ]] && MANAGER_IPv4_LIST=$(/usr/bin/awk '{print $NF;}' <<< "${DNS_QUERY_IPv4}") #'
MANAGER_HOST_LIST=$(for mgr in ${MANAGER_IPv4_LIST}; do host ${mgr} |/usr/bin/awk '{gsub(".$","",$NF); print $NF;}';done | sort -u)
MANAGER_IP_LIST=$(host "${MANAGERHOST}"| /usr/bin/awk '{print $NF;}')
#is my ip in manager ip list; so far we check only for ipv4 as storage have to be dual-stack anyway
[[ "${MANAGER_IP_LIST}" =~ ${MYIP} ]] && ROLE="manager";
# if MANGERHOST fqdn is an alias then register servers to all ips ## to be redone
MANAGER_IS_ALIAS=$(echo "${MANAGER_HOST_LIST}" | /usr/bin/wc -l)
export MONALISA_HOST MANAGERHOST MANAGERPORT LOCALPATHPFX ROLE MANAGER_IS_ALIAS
}
######################################
checkkeys() {
getLocations
local KEYS_REPO="http://alitorrent.cern.ch/src/xrd3/keys/"
local authz_dir1="/etc/grid-security/xrootd/"
local authz_dir2="${XRDHOME}/.globus/xrootd/"
local authz_dir3="${XRDHOME}/.authz/xrootd/"
local authz_dir=${authz_dir3} # default dir
for dir in ${authz_dir1} ${authz_dir2} ${authz_dir3}; do ## unless keys are found in locations searched by xrootd
[[ -e ${dir}/privkey.pem && -e ${dir}/pubkey.pem ]] && return 0;
done
[[ $(/usr/bin/id -u) == "0" ]] && authz_dir=${authz_dir1}
/bin/mkdir -p "${authz_dir}"
echo "Getting Keys and bootstrapping ${authz_dir}/TkAuthz.Authorization ..."
/usr/bin/curl -fsSLk -o "${authz_dir}/pubkey.pem" "${KEYS_REPO}/pubkey.pem" -o "${authz_dir}/privkey.pem" "${KEYS_REPO}/privkey.pem"
/bin/chmod 400 "${authz_dir}/privkey.pem" "${authz_dir}/pubkey.pem"
create_tkauthz "${authz_dir}"
/bin/chown -R "${XRDUSER}" "${XRDHOME}/.authz"
}
######################################
create_limits_conf () {
local FILE
FILE="99-xrootd_limits.conf"
echo "The generated file ${FILE} should be placed in /etc/security/limits.d/"
cat > ${FILE} <<EOF
${USER} hard nofile 65536
${USER} soft nofile 65536
${USER} hard nproc 1024
${USER} soft nproc 1024
EOF
echo "Generated file is ${FILE} with content :"
cat ${FILE}
echo "try : sudo cp ${FILE} /etc/security/limits.d/"
}
######################################
generate_systemd () {
# get information from the configuration file ${XRDCF}
eval "$(sed -ne 's/\#@@/local /gp;' ${XRDCF})"
[[ -z "${INSTANCE_NAME}" ]] && local INSTANCE_NAME="${__XRD_INSTANCE_NAME}"
# first we prepare the configuration file (it should be prezent)
cp -f "${XRDCF}" "xrootd-${INSTANCE_NAME}.cfg"
# remove all.pidpath; there will be files in /tmp/<instance name>/ but we will ignore them
sed -i '/all.pidpath/d' "xrootd-${INSTANCE_NAME}.cfg"
# adjust all.adminpath to /var/adm/xrootd-<instance name>
sed -i "/adminpath/s/.*/\/var\/adm\/xrootd-${INSTANCE_NAME}/" "xrootd-${INSTANCE_NAME}.cfg" #"
echo -e "The configuration file should be copied to /etc/xrootd/ directory :
sudo cp -f xrootd-${INSTANCE_NAME}.cfg /etc/xrootd/
and then enable the system provided xrootd systemd service :
sudo systemctl enable cmsd@${INSTANCE_NAME}.service xrootd@${INSTANCE_NAME}.service
N.B.!!! the format used specify the _instance_name_ : xrootd@<INSTANCE_NAME>.service
and assumes the configuration name format (and path) : /etc/xrootd/xrootd-<INSTANCE_NAME>.cfg
"
# now we have to customize the system provided systemd files
local cmsd_systemd_dir="/etc/systemd/system/cmsd@${INSTANCE_NAME}.service.d/"
local cmsd_custom_file="override_cmsd.conf"
local xrootd_systemd_dir="/etc/systemd/system/xrootd@${INSTANCE_NAME}.service.d/"
local xrootd_custom_file="override_xrootd.conf"
# log file is automatically "fenced" (taged with instance name) so lets leave it like this
# cmsd systemd conf file
cat > "${cmsd_custom_file}" <<EOF
[Unit]
AssertPathExists=/etc/xrootd/xrootd-%i.cfg
PartOf=xrootd@%i.service
Before=xrootd@%i.service
[Service]
User=${XRDUSER}
Group=${XRDUSER}
ExecStartPre=/usr/bin/mkdir -p /var/adm/xrootd-%i
ExecStartPre=/usr/bin/chown -R ${XRDUSER}:${XRDUSER} /var/adm/xrootd-%i
ExecStartPre=/usr/bin/chmod 1777 /var/log/xrootd /var/run/xrootd
WorkingDirectory=/var/adm/xrootd-%i
ExecStart=
ExecStart=/usr/bin/cmsd ${__CMSD_DEBUG} -k fifo -l /var/log/xrootd/cmsd.log -s /var/run/xrootd/cmsd-%i.pid -c /etc/xrootd/xrootd-%i.cfg -n %i
EOF
# xrootd systemd conf file
cat > "${xrootd_custom_file}" <<EOF
[Unit]
AssertPathExists=/etc/xrootd/xrootd-%i.cfg
After=cmsd@%i.service
BindsTo=cmsd@%i.service
[Service]
User=${XRDUSER}
Group=${XRDUSER}
ExecStartPre=/usr/bin/mkdir -p /var/adm/xrootd-%i
ExecStartPre=/usr/bin/chown -R ${XRDUSER}:${XRDUSER} /var/adm/xrootd-%i
ExecStartPre=/usr/bin/chmod 1777 /var/log/xrootd /var/run/xrootd
WorkingDirectory=/var/adm/xrootd-%i
ExecStart=
ExecStart=/usr/bin/xrootd ${__XRD_DEBUG} -k fifo -l /var/log/xrootd/xrootd.log -s /var/run/xrootd/xrootd-%i.pid -c /etc/xrootd/xrootd-%i.cfg -n %i
EOF
echo "
Check the contents of the two systemd service override files (${cmsd_custom_file} and ${xrootd_custom_file})
and then copy these files to the locations for systemd service customisation :
sudo -- bash -c 'mkdir -p ${cmsd_systemd_dir} ; cp -f ${cmsd_custom_file} ${cmsd_systemd_dir}'
sudo -- bash -c 'mkdir -p ${xrootd_systemd_dir} ; cp -f ${xrootd_custom_file} ${xrootd_systemd_dir}'
then start the services:
systemctl start xrootd@${INSTANCE_NAME}.service
systemctl status xrootd@${INSTANCE_NAME}.service
"
}
################################################################################################################
### START OF MAIN CODEPATH
## find the location of xrdctl script
SOURCE="${BASH_SOURCE[0]}"
while [ -h "${SOURCE}" ]; do ## resolve $SOURCE until the file is no longer a symlink
XRDCTLDIR="$( cd -P "$(dirname "${SOURCE}" )" && pwd )" ##"
SOURCE="$(readlink "${SOURCE}")" ##"
[[ "${SOURCE}" != /* ]] && SOURCE="${XRDCTLDIR}/${SOURCE}" ## if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
XRDCTLDIR="$(cd -P "$( dirname "${SOURCE}" )" && pwd)" ##"
XRDRUNDIR=${XRDRUNDIR:-${XRDCTLDIR}/run/} # location of logs, admin, core dirs
XRDCONFDIR=${XRDCONFDIR:-${XRDCTLDIR}/xrootd.conf/} # location of configuration file(s)
mkdir -p "${XRDRUNDIR}" "${XRDCONFDIR}"
if [[ -n "${1}" ]]; then
XRDCF_TMP="$(realpath -e ${1})"
shift
else
XRDCF_TMP="${XRDCONFDIR}/xrootd.xrootd.cf.tmp"
fi
[[ ! -e "${XRDCF_TMP}" ]] && { echo "Infered template conf file ${XRDCF_TMP} not found"; exit 1; }
SYSCNF="$(dirname $(realpath -e ${XRDCF_TMP}))/system.cnf" # main steering configuration file
[[ ! -e "${SYSCNF}" ]] && { echo "${SYSCNF} not found"; exit 1; }
source "${SYSCNF}"
if [[ -n "${XRDCTL_DEBUG}" ]]; then
echo "XRDCTL dir is : ${XRDCTLDIR}"
echo "XRDCONFDIR is : ${XRDCONFDIR}"
echo "XRDCF_TMP file is : ${XRDCF_TMP}"
fi
# array of defined oss.space partition
declare -a OSS_SPACE_LIST
for SPACE in $(ls -1d ${OSS_SPACE_DIRS} 2>/dev/null | sort -u); do
[[ ! -w "${SPACE}" ]] && echo "${SPACE} have no write permission for the current user ($(id -nu))"
OSS_SPACE_LIST+=("${SPACE}");
done
NR_SPACES="${#OSS_SPACE_LIST[@]}"
(( "${NR_SPACES}" < "1" )) && { echo "No OSS_SPACE_DIRS found in the declaration: ${OSS_SPACE_DIRS}"; exit 1; }
# establish the configuration files to be acted upon
declare -a CONF_LIST # container for configuration file(s)
if [[ -n ${XRD_MULTISRV} ]]; then
for DIR in "${OSS_SPACE_LIST[@]}"; do
CONF_LIST+=("${XRDCONFDIR}/$(sed 's#^/##;s#/#_#;s#_$##' <<< ${DIR}).xrdcfg");
done
else
# single server, let's have a clear hostname based name
CONF_LIST+=("${XRDCONFDIR}/$(hostname -s).xrdcfg");
fi
# clean up all previous .xrdcfg files
rm -f ${XRDCONFDIR}/*.xrdcfg
# let's query monalisa for info
monalisa_info
for i in "${!CONF_LIST[@]}"; do
CFG="${CONF_LIST[i]}"
cp "${XRDCF_TMP}" "${CFG}"
INSTANCE_NAME=$(basename "${CFG}" .xrdcfg)
## set the instance name for both processes xrootd and cmsd
cfg_set_xrdvalue "${CFG}" __INSTANCE_NAME "${INSTANCE_NAME}"
## set the xrootd and cmsd log file
cfg_set_xrdvalue "${CFG}" __XRD_LOG "${XRDRUNDIR}/logs/xrdlog"
cfg_set_xrdvalue "${CFG}" __CMSD_LOG "${XRDRUNDIR}/logs/cmslog"
## Subscribe to all redirector ips and use load-balancing mode
## see http://xrootd.org/doc/dev49/cms_config.htm#_Toc506069400
(( MANAGER_IS_ALIAS > 1 )) && sed --follow-symlinks -i '/all\.manager/s/.*/all.manager all $myRedirector+ $portCMSD/' "${CFG}"
sed --follow-symlinks -i "
s#SITENAME#${SE_NAME}#g;
s#MANAGERHOST#${MANAGERHOST}#g;
s#XRDMANAGERPORT#${XRDMANAGERPORT}#g;
s#CMSDMANAGERPORT#${CMSDMANAGERPORT}#g;
s#LOCALPATHPFX#${LOCALPATHPFX}#g;
s#MONALISA_HOST#${MONALISA_HOST}#g;
" "${CFG}";
# Configure the threads scheduling for xrootd
# we allow xrootd to use up to 90% of maximum number of threads allowed to user
# XRD_MAX_PROCS=$(/usr/bin/bc -l <<< "scale=0; ($(ulimit -u) * 0.9)/1" ) #"
# let's use a hard relativly small number; in my case the IOWait load will increase to this number for many concurent requests
XRD_MAX_PROCS="128"
# we compute the number of idle threads waiting for connections as the number of logical cores found
XRD_IDLE_THREADS=$(grep -c '^processor' /proc/cpuinfo)
# now use these info in the configuration file; we set unsed threads cleaning time to 60s
sed --follow-symlinks -i "/xrd.sched/s/.*/xrd.sched mint 16 idle 60 avlt ${XRD_IDLE_THREADS} maxt ${XRD_MAX_PROCS}/" "${CFG}";
if [[ -n ${XRD_MULTISRV} || "${NR_SPACES}" -lt "2" ]]; then
sed --follow-symlinks -i "
s#LOCALROOT#${OSS_SPACE_LIST[i]}#g;
s/^[[:space:]]*OSS_SPACE/## OSS_SPACE/g;
" "${CFG}";
# configure server port
XRDSERVERPORT_MULTISRV=$(( XRDSERVERPORT + i))
sed --follow-symlinks -i "s#XRDSERVERPORT#${XRDSERVERPORT_MULTISRV}#g;" "${CFG}";
else
sed --follow-symlinks -i "
s#XRDSERVERPORT#${XRDSERVERPORT}#g;
s#LOCALROOT#${LOCALROOT}#g;
" "${CFG}";
OSS_SPACE_TXT=""
for DIR in "${OSS_SPACE_LIST[@]}"; do
[[ -n "${OSS_SPACE_TXT}" ]] && OSS_SPACE_TXT="${OSS_SPACE_TXT}\noss.space ${OSS_SPACE_NAME} ${DIR}" || OSS_SPACE_TXT="oss.space ${OSS_SPACE_NAME} ${DIR}"
done
sed --follow-symlinks -i "s#^.*OSS_SPACE.*\$#${OSS_SPACE_TXT}#g;" "${CFG}";
fi
done