2025-10-05 02:36:05 +02:00
# 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 ](tisbackup.py )) for executing backups, cleanup, and monitoring
- A Flask web GUI ([tisbackup_gui.py ](tisbackup_gui.py )) for managing backups
- A pluggable backup driver architecture in [libtisbackup/ ](libtisbackup/ )
- Task queue system using Huey with Redis ([tasks.py ](tasks.py ), [config.py ](config.py ))
- Docker-based deployment with cron scheduling
## Development Commands
2025-10-05 23:54:26 +02:00
**IMPORTANT: Always use `uv run` to execute Python commands in this project.**
2025-10-05 02:36:05 +02:00
### Dependency Management
```bash
# Install dependencies (uses uv)
uv sync --locked
# Update dependencies
uv lock
```
### Linting
```bash
2025-10-05 23:54:26 +02:00
# Run ruff linter (fast, primary linter)
uv run ruff check .
2025-10-05 02:36:05 +02:00
# Auto-fix linting issues
2025-10-05 23:54:26 +02:00
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
```bash
# 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
2025-10-05 02:36:05 +02:00
```
2025-10-05 23:54:26 +02:00
**Coverage reports:**
- Terminal report: Shows coverage percentage with missing line numbers
- HTML report: Detailed interactive report in `htmlcov/` directory
See [tests/README.md ](tests/README.md ) for detailed testing documentation.
2025-10-05 02:36:05 +02:00
### Running the Application
**Web GUI (development):**
```bash
2025-10-05 23:54:26 +02:00
uv run python tisbackup_gui.py
2025-10-05 02:36:05 +02:00
# Runs on port 8080, requires config at /etc/tis/tisbackup_gui.ini
```
**CLI Commands:**
```bash
# Run backups
2025-10-05 23:54:26 +02:00
uv run python tisbackup.py -c /etc/tis/tisbackup-config.ini backup
2025-10-05 02:36:05 +02:00
# Run specific backup section
2025-10-05 23:54:26 +02:00
uv run python tisbackup.py -c /etc/tis/tisbackup-config.ini -s section_name backup
2025-10-05 02:36:05 +02:00
# Cleanup old backups
2025-10-05 23:54:26 +02:00
uv run python tisbackup.py -c /etc/tis/tisbackup-config.ini cleanup
2025-10-05 02:36:05 +02:00
# Check backup status (for Nagios)
2025-10-05 23:54:26 +02:00
uv run python tisbackup.py -c /etc/tis/tisbackup-config.ini checknagios
2025-10-05 02:36:05 +02:00
# List available backup drivers
2025-10-05 23:54:26 +02:00
uv run python tisbackup.py listdrivers
2025-10-05 02:36:05 +02:00
```
### Docker
```bash
# 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 ](tisbackup.py ) - CLI application with argument parsing and action routing (backup, cleanup, checknagios, etc.)
- [tisbackup_gui.py ](tisbackup_gui.py ) - Flask web application providing UI for backup management and status monitoring
- [tasks.py ](tasks.py ) - Huey task definitions for async operations (export_backup)
**Backup Driver System:**
2025-10-05 23:54:26 +02:00
All backup logic is implemented via driver classes in [libtisbackup/drivers/ ](libtisbackup/drivers/ ):
2025-10-05 02:36:05 +02:00
2025-10-05 23:54:26 +02:00
- Base class: `backup_generic` in [base_driver.py ](libtisbackup/base_driver.py ) (abstract)
2025-10-05 02:36:05 +02:00
- 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
2025-10-05 23:54:26 +02:00
- All driver implementations are in [libtisbackup/drivers/ ](libtisbackup/drivers/ ) subdirectory
**Library Modules:**
- [base_driver.py ](libtisbackup/base_driver.py ) - Core `backup_generic` class, driver registry, Nagios states
- [database.py ](libtisbackup/database.py ) - `BackupStat` class for SQLite operations
- [ssh.py ](libtisbackup/ssh.py ) - SSH utilities with modern key support (Ed25519, ECDSA, RSA)
- [process.py ](libtisbackup/process.py ) - Process execution and monitoring utilities
- [utils.py ](libtisbackup/utils.py ) - Date/time formatting, number formatting, validation helpers
- [__init__.py ](libtisbackup/__init__.py ) - Package exports for backward compatibility
- [drivers/ ](libtisbackup/drivers/ ) - All backup driver implementations
2025-10-05 02:36:05 +02:00
**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
2025-10-05 23:54:26 +02:00
- `backup_xva` / `backup_xcp_metadata` / `copy_vm_xcp` - XenServer VM backups
- `backup_vmdk` - VMware VMDK backups (requires pyVmomi)
2025-10-05 02:36:05 +02:00
- `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 ](libtisbackup/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 ](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
2025-10-05 23:54:26 +02:00
## Commit Message Guidelines
**IMPORTANT: This project uses [Conventional Commits](https://www.conventionalcommits.org/) 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.
2025-10-05 02:36:05 +02:00
## Important Patterns
**Adding a new backup driver:**
2025-10-05 23:54:26 +02:00
1. Create `backup_<type>.py` in [libtisbackup/drivers/ ](libtisbackup/drivers/ )
2025-10-05 02:36:05 +02:00
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>)`
2025-10-05 23:54:26 +02:00
6. Import in [libtisbackup/drivers/__init__.py ](libtisbackup/drivers/__init__.py )
2025-10-05 02:36:05 +02:00
**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}/`