# sown/backup architecture

> Architecture diagram of the GitHub repository sown/backup, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/sown/backup
- Repository: https://github.com/sown/backup

## Overview

SOWN Backup selects NetBox hosts tagged for backup, then provisions a local ZFS dataset, reads remote exclusions and runs hooks, synchronizes the host filesystem, rotates snapshots, and reports successful completion to Icinga. The CLI also supports a forced single-host run. Paths and calls are grounded in the sampled source; the README documents the scheduled operation and ZFS snapshot exposure, but no separate scheduler implementation is present in this repository.

Main entry points: [`backup/backup.py`](https://github.com/sown/backup/blob/main/backup/backup.py) (Host backup), [`backup/cli.py`](https://github.com/sown/backup/blob/main/backup/cli.py) (Backup CLI), [`backup/rotation.py`](https://github.com/sown/backup/blob/main/backup/rotation.py) (Snapshot rotation), [`backup/icinga.py`](https://github.com/sown/backup/blob/main/backup/icinga.py) (Icinga reporter)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_selection["Host selection"]
  node_cli["Backup CLI<br/>[cli.py]"]
  node_netbox_client["NetBox client<br/>[netbox.py]"]
end

subgraph group_backup["Backup execution"]
  node_backup_runner["Host backup<br/>[backup.py]"]
  node_rsync["rsync process"]
  node_standard_excludes["Standard excludes<br/>[excludes.py]"]
end

subgraph group_storage["Snapshots and storage"]
  node_zfs_ops["ZFS commands<br/>[zfs.py]"]
  node_rotation["Snapshot rotation<br/>[rotation.py]"]
  node_schedules["Rotation schedule<br/>[schedules.py]"]
end

subgraph group_operations["Monitoring and logs"]
  node_config["Runtime config<br/>[config.example.py]"]
  node_icinga_client["Icinga reporter<br/>[icinga.py]"]
  node_logger["Logger setup<br/>[logconfig.py]"]
end

node_operator(("Operator or cron"))
node_netbox{{"NetBox"}}
node_remote_host{{"Backup host"}}
node_zfs_store[("ZFS datasets")]
node_icinga{{"Icinga API"}}
node_syslog{{"Syslog"}}

node_operator -->|"invokes"| node_cli
node_cli -->|"requests hosts"| node_netbox_client
node_netbox_client -->|"queries"| node_netbox
node_cli -->|"dispatches backup"| node_backup_runner
node_cli -->|"sets up logging"| node_logger
node_logger -->|"writes logs"| node_syslog
node_backup_runner -->|"reads excludes; runs hooks"| node_remote_host
node_backup_runner -->|"reads"| node_standard_excludes
node_backup_runner -->|"checks or creates dataset"| node_zfs_ops
node_backup_runner -->|"runs sync"| node_rsync
node_rsync -->|"reads root filesystem"| node_remote_host
node_rsync -->|"writes backup files"| node_zfs_store
node_backup_runner -->|"rotates after sync"| node_rotation
node_rotation -->|"reads schedule"| node_schedules
node_rotation -->|"lists, snapshots, deletes"| node_zfs_ops
node_zfs_ops -->|"manages datasets"| node_zfs_store
node_backup_runner -->|"reports successful backup"| node_icinga_client
node_icinga_client -->|"posts check result"| node_icinga
node_backup_runner -->|"reads hostname setting"| node_config
node_icinga_client -->|"reads API settings"| node_config
node_rotation -->|"reads rotation settings"| node_config

click node_cli "https://github.com/sown/backup/blob/main/backup/cli.py"
click node_netbox_client "https://github.com/sown/backup/blob/main/backup/netbox.py"
click node_backup_runner "https://github.com/sown/backup/blob/main/backup/backup.py"
click node_standard_excludes "https://github.com/sown/backup/blob/main/backup/excludes.py"
click node_zfs_ops "https://github.com/sown/backup/blob/main/backup/zfs.py"
click node_rotation "https://github.com/sown/backup/blob/main/backup/rotation.py"
click node_schedules "https://github.com/sown/backup/blob/main/backup/schedules.py"
click node_config "https://github.com/sown/backup/blob/main/backup/config.example.py"
click node_icinga_client "https://github.com/sown/backup/blob/main/backup/icinga.py"
click node_logger "https://github.com/sown/backup/blob/main/backup/logconfig.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_cli,node_netbox_client toneBlue
class node_backup_runner,node_rsync,node_standard_excludes,node_zfs_store toneAmber
class node_zfs_ops,node_rotation,node_schedules,node_icinga toneMint
class node_config,node_icinga_client,node_logger toneRose
class node_operator,node_netbox,node_remote_host,node_syslog toneIndigo
```

## Components

### Host selection

- [Backup CLI](https://github.com/sown/backup/blob/main/backup/cli.py): `backup/cli.py`
- [NetBox client](https://github.com/sown/backup/blob/main/backup/netbox.py): `backup/netbox.py`

### Backup execution

- [Host backup](https://github.com/sown/backup/blob/main/backup/backup.py): `backup/backup.py`
- **rsync process**
- [Standard excludes](https://github.com/sown/backup/blob/main/backup/excludes.py): `backup/excludes.py`

### Snapshots and storage

- [ZFS commands](https://github.com/sown/backup/blob/main/backup/zfs.py): `backup/zfs.py`
- [Snapshot rotation](https://github.com/sown/backup/blob/main/backup/rotation.py): `backup/rotation.py`
- [Rotation schedule](https://github.com/sown/backup/blob/main/backup/schedules.py): `backup/schedules.py`

### Monitoring and logs

- [Runtime config](https://github.com/sown/backup/blob/main/backup/config.example.py): `backup/config.example.py`
- [Icinga reporter](https://github.com/sown/backup/blob/main/backup/icinga.py): `backup/icinga.py`
- [Logger setup](https://github.com/sown/backup/blob/main/backup/logconfig.py): `backup/logconfig.py`

### Other components

- **Operator or cron**
- **NetBox**
- **Backup host**
- **ZFS datasets**
- **Icinga API**
- **Syslog**

## Connections

- Operator or cron → Backup CLI: invokes
- Backup CLI → NetBox client: requests hosts
- NetBox client → NetBox: queries
- Backup CLI → Host backup: dispatches backup
- Backup CLI → Logger setup: sets up logging
- Logger setup → Syslog: writes logs
- Host backup → Backup host: reads excludes; runs hooks
- Host backup → Standard excludes: reads
- Host backup → ZFS commands: checks or creates dataset
- Host backup → rsync process: runs sync
- rsync process → Backup host: reads root filesystem
- rsync process → ZFS datasets: writes backup files
- Host backup → Snapshot rotation: rotates after sync
- Snapshot rotation → Rotation schedule: reads schedule
- Snapshot rotation → ZFS commands: lists, snapshots, deletes
- ZFS commands → ZFS datasets: manages datasets
- Host backup → Icinga reporter: reports successful backup
- Icinga reporter → Icinga API: posts check result
- Host backup → Runtime config: reads hostname setting
- Icinga reporter → Runtime config: reads API settings
- Snapshot rotation → Runtime config: reads rotation settings
