basmach 0.1.8
Remote system backup over SSH
Requires Python: >=3.6

Remote system backup tool
=========================

How it works
------------

1. optionally save boot area from the boot device of remote system to <storage>/<hostname>/boot/<filename>
2. rsync remote directories to <storage>/<hostname>/sync/
3. if rsync has transferred something, archive <storage>/<hostname>/{sync,boot}
   to <storage>/<hostname>/archives/
4. drop old files from <storage>/archives

There's also persistent archives which can be created manually
in <storage>/<hostname>/archives/persistent/::

    basmach "persistent=Message, e.g. 'this is a persistent backup'"

Persistent backups always create archives even if rsync transferred no changes or `archive` option is false.


Configuration
-------------

By default the configuration is read from :file:`~/basmach.yaml`, however this
file name can be overriden with `config` command line option, e.g.::

    config=/etc/basmach.yaml

Configuration file uses YAML format::

    params:
        storage: <directory>  # required, path to the directory for storing backups
        parallel_backups: <int> # run backups for N hosts in parallel,
                                # default is 1 which means sequental backup
                                # (false and 0 are allowed too)
                                # XXX not recommended because file I/O is not asynchronous

    <hostname>:
        user: <str>           # optional, default is root
        password: <str>       # optional
        port: <int>           # optional
        key_file: <filename>  # optional, private key file for key-based authorization

        boot_area: true/false # optional, backup sectors before the first
                              # partition on the boot device, default is false
        # or, specific device:
        boot_area: /dev/mmcblk0
        # or, list specific devices:
        boot_area:
            - /dev/mmcblk0
            - /dev/nvme0n1

        root_mount: /mnt/root  # optional, directory to mount root partition before backup
        #or,
        root_mount: [ /dev/sda1, /mnt/root ]  # if root device autodetection is not desirable

        rsync_directories:
            - [ /mnt/root, / ] # rsync <hostname>:/mnt/root/ <storage>/<hostname>/sync/
        # or:
        rsync_directories:
            - /etc    # rsync <hostname>:/etc/ <storage>/<hostname>/sync/etc/
            - /home
            - /var

        rsync_exclude:  # list of exclude patterns for rsync or null
            - "*.avi"
            - "*.mkv"

        archive: trus/false # create archives, default is true
        keep_policy:            # None, or:
            max_last_dates: 3   # max number of last dates for which to keep archives and logs
            max_last_weeks: 3   # number of archives and logs to keep for last weeks, with lowest weekday
            max_last_months: 3  # number of archives and logs to keep for last weeks, with lowest day of month


Real configuration example
--------------------------

::

    params:
        storage: /mnt/backup-storage

    mediacenter.home:
        # Mediacenter is based on NanoPi M4v2. This board has an NVMe device, but cannot boot from it.
        # It starts booting from a MicroSD card, but the root filesystem setings point to NVMe
        # in the following files: /boot/armbianEnv.txt and /etc/fstab.
        # So, the root device is NVMe, but it has no u-boot section. We should backup u-boot from the boot device,
        # which is the MicroSD card. The boot device cannot be detected automatically and we have to specify
        # it explicitly.
        key_file: ~/backup_ecdsa
        boot_area: /dev/mmcblk0
        root_mount: [ /dev/nvme0n1, /mnt/root ]
        rsync_directories:
            - [ /mnt/root, / ]
        rsync_exclude:
            - "*.mp4"
            - "*.avi"
            - "*.mkv"
            - "*.wmv"

    fileserver.home:
        key_file: ~/backup_ecdsa
        boot_area: true
        root_mount: /mnt/root
        rsync_directories:
            - [ /mnt/root, / ]

    my-linux-vps.example.com:
        key_file: ~/.ssh/vps-backup
        rsync_directories:
            - /etc
            - /home
            - /root
            - /var/log/nginx
            - /var/www
        archive: false

    my-freebsd-vps.example.com:
        key_file: ~/.ssh/vps-backup
        rsync_directories:
            - /etc
            - /root
            - /usr/home
            - /usr/local/etc
        archive: false


Invocation
----------

Run backup using default configuration::

    basmach

You can make this a cron job::

    ln -s `which basmach` /etc/cron.daily/

Run backup for specific hosts::

    basmach host=<hostname1> host=<hostname2>

Make persistent backups for all hosts::

    basmach "persistent=Message, e.g. 'this is a persistent backup'"

Make persistent backups for specific hosts::

    basmach host=<hostname1> host=<hostname2> "persistent=Message, e.g. 'this is a persistent backup'"

Use specific configuration (you can provide all above arguments as well)::

    basmach config=/etc/basmach.yaml


File ownership
--------------

This tool forces rsync and tar to use numeric identifiers for user and group so they are not mapped
to local users and groups.


Security issues
---------------

Host key checking is disabled to avoid known_hosts prompt.


General issues
--------------

Root and boot devices autodetection, and boot area backup work for linux only.