#!/bin/bash # Define logging functions send_systemd_notify() { # return if no systemd-notify found type systemd-notify >/dev/null 2>&1 || return systemd-notify "$@" } log_failure_msg() { send_systemd_notify --status "Error: $@" echo $@ } # Create bdii config for the NorduGrid/ARC information system ARC_LOCATION=${ARC_LOCATION:-/cvmfs/dirac.egi.eu/dirac/v8.0.47/Linux-x86_64} if [ ! -d "$ARC_LOCATION" ]; then log_failure_msg "ARC_LOCATION ($ARC_LOCATION) not found" exit 1 fi # ARC_CONFIG if [ "x$ARC_CONFIG" = "x" ]; then if [ -r $ARC_LOCATION/etc/arc.conf ]; then ARC_CONFIG=$ARC_LOCATION/etc/arc.conf elif [ -r /etc/arc.conf ]; then ARC_CONFIG=/etc/arc.conf fi if [ ! -r "$ARC_CONFIG" ]; then log_failure_msg "arc.conf is missing at path: $ARC_CONFIG or no ARC_LOCATION is set" log_failure_msg "If this file is in a non-standard place it can be set" log_failure_msg " with the ARC_CONFIG environment variable" exit 1 fi fi # Define runtime config location for infosys LDAP prefix=/cvmfs/dirac.egi.eu/dirac/v8.0.47/Linux-x86_64 runtime_config_dir=/run/arc if [ ! -d "$runtime_config_dir" ]; then mkdir -p "$runtime_config_dir" fi export ARC_RUNCONFIG="$runtime_config_dir/arc-infosys-ldap.conf" unset runtime_config_dir unset prefix # Define arcconfig-parser and dump running configuration arcconfig_parser=${ARC_LOCATION}/libexec/arc/arcconfig-parser ${arcconfig_parser} -c ${ARC_CONFIG} --save -r ${ARC_RUNCONFIG} # Check for infosys block if ! ${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b infosys; then log_failure_msg "Missing [infosys] configuration block" exit 1 fi # Check for infosys/ldap block if ! ${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b infosys/ldap; then log_failure_msg "Missing [infosys/ldap] configuration block" exit 1 fi eval $(${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b infosys/ldap -b infosys -b common -e bash) bdii_user=$CONFIG_user if [ -z "$bdii_user" ]; then # Get ldap user from passwd bdii_user=`getent passwd ldap openldap | sed 's/:.*//;q'` if [ -z "$bdii_user" ]; then echo "Warning, could not find ldap or openldap user" echo "resorting to using the root user" bdii_user=root fi fi # These values may be set in arc.conf, otherwise use sensible defaults providerlog=${CONFIG_logfile:-/var/log/arc/infoprovider.log} bdii_location=${CONFIG_bdii_location:-/usr} bdii_update_cmd=${CONFIG_bdii_update_cmd:-${bdii_location}/sbin/bdii-update} if [ ! -x $bdii_update_cmd ]; then log_failure_msg "Can not find bdii-update command at: $bdii_update_cmd." echo "Please set bdii_update_cmd in arc.conf" exit 1 fi infosys_ldap_run_dir=${CONFIG_infosys_ldap_run_dir:-/run/arc/infosys} mkdir -p ${infosys_ldap_run_dir} chown ${bdii_user}: ${infosys_ldap_run_dir} # Put BDII update helper to known directory helpers_dir=$infosys_ldap_run_dir if [ -n "$FORCE_ARC_RUNDIR" ]; then helpers_dir="${FORCE_ARC_RUNDIR}/infosys" mkdir -p "${helpers_dir}" fi bdii_update_exechelper_cmd=${helpers_dir}/bdii-update.cmd rm -f $bdii_update_exechelper_cmd bdii_update_posthelper_cmd=${helpers_dir}/bdii-update-post.cmd rm -f $bdii_update_posthelper_cmd bdii_debug_level=${CONFIG_bdii_debug_level:-WARNING} bdii_tmp_dir=${CONFIG_bdii_tmp_dir:-/var/tmp/arc/bdii} bdii_var_dir=${CONFIG_bdii_var_dir:-/var/lib/arc/bdii} bdii_run_dir=${CONFIG_bdii_run_dir:-/run/arc/bdii} bdii_log_dir=${CONFIG_bdii_log_dir:-/var/log/arc/bdii} bdii_log_file="${bdii_log_dir}/bdii-update.log" bdii_slapd_conf=${infosys_ldap_run_dir}/bdii-slapd.conf bdii_default_ldif=${bdii_tmp_dir}/provider/arc-default.ldif.pl bdii_ldif_dir=${bdii_tmp_dir}/ldif bdii_provider_dir=${bdii_tmp_dir}/provider bdii_plugin_dir=${bdii_tmp_dir}/plugin bdii_port=${CONFIG_port:-2135} # Using uppercase characters in bdii_bind will break infosys. bdii_bind="o=grid" # $bdii_provider_timeout refers to the time bdii waits for the provider output to complete. bdii_provider_timeout=${CONFIG_bdii_provider_timeout:-10800} # $infoproviders_timelimit is a-rex's infoproviders timeout. infoproviders_timelimit=$(${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b arex -o infoproviders_timelimit) infoproviders_timelimit=${infoproviders_timelimit:-10800} # $wakeupperiod is the time a-rex waits before running infoproviders again. wakeupperiod=$(${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b arex -o wakeupperiod) wakeupperiod=${wakeupperiod:-120} bdii_archive_size=${CONFIG_bdii_archive_size:-0} # The infoprovider does the waiting, no need for BDII to do it too. Use # some small timeout to protect the system in case there is a problem with # the provier bdii_breathe_time=${CONFIG_bdii_breathe_time:-10} # max_cycle is the time bdii will trust the content of any provider to be fresh enough max_cycle=$(( $bdii_provider_timeout + $infoproviders_timelimit + $wakeupperiod )) bdii_read_timeout=${CONFIG_bdii_read_timeout:-$max_cycle} bdii_delete_delay=${CONFIG_bdii_delete_delay:-0} # PIDFile location handling update_pid_file=$( readlink -m ${CONFIG_bdii_update_pid_file:-$bdii_run_dir/bdii-update.pid} ) # forced pidfile location instead of arc.conf-based (if FORCE_ARC_RUNDIR is set) if [ -n "$FORCE_ARC_RUNDIR" ]; then pid_dir="${FORCE_ARC_RUNDIR}/bdii" mkdir -p "$pid_dir" chown -R ${bdii_user}: "$pid_dir" pid_file="$( readlink -m ${pid_dir}/bdii-update.pid )" if [ "x${update_pid_file}" != "x${pid_file}" ]; then custom_pid_file="${update_pid_file}" rm -f "${custom_pid_file}" update_pid_file="${pid_file}" fi unset pid_dir pid_file fi rm -f "${update_pid_file}" # Debian does not have /run/lock/subsys if [ -d /run/lock/subsys ]; then update_lock_file=${update_lock_file:-/run/lock/subsys/arc-bdii-update} else update_lock_file=${update_lock_file:-/run/lock/arc-bdii-update} fi # Check directories and permissions mkdir -p `dirname $providerlog` touch ${providerlog} chown ${bdii_user}: ${providerlog} mkdir -p $bdii_log_dir chown -R ${bdii_user}: ${bdii_log_dir} if ${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b infosys/nordugrid || \ ${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b infosys/glue1 || \ ${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b infosys/glue2/ldap; then if [ ! -f "$ARC_LOCATION/share/arc/InfosysHelper.pm" ]; then log_failure_msg "InfosysHelper.pm not found. Is A-REX installed?" echo "For operation without A-REX, disable publishing of cluster information" echo "([infosys/nordugrid], [infosys/glue1] and [infosys/glue2/ldap])" exit 1 fi fi BDII_CONF=${CONFIG_bdii_conf:-${infosys_ldap_run_dir}/bdii.conf} resource_location="" resource_latitude="" resource_longitude="" cpuscalingreferencesi00="" processorotherdescription="" gluesiteweb="" gluesiteuniqueid="" if ${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b infosys/glue1; then eval $(${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b infosys/glue1 -e bash) resource_location=${CONFIG_resource_location} resource_latitude=${CONFIG_resource_latitude} resource_longitude=${CONFIG_resource_longitude} cpuscalingreferencesi00=${CONFIG_cpu_scaling_reference_si00} processorotherdescription=${CONFIG_processor_other_description} gluesiteweb=${CONFIG_glue_site_web} gluesiteuniqueid=${CONFIG_glue_site_unique_id} if ${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b infosys/glue1/site-bdii ; then provide_glue_site_info="true" else provide_glue_site_info="false" fi if [ "x$resource_location" = "x" ]; then log_failure_msg "If [infosys/glue1] is enabled, then resource_location must be set." echo "It should be set to a free-form string describing the location," echo "for example: 'Kastrup, Denmark'" exit 1 fi if [[ "x$resource_location" =~ "/" ]]; then log_failure_msg "Wrong location format. Please do NOT use slashes / ." echo "It should be set to a free-form string describing the location," echo "for example: 'Kastrup, Denmark'" exit 1 fi if [ "x$resource_latitude" = "x" ]; then log_failure_msg "If [infosys/glue1] is enabled, then resource_latitude must be set." echo "It should be set to the latitude for the location," echo "for example: '55.75000'" exit 1 fi if [ "x$resource_longitude" = "x" ]; then log_failure_msg "If [infosys/glue1] is enabled, then resource_longitude must be set." echo "It should be set to the longitude for the location," echo "for example: '12.41670'" exit 1 fi if [ "x$cpuscalingreferencesi00" = "x" ]; then log_failure_msg "If [infosys/glue1] is enabled, then cpu_scaling_reference_si00 must be set." echo "It should be set to the SI00 value," echo "for example: '2400'" exit 1 fi if [ "x$processorotherdescription" = "x" ]; then log_failure_msg "If [infosys/glue1] is enabled, then processor_other_description must be set." echo "It should be set to a value like in the example,where cores is the average number" echo "of cores in the machine" echo "for example: 'Cores=3,Benchmark=9.8-HEP-SPEC06'" exit 1 fi if [ "x$gluesiteweb" = "x" ]; then log_failure_msg "If [infosys/glue1] is enabled, then glue_site_web must be set." echo "It should be set to a url for the website belonging to the institution holding the resource," echo "for example: 'http://www.ndgf.org'" exit 1 fi if [ "x$gluesiteuniqueid" = "x" ]; then log_failure_msg "If [infosys/glue1] is enabled, then glue_site_unique_id must be set." echo "It should be set to a unique id to the resource, this should be entered into the GocDb" echo "for example: 'NDGF-T1'" exit 1 fi fi # Create directories for storing temporary scripts and check permissions etc mkdir -p $bdii_var_dir mkdir -p $bdii_run_dir mkdir -p $bdii_tmp_dir mkdir -p $bdii_tmp_dir/ldif mkdir -p $bdii_tmp_dir/provider mkdir -p $bdii_tmp_dir/plugin # change permissions if user is not root chown -R ${bdii_user}: ${bdii_var_dir} chown -R ${bdii_user}: ${bdii_run_dir} chown -R ${bdii_user}: ${bdii_tmp_dir} # Generate bdii configuration rm -f ${BDII_CONF} cat <<-EOF >> ${BDII_CONF} # This file was automatically generated by $0 # Do not modify BDII_LOG_FILE=$bdii_log_file BDII_PID_FILE=$update_pid_file BDII_LOG_LEVEL=$bdii_debug_level BDII_LDIF_DIR=$bdii_ldif_dir BDII_PROVIDER_DIR=$bdii_provider_dir BDII_PLUGIN_DIR=$bdii_plugin_dir BDII_PORT=$bdii_port BDII_BREATHE_TIME=$bdii_breathe_time BDII_READ_TIMEOUT=$bdii_read_timeout BDII_ARCHIVE_SIZE=$bdii_archive_size BDII_DELETE_DELAY=$bdii_delete_delay BDII_USER=$bdii_user BDII_VAR_DIR=$bdii_var_dir BDII_RUN_DIR=$bdii_run_dir BDII_BIND=$bdii_bind SLAPD_CONF=$bdii_slapd_conf EOF # Generate default ldif cat <<-EOF > $bdii_default_ldif #!/usr/bin/perl # This file was automatically generated by $0 # Do not modify use POSIX; print "\n"; print "dn: o=grid\n"; print "objectClass: organization\n"; print "o: grid\n"; print "\n"; print "dn: Mds-Vo-name=local,o=grid\n"; print "objectClass: Mds\n"; print "Mds-Vo-name: local\n"; print "Mds-validfrom: " . strftime("%Y%m%d%H%M%SZ\n", gmtime()); print "Mds-validto: " . strftime("%Y%m%d%H%M%SZ\n", gmtime(time() + 3600)); print "\n"; print "dn: Mds-Vo-name=resource,o=grid\n"; print "objectClass: Mds\n"; print "Mds-Vo-name: resource\n"; print "Mds-validfrom: " . strftime("%Y%m%d%H%M%SZ\n", gmtime()); print "Mds-validto: " . strftime("%Y%m%d%H%M%SZ\n", gmtime(time() + 3600)); print "\n"; print "dn: o=glue\n"; print "objectClass: organization\n"; print "o: glue\n"; EOF chmod +x $bdii_default_ldif # Create ARC ldif generator file ldif_generator_file=${bdii_tmp_dir}/provider/arc-nordugrid-bdii-ldif rm -f ${ldif_generator_file} touch ${ldif_generator_file} ldif_glue1_generator=${infosys_ldap_run_dir}/arc-glue-bdii-ldif ldif_script=${infosys_ldap_run_dir}/ldif-provider.sh cat <<-EOF > ${ldif_generator_file} #!/usr/bin/perl # This file was automatically generated by the $0 # Do not modify EOF # NG and GLUE2 come directly from a-rex infoprovider cat <<-EOF >> ${ldif_generator_file} BEGIN { unshift @INC, '$ARC_LOCATION/share/arc'; } use InfosysHelper; exit 1 unless InfosysHelper::ldifIsReady('$infosys_ldap_run_dir', '$max_cycle'); EOF if ${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b infosys/nordugrid || \ ${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b infosys/glue2/ldap; then echo "system('$ldif_script');" >> ${ldif_generator_file} fi if ${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b infosys/glue1; then ldif_generator_file_ng=${bdii_tmp_dir}/provider/arc-nordugrid-bdii-ldif ldif_generator_file_glue=${bdii_tmp_dir}/provider/arc-glue-bdii-ldif rm -f ${ldif_generator_file_glue} touch ${ldif_generator_file_glue} # We use , instead of / here to allow for / in path # resource_location though, can contain commas.. sed "s,\$LDIF_GENERATOR_FILE_NG,$ldif_generator_file_ng,g; s/\$LOC/\"$resource_location\"/g; s/\$LAT/$resource_latitude/g; s/\$LONG/$resource_longitude/g; s/\$CPUSCALINGREFERENCESI00/$cpuscalingreferencesi00/g; s/\$PROCESSOROTHERDESCRIPTION/$processorotherdescription/g; s,\$GLUESITEWEB,$gluesiteweb,g; s,\$BDIIPORT,$bdii_port,g; s,\$GLUESITEUNIQUEID,$gluesiteuniqueid,g; s,\$PROVIDE_GLUE_SITE_INFO,$provide_glue_site_info,g; " $ARC_LOCATION/share/arc/glue-generator.pl > ${ldif_generator_file_glue} chmod +x ${ldif_generator_file_glue} echo "system('$ldif_glue1_generator');" >> ${ldif_generator_file} fi chmod +x ${ldif_generator_file} # Site BDII if [ "x$provide_glue_site_info" == "xtrue" ]; then eval $(${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b infosys/glue1/site-bdii -e bash) unique_id=${CONFIG_unique_id} url=${CONFIG_url} if [ -z "$unique_id" -o -z "$url" ]; then log_failure_msg "Mandaroty options 'unique_id' and 'url' should be configured for Site-BDII." exit 1 fi site_config="${bdii_tmp_dir}/${unique_id}.conf" site_provider="$bdii_provider_dir/site_${unique_id}.sh" echo "$unique_id $url" > "$site_config" # Create script and make glite provider use arc directories cat <<-EOF > $site_provider #!/bin/sh export GLITE_LOCATION_VAR=${bdii_tmp_dir} $ARC_LOCATION/share/arc/glite-info-provider-ldap -m "$unique_id" -c $site_config EOF chmod +x $site_provider fi # Helper script to start BDII Update switching to BDII user if [ -x /sbin/runuser ]; then RUNUSER=runuser else RUNUSER=su fi USERSHELL=${USERSHELL:-"/bin/sh"} if [ ! -x ${USERSHELL} ]; then log_failure_msg "Could not find ${USERSHELL}" exit 1 fi cat <<-EOF > ${bdii_update_exechelper_cmd} if [ \$( id -u ) = 0 ]; then exec $RUNUSER -s "$USERSHELL" -c "${bdii_update_cmd} -c ${BDII_CONF} -d" ${bdii_user} else exec ${bdii_update_cmd} -c ${BDII_CONF} -d fi EOF cat <<-EOF > ${bdii_update_posthelper_cmd} iterlimit=30 while [ \$iterlimit -ge 0 ] && ! [ -r "${update_pid_file}" ]; do sleep 1 iterlimit=\$(expr \$iterlimit - 1) done EOF # copy forced pidfile to custom arc.conf pidfile (if needed) if [ -n "${custom_pid_file}" ]; then echo "mkdir -p \"${custom_pid_file%/*}\"" >> ${bdii_update_posthelper_cmd} echo "cp -a \"${update_pid_file}\" \"${custom_pid_file}\"" >> ${bdii_update_posthelper_cmd} fi