backup-rsync-base


Namebackup-rsync-base JSON
Version 0.2.0 PyPI version JSON
download
home_pageNone
SummaryA base class for supporting cross-platform backups using rsync
upload_time2025-08-07 03:19:30
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseNone
keywords backup rsync maintenance
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            * website: <https://arrizza.com/python-backup-rsync-base.html>
* installation: see <https://arrizza.com/setup-common.html>

## Summary

This project is python module for running rsync sessions, typically for backups.

The intent is to use it as a base class and then have specific directories and other extensions as you need
for your backups.

## Sample

An example of using it is in sample/app.py.
That sample depends on a home directory called tmp-backups.

```bash
mkdir -p ~/tmp-backups
./doit
ls -al ~/tmp-backups
# there should be a directory with your PC's hostname in there.
# and within that there should be a couple directories:
# inventory and sample
```

Typical output:

```text
<snip>
00.000      sample: this pc    your-hostname
00.000      sample: bkp host   None                                       <== shows local backup
00.000      sample: bkp root   /home/yourid/tmp-backups/your-hostname     <== destination of backups
00.000      sample: inc dir    /home/yourid/tmp-backups/your-hostname/inc_backup_2025-05-16_21-23-23
00.000 ---> sample: dobackup starting: /home/yourid/projects/path/to/backup-rsync-base/sample/ extra_opts=...
00.003  --    1] sending incremental file list
00.003  --    2] created 1 directory for /home/arrizza/tmp-backups/john26/sample
00.003  --    3] ./
00.003  --    4] __init__.py                                              <== rsync files that were backed up
00.003  --    5] app.py
00.003  --    6] main.py
00.044  --    7] 
00.044  --    8] Number of files: 4 (reg: 3, dir: 1)
00.044  --    9] Number of created files: 3 (reg: 3)
00.044  --   10] Number of deleted files: 0
00.044  --   11] Number of regular files transferred: 3
00.044  --   12] Total file size: 2.50K bytes
00.044  --   13] Total transferred file size: 2.50K bytes
00.044  --   14] Literal data: 2.50K bytes
00.044  --   15] Matched data: 0 bytes
00.044  --   16] File list size: 0
00.044  --   17] File list generation time: 0.001 seconds
00.044  --   18] File list transfer time: 0.000 seconds
00.044  --   19] Total bytes sent: 2.76K
00.044  --   20] Total bytes received: 151
00.044  --   21] 
00.044  --   22] sent 2.76K bytes  received 151 bytes  5.82K bytes/sec
00.044  --   23] total size is 2.50K  speedup is 0.86
00.044 OK   do_backup path:/home/yourid/projects/path/to/backup-rsync-base/sample/   <== successful backup occurred
00.044 ---> sample: ubuntu get_packages
00.044      sample: get_os_packages
00.205 OK    - get pkg list            <== getting list of apt packages
00.248 OK    - get snap list           <== getting list of snap packages 
00.344 OK    - get gem list            <== getting list of ruby gems
00.580 OK    - get pip list            <== getting list of python pip modules 
00.583 OK   Overall rc: 0
00.583 ---> notification:
00.583         source: your-hostname
00.583         event : base sample
00.583         status: ok
00.583         desc  : 00:00:00 overallrc=0; done:1 warns:0 failed:0; all done
<snip>
```

## How to use

See sample/app.py for an example.

* inherit from BackupBase

```text
class App(BackupBase):
```

* tag: set logging tag, also used in notifications
* print_cb: call back to use for logging. This should save the output where you can review it later as needed

```text
def run(self):
    # set logging and notification tag
    self.tag = 'sample'

    # add callback to cmd_runner to print lines to the logger
    self.print_cb = self._print
    <skip>

# prints output lines to stdout    
def _print(self, lineno, line):
    self.log.output(lineno, line)
```

* bkp_host: set the hostname of the PC that holds the backup directory destination.
    * This host name will need to be accessed via SSH.
    * Use the name you have in .ssh/config to make this more secure using ssh ed25519 keys (for example)
    * should not require you to enter a password
    * if you use None, then the host is the current PC

* bkp_root: the full path name inside the bkp_host to directory that will hold the backups
    * if you use None for bkp_host, then you can use "~" here, otherwise an absolute path name is required

```text
    # does a local rsync (no ssh) to a local directory
    self.bkp_host = None
    self.bkp_root = os.path.expanduser(os.path.join('~', 'tmp-backups', self.this))
```

* opts: a list of rsync options you can extend.
    * typically these set directories for rsync to exclude (i.e. not back up)

```text
    # skip some common directories
    self.opts = ''
    self.opts_set_base()
    self.opts += '--exclude venv '
    <snip>
```

* do initialization and some logging to show the current state

```text
    # do initialization for the base class
    self.init_base()

    # report current state
    self.report_base()
```

* do the backups. The parameters are:
    * root - the path to the root directory e.g. ~/projects/you/want/to/backup
    * bkp_dir - the directory within root you want to back up now
    * extra_opts - additional rsync options you want to use for this particular run

