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
|
# 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
|
## Features
|
||||||
|
|
||||||
- 🌡️ **Temperature Monitoring** - IPMI and HTTP (lm-sensors) sensor support
|
- 🌡️ **Dual Sensor Support** - IPMI + HTTP (lm-sensors from Proxmox/host)
|
||||||
- 🌬️ **Fan Control** - Automatic curves, manual control, panic mode
|
- 🌬️ **Smart Fan Control** - Automatic curves, manual control, panic mode
|
||||||
- 👥 **Fan Groups** - Group fans with different curves
|
- 📊 **3 Preset Curves** - Balanced (default), Silent, Performance
|
||||||
|
- 👥 **Fan Groups** - Organize and control fans individually or in groups
|
||||||
- 🔍 **Fan Identify** - Visual fan identification
|
- 🔍 **Fan Identify** - Visual fan identification
|
||||||
- 🎨 **Dark/Light Mode** - Theme switching
|
- 🎨 **Themes** - Dark and Light mode
|
||||||
- 📊 **Public API** - For external integrations
|
- 📱 **Responsive Web UI** - Works on desktop and mobile
|
||||||
- 🔒 **Secure** - Password protected with JWT auth
|
- 🔌 **Public API** - For external integrations
|
||||||
|
- 💾 **Persistent Settings** - Survives restarts and updates
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
### Requirements
|
### Automated Install (Recommended)
|
||||||
- Python 3.10+
|
|
||||||
- ipmitool
|
|
||||||
- Linux server (tested on Dell T710)
|
|
||||||
|
|
||||||
### Install
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/yourusername/ipmi-controller.git
|
git clone https://github.com/yourusername/ipmi-controller.git
|
||||||
cd ipmi-controller
|
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
|
```bash
|
||||||
|
# Install dependencies
|
||||||
|
sudo apt-get install -y ipmitool python3-pip
|
||||||
|
pip3 install -r requirements.txt
|
||||||
|
|
||||||
|
# Run
|
||||||
python3 web_server.py
|
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
|
```bash
|
||||||
docker build -t ipmi-controller .
|
cd ipmi-controller
|
||||||
docker run -d -p 8000:8000 -v ./data:/app/data 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
|
## 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
|
- [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
|
## License
|
||||||
|
|
||||||
MIT 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
|
||||||
250
install.sh
250
install.sh
|
|
@ -1,111 +1,161 @@
|
||||||
#!/bin/bash
|
#!/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
|
set -e
|
||||||
|
|
||||||
echo "🌬️ IPMI Fan Controller v2 - Setup"
|
INSTALL_DIR="${1:-/opt/ipmi-controller}"
|
||||||
echo "=================================="
|
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
|
# Check if running as root for system-wide install
|
||||||
if [ "$EUID" -eq 0 ]; then
|
if [ "$EUID" -ne 0 ]; then
|
||||||
INSTALL_SYSTEM=true
|
echo "⚠️ Not running as root. Installing to $HOME/ipmi-controller instead."
|
||||||
INSTALL_DIR="/opt/ipmi-fan-controller"
|
INSTALL_DIR="$HOME/ipmi-controller"
|
||||||
CONFIG_DIR="/etc/ipmi-fan-controller"
|
DATA_DIR="$INSTALL_DIR/data"
|
||||||
|
SYSTEM_INSTALL=false
|
||||||
else
|
else
|
||||||
INSTALL_SYSTEM=false
|
SYSTEM_INSTALL=true
|
||||||
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 ""
|
|
||||||
fi
|
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
|
# Create directories
|
||||||
echo ""
|
|
||||||
echo "📁 Creating directories..."
|
echo "📁 Creating directories..."
|
||||||
mkdir -p "$INSTALL_DIR"
|
mkdir -p "$INSTALL_DIR"
|
||||||
mkdir -p "$CONFIG_DIR"
|
mkdir -p "$DATA_DIR"
|
||||||
mkdir -p "$INSTALL_DIR/logs"
|
|
||||||
|
|
||||||
# Copy files
|
# Copy files
|
||||||
echo ""
|
echo "📋 Copying files..."
|
||||||
echo "📋 Installing files..."
|
cp -r . "$INSTALL_DIR/" 2>/dev/null || true
|
||||||
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/"
|
|
||||||
|
|
||||||
# Install Python dependencies
|
# Ensure data directory exists with proper files
|
||||||
echo ""
|
if [ ! -f "$DATA_DIR/config.json" ]; then
|
||||||
echo "🐍 Installing Python dependencies..."
|
echo "⚙️ Creating default config..."
|
||||||
python3 -m pip install -q -r "$INSTALL_DIR/requirements.txt"
|
cat > "$DATA_DIR/config.json" << 'EOF'
|
||||||
|
|
||||||
# Create default config if not exists
|
|
||||||
if [ ! -f "$CONFIG_DIR/config.json" ]; then
|
|
||||||
echo ""
|
|
||||||
echo "⚙️ Creating default configuration..."
|
|
||||||
cat > "$CONFIG_DIR/config.json" << 'EOF'
|
|
||||||
{
|
{
|
||||||
"host": "",
|
"ipmi_host": "",
|
||||||
"username": "root",
|
"ipmi_username": "",
|
||||||
"password": "",
|
"ipmi_password": "",
|
||||||
"port": 623,
|
"ipmi_port": 623,
|
||||||
|
"http_sensor_enabled": false,
|
||||||
|
"http_sensor_url": "",
|
||||||
|
"http_sensor_timeout": 10,
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"interval": 10,
|
"poll_interval": 10,
|
||||||
"min_speed": 10,
|
"min_speed": 10,
|
||||||
"max_speed": 100,
|
"max_speed": 100,
|
||||||
"fan_curve": [
|
"panic_temp": 85,
|
||||||
{"temp": 30, "speed": 15},
|
"panic_speed": 100,
|
||||||
{"temp": 40, "speed": 25},
|
"panic_on_no_data": true,
|
||||||
{"temp": 50, "speed": 40},
|
"no_data_timeout": 60,
|
||||||
{"temp": 60, "speed": 60},
|
"primary_sensor": "cpu",
|
||||||
{"temp": 70, "speed": 80},
|
"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}
|
{"temp": 80, "speed": 100}
|
||||||
],
|
],
|
||||||
"panic_temp": 85,
|
"sensor_source": "cpu",
|
||||||
"panic_speed": 100
|
"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
|
EOF
|
||||||
fi
|
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)
|
# Create systemd service (system-wide only)
|
||||||
if [ "$INSTALL_SYSTEM" = true ]; then
|
if [ "$SYSTEM_INSTALL" = true ]; then
|
||||||
echo ""
|
|
||||||
echo "🔧 Creating systemd service..."
|
echo "🔧 Creating systemd service..."
|
||||||
cat > /etc/systemd/system/ipmi-fan-controller.service << EOF
|
cat > "/etc/systemd/system/$SERVICE_NAME.service" << EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=IPMI Fan Controller v2
|
Description=IPMI Controller
|
||||||
After=network.target
|
After=network.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
User=root
|
User=$USER
|
||||||
WorkingDirectory=$INSTALL_DIR
|
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
|
ExecStart=/usr/bin/python3 $INSTALL_DIR/web_server.py
|
||||||
ExecStop=/usr/bin/python3 -c "import requests; requests.post('http://localhost:8000/api/shutdown')"
|
ExecStop=/bin/kill -TERM \$MAINPID
|
||||||
Restart=on-failure
|
Restart=always
|
||||||
RestartSec=10
|
RestartSec=10
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
|
|
@ -113,35 +163,53 @@ WantedBy=multi-user.target
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl enable ipmi-fan-controller.service
|
systemctl enable "$SERVICE_NAME"
|
||||||
|
|
||||||
|
# Set proper ownership
|
||||||
|
chown -R "$USER:$USER" "$INSTALL_DIR"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "✅ Installation complete!"
|
echo "✅ Installation complete!"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Next steps:"
|
echo "Start the service:"
|
||||||
echo " 1. Edit config: sudo nano $CONFIG_DIR/config.json"
|
echo " sudo systemctl start $SERVICE_NAME"
|
||||||
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 ""
|
||||||
echo "Or test from CLI:"
|
echo "Check status:"
|
||||||
echo " python3 $INSTALL_DIR/fan_controller.py <host> <user> <pass>"
|
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
|
else
|
||||||
|
# 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 ""
|
||||||
echo "✅ User installation complete!"
|
echo "✅ User installation complete!"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Next steps:"
|
echo "Start manually:"
|
||||||
echo " 1. Edit config: nano $CONFIG_DIR/config.json"
|
echo " cd $INSTALL_DIR && ./start.sh"
|
||||||
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 ""
|
||||||
echo "Or test from CLI:"
|
echo "Or create a systemd service manually:"
|
||||||
echo " python3 $INSTALL_DIR/fan_controller.py <host> <user> <pass>"
|
echo " nano ~/.config/systemd/user/ipmi-controller.service"
|
||||||
|
echo ""
|
||||||
|
echo "Access: http://localhost:8000"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo ""
|
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