-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
242 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
name: IdracFanControl Docker Build and Push to GHCR | ||
|
||
on: | ||
push: | ||
branches: | ||
- master # Change this to your default branch if it's different | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
# Step 1: Checkout the repository | ||
- name: Checkout code | ||
uses: actions/checkout@v3 | ||
|
||
# Step 2: Log in to GitHub Container Registry | ||
- name: Log in to GHCR | ||
uses: docker/login-action@v2 | ||
with: | ||
registry: ghcr.io | ||
username: ${{ github.actor }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
# Step 3: Build the Docker image | ||
- name: Build Docker image | ||
run: | | ||
docker build -t ghcr.io/${{ github.repository_owner }}/idrac-fan-control:latest . | ||
# Step 4: Push the Docker image to GHCR | ||
- name: Push Docker image | ||
run: | | ||
docker push ghcr.io/${{ github.repository_owner }}/idrac-fan-control:latest |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Use Alpine as the base image for its small size | ||
FROM alpine:latest | ||
|
||
# Install required packages (ipmitool, bash, bc for hex conversion) | ||
RUN apk add --no-cache bash ipmitool bc | ||
|
||
# Copy the fan control script into the container | ||
COPY fan_control.sh /usr/local/bin/fan_control.sh | ||
|
||
# Make the script executable | ||
RUN chmod +x /usr/local/bin/fan_control.sh | ||
|
||
# Set the environment variables (you can override these during runtime) | ||
ENV IDRAC_IP="REPLACE_TO_YOUR_IDRAC_IP" | ||
ENV IDRAC_ID="REPLACE_TO_YOUR_IDRAC_ID" | ||
ENV IDRAC_PASSWORD="REPLACE_TO_YOUR_IDRAC_PASSWORD" | ||
ENV DRIVE_DEVICE="t10.NVMe____KCD61LUL7T68_________________________" | ||
ENV OPERATION_MODE="auto" | ||
|
||
# Set the entrypoint to the fan control script | ||
ENTRYPOINT ["/usr/local/bin/fan_control.sh"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# .env file for iDRAC Fan Control | ||
|
||
# iDRAC IP address, ID, and Password | ||
IDRAC_IP=REPLACE_TO_YOUR_IDRAC_IP | ||
IDRAC_ID=REPLACE_TO_YOUR_IDRAC_ID | ||
IDRAC_PASSWORD=REPLACE_TO_YOUR_IDRAC_PASSWORD | ||
|
||
# NVMe drive identifier | ||
DRIVE_DEVICE=t10.NVMe____KCD61LUL7T68_________________________ | ||
|
||
# Temperature thresholds (optional, these are the defaults in the script) | ||
TEMP_LOW=65 | ||
TEMP_MEDIUM=70 | ||
TEMP_HIGH=75 | ||
TEMP_CRITICAL=80 | ||
|
||
# Fan speed percentages for each temperature range (optional, defaults in script) | ||
FAN_SPEED_LOW=30 | ||
FAN_SPEED_MEDIUM=35 | ||
FAN_SPEED_HIGH=40 | ||
FAN_SPEED_CRITICAL= | ||
|
||
# Operation mode: 'auto' or 'manual' | ||
OPERATION_MODE=auto | ||
|
||
# Interval to check the temperature in seconds (only applicable in auto mode) | ||
CHECK_INTERVAL=60 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
#!/bin/bash | ||
# Auto fan speed control based on NVMe drive temperature | ||
# Support environment variable configuration | ||
|
||
|
||
# Add path to common command locations in Alpine | ||
PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH" | ||
|
||
# Default values and environment variable loading | ||
IDRAC_IP=${IDRAC_IP:-"REPLACE_TO_YOUR_IDRAC_IP"} | ||
IDRAC_ID=${IDRAC_ID:-"REPLACE_TO_YOUR_IDRAC_ID"} | ||
IDRAC_PASSWORD=${IDRAC_PASSWORD:-"REPLACE_TO_YOUR_IDRAC_PASSWORD"} | ||
DRIVE_DEVICE=${DRIVE_DEVICE:-"t10.NVMe____KCD61LUL7T68_________________________"} | ||
|
||
# Temperature thresholds (Celsius) -xx means default value | ||
TEMP_LOW=${TEMP_LOW:-45} | ||
TEMP_MEDIUM=${TEMP_MEDIUM:-55} | ||
TEMP_HIGH=${TEMP_HIGH:-65} | ||
TEMP_CRITICAL=${TEMP_CRITICAL:-70} | ||
|
||
# Fan speeds for each temperature range (percentage) | ||
FAN_SPEED_LOW=${FAN_SPEED_LOW:-20} | ||
FAN_SPEED_MEDIUM=${FAN_SPEED_MEDIUM:-30} | ||
FAN_SPEED_HIGH=${FAN_SPEED_HIGH:-40} | ||
FAN_SPEED_CRITICAL=${FAN_SPEED_CRITICAL:-60} | ||
|
||
# Operation mode: auto or manual | ||
OPERATION_MODE=${OPERATION_MODE:-"manual"} | ||
|
||
# Check interval (seconds) for auto mode | ||
CHECK_INTERVAL=${CHECK_INTERVAL:-60} | ||
|
||
# Function to get current drive temperature | ||
get_drive_temp() { | ||
local temp=$(esxcli storage core device smart get -d "$DRIVE_DEVICE" | \ | ||
awk '/Drive Temperature/ {print $3}') | ||
echo "${temp:-0}" | ||
} | ||
|
||
# Function to set fan speed | ||
set_fan_speed() { | ||
local fan_speed=$1 | ||
|
||
# Convert decimal to hex | ||
local hex_speed=$(echo "obase=16;$fan_speed" | bc) | ||
echo "Setting fan speed to ${fan_speed}% (hex: ${hex_speed})" | ||
|
||
# Set fan control to manual | ||
ipmitool -I lanplus -H ${IDRAC_IP} -U ${IDRAC_ID} -P ${IDRAC_PASSWORD} raw 0x30 0x30 0x01 0x00 | ||
|
||
# Set fan speed | ||
local raw_command="0x30 0x30 0x02 0xff 0x${hex_speed}" | ||
ipmitool -I lanplus -H ${IDRAC_IP} -U ${IDRAC_ID} -P ${IDRAC_PASSWORD} raw ${raw_command} | ||
} | ||
|
||
# Function to restore automatic fan control | ||
restore_auto_control() { | ||
echo "Restoring automatic fan control..." | ||
ipmitool -I lanplus -H ${IDRAC_IP} -U ${IDRAC_ID} -P ${IDRAC_PASSWORD} raw 0x30 0x30 0x01 0x01 | ||
} | ||
|
||
# Function to validate configuration | ||
validate_config() { | ||
local error=0 | ||
|
||
# Check required variables | ||
if [[ "$IDRAC_IP" == "REPLACE_TO_YOUR_IDRAC_IP" ]]; then | ||
echo "Error: IDRAC_IP not configured" | ||
error=1 | ||
fi | ||
if [[ "$IDRAC_ID" == "REPLACE_TO_YOUR_IDRAC_ID" ]]; then | ||
echo "Error: IDRAC_ID not configured" | ||
error=1 | ||
fi | ||
if [[ "$IDRAC_PASSWORD" == "REPLACE_TO_YOUR_IDRAC_PASSWORD" ]]; then | ||
echo "Error: IDRAC_PASSWORD not configured" | ||
error=1 | ||
fi | ||
|
||
if [ $error -eq 1 ]; then | ||
exit 1 | ||
fi | ||
} | ||
|
||
# Function to run in manual mode | ||
manual_mode() { | ||
echo "Manual fan speed control mode" | ||
echo "Please input fan speed (1-100):" | ||
read -r fanSpeed | ||
|
||
# Validate input | ||
if ! [[ "$fanSpeed" =~ ^[0-9]+$ ]] || [ "$fanSpeed" -lt 1 ] || [ "$fanSpeed" -gt 100 ]; then | ||
echo "Invalid input: Fan speed must be a number between 1 and 100" | ||
exit 1 | ||
fi | ||
|
||
# Set the fan speed to the provided value | ||
set_fan_speed "$fanSpeed" | ||
} | ||
|
||
# Function to run in automatic mode | ||
auto_mode() { | ||
echo "Automatic fan speed control mode" | ||
echo "Press Ctrl+C to exit and restore automatic control" | ||
|
||
# Set up trap for clean exit | ||
trap restore_auto_control EXIT | ||
|
||
local last_speed="" | ||
|
||
while true; do | ||
# Get current temperature | ||
local temp=$(get_drive_temp) | ||
echo "$(date '+%Y-%m-%d %H:%M:%S') - Drive temperature: ${temp}°C" | ||
|
||
# Determine appropriate fan speed based on temperature | ||
local target_speed | ||
if [ "$temp" -ge "$TEMP_CRITICAL" ]; then | ||
target_speed=$FAN_SPEED_CRITICAL | ||
elif [ "$temp" -ge "$TEMP_HIGH" ]; then | ||
target_speed=$FAN_SPEED_HIGH | ||
elif [ "$temp" -ge "$TEMP_MEDIUM" ]; then | ||
target_speed=$FAN_SPEED_MEDIUM | ||
else | ||
target_speed=$FAN_SPEED_LOW | ||
fi | ||
|
||
# Only change speed if it's different from last setting | ||
if [ "$target_speed" != "$last_speed" ]; then | ||
set_fan_speed "$target_speed" | ||
last_speed="$target_speed" | ||
echo "Fan speed adjusted to ${target_speed}%" | ||
fi | ||
|
||
# Log the status | ||
echo "$(date '+%Y-%m-%d %H:%M:%S') - Temp: ${temp}°C, Fan: ${target_speed}%" >> fan_control.log | ||
|
||
sleep "$CHECK_INTERVAL" | ||
done | ||
} | ||
|
||
# Main script | ||
echo "iDRAC Fan Control Script" | ||
echo "Operation Mode: ${OPERATION_MODE}" | ||
|
||
# Validate configuration | ||
validate_config | ||
|
||
# Run in specified mode | ||
case $OPERATION_MODE in | ||
"manual") | ||
manual_mode | ||
;; | ||
"auto") | ||
auto_mode | ||
;; | ||
*) | ||
echo "Invalid operation mode: ${OPERATION_MODE} (must be 'auto' or 'manual')" | ||
exit 1 | ||
;; | ||
esac |