TISbackup/CLAUDE.md
k3nny 1cb731cbdb
Some checks failed
lint / docker (push) Has been cancelled
refactor(drivers): organize backup modules into drivers subfolder
- Move all backup_*.py files to libtisbackup/drivers/ subdirectory
- Move XenAPI.py and copy_vm_xcp.py to drivers/ (driver-specific)
- Create drivers/__init__.py with automatic driver imports
- Update tisbackup.py imports to use new structure
- Add pyvmomi>=8.0.0 as mandatory dependency
- Sync requirements.txt with pyproject.toml dependencies
- Add pylint>=3.0.0 and pytest-cov>=6.0.0 to dev dependencies
- Configure pylint and coverage tools in pyproject.toml
- Add conventional commits guidelines to CLAUDE.md
- Enhance .gitignore with comprehensive patterns for Python, IDEs, testing, and secrets
- Update CLAUDE.md documentation with new structure and tooling

Breaking Changes:
- Drivers must now be imported from libtisbackup.drivers instead of libtisbackup
- All backup driver files relocated to drivers/ subdirectory

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-05 23:54:26 +02:00

8.5 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

TISBackup is a server-side backup orchestration system written in Python. It executes scheduled backups of various data sources (databases, files, VMs) from remote Linux and Windows systems. The project consists of:

  • A CLI tool (tisbackup.py) for executing backups, cleanup, and monitoring
  • A Flask web GUI (tisbackup_gui.py) for managing backups
  • A pluggable backup driver architecture in libtisbackup/
  • Task queue system using Huey with Redis (tasks.py, config.py)
  • Docker-based deployment with cron scheduling

Development Commands

IMPORTANT: Always use uv run to execute Python commands in this project.

Dependency Management

# Install dependencies (uses uv)
uv sync --locked

# Update dependencies
uv lock

Linting

# Run ruff linter (fast, primary linter)
uv run ruff check .

# Auto-fix linting issues
uv run ruff check --fix .

# Run pylint (comprehensive static analysis)
uv run pylint libtisbackup/

# Run pylint on specific file
uv run pylint libtisbackup/ssh.py

Testing

# Run all tests
uv run pytest

# Run tests for specific module
uv run pytest tests/test_ssh.py

# Run with verbose output
uv run pytest -v

# Run tests matching a pattern
uv run pytest -k "ssh"

# Run with coverage report
uv run pytest --cov=libtisbackup --cov-report=html --cov-report=term-missing

# Run tests with coverage and show only missing lines
uv run pytest --cov=libtisbackup --cov-report=term-missing

# Generate HTML coverage report (opens in browser)
uv run pytest --cov=libtisbackup --cov-report=html
# Then open htmlcov/index.html

Coverage reports:

  • Terminal report: Shows coverage percentage with missing line numbers
  • HTML report: Detailed interactive report in htmlcov/ directory

See tests/README.md for detailed testing documentation.

Running the Application

Web GUI (development):

uv run python tisbackup_gui.py
# Runs on port 8080, requires config at /etc/tis/tisbackup_gui.ini

CLI Commands:

# Run backups
uv run python tisbackup.py -c /etc/tis/tisbackup-config.ini backup

# Run specific backup section
uv run python tisbackup.py -c /etc/tis/tisbackup-config.ini -s section_name backup

# Cleanup old backups
uv run python tisbackup.py -c /etc/tis/tisbackup-config.ini cleanup

# Check backup status (for Nagios)
uv run python tisbackup.py -c /etc/tis/tisbackup-config.ini checknagios

# List available backup drivers
uv run python tisbackup.py listdrivers

Docker

# Build image
docker build . -t tisbackup:latest

# Run via docker compose (see README.md for full setup)
docker compose up -d

Architecture

Core Components

Main Entry Points:

  • tisbackup.py - CLI application with argument parsing and action routing (backup, cleanup, checknagios, etc.)
  • tisbackup_gui.py - Flask web application providing UI for backup management and status monitoring
  • tasks.py - Huey task definitions for async operations (export_backup)

Backup Driver System:

All backup logic is implemented via driver classes in libtisbackup/drivers/:

  • Base class: backup_generic in base_driver.py (abstract)
  • Each driver inherits from backup_generic and implements specific backup logic
  • Drivers are registered via the register_driver() decorator function
  • Configuration is read from INI files using the read_config() method
  • All driver implementations are in libtisbackup/drivers/ subdirectory

