Add persistence: install script, backup/restore, systemd service, docker-compose, docs
This commit is contained in:
parent
1d258875a8
commit
3dfdcd1865
|
|
@ -0,0 +1,99 @@
|
|||
# IPMI Controller - Persistence Setup
|
||||
|
||||
## Data Persistence
|
||||
|
||||
All configuration and user data is stored in the `data/` directory:
|
||||
- `data/config.json` - All settings, fan curves, IPMI config
|
||||
- `data/users.json` - User accounts and passwords
|
||||
|
||||
**IMPORTANT:** The `data/` directory is committed to git for version control of your settings.
|
||||
|
||||
## Backup Your Settings
|
||||
|
||||
```bash
|
||||
# Create backup
|
||||
cd ~/ipmi-controller
|
||||
cp -r data data.backup.$(date +%Y%m%d)
|
||||
|
||||
# Or backup to external location
|
||||
cp data/config.json /mnt/backup/ipmi-controller-config.json
|
||||
```
|
||||
|
||||
## Auto-Start on Boot (systemd)
|
||||
|
||||
1. **Create service file:**
|
||||
```bash
|
||||
sudo tee /etc/systemd/system/ipmi-controller.service << 'EOF'
|
||||
[Unit]
|
||||
Description=IPMI Controller
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=devmatrix
|
||||
WorkingDirectory=/home/devmatrix/ipmi-controller
|
||||
ExecStart=/usr/bin/python3 /home/devmatrix/ipmi-controller/web_server.py
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
```
|
||||
|
||||
2. **Enable and start:**
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable ipmi-controller
|
||||
sudo systemctl start ipmi-controller
|
||||
```
|
||||
|
||||
3. **Check status:**
|
||||
```bash
|
||||
sudo systemctl status ipmi-controller
|
||||
sudo journalctl -u ipmi-controller -f
|
||||
```
|
||||
|
||||
## Docker Deployment (Persistent)
|
||||
|
||||
```bash
|
||||
# Using docker-compose
|
||||
cd ~/ipmi-controller
|
||||
docker-compose up -d
|
||||
|
||||
# Data is persisted in ./data directory
|
||||
```
|
||||
|
||||
## Updating Without Losing Settings
|
||||
|
||||
```bash
|
||||
cd ~/ipmi-controller
|
||||
|
||||
# Backup first
|
||||
cp -r data data.backup
|
||||
|
||||
# Pull updates
|
||||
git pull
|
||||
|
||||
# Restart
|
||||
sudo systemctl restart ipmi-controller
|
||||
# OR if using docker:
|
||||
docker-compose restart
|
||||
```
|
||||
|
||||
## What Gets Persisted
|
||||
|
||||
✅ IPMI connection settings
|
||||
✅ HTTP sensor configuration
|
||||
✅ Fan curves (Balanced, Silent, Performance, etc.)
|
||||
✅ User accounts and passwords
|
||||
✅ Theme preference (dark/light)
|
||||
✅ Fan groups and custom names
|
||||
✅ All control settings (poll interval, panic temps, etc.)
|
||||
|
||||
## Migration to New Server
|
||||
|
||||
1. Copy `data/config.json` and `data/users.json` to new server
|
||||
2. Install ipmitool: `sudo apt-get install ipmitool`
|
||||
3. Install Python deps: `pip install -r requirements.txt`
|
||||
4. Start server: `python3 web_server.py`
|
||||
144
README.md
144
README.md
|
|
@ -1,50 +1,156 @@
|
|||
# IPMI Controller
|
||||
|
||||
Advanced IPMI fan control for Dell servers with web interface, HTTP sensor support, fan groups, and multiple fan curves.
|
||||
Advanced IPMI fan control for Dell servers with web interface, HTTP sensor support, multiple fan curves, and persistent configuration.
|
||||
|
||||
## Features
|
||||
|
||||
- 🌡️ **Temperature Monitoring** - IPMI and HTTP (lm-sensors) sensor support
|
||||
- 🌬️ **Fan Control** - Automatic curves, manual control, panic mode
|
||||
- 👥 **Fan Groups** - Group fans with different curves
|
||||
- 🌡️ **Dual Sensor Support** - IPMI + HTTP (lm-sensors from Proxmox/host)
|
||||
- 🌬️ **Smart Fan Control** - Automatic curves, manual control, panic mode
|
||||
- 📊 **3 Preset Curves** - Balanced (default), Silent, Performance
|
||||
- 👥 **Fan Groups** - Organize and control fans individually or in groups
|
||||
- 🔍 **Fan Identify** - Visual fan identification
|
||||
- 🎨 **Dark/Light Mode** - Theme switching
|
||||
- 📊 **Public API** - For external integrations
|
||||
- 🔒 **Secure** - Password protected with JWT auth
|
||||
- 🎨 **Themes** - Dark and Light mode
|
||||
- 📱 **Responsive Web UI** - Works on desktop and mobile
|
||||
- 🔌 **Public API** - For external integrations
|
||||
- 💾 **Persistent Settings** - Survives restarts and updates
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Requirements
|
||||
- Python 3.10+
|
||||
- ipmitool
|
||||
- Linux server (tested on Dell T710)
|
||||
### Automated Install (Recommended)
|
||||
|
||||
### Install
|
||||
```bash
|
||||
git clone https://github.com/yourusername/ipmi-controller.git
|
||||
cd ipmi-controller
|
||||
pip install -r requirements.txt
|
||||
chmod +x install.sh
|
||||
sudo ./install.sh
|
||||
```
|
||||
|
||||
### Run
|
||||
This will:
|
||||
- Install all dependencies
|
||||
- Create systemd service for auto-start
|
||||
- Set up persistent data directory
|
||||
- Start the controller on boot
|
||||
|
||||
### Manual Install
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
sudo apt-get install -y ipmitool python3-pip
|
||||
pip3 install -r requirements.txt
|
||||
|
||||
# Run
|
||||
python3 web_server.py
|
||||
```
|
||||
|
||||
Open `http://your-server:8000` and complete the setup wizard.
|
||||
Access at `http://your-server:8000`
|
||||
|
||||
## Docker
|
||||
## Initial Setup
|
||||
|
||||
1. Complete the setup wizard (create admin + IPMI config)
|
||||
2. Login with your admin credentials
|
||||
3. (Optional) Set up HTTP sensor on your Proxmox host:
|
||||
```bash
|
||||
# On Proxmox server
|
||||
curl -O https://raw.githubusercontent.com/yourusername/ipmi-controller/main/setup-sensors-server.sh
|
||||
sudo ./setup-sensors-server.sh
|
||||
```
|
||||
4. Enable auto control and enjoy automatic fan management!
|
||||
|
||||
## Persistence
|
||||
|
||||
All your settings are automatically saved to `data/config.json`:
|
||||
|
||||
✅ IPMI configuration
|
||||
✅ HTTP sensor settings
|
||||
✅ Fan curves (Balanced, Silent, Performance)
|
||||
✅ User accounts
|
||||
✅ Theme preference
|
||||
✅ All control settings
|
||||
|
||||
**Backups:**
|
||||
```bash
|
||||
./backup.sh backup # Create backup
|
||||
./backup.sh list # List backups
|
||||
./backup.sh restore [file] # Restore from backup
|
||||
```
|
||||
|
||||
**Auto-backup via cron:**
|
||||
```bash
|
||||
# Add to crontab (keeps 30 days of backups)
|
||||
0 2 * * * /opt/ipmi-controller/backup.sh auto
|
||||
```
|
||||
|
||||
## Updating
|
||||
|
||||
```bash
|
||||
docker build -t ipmi-controller .
|
||||
docker run -d -p 8000:8000 -v ./data:/app/data ipmi-controller
|
||||
cd ipmi-controller
|
||||
git pull
|
||||
|
||||
# Settings are preserved automatically
|
||||
sudo systemctl restart ipmi-controller
|
||||
```
|
||||
|
||||
## Fan Curves
|
||||
|
||||
**Balanced** (Default) - Best for most users:
|
||||
```
|
||||
30°C → 10% | 40°C → 15% | 50°C → 30% | 60°C → 55% | 70°C → 85% | 80°C → 100%
|
||||
```
|
||||
|
||||
**Silent** - Noise-sensitive environments:
|
||||
```
|
||||
30°C → 5% | 40°C → 10% | 50°C → 15% | 60°C → 35% | 70°C → 70% | 80°C → 100%
|
||||
```
|
||||
|
||||
**Performance** - Heavy workloads:
|
||||
```
|
||||
30°C → 20% | 40°C → 35% | 50°C → 55% | 60°C → 85% | 70°C → 100%
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
- [Setup Guide](SETUP.md) - Full installation and configuration
|
||||
- [Setup Guide](SETUP.md) - Full installation instructions
|
||||
- [Persistence Guide](PERSISTENCE.md) - Backup and restore
|
||||
- [API Reference](API.md) - Public API documentation
|
||||
|
||||
## Docker
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
Data persists in `./data` directory.
|
||||
|
||||
## Management Commands
|
||||
|
||||
```bash
|
||||
# Status
|
||||
sudo systemctl status ipmi-controller
|
||||
|
||||
# Logs
|
||||
sudo journalctl -u ipmi-controller -f
|
||||
|
||||
# Restart
|
||||
sudo systemctl restart ipmi-controller
|
||||
|
||||
# Stop
|
||||
sudo systemctl stop ipmi-controller
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**IPMI Connection Failed:**
|
||||
- Verify IPMI IP, username, password
|
||||
- Test: `ipmitool -I lanplus -H <ip> -U <user> -P <pass> mc info`
|
||||
|
||||
**No Temperature Data:**
|
||||
- Check HTTP sensor: `curl http://proxmox-ip:8888`
|
||||
- Verify `sensor_preference` is set to "auto" or "http"
|
||||
|
||||
**Settings Lost After Update:**
|
||||
- Ensure `data/` directory is not deleted
|
||||
- Check file permissions: `ls -la data/`
|
||||
|
||||
## License
|
||||
|
||||
MIT License
|
||||
|
|
|
|||
|
|
@ -0,0 +1,141 @@
|
|||
#!/bin/bash
|
||||
# IPMI Controller - Backup and Restore
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
DATA_DIR="${DATA_DIR:-$SCRIPT_DIR/data}"
|
||||
BACKUP_DIR="${BACKUP_DIR:-$SCRIPT_DIR/backups}"
|
||||
|
||||
show_help() {
|
||||
echo "IPMI Controller - Backup/Restore Tool"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo " $0 backup - Create backup"
|
||||
echo " $0 restore [filename] - Restore from backup"
|
||||
echo " $0 list - List available backups"
|
||||
echo " $0 auto - Auto-backup (cron-friendly)"
|
||||
echo ""
|
||||
}
|
||||
|
||||
create_backup() {
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||
BACKUP_FILE="$BACKUP_DIR/ipmi-controller-backup-$TIMESTAMP.tar.gz"
|
||||
|
||||
echo "📦 Creating backup..."
|
||||
tar -czf "$BACKUP_FILE" -C "$SCRIPT_DIR" data/ 2>/dev/null
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ Backup created: $BACKUP_FILE"
|
||||
echo ""
|
||||
ls -lh "$BACKUP_FILE"
|
||||
else
|
||||
echo "❌ Backup failed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
restore_backup() {
|
||||
if [ -z "$1" ]; then
|
||||
echo "❌ Please specify backup file"
|
||||
list_backups
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BACKUP_FILE="$BACKUP_DIR/$1"
|
||||
if [ ! -f "$BACKUP_FILE" ]; then
|
||||
BACKUP_FILE="$1"
|
||||
fi
|
||||
|
||||
if [ ! -f "$BACKUP_FILE" ]; then
|
||||
echo "❌ Backup file not found: $1"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "⚠️ This will overwrite current settings!"
|
||||
read -p "Are you sure? (yes/no): " confirm
|
||||
|
||||
if [ "$confirm" != "yes" ]; then
|
||||
echo "Aborted"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Create safety backup first
|
||||
echo "📦 Creating safety backup..."
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||
tar -czf "$BACKUP_DIR/safety-backup-before-restore-$TIMESTAMP.tar.gz" -C "$SCRIPT_DIR" data/ 2>/dev/null
|
||||
|
||||
# Stop service if running
|
||||
if systemctl is-active --quiet ipmi-controller 2>/dev/null; then
|
||||
echo "🛑 Stopping service..."
|
||||
sudo systemctl stop ipmi-controller
|
||||
WAS_RUNNING=true
|
||||
else
|
||||
WAS_RUNNING=false
|
||||
fi
|
||||
|
||||
# Restore
|
||||
echo "📥 Restoring from backup..."
|
||||
tar -xzf "$BACKUP_FILE" -C "$SCRIPT_DIR"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ Restore complete"
|
||||
|
||||
# Restart service if it was running
|
||||
if [ "$WAS_RUNNING" = true ]; then
|
||||
echo "🚀 Starting service..."
|
||||
sudo systemctl start ipmi-controller
|
||||
fi
|
||||
else
|
||||
echo "❌ Restore failed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
list_backups() {
|
||||
echo "📂 Available backups:"
|
||||
echo ""
|
||||
|
||||
if [ -d "$BACKUP_DIR" ] && [ "$(ls -A "$BACKUP_DIR")" ]; then
|
||||
ls -lh "$BACKUP_DIR"/*.tar.gz 2>/dev/null | awk '{print " " $9 " (" $5 ")"}'
|
||||
else
|
||||
echo " No backups found"
|
||||
fi
|
||||
}
|
||||
|
||||
auto_backup() {
|
||||
# This is cron-friendly - keeps only last 30 days
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# Create backup
|
||||
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||
BACKUP_FILE="$BACKUP_DIR/auto-backup-$TIMESTAMP.tar.gz"
|
||||
tar -czf "$BACKUP_FILE" -C "$SCRIPT_DIR" data/ 2>/dev/null
|
||||
|
||||
# Clean old backups (keep last 30 days)
|
||||
find "$BACKUP_DIR" -name "auto-backup-*.tar.gz" -mtime +30 -delete 2>/dev/null
|
||||
|
||||
echo "Auto-backup complete: $BACKUP_FILE"
|
||||
}
|
||||
|
||||
case "${1:-}" in
|
||||
backup)
|
||||
create_backup
|
||||
;;
|
||||
restore)
|
||||
restore_backup "$2"
|
||||
;;
|
||||
list)
|
||||
list_backups
|
||||
;;
|
||||
auto)
|
||||
auto_backup
|
||||
;;
|
||||
help|--help|-h)
|
||||
show_help
|
||||
;;
|
||||
*)
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
version: '3.8'
|
||||
|
||||
services:
|
||||
ipmi-controller:
|
||||
build: .
|
||||
container_name: ipmi-controller
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8000:8000"
|
||||
volumes:
|
||||
# Persist data directory
|
||||
- ./data:/app/data
|
||||
# Optional: mount ipmitool from host if needed
|
||||
- /usr/bin/ipmitool:/usr/bin/ipmitool:ro
|
||||
environment:
|
||||
- PYTHONUNBUFFERED=1
|
||||
- DATA_DIR=/app/data
|
||||
# Required for ipmitool to work in container
|
||||
privileged: true
|
||||
network_mode: host
|
||||
278
install.sh
278
install.sh
|
|
@ -1,147 +1,215 @@
|
|||
#!/bin/bash
|
||||
# Setup script for IPMI Fan Controller v2
|
||||
# IPMI Controller - Install Script with Persistence
|
||||
# This sets up auto-start and ensures settings persist
|
||||
|
||||
set -e
|
||||
|
||||
echo "🌬️ IPMI Fan Controller v2 - Setup"
|
||||
echo "=================================="
|
||||
INSTALL_DIR="${1:-/opt/ipmi-controller}"
|
||||
DATA_DIR="$INSTALL_DIR/data"
|
||||
SERVICE_NAME="ipmi-controller"
|
||||
USER="${SUDO_USER:-$USER}"
|
||||
|
||||
echo "🌡️ IPMI Controller Installation"
|
||||
echo "================================"
|
||||
echo "Install dir: $INSTALL_DIR"
|
||||
echo "Data dir: $DATA_DIR"
|
||||
echo "Service user: $USER"
|
||||
echo ""
|
||||
|
||||
# Check if running as root for system-wide install
|
||||
if [ "$EUID" -eq 0 ]; then
|
||||
INSTALL_SYSTEM=true
|
||||
INSTALL_DIR="/opt/ipmi-fan-controller"
|
||||
CONFIG_DIR="/etc/ipmi-fan-controller"
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "⚠️ Not running as root. Installing to $HOME/ipmi-controller instead."
|
||||
INSTALL_DIR="$HOME/ipmi-controller"
|
||||
DATA_DIR="$INSTALL_DIR/data"
|
||||
SYSTEM_INSTALL=false
|
||||
else
|
||||
INSTALL_SYSTEM=false
|
||||
INSTALL_DIR="$HOME/.local/ipmi-fan-controller"
|
||||
CONFIG_DIR="$HOME/.config/ipmi-fan-controller"
|
||||
echo "⚠️ Running as user - installing to $INSTALL_DIR"
|
||||
echo " (Run with sudo for system-wide install)"
|
||||
echo ""
|
||||
SYSTEM_INSTALL=true
|
||||
fi
|
||||
|
||||
# Check dependencies
|
||||
echo "📦 Checking dependencies..."
|
||||
|
||||
if ! command -v python3 &> /dev/null; then
|
||||
echo "❌ Python 3 is required but not installed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v ipmitool &> /dev/null; then
|
||||
echo "⚠️ ipmitool not found. Installing..."
|
||||
if [ "$INSTALL_SYSTEM" = true ]; then
|
||||
apt-get update && apt-get install -y ipmitool
|
||||
else
|
||||
echo "❌ Please install ipmitool: sudo apt-get install ipmitool"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "✓ Python 3: $(python3 --version)"
|
||||
echo "✓ ipmitool: $(ipmitool -V)"
|
||||
|
||||
# Create directories
|
||||
echo ""
|
||||
echo "📁 Creating directories..."
|
||||
mkdir -p "$INSTALL_DIR"
|
||||
mkdir -p "$CONFIG_DIR"
|
||||
mkdir -p "$INSTALL_DIR/logs"
|
||||
mkdir -p "$DATA_DIR"
|
||||
|
||||
# Copy files
|
||||
echo ""
|
||||
echo "📋 Installing files..."
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cp "$SCRIPT_DIR/fan_controller.py" "$INSTALL_DIR/"
|
||||
cp "$SCRIPT_DIR/web_server.py" "$INSTALL_DIR/"
|
||||
cp "$SCRIPT_DIR/requirements.txt" "$INSTALL_DIR/"
|
||||
echo "📋 Copying files..."
|
||||
cp -r . "$INSTALL_DIR/" 2>/dev/null || true
|
||||
|
||||
# Install Python dependencies
|
||||
echo ""
|
||||
echo "🐍 Installing Python dependencies..."
|
||||
python3 -m pip install -q -r "$INSTALL_DIR/requirements.txt"
|
||||
|
||||
# Create default config if not exists
|
||||
if [ ! -f "$CONFIG_DIR/config.json" ]; then
|
||||
echo ""
|
||||
echo "⚙️ Creating default configuration..."
|
||||
cat > "$CONFIG_DIR/config.json" << 'EOF'
|
||||
# Ensure data directory exists with proper files
|
||||
if [ ! -f "$DATA_DIR/config.json" ]; then
|
||||
echo "⚙️ Creating default config..."
|
||||
cat > "$DATA_DIR/config.json" << 'EOF'
|
||||
{
|
||||
"host": "",
|
||||
"username": "root",
|
||||
"password": "",
|
||||
"port": 623,
|
||||
"ipmi_host": "",
|
||||
"ipmi_username": "",
|
||||
"ipmi_password": "",
|
||||
"ipmi_port": 623,
|
||||
"http_sensor_enabled": false,
|
||||
"http_sensor_url": "",
|
||||
"http_sensor_timeout": 10,
|
||||
"enabled": false,
|
||||
"interval": 10,
|
||||
"poll_interval": 10,
|
||||
"min_speed": 10,
|
||||
"max_speed": 100,
|
||||
"fan_curve": [
|
||||
{"temp": 30, "speed": 15},
|
||||
{"temp": 40, "speed": 25},
|
||||
{"temp": 50, "speed": 40},
|
||||
{"temp": 60, "speed": 60},
|
||||
{"temp": 70, "speed": 80},
|
||||
{"temp": 80, "speed": 100}
|
||||
],
|
||||
"panic_temp": 85,
|
||||
"panic_speed": 100
|
||||
"panic_speed": 100,
|
||||
"panic_on_no_data": true,
|
||||
"no_data_timeout": 60,
|
||||
"primary_sensor": "cpu",
|
||||
"sensor_preference": "auto",
|
||||
"fans": {},
|
||||
"fan_groups": {},
|
||||
"fan_curves": {
|
||||
"Balanced": {
|
||||
"points": [
|
||||
{"temp": 30, "speed": 10},
|
||||
{"temp": 35, "speed": 12},
|
||||
{"temp": 40, "speed": 15},
|
||||
{"temp": 45, "speed": 20},
|
||||
{"temp": 50, "speed": 30},
|
||||
{"temp": 55, "speed": 40},
|
||||
{"temp": 60, "speed": 55},
|
||||
{"temp": 65, "speed": 70},
|
||||
{"temp": 70, "speed": 85},
|
||||
{"temp": 75, "speed": 95},
|
||||
{"temp": 80, "speed": 100}
|
||||
],
|
||||
"sensor_source": "cpu",
|
||||
"applies_to": "all"
|
||||
},
|
||||
"Silent": {
|
||||
"points": [
|
||||
{"temp": 30, "speed": 5},
|
||||
{"temp": 40, "speed": 10},
|
||||
{"temp": 50, "speed": 15},
|
||||
{"temp": 55, "speed": 25},
|
||||
{"temp": 60, "speed": 35},
|
||||
{"temp": 65, "speed": 50},
|
||||
{"temp": 70, "speed": 70},
|
||||
{"temp": 75, "speed": 85},
|
||||
{"temp": 80, "speed": 100}
|
||||
],
|
||||
"sensor_source": "cpu",
|
||||
"applies_to": "all"
|
||||
},
|
||||
"Performance": {
|
||||
"points": [
|
||||
{"temp": 30, "speed": 20},
|
||||
{"temp": 35, "speed": 25},
|
||||
{"temp": 40, "speed": 35},
|
||||
{"temp": 45, "speed": 45},
|
||||
{"temp": 50, "speed": 55},
|
||||
{"temp": 55, "speed": 70},
|
||||
{"temp": 60, "speed": 85},
|
||||
{"temp": 65, "speed": 95},
|
||||
{"temp": 70, "speed": 100}
|
||||
],
|
||||
"sensor_source": "cpu",
|
||||
"applies_to": "all"
|
||||
}
|
||||
},
|
||||
"active_curve": "Balanced",
|
||||
"theme": "dark"
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
if [ ! -f "$DATA_DIR/users.json" ]; then
|
||||
echo "👤 Creating users file..."
|
||||
echo '{"users": {}}' > "$DATA_DIR/users.json"
|
||||
fi
|
||||
|
||||
# Install Python dependencies
|
||||
echo "🐍 Installing dependencies..."
|
||||
if [ "$SYSTEM_INSTALL" = true ]; then
|
||||
pip3 install -q -r "$INSTALL_DIR/requirements.txt" || pip install -q -r "$INSTALL_DIR/requirements.txt"
|
||||
else
|
||||
pip3 install --user -q -r "$INSTALL_DIR/requirements.txt" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Install ipmitool if not present
|
||||
if ! command -v ipmitool &> /dev/null; then
|
||||
echo "📦 Installing ipmitool..."
|
||||
if [ "$SYSTEM_INSTALL" = true ]; then
|
||||
apt-get update -qq && apt-get install -y -qq ipmitool
|
||||
else
|
||||
echo "⚠️ Please install ipmitool manually: sudo apt-get install ipmitool"
|
||||
fi
|
||||
else
|
||||
echo "✓ ipmitool already installed"
|
||||
fi
|
||||
|
||||
# Create systemd service (system-wide only)
|
||||
if [ "$INSTALL_SYSTEM" = true ]; then
|
||||
echo ""
|
||||
echo "🔧 Creating systemd service..."
|
||||
cat > /etc/systemd/system/ipmi-fan-controller.service << EOF
|
||||
if [ "$SYSTEM_INSTALL" = true ]; then
|
||||
echo "🔧 Creating systemd service..."
|
||||
cat > "/etc/systemd/system/$SERVICE_NAME.service" << EOF
|
||||
[Unit]
|
||||
Description=IPMI Fan Controller v2
|
||||
Description=IPMI Controller
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
User=$USER
|
||||
WorkingDirectory=$INSTALL_DIR
|
||||
Environment="CONFIG_PATH=$CONFIG_DIR/config.json"
|
||||
Environment="PYTHONUNBUFFERED=1"
|
||||
Environment="DATA_DIR=$DATA_DIR"
|
||||
ExecStart=/usr/bin/python3 $INSTALL_DIR/web_server.py
|
||||
ExecStop=/usr/bin/python3 -c "import requests; requests.post('http://localhost:8000/api/shutdown')"
|
||||
Restart=on-failure
|
||||
ExecStop=/bin/kill -TERM \$MAINPID
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable ipmi-fan-controller.service
|
||||
|
||||
echo ""
|
||||
echo "✅ Installation complete!"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Edit config: sudo nano $CONFIG_DIR/config.json"
|
||||
echo " 2. Start service: sudo systemctl start ipmi-fan-controller"
|
||||
echo " 3. View status: sudo systemctl status ipmi-fan-controller"
|
||||
echo " 4. Open web UI: http://$(hostname -I | awk '{print $1}'):8000"
|
||||
echo ""
|
||||
echo "Or test from CLI:"
|
||||
echo " python3 $INSTALL_DIR/fan_controller.py <host> <user> <pass>"
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable "$SERVICE_NAME"
|
||||
|
||||
# Set proper ownership
|
||||
chown -R "$USER:$USER" "$INSTALL_DIR"
|
||||
|
||||
echo ""
|
||||
echo "✅ Installation complete!"
|
||||
echo ""
|
||||
echo "Start the service:"
|
||||
echo " sudo systemctl start $SERVICE_NAME"
|
||||
echo ""
|
||||
echo "Check status:"
|
||||
echo " sudo systemctl status $SERVICE_NAME"
|
||||
echo ""
|
||||
echo "View logs:"
|
||||
echo " sudo journalctl -u $SERVICE_NAME -f"
|
||||
echo ""
|
||||
echo "Access: http://$(hostname -I | awk '{print $1}'):8000"
|
||||
|
||||
else
|
||||
|
||||
echo ""
|
||||
echo "✅ User installation complete!"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Edit config: nano $CONFIG_DIR/config.json"
|
||||
echo " 2. Start manually:"
|
||||
echo " CONFIG_PATH=$CONFIG_DIR/config.json python3 $INSTALL_DIR/web_server.py"
|
||||
echo " 3. Open web UI: http://localhost:8000"
|
||||
echo ""
|
||||
echo "Or test from CLI:"
|
||||
echo " python3 $INSTALL_DIR/fan_controller.py <host> <user> <pass>"
|
||||
|
||||
# User install - create a simple start script
|
||||
cat > "$INSTALL_DIR/start.sh" << 'EOF'
|
||||
#!/bin/bash
|
||||
cd "$(dirname "$0")"
|
||||
export DATA_DIR="./data"
|
||||
export PYTHONUNBUFFERED=1
|
||||
echo "Starting IPMI Controller..."
|
||||
echo "Data directory: $DATA_DIR"
|
||||
python3 web_server.py
|
||||
EOF
|
||||
chmod +x "$INSTALL_DIR/start.sh"
|
||||
|
||||
echo ""
|
||||
echo "✅ User installation complete!"
|
||||
echo ""
|
||||
echo "Start manually:"
|
||||
echo " cd $INSTALL_DIR && ./start.sh"
|
||||
echo ""
|
||||
echo "Or create a systemd service manually:"
|
||||
echo " nano ~/.config/systemd/user/ipmi-controller.service"
|
||||
echo ""
|
||||
echo "Access: http://localhost:8000"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "📖 Configuration file: $CONFIG_DIR/config.json"
|
||||
echo "📁 Your settings are stored in: $DATA_DIR"
|
||||
echo " - config.json: All configuration"
|
||||
echo " - users.json: User accounts"
|
||||
echo ""
|
||||
echo "💾 These files persist across restarts and updates!"
|
||||
|
|
|
|||
Loading…
Reference in New Issue