- Add SFTP upload support with paramiko
- Add database columns for offsite tracking (status, location, attempts, error)
- Add manual upload endpoint /api/v1/backups/offsite/{job_id}
- Add frontend button for offsite upload
- Add SFTP configuration in config.py
- Fix infinite loop in _ensure_remote_directory for relative paths
- Add upload verification and retry mechanism
- Add progress tracking and logging
162 lines
4.8 KiB
Markdown
162 lines
4.8 KiB
Markdown
# Release Notes - v1.3.75
|
|
|
|
**Release Date:** 2. januar 2026
|
|
|
|
## ✨ New Features
|
|
|
|
### SFTP Offsite Backup
|
|
- **Implemented SFTP offsite backup** - Backups can now be uploaded to remote SFTP server
|
|
- **Auto-upload support** - Backups can be automatically uploaded after creation
|
|
- **Manual upload** - Backups can be manually uploaded via web UI
|
|
- **Upload verification** - File size verification ensures successful upload
|
|
- **Retry mechanism** - Failed uploads can be retried with error tracking
|
|
|
|
### Database Schema Updates
|
|
- Added `offsite_status` column (pending, uploading, uploaded, failed)
|
|
- Added `offsite_location` column for remote file path
|
|
- Added `offsite_attempts` counter for retry tracking
|
|
- Added `offsite_last_error` for error logging
|
|
|
|
## 🔧 Technical Improvements
|
|
|
|
### SFTP Implementation
|
|
- Uses `paramiko` library for SFTP connections
|
|
- Supports password authentication
|
|
- Automatic directory creation on remote server
|
|
- Progress tracking during upload
|
|
- Connection timeout protection (30s banner timeout)
|
|
|
|
### Configuration
|
|
- `OFFSITE_ENABLED` - Enable/disable offsite uploads
|
|
- `SFTP_HOST` - Remote SFTP server hostname
|
|
- `SFTP_PORT` - SFTP port (default: 22)
|
|
- `SFTP_USER` - SFTP username
|
|
- `SFTP_PASSWORD` - SFTP password
|
|
- `SFTP_REMOTE_PATH` - Remote directory path
|
|
|
|
### Bug Fixes
|
|
- Fixed infinite loop in `_ensure_remote_directory()` for relative paths
|
|
- Fixed duplicate `upload_to_offsite()` method - removed redundant code
|
|
- Fixed router method name mismatch (`upload_offsite` vs `upload_to_offsite`)
|
|
- Added protection against empty/root path directory creation
|
|
|
|
## 📝 Files Changed
|
|
|
|
- `app/backups/backend/service.py` - SFTP upload implementation
|
|
- `app/backups/backend/router.py` - Offsite upload endpoint
|
|
- `app/backups/templates/index.html` - Frontend offsite upload button
|
|
- `app/core/config.py` - SFTP configuration settings
|
|
- `migrations/052_backup_offsite_columns.sql` - Database schema migration
|
|
- `.env` - SFTP configuration
|
|
|
|
## 🚀 Deployment Instructions
|
|
|
|
### Prerequisites
|
|
- Ensure `.env` file contains SFTP credentials
|
|
- Database migration must be applied
|
|
|
|
### Production Server Update
|
|
|
|
1. **SSH til serveren:**
|
|
```bash
|
|
ssh bmcadmin@172.16.31.183
|
|
```
|
|
|
|
2. **Naviger til projekt directory:**
|
|
```bash
|
|
cd /opt/bmc_hub # Eller korrekt sti
|
|
```
|
|
|
|
3. **Pull ny version:**
|
|
```bash
|
|
git fetch --tags
|
|
git checkout v1.3.75
|
|
```
|
|
|
|
4. **Opdater .env fil med SFTP credentials:**
|
|
```bash
|
|
nano .env
|
|
# Tilføj:
|
|
# OFFSITE_ENABLED=true
|
|
# SFTP_HOST=sftp.acdu.dk
|
|
# SFTP_PORT=9022
|
|
# SFTP_USER=sftp_bmccrm
|
|
# SFTP_PASSWORD=<password>
|
|
# SFTP_REMOTE_PATH=SFTP_BMCCRM
|
|
```
|
|
|
|
5. **Kør database migration:**
|
|
```bash
|
|
docker-compose exec postgres psql -U bmcnetworks -d bmc_hub -f /migrations/052_backup_offsite_columns.sql
|
|
# ELLER manuel ALTER TABLE:
|
|
docker-compose exec postgres psql -U bmcnetworks -d bmc_hub -c "
|
|
ALTER TABLE backup_jobs ADD COLUMN IF NOT EXISTS offsite_status VARCHAR(20) CHECK(offsite_status IN ('pending','uploading','uploaded','failed'));
|
|
ALTER TABLE backup_jobs ADD COLUMN IF NOT EXISTS offsite_location VARCHAR(500);
|
|
ALTER TABLE backup_jobs ADD COLUMN IF NOT EXISTS offsite_attempts INTEGER DEFAULT 0;
|
|
ALTER TABLE backup_jobs ADD COLUMN IF NOT EXISTS offsite_last_error TEXT;
|
|
"
|
|
```
|
|
|
|
6. **Genstart containers:**
|
|
```bash
|
|
docker-compose down
|
|
docker-compose up -d --build
|
|
```
|
|
|
|
7. **Verificer:**
|
|
```bash
|
|
docker-compose logs -f api | grep -i offsite
|
|
curl http://localhost:8001/health
|
|
# Test offsite upload:
|
|
curl -X POST http://localhost:8001/api/v1/backups/offsite/{job_id}
|
|
```
|
|
|
|
## 🧪 Testing
|
|
|
|
### Verify SFTP Connection
|
|
```bash
|
|
# From inside API container:
|
|
docker-compose exec api bash
|
|
apt-get update && apt-get install -y lftp
|
|
lftp -u sftp_bmccrm,'<password>' sftp://sftp.acdu.dk:9022 -e 'ls SFTP_BMCCRM; quit'
|
|
```
|
|
|
|
### Test Upload
|
|
1. Create a backup via web UI: http://localhost:8001/backups
|
|
2. Click "Upload to Offsite" button for the backup
|
|
3. Check logs for "✅ Upload completed"
|
|
4. Verify `offsite_uploaded_at` is set in database
|
|
|
|
## ⚠️ Breaking Changes
|
|
|
|
None - this is a feature addition
|
|
|
|
## 📊 Database Migration
|
|
|
|
**Migration File:** `migrations/052_backup_offsite_columns.sql`
|
|
|
|
**Impact:** Adds 4 new columns to `backup_jobs` table
|
|
- Safe to run on existing data (uses ADD COLUMN IF NOT EXISTS)
|
|
- No data loss risk
|
|
- Existing backups will have NULL values for new columns
|
|
|
|
## 🔐 Security Notes
|
|
|
|
- SFTP password stored in `.env` file (not in repository)
|
|
- Uses paramiko's `AutoAddPolicy` for host keys
|
|
- File size verification prevents corrupt uploads
|
|
- Connection timeout prevents indefinite hangs
|
|
|
|
## 📞 Support
|
|
|
|
Ved problemer, kontakt Christian Thomas eller check logs:
|
|
```bash
|
|
docker-compose logs -f api | grep -E "(offsite|SFTP|Upload)"
|
|
```
|
|
|
|
---
|
|
|
|
**Git Tag:** v1.3.75
|
|
**Previous Version:** v1.3.74
|
|
**Tested on:** Local development environment (macOS Docker)
|