```text
    root = os.getcwd()   <== set the root directory.

    # do a backup
    self.do_backup(root, 'sample')
    self.do_backup(root, 'ut')
    self.do_backup(root, 'ver')
    <etc.>
```

* add additional information to the notification description.
  This can be done as needed.

```
   # add extra text to notification
   self.add_to_desc('all done')
```

* if you wish to capture inventories of that PC use the following
* these will that are currently installed:
    * Ubuntu apt packages, macOS Brew packages, or MSYS2 pacman packages on windows
    * Ubuntu snap packages
    * ruby gems
    * python pip modules

```text
    inventory_path = os.path.join(self.bkp_root, 'inventory')   <== where to back up the files
    if not os.path.exists(inventory_path):                      <== make sure it exists  
        os.makedirs(inventory_path)
    self.get_packages(inventory_path)                           <== gather the inventory lists
```

* send or report a notification indicating the status of the backup.

```
    self.send_overall_status()
    <snip>
```

The default notify() function uses my notify_client_server module to send the notification to a local web page.
See [Notify Client Server](/python-notify-client-server)

For other scenarios, use this function as a template:

```
# ---------------------
def notify(self, status, desc):
    source = self.this
    event = f'base {self.tag}'
    self.log.highlight('notification:')
    self.log.line(f'   source: {source}')
    self.log.line(f'   event : {event}')
    self.log.line(f'   status: {status}')
    self.log.line(f'   desc  : {desc}')
```

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "backup-rsync-base",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": "\"J. Arrizza\" <cppgent0@gmail.com>",
    "keywords": "backup, rsync, maintenance",
    "author": null,
    "author_email": "\"J. Arrizza\" <cppgent0@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/41/2a/5dbc2bdce1057a126606e3138f1cc8db46ff6906f0b544530e7c37d5da3b/backup_rsync_base-0.2.0.tar.gz",
    "platform": null,
    "description": "* website: <https://arrizza.com/python-backup-rsync-base.html>\n* installation: see <https://arrizza.com/setup-common.html>\n\n## Summary\n\nThis project is python module for running rsync sessions, typically for backups.\n\nThe intent is to use it as a base class and then have specific directories and other extensions as you need\nfor your backups.\n\n## Sample\n\nAn example of using it is in sample/app.py.\nThat sample depends on a home directory called tmp-backups.\n\n```bash\nmkdir -p ~/tmp-backups\n./doit\nls -al ~/tmp-backups\n# there should be a directory with your PC's hostname in there.\n# and within that there should be a couple directories:\n# inventory and sample\n```\n\nTypical output:\n\n```text\n<snip>\n00.000      sample: this pc    your-hostname\n00.000      sample: bkp host   None                                       <== shows local backup\n00.000      sample: bkp root   /home/yourid/tmp-backups/your-hostname     <== destination of backups\n00.000      sample: inc dir    /home/yourid/tmp-backups/your-hostname/inc_backup_2025-05-16_21-23-23\n00.000 ---> sample: dobackup starting: /home/yourid/projects/path/to/backup-rsync-base/sample/ extra_opts=...\n00.003  --    1] sending incremental file list\n00.003  --    2] created 1 directory for /home/arrizza/tmp-backups/john26/sample\n00.003  --    3] ./\n00.003  --    4] __init__.py                                              <== rsync files that were backed up\n00.003  --    5] app.py\n00.003  --    6] main.py\n00.044  --    7] \n00.044  --    8] Number of files: 4 (reg: 3, dir: 1)\n00.044  --    9] Number of created files: 3 (reg: 3)\n00.044  --   10] Number of deleted files: 0\n00.044  --   11] Number of regular files transferred: 3\n00.044  --   12] Total file size: 2.50K bytes\n00.044  --   13] Total transferred file size: 2.50K bytes\n00.044  --   14] Literal data: 2.50K bytes\n00.044  --   15] Matched data: 0 bytes\n00.044  --   16] File list size: 0\n00.044  --   17] File list generation time: 0.001 seconds\n00.044  --   18] File list transfer time: 0.000 seconds\n00.044  --   19] Total bytes sent: 2.76K\n00.044  --   20] Total bytes received: 151\n00.044  --   21] \n00.044  --   22] sent 2.76K bytes  received 151 bytes  5.82K bytes/sec\n00.044  --   23] total size is 2.50K  speedup is 0.86\n00.044 OK   do_backup path:/home/yourid/projects/path/to/backup-rsync-base/sample/   <== successful backup occurred\n00.044 ---> sample: ubuntu get_packages\n00.044      sample: get_os_packages\n00.205 OK    - get pkg list            <== getting list of apt packages\n00.248 OK    - get snap list           <== getting list of snap packages \n00.344 OK    - get gem list            <== getting list of ruby gems\n00.580 OK    - get pip list            <== getting list of python pip modules \n00.583 OK   Overall rc: 0\n00.583 ---> notification:\n00.583         source: your-hostname\n00.583         event : base sample\n00.583         status: ok\n00.583         desc  : 00:00:00 overallrc=0; done:1 warns:0 failed:0; all done\n<snip>\n```\n\n## How to use\n\nSee sample/app.py for an example.\n\n* inherit from BackupBase\n\n```text\nclass App(BackupBase):\n```\n\n* tag: set logging tag, also used in notifications\n* print_cb: call back to use for logging. This should save the output where you can review it later as needed\n\n```text\ndef run(self):\n    # set logging and notification tag\n    self.tag = 'sample'\n\n    # add callback to cmd_runner to print lines to the logger\n    self.print_cb = self._print\n    <skip>\n\n# prints output lines to stdout    \ndef _print(self, lineno, line):\n    self.log.output(lineno, line)\n```\n\n* bkp_host: set the hostname of the PC that holds the backup directory destination.\n    * This host name will need to be accessed via SSH.\n    * Use the name you have in .ssh/config to make this more secure using ssh ed25519 keys (for example)\n    * should not require you to enter a password\n    * if you use None, then the host is the current PC\n\n* bkp_root: the full path name inside the bkp_host to directory that will hold the backups\n    * if you use None for bkp_host, then you can use \"~\" here, otherwise an absolute path name is required\n\n```text\n    # does a local rsync (no ssh) to a local directory\n    self.bkp_host = None\n    self.bkp_root = os.path.expanduser(os.path.join('~', 'tmp-backups', self.this))\n```\n\n* opts: a list of rsync options you can extend.\n    * typically these set directories for rsync to exclude (i.e. not back up)\n\n```text\n    # skip some common directories\n    self.opts = ''\n    self.opts_set_base()\n    self.opts += '--exclude venv '\n    <snip>\n```\n\n* do initialization and some logging to show the current state\n\n```text\n    # do initialization for the base class\n    self.init_base()\n\n    # report current state\n    self.report_base()\n```\n\n* do the backups. The parameters are:\n    * root - the path to the root directory e.g. ~/projects/you/want/to/backup\n    * bkp_dir - the directory within root you want to back up now\n    * extra_opts - additional rsync options you want to use for this particular run\n\n```text\n    root = os.getcwd()   <== set the root directory.\n\n    # do a backup\n    self.do_backup(root, 'sample')\n    self.do_backup(root, 'ut')\n    self.do_backup(root, 'ver')\n    <etc.>\n```\n\n* add additional information to the notification description.\n  This can be done as needed.\n\n```\n   # add extra text to notification\n   self.add_to_desc('all done')\n```\n\n* if you wish to capture inventories of that PC use the following\n* these will that are currently installed:\n    * Ubuntu apt packages, macOS Brew packages, or MSYS2 pacman packages on windows\n    * Ubuntu snap packages\n    * ruby gems\n    * python pip modules\n\n```text\n    inventory_path = os.path.join(self.bkp_root, 'inventory')   <== where to back up the files\n    if not os.path.exists(inventory_path):                      <== make sure it exists  \n        os.makedirs(inventory_path)\n    self.get_packages(inventory_path)                           <== gather the inventory lists\n```\n\n* send or report a notification indicating the status of the backup.\n\n```\n    self.send_overall_status()\n    <snip>\n```\n\nThe default notify() function uses my notify_client_server module to send the notification to a local web page.\nSee [Notify Client Server](/python-notify-client-server)\n\nFor other scenarios, use this function as a template:\n\n```\n# ---------------------\ndef notify(self, status, desc):\n    source = self.this\n    event = f'base {self.tag}'\n    self.log.highlight('notification:')\n    self.log.line(f'   source: {source}')\n    self.log.line(f'   event : {event}')\n    self.log.line(f'   status: {status}')\n    self.log.line(f'   desc  : {desc}')\n```\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A base class for supporting cross-platform backups using rsync",
    "version": "0.2.0",
    "project_urls": {
        "Download": "https://bitbucket.org/arrizza-public/backup-rsync-base/get/master.zip",
        "Source": "https://bitbucket.org/arrizza-public/backup-rsync-base/src/master",
        "Website": "https://arrizza.com/python-backup-rsync-base"
    },
    "split_keywords": [
        "backup",
        " rsync",
        " maintenance"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "412a5dbc2bdce1057a126606e3138f1cc8db46ff6906f0b544530e7c37d5da3b",
                "md5": "c4397588bed86938605cb103e57fd3fc",
                "sha256": "b1cb6e6a7a8d7e69336792ee268e948c0aa5b449968c38f5ccbdbd486666c119"
            },
            "downloads": -1,
            "filename": "backup_rsync_base-0.2.0.tar.gz",
            "has_sig": false,
            "md5_digest": "c4397588bed86938605cb103e57fd3fc",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 11965,
            "upload_time": "2025-08-07T03:19:30",
            "upload_time_iso_8601": "2025-08-07T03:19:30.003813Z",
            "url": "https://files.pythonhosted.org/packages/41/2a/5dbc2bdce1057a126606e3138f1cc8db46ff6906f0b544530e7c37d5da3b/backup_rsync_base-0.2.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-07 03:19:30",
    "github": false,
    "gitlab": false,
    "bitbucket": true,
    "codeberg": false,
    "bitbucket_user": "arrizza-public",
    "bitbucket_project": "backup-rsync-base",
    "lcname": "backup-rsync-base"
}
        
Elapsed time: 1.20654s