Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.git
.github
.sisyphus

.env
.env.*
!.env.example

logs
tests
README.md
USAGE_GUIDE.md
images

*.log
.DS_Store
Thumbs.db
61 changes: 0 additions & 61 deletions .env

This file was deleted.

126 changes: 78 additions & 48 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,65 +1,95 @@
# 範例 .env 文件 - 複製為 .env 並修改設定
# Example .env file - Copy to .env and modify the settings
# Copy this file to .env and edit it for your server.
# Never commit your real .env because it contains management credentials.

# ===== iDRAC 設定 / iDRAC Configuration =====
# iDRAC IP 位址、使用者 ID 和密碼
# iDRAC IP address, User ID, and Password
IDRAC_IP=192.168.1.100
# -----------------------------------------------------------------------------
# iDRAC / IPMI
# -----------------------------------------------------------------------------
IDRAC_IP=192.0.2.10
IDRAC_ID=root
IDRAC_PASSWORD=calvin
IDRAC_PASSWORD=change-me
IPMI_INTERFACE=lanplus
IPMI_TIMEOUT=5
IPMI_RETRIES=2

# ===== 儲存裝置設定 / Storage Configuration =====
# NVMe 磁碟識別碼 - 可透過 ESXi 主機上的 esxcli storage core device list 取得
# NVMe drive identifier - Can be obtained via esxcli storage core device list on ESXi host
DRIVE_DEVICE=t10.NVMe____KCD61LUL7T68____________________________015E8306E28EE38C
# -----------------------------------------------------------------------------
# Runtime mode
# -----------------------------------------------------------------------------
# auto: continuously monitor temperatures and adjust fan speed
# once: run one automatic control cycle and exit
# manual: set MANUAL_FAN_SPEED or pass a speed argument
OPERATION_MODE=auto
CHECK_INTERVAL=60
COMMAND_TIMEOUT=20
DRY_RUN=false

# restore iDRAC automatic fan control when auto mode exits
RESTORE_AUTO_ON_EXIT=true

# -----------------------------------------------------------------------------
# Temperature sources
# -----------------------------------------------------------------------------
# Supported values: esxi, idrac, gpu. Use comma-separated values for hybrid mode.
# esxi reads one NVMe SMART temperature through ESXi SSH.
# idrac reads all iDRAC temperature sensors through ipmitool.
# gpu reads NVIDIA GPU temperatures through nvidia-smi.
TEMPERATURE_SOURCES=esxi

# Backward-compatible GPU switch. If true, gpu is appended to TEMPERATURE_SOURCES.
WITH_GPU_TEMP=false
GPU_TEMP_OFFSET=15

# Optional iDRAC sensor filtering. Leave include blank to use all readable
# temperature sensors returned by: ipmitool sdr type Temperature
IDRAC_SENSOR_INCLUDE_REGEX=
IDRAC_SENSOR_EXCLUDE_REGEX=no reading|disabled|not readable

# ===== 溫度閾值設定 / Temperature Thresholds =====
# 溫度閾值 (攝氏度)
# Temperature thresholds (Celsius)
# -----------------------------------------------------------------------------
# ESXi source settings
# Required only when TEMPERATURE_SOURCES includes esxi.
# -----------------------------------------------------------------------------
ESXI_HOST=192.0.2.20
ESXI_USERNAME=root
ESXI_PASSWORD=change-me
ESXI_SSH_KEY=
ESXI_SSH_PORT=22
SSH_CONNECT_TIMEOUT=10
SSH_STRICT_HOST_KEY_CHECKING=accept-new
DRIVE_DEVICE=t10.NVMe____replace_with_your_device_identifier

# -----------------------------------------------------------------------------
# Fan curve
# -----------------------------------------------------------------------------
# The controller chooses the highest matching level:
# idle: temp < TEMP_LOW
# low: TEMP_LOW <= temp < TEMP_MEDIUM
# medium: TEMP_MEDIUM <= temp < TEMP_HIGH
# high: TEMP_HIGH <= temp < TEMP_CRITICAL
# critical: temp >= TEMP_CRITICAL
TEMP_LOW=65
TEMP_MEDIUM=70
TEMP_HIGH=75
TEMP_CRITICAL=80

