#!/bin/sh ############################################################################# # # exchange-bmc-os-info: Set OS and BMC (Baseboard Management Controller) # parameters during system startup. # # version: 0.72 # # Authors: Charles Rose # Jordan Hargrave # # Description: Script to set OS information in the BMC; fetch BMC IP/URL # and set in the OS for use by other scripts/user. # # BMC IP and URL are made available in /var/run/bmc-info # # Example to launch BMC web-interface: # # . /var/run/bmc-info # # xdg-open $BMC_URL # # See here for details: # https://fedoraproject.org/wiki/Features/AgentFreeManagement # # OEM Specific: OEM specific ipmi commands go in: # 'oem_set_os_version' and 'oem_get_bmc_url' ############################################################################# # # chkconfig: 345 99 00 # description: Set OS name, hostname in BMC; make BMC IP/URL available in OS # processname: exchange-bmc-os-info # config: /etc/sysconfig/exchange-bmc-os-info # ### BEGIN INIT INFO # Provides: exchange-bmc-os-info # Required-Start: ipmi # Default-Start: 3 4 5 # Default-Stop: 0 1 2 6 ############################################################################# # GLOBALS ############################################################################# CONFIGFILE=/etc/sysconfig/exchange-bmc-os-info IPMI_TOOL=/usr/bin/ipmitool BMC_INFO=/var/run/bmc-info # BMC Manufacturer ID used in 'oem_set_os_version' and 'oem_get_bmc_url' DELL="674" #OTHER_OEM="123" # Defaults for ${CONFIGFILE} SET_OS_INFO="yes" RESET_OS_INFO="no" SET_BMC_INFO="yes" # getsysinfo and setsysinfo commands IPMI_SET_SYSINFO="${IPMI_TOOL} mc setsysinfo" IPMI_GET_SYSINFO="${IPMI_TOOL} mc getsysinfo" ############################################################################# SCRIPT_NAME=$(basename $0) # source config [ -r ${CONFIGFILE} ] && . ${CONFIGFILE} RETVAL=0 if [ -f /bin/gettext.sh ]; then GETTEXT=1 . /bin/gettext.sh OUTPUT="eval_gettext" else GETTEXT=0 OUTPUT="echo" fi ############################################################################# # Get Vendor ID of BMC for use in 'oem_set_os_version' and 'oem_get_bmc_url' # get_bmc_vendor_id() { BMC_VENDOR=$(${IPMI_TOOL} mc info 2>/dev/null | \ sed -n "s#^Manufacturer ID.*: ##p") [ -z "${BMC_VENDOR}" ] && RETVAL=4 } # set/getsysinfo support was added to ipmitool post v1.8.12 via this patch # http://sourceforge.net/mailarchive/message.php?msg_id=29647222 check_ipmitool() { if [ -x ${IPMI_TOOL} ]; then [ ! ${IPMI_GET_SYSINFO} >/dev/null 2>&1 ] && \ RETVAL=3 else RETVAL=2 fi } bmc_exists() { check_ipmitool [ $RETVAL -eq 0 ] && get_bmc_vendor_id return $RETVAL } ############################################################################# get_os_info() { OS_HOSTNAME=$(hostname) KERNEL_VERSION=$(uname -r -m) if [ -e /etc/lsb-release ] ; then . /etc/lsb-release NAME=${DISTRIB_ID} VERSION="${DISTRIB_RELEASE} ${DISTRIB_CODENAME}" fi # we prefer systemd's /etc/os-release over other sources [ -e /etc/os-release ] && . /etc/os-release OS_NAME=${NAME} OS_VERSION="${VERSION} kernel ${KERNEL_VERSION}" } oem_set_os_version() { # OS Version setting is not standard yet # we need per vendor oem commands case "${BMC_VENDOR}" in $DELL) ${IPMI_SET_SYSINFO} delloem_os_version \ "${OS_VERSION}" > /dev/null 2>&1 return $? ;; # Add OEM specific commands. # Example: # $OTHER_OEM) ${IPMI_SET_SYSINFO} otheroem_os_version \ # "${OS_VERSION}" > /dev/null 2>&1 # return $? # ;; *) return 0 ;; esac } set_os_info() { # Set and reset OS info in the BMC if [ "$1" = "reset" ]; then OS_NAME="" OS_HOSTNAME="" OS_VERSION="" fi ${IPMI_SET_SYSINFO} os_name "${OS_NAME}" >/dev/null 2>&1 \ || RETVAL=6 ${IPMI_SET_SYSINFO} primary_os_name "${OS_NAME}" >/dev/null 2>&1 \ || RETVAL=6 ${IPMI_SET_SYSINFO} system_name "${OS_HOSTNAME}" >/dev/null 2>&1 \ || RETVAL=6 oem_set_os_version || RETVAL=6 } ############################################################################# valid_url() { url="(https?|http)://[a-z0-9-]+(\.[a-z0-9-]+)+([/?].*)?" printf -- "%s" "${TMP_URL}"| grep -Eq "^${url}" return $? } oem_get_bmc_url() { # BMC URL is not standard yet # we need per vendor oem commands case "$BMC_VENDOR" in $DELL) TMP_URL=$(${IPMI_GET_SYSINFO} delloem_url 2> /dev/null) ;; # Add OEM specific commands # Example: # $OTHER_OEM) # TMP_URL=$(${IPMI_GET_SYSINFO} otheroem_url 2> /dev/null) # ;; *) TMP_URL="" ;; esac valid_url && BMC_URL=${TMP_URL} || BMC_URL="" } valid_ip() { #Thanks to mkyong.com octet="([01]?[[:digit:]][[:digit:]]?|2[0-4][[:digit:]]|25[0-5])" printf -- "%s" "${TMP_IPv4}"| grep -Eq "^${octet}\\.${octet}\\.${octet}\\.${octet}$" return $? } get_bmc_ip() { #Thanks to http://ingvar.blog.redpill-linpro.com for CHANNEL in `seq 1 14` do [ $(${IPMI_TOOL} lan print ${CHANNEL} 2>/dev/null \ | grep -q "^Set") ] || break done # Get BMC_IPv4 and BMC_URL from BMC TMP_IPv4=$(${IPMI_TOOL} lan print ${CHANNEL} 2>/dev/null \ | sed -n "s#^IP Address .*: ##p") valid_ip && BMC_IPv4=${TMP_IPv4} || BMC_IPv4="" } get_bmc_info() { get_bmc_ip if [ -z "${BMC_IPv4}" ] || [ "${BMC_IPv4}" = "0.0.0.0" ]; then BMC_IPv4="" RETVAL=5 else # URL makes sense only if there is an IP oem_get_bmc_url fi } set_bmc_info() { if [ ! $(touch "${BMC_INFO}" && chmod 600 "${BMC_INFO}") ]; then printf "BMC_IPv4=%s\n" "${BMC_IPv4}" > "${BMC_INFO}" [ -n "${BMC_URL}" ] && \ printf "BMC_URL=%s\n" "${BMC_URL}" >> "${BMC_INFO}" else RETVAL=5 fi } unset_bmc_info() { [ -f ${BMC_INFO} ] && rm -f ${BMC_INFO} > /dev/null 2>&1 } ############################################################################# start() { if bmc_exists; then [ "${SET_OS_INFO}" = "yes" ] && \ get_os_info && set_os_info if [ "${SET_BMC_INFO}" = "yes" ]; then get_bmc_info if [ ${RETVAL} -eq 0 ]; then set_bmc_info fi fi fi } ############################################################################# stop() { if bmc_exists; then # reset OS info while system reboots # aids with debugging OS boot-up issues if [ "${RESET_OS_INFO}" = "yes" ]; then set_os_info reset fi unset_bmc_info fi } ############################################################################# restart() { stop [ $RETVAL -eq 0 ] && start } ############################################################################# status() { [ -r ${BMC_INFO} ] && \ grep -q "BMC_IPv4" "${BMC_INFO}" >/dev/null 1>&2 && \ BMC_STATUS="ok" || BMC_STATUS="inactive" ${OUTPUT} "${SCRIPT_NAME}: ${BMC_STATUS}" 1>&2 [ ${GETTEXT} -eq 1 ] && echo } ############################################################################# usage() { ${OUTPUT} "Usage: ${SCRIPT_NAME} {start|stop|restart|status}" 1>&2 [ ${GETTEXT} -eq 1 ] && echo RETVAL=1 } ############################################################################# # MAIN ############################################################################# case "$1" in start) start ;; stop) stop ;; restart) restart ;; status) status ;; *) usage ;; esac case "$RETVAL" in 0|1) ;; 2) ${OUTPUT} "${SCRIPT_NAME}: ipmitool(1) not found." 1>&2 ;; 3) ${OUTPUT} "${SCRIPT_NAME}: this version of ipmitool does not support getsysinfo." 1>&2 ;; 4) ${OUTPUT} "${SCRIPT_NAME}: failed to communicate with BMC." 1>&2 ;; 5) ${OUTPUT} "${SCRIPT_NAME}: failed to set OS information in BMC." 1>&2 ;; 6) ${OUTPUT} "${SCRIPT_NAME}: failed to get BMC information." 1>&2 ;; *) ${OUTPUT} "${SCRIPT_NAME}: unexpected error." 1>&2 ;; esac if [ ${RETVAL} -gt 1 ]; then ${OUTPUT} " Return code: ${RETVAL}" 1>&2 [ ${GETTEXT} -eq 1 ] && echo fi exit ${RETVAL} ############################################################################# # end of file #############################################################################