diff --git a/Dell_iDRAC_fan_controller.sh b/Dell_iDRAC_fan_controller.sh index 393719a..a932c9a 100644 --- a/Dell_iDRAC_fan_controller.sh +++ b/Dell_iDRAC_fan_controller.sh @@ -4,99 +4,7 @@ # Not working in some setups : https://github.com/tigerblue77/Dell_iDRAC_fan_controller/issues/48 # set -euo pipefail -# Define global functions -# This function applies Dell's default dynamic fan control profile -function apply_Dell_fan_control_profile () { - # Use ipmitool to send the raw command to set fan control to Dell default - ipmitool -I $IDRAC_LOGIN_STRING raw 0x30 0x30 0x01 0x01 > /dev/null - CURRENT_FAN_CONTROL_PROFILE="Dell default dynamic fan control profile" -} - -# This function applies a user-specified static fan control profile -function apply_user_fan_control_profile () { - # Use ipmitool to send the raw command to set fan control to user-specified value - ipmitool -I $IDRAC_LOGIN_STRING raw 0x30 0x30 0x01 0x00 > /dev/null - ipmitool -I $IDRAC_LOGIN_STRING raw 0x30 0x30 0x02 0xff $HEXADECIMAL_FAN_SPEED > /dev/null - CURRENT_FAN_CONTROL_PROFILE="User static fan control profile ($DECIMAL_FAN_SPEED%)" -} - -# Retrieve temperature sensors data using ipmitool -# Usage : retrieve_temperatures $IS_EXHAUST_TEMPERATURE_SENSOR_PRESENT $IS_CPU2_TEMPERATURE_SENSOR_PRESENT -function retrieve_temperatures () { - if (( $# != 2 )) - then - printf "Illegal number of parameters.\nUsage: retrieve_temperatures \$IS_EXHAUST_TEMPERATURE_SENSOR_PRESENT \$IS_CPU2_TEMPERATURE_SENSOR_PRESENT" >&2 - return 1 - fi - local IS_EXHAUST_TEMPERATURE_SENSOR_PRESENT=$1 - local IS_CPU2_TEMPERATURE_SENSOR_PRESENT=$2 - - local DATA=$(ipmitool -I $IDRAC_LOGIN_STRING sdr type temperature | grep degrees) - - # Parse CPU data - local CPU_DATA=$(echo "$DATA" | grep "3\." | grep -Po '\d{2}') - CPU1_TEMPERATURE=$(echo $CPU_DATA | awk '{print $1;}') - if $IS_CPU2_TEMPERATURE_SENSOR_PRESENT - then - CPU2_TEMPERATURE=$(echo $CPU_DATA | awk '{print $2;}') - else - CPU2_TEMPERATURE="-" - fi - - # Parse inlet temperature data - INLET_TEMPERATURE=$(echo "$DATA" | grep Inlet | grep -Po '\d{2}' | tail -1) - - # If exhaust temperature sensor is present, parse its temperature data - if $IS_EXHAUST_TEMPERATURE_SENSOR_PRESENT - then - EXHAUST_TEMPERATURE=$(echo "$DATA" | grep Exhaust | grep -Po '\d{2}' | tail -1) - else - EXHAUST_TEMPERATURE="-" - fi -} - -function enable_third_party_PCIe_card_Dell_default_cooling_response () { - # We could check the current cooling response before applying but it's not very useful so let's skip the test and apply directly - ipmitool -I $IDRAC_LOGIN_STRING raw 0x30 0xce 0x00 0x16 0x05 0x00 0x00 0x00 0x05 0x00 0x00 0x00 0x00 > /dev/null -} - -function disable_third_party_PCIe_card_Dell_default_cooling_response () { - # We could check the current cooling response before applying but it's not very useful so let's skip the test and apply directly - ipmitool -I $IDRAC_LOGIN_STRING raw 0x30 0xce 0x00 0x16 0x05 0x00 0x00 0x00 0x05 0x00 0x01 0x00 0x00 > /dev/null -} - -# Returns : -# - 0 if third-party PCIe card Dell default cooling response is currently DISABLED -# - 1 if third-party PCIe card Dell default cooling response is currently ENABLED -# - 2 if the current status returned by ipmitool command output is unexpected -# function is_third_party_PCIe_card_Dell_default_cooling_response_disabled() { -# THIRD_PARTY_PCIE_CARD_COOLING_RESPONSE=$(ipmitool -I $IDRAC_LOGIN_STRING raw 0x30 0xce 0x01 0x16 0x05 0x00 0x00 0x00) - -# if [ "$THIRD_PARTY_PCIE_CARD_COOLING_RESPONSE" == "16 05 00 00 00 05 00 01 00 00" ]; then -# return 0 -# elif [ "$THIRD_PARTY_PCIE_CARD_COOLING_RESPONSE" == "16 05 00 00 00 05 00 00 00 00" ]; then -# return 1 -# else -# echo "Unexpected output: $THIRD_PARTY_PCIE_CARD_COOLING_RESPONSE" >&2 -# return 2 -# fi -# } - -# Prepare traps in case of container exit -function gracefull_exit () { - apply_Dell_fan_control_profile - enable_third_party_PCIe_card_Dell_default_cooling_response - echo "/!\ WARNING /!\ Container stopped, Dell default dynamic fan control profile applied for safety." - exit 0 -} - -# Helps debugging when people are posting their output -function get_Dell_server_model () { - IPMI_FRU_content=$(ipmitool fru 2>/dev/null) # FRU stands for "Field Replaceable Unit" - - SERVER_MANUFACTURER=$(echo "$IPMI_FRU_content" | grep "Product Manufacturer" | awk -F ': ' '{print $2}') - SERVER_MODEL=$(echo "$IPMI_FRU_content" | grep "Product Name" | awk -F ': ' '{print $2}') -} +source functions.sh # Trap the signals for container exit and run gracefull_exit function trap 'gracefull_exit' SIGQUIT SIGKILL SIGTERM diff --git a/Dockerfile b/Dockerfile index 3c9d72c..523ca2a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,9 +6,12 @@ RUN apt-get update RUN apt-get install ipmitool -y -ADD Dell_iDRAC_fan_controller.sh /Dell_iDRAC_fan_controller.sh +ADD functions.sh /app/functions.sh +ADD Dell_iDRAC_fan_controller.sh /app/Dell_iDRAC_fan_controller.sh -RUN chmod 0777 /Dell_iDRAC_fan_controller.sh +RUN chmod 0777 /app/functions.sh /app/Dell_iDRAC_fan_controller.sh + +WORKDIR /app # you should override these default values when running. See README.md #ENV IDRAC_HOST 192.168.1.100 @@ -20,4 +23,4 @@ ENV CPU_TEMPERATURE_THRESHOLD 50 ENV CHECK_INTERVAL 60 ENV DISABLE_THIRD_PARTY_PCIE_CARD_DELL_DEFAULT_COOLING_RESPONSE false -CMD ["/Dell_iDRAC_fan_controller.sh"] +CMD ["./Dell_iDRAC_fan_controller.sh"] diff --git a/functions.sh b/functions.sh new file mode 100644 index 0000000..a70bb9c --- /dev/null +++ b/functions.sh @@ -0,0 +1,93 @@ +# Define global functions +# This function applies Dell's default dynamic fan control profile +function apply_Dell_fan_control_profile () { + # Use ipmitool to send the raw command to set fan control to Dell default + ipmitool -I $IDRAC_LOGIN_STRING raw 0x30 0x30 0x01 0x01 > /dev/null + CURRENT_FAN_CONTROL_PROFILE="Dell default dynamic fan control profile" +} + +# This function applies a user-specified static fan control profile +function apply_user_fan_control_profile () { + # Use ipmitool to send the raw command to set fan control to user-specified value + ipmitool -I $IDRAC_LOGIN_STRING raw 0x30 0x30 0x01 0x00 > /dev/null + ipmitool -I $IDRAC_LOGIN_STRING raw 0x30 0x30 0x02 0xff $HEXADECIMAL_FAN_SPEED > /dev/null + CURRENT_FAN_CONTROL_PROFILE="User static fan control profile ($DECIMAL_FAN_SPEED%)" +} + +# Retrieve temperature sensors data using ipmitool +# Usage : retrieve_temperatures $IS_EXHAUST_TEMPERATURE_SENSOR_PRESENT $IS_CPU2_TEMPERATURE_SENSOR_PRESENT +function retrieve_temperatures () { + if (( $# != 2 )) + then + printf "Illegal number of parameters.\nUsage: retrieve_temperatures \$IS_EXHAUST_TEMPERATURE_SENSOR_PRESENT \$IS_CPU2_TEMPERATURE_SENSOR_PRESENT" >&2 + return 1 + fi + local IS_EXHAUST_TEMPERATURE_SENSOR_PRESENT=$1 + local IS_CPU2_TEMPERATURE_SENSOR_PRESENT=$2 + + local DATA=$(ipmitool -I $IDRAC_LOGIN_STRING sdr type temperature | grep degrees) + + # Parse CPU data + local CPU_DATA=$(echo "$DATA" | grep "3\." | grep -Po '\d{2}') + CPU1_TEMPERATURE=$(echo $CPU_DATA | awk '{print $1;}') + if $IS_CPU2_TEMPERATURE_SENSOR_PRESENT + then + CPU2_TEMPERATURE=$(echo $CPU_DATA | awk '{print $2;}') + else + CPU2_TEMPERATURE="-" + fi + + # Parse inlet temperature data + INLET_TEMPERATURE=$(echo "$DATA" | grep Inlet | grep -Po '\d{2}' | tail -1) + + # If exhaust temperature sensor is present, parse its temperature data + if $IS_EXHAUST_TEMPERATURE_SENSOR_PRESENT + then + EXHAUST_TEMPERATURE=$(echo "$DATA" | grep Exhaust | grep -Po '\d{2}' | tail -1) + else + EXHAUST_TEMPERATURE="-" + fi +} + +function enable_third_party_PCIe_card_Dell_default_cooling_response () { + # We could check the current cooling response before applying but it's not very useful so let's skip the test and apply directly + ipmitool -I $IDRAC_LOGIN_STRING raw 0x30 0xce 0x00 0x16 0x05 0x00 0x00 0x00 0x05 0x00 0x00 0x00 0x00 > /dev/null +} + +function disable_third_party_PCIe_card_Dell_default_cooling_response () { + # We could check the current cooling response before applying but it's not very useful so let's skip the test and apply directly + ipmitool -I $IDRAC_LOGIN_STRING raw 0x30 0xce 0x00 0x16 0x05 0x00 0x00 0x00 0x05 0x00 0x01 0x00 0x00 > /dev/null +} + +# Returns : +# - 0 if third-party PCIe card Dell default cooling response is currently DISABLED +# - 1 if third-party PCIe card Dell default cooling response is currently ENABLED +# - 2 if the current status returned by ipmitool command output is unexpected +# function is_third_party_PCIe_card_Dell_default_cooling_response_disabled() { +# THIRD_PARTY_PCIE_CARD_COOLING_RESPONSE=$(ipmitool -I $IDRAC_LOGIN_STRING raw 0x30 0xce 0x01 0x16 0x05 0x00 0x00 0x00) + +# if [ "$THIRD_PARTY_PCIE_CARD_COOLING_RESPONSE" == "16 05 00 00 00 05 00 01 00 00" ]; then +# return 0 +# elif [ "$THIRD_PARTY_PCIE_CARD_COOLING_RESPONSE" == "16 05 00 00 00 05 00 00 00 00" ]; then +# return 1 +# else +# echo "Unexpected output: $THIRD_PARTY_PCIE_CARD_COOLING_RESPONSE" >&2 +# return 2 +# fi +# } + +# Prepare traps in case of container exit +function gracefull_exit () { + apply_Dell_fan_control_profile + enable_third_party_PCIe_card_Dell_default_cooling_response + echo "/!\ WARNING /!\ Container stopped, Dell default dynamic fan control profile applied for safety." + exit 0 +} + +# Helps debugging when people are posting their output +function get_Dell_server_model () { + IPMI_FRU_content=$(ipmitool fru 2>/dev/null) # FRU stands for "Field Replaceable Unit" + + SERVER_MANUFACTURER=$(echo "$IPMI_FRU_content" | grep "Product Manufacturer" | awk -F ': ' '{print $2}') + SERVER_MODEL=$(echo "$IPMI_FRU_content" | grep "Product Name" | awk -F ': ' '{print $2}') +}