# ===== 風扇轉速設定 / Fan Speed Configuration =====
# 各溫度範圍對應的風扇轉速百分比
# Fan speed percentages for each temperature range
FAN_SPEED_IDLE=25
FAN_SPEED_LOW=30
FAN_SPEED_MEDIUM=40
FAN_SPEED_HIGH=50
FAN_SPEED_CRITICAL=60

# ===== 操作模式設定 / Operation Mode =====
# 操作模式:'auto' 或 'manual'
# Operation mode: 'auto' or 'manual'
OPERATION_MODE=auto

# 檢查間隔 (秒) - 僅在自動模式下有效
# Check interval in seconds (only applicable in auto mode)
CHECK_INTERVAL=60
# Prevent fan speed flapping near thresholds. Downshifts wait until the
# temperature falls this many degrees below the previous level threshold.
HYSTERESIS=2

# ===== GPU 溫度監控設定 / GPU Temperature Monitoring =====
# GPU 溫度控制開關
# 設定為 'true' 以啟用 GPU 溫度監控進行決策溫度計算
# 決策溫度 = max(磁碟溫度, GPU溫度 - GPU_TEMP_OFFSET)
# 預設值:false (僅使用磁碟溫度)
# GPU temperature control flag
# Set to 'true' to enable GPU temperature monitoring for decision temperature calculation
# Decision Temperature = max(Disk Temperature, GPU Temperature - GPU_TEMP_OFFSET)
# Default: false (only use disk temperature)
WITH_GPU_TEMP=false
# If all temperature sources fail, use this conservative fan speed instead of
# dropping to the lowest fan curve level.
FAILSAFE_ON_ERROR=true
FAILSAFE_FAN_SPEED=70

# GPU 溫度偏移量 (攝氏度)
# 用於調整 GPU 溫度對風扇控制的影響程度
# 預設值為 15°C,即 GPU 溫度會減去此值後與磁碟溫度比較
# GPU temperature offset (Celsius)
# Used to adjust GPU temperature's impact on fan control
# Default is 15°C, meaning GPU temperature minus this value will be compared with disk temperature
GPU_TEMP_OFFSET=15
# Manual mode only. You can also run: fan-control.sh manual 35
MANUAL_FAN_SPEED=35

# ===== ESXi 主機設定 / ESXi Host Configuration =====
# ESXi 主機連線設定 - 用於取得磁碟溫度
# ESXi host connection settings - Used for retrieving disk temperature
ESXI_HOST=192.168.1.10
ESXI_USERNAME=root
ESXI_PASSWORD=your_esxi_password
# -----------------------------------------------------------------------------
# Logging
# -----------------------------------------------------------------------------
LOG_DIR=/var/log/fan-control
LOG_FILE=fan_control.log
100 changes: 65 additions & 35 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
@@ -1,43 +1,73 @@
name: IdracFanControl Docker Build and Push to GHCR
name: Build and publish Docker image

on:
push:
branches:
- master # Change this to your default branch if it's different
- master
tags:
- "v*"
pull_request:
branches:
- master

permissions:
contents: read
packages: write

jobs:
build:
test:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Run tests
run: make test

- name: Validate Compose file
run: |
cp .env.example .env
docker compose config >/tmp/compose.yml

docker:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
needs: test
if: github.event_name == 'push'
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.GH_TOKEN }}

- name: Convert repository owner to lowercase
id: repo_owner_lowercase
run: echo "REPO_OWNER=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV

- name: Log repository owner
run: echo "Repository owner in lowercase is $REPO_OWNER"


# Step 3: Build the Docker image
- name: Build Docker image
run: |
docker build -t ghcr.io/$REPO_OWNER/idrac-fan-control:latest .

# Step 4: Push the Docker image to GHCR
- name: Push Docker image
run: |
docker push ghcr.io/$REPO_OWNER/idrac-fan-control:latest
- name: Check out repository
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Normalize image name
id: image
run: |
owner="$(printf '%s' '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')"
echo "name=ghcr.io/${owner}/idrac-fan-control" >> "$GITHUB_OUTPUT"

- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ steps.image.outputs.name }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,prefix=sha-

- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.env
.env.*
!.env.example

logs/
*.log

.DS_Store
Thumbs.db

.sisyphus/
Loading
Loading