Library Modules:

  • base_driver.py - Core backup_generic class, driver registry, Nagios states
  • database.py - BackupStat class for SQLite operations
  • ssh.py - SSH utilities with modern key support (Ed25519, ECDSA, RSA)
  • process.py - Process execution and monitoring utilities
  • utils.py - Date/time formatting, number formatting, validation helpers
  • init.py - Package exports for backward compatibility
  • drivers/ - All backup driver implementations

Available Drivers:

  • backup_rsync / backup_rsync_ssh - File-based backups via rsync
  • backup_rsync_btrfs / backup_rsync__btrfs_ssh - Btrfs snapshot-based backups
  • backup_mysql - MySQL database dumps
  • backup_pgsql - PostgreSQL database dumps
  • backup_oracle - Oracle database backups
  • backup_sqlserver - SQL Server backups
  • backup_samba4 - Samba4 AD backups
  • backup_xva / backup_xcp_metadata / copy_vm_xcp - XenServer VM backups
  • backup_vmdk - VMware VMDK backups (requires pyVmomi)
  • backup_switch - Network switch configuration backups
  • backup_null - No-op driver for testing

State Management:

  • SQLite database tracks backup history, status, and statistics
  • BackupStat class in common.py handles DB operations
  • Database location: {backup_base_dir}/log/tisbackup.sqlite

Configuration

Two separate INI configuration files:

  1. tisbackup-config.ini - Backup definitions

    • [global] section with defaults (backup_base_dir, backup_retention_time, maximum_backup_age)
    • One section per backup job with driver type and parameters
  2. tisbackup_gui.ini - GUI settings

    • Points to tisbackup-config.ini location(s)
    • Defines admin email, base directories

Task Queue

  • Uses Huey (Redis-backed) for async job processing
  • Currently implements run_export_backup for exporting backups to external storage
  • Task state tracked in tasks.sqlite

Docker Deployment

Two-container architecture:

  • tisbackup_gui: Runs Flask web interface
  • tisbackup_cron: Runs scheduled backups via cron (executes backup.sh at 03:59 daily)

Code Style

  • Line length: 140 characters (configured in pyproject.toml)
  • Ruff ignores: F401, F403, F405, E402, E701, E722, E741
  • Python 3.13+ required

Commit Message Guidelines

IMPORTANT: This project uses Conventional Commits format.

All commit messages must follow this format:

<type>(<scope>): <description>

[optional body]

[optional footer(s)]

Types:

  • feat: A new feature
  • fix: A bug fix
  • docs: Documentation only changes
  • refactor: Code change that neither fixes a bug nor adds a feature
  • test: Adding missing tests or correcting existing tests
  • chore: Changes to build process or auxiliary tools
  • perf: Performance improvements
  • style: Code style changes (formatting, missing semicolons, etc.)

Scopes (commonly used):

  • auth: Authentication/authorization changes
  • security: Security-related changes
  • drivers: Backup driver changes
  • gui: Web GUI changes
  • api: API changes
  • readme: README.md changes
  • claude: CLAUDE.md changes
  • core: Core library changes

Examples:

  • feat(auth): add pluggable authentication system for Flask routes
  • fix(security): replace os.popen/os.system with subprocess
  • docs(readme): add comprehensive security and authentication documentation
  • refactor(drivers): organize backup modules into drivers subfolder
  • chore(deps): add pyvmomi as mandatory dependency

Breaking Changes: Add ! after type/scope for breaking changes:

  • feat(api)!: remove deprecated endpoint

Note: Always include a scope in parentheses, even for documentation changes.

When Claude Code creates commits, it will automatically follow this format.

Important Patterns

Adding a new backup driver:

  1. Create backup_<type>.py in libtisbackup/drivers/
  2. Inherit from backup_generic
  3. Set class attributes: type, required_params, optional_params
  4. Implement abstract methods: do_backup(), cleanup(), checknagios()
  5. Register with register_driver(backup_<type>)
  6. Import in libtisbackup/drivers/init.py

SSH Operations:

  • Uses paramiko for SSH connections
  • Supports both RSA and DSA keys
  • Private key path specified per backup section via private_key parameter
  • Pre/post-exec hooks run remote commands via SSH

Path Handling:

  • Module imports use sys.path manipulation to include lib/ and libtisbackup/
  • All backup drivers expect absolute paths for backup_dir
  • Backup directory structure: {backup_base_dir}/{section_name}/{timestamp}/