bmc_hub/RELEASE_NOTES_v1.3.75.md
Christian 6c4042b9b6 feat: Implement SFTP offsite backup functionality (v1.3.75)
- 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
2026-01-02 12:35:02 +01:00

4.8 KiB

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:

    ssh bmcadmin@172.16.31.183
    
  2. Naviger til projekt directory:

    cd /opt/bmc_hub  # Eller korrekt sti
    
  3. Pull ny version:

    git fetch --tags
    git checkout v1.3.75
    
  4. Opdater .env fil med SFTP credentials:

    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:

    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:

    docker-compose down
    docker-compose up -d --build
    
  7. Verificer:

    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

# 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:

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)