{ "info": { "author": "Peter Odding", "author_email": "peter@peterodding.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Console", "Intended Audience :: Developers", "Intended Audience :: System Administrators", "License :: OSI Approved :: MIT License", "Operating System :: POSIX :: Linux", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: System :: Archiving :: Backup", "Topic :: System :: Systems Administration" ], "description": "rsync-system-backup: Linux system backups powered by rsync\n==========================================================\n\n.. image:: https://travis-ci.org/xolox/python-rsync-system-backup.svg?branch=master\n :target: https://travis-ci.org/xolox/python-rsync-system-backup\n\n.. image:: https://coveralls.io/repos/xolox/python-rsync-system-backup/badge.svg?branch=master\n :target: https://coveralls.io/r/xolox/python-rsync-system-backup?branch=master\n\nThe rsync-system-backup program uses rsync_ to create full system backups of\nLinux_ systems. Supported backup destinations include local disks (possibly\nencrypted using LUKS_) and remote systems that are running an SSH_ server or\n`rsync daemon`_. Each backup produces a timestamped snapshot and these\nsnapshots are rotated according to a rotation scheme that you can configure.\nThe package is currently tested on cPython 2.7, 3.4, 3.5, 3.6, 3.7 and PyPy\n(2.7).\n\n.. contents::\n :depth: 3\n :local:\n\nStatus\n------\n\nWhile this project brings together more than ten years of experience in\ncreating (system) backups using rsync_, all of the actual Python code was\nwritten in the first few months of 2017 and has seen limited real world use.\nThe project does however have an automated test suite with more than 90% test\ncoverage and my intention is to extend the test coverage further.\n\nIn May 2018 I changed the status from alpha to beta as part of release 1.0. The\nbump in major version number was triggered by a backwards incompatible code\nchange, however at that point I had been using `rsync-system-backup` to make\nlocal backups of several of my Linux systems for the majority of a year. Also\nseveral colleagues of mine have used the how-to on setting up unattended\nbackups to an encrypted USB disk.\n\n.. warning:: Please use the ``--dry-run`` option when you're getting familiar\n with how `rsync-system-backup` works and don't remove the option\n until you're confident that you have the right command line,\n because using `rsync-system-backup` in the wrong way can cause\n data loss (for example by accidentally swapping the ``SOURCE``\n and ``DESTINATION`` arguments).\n\nInstallation\n------------\n\nThe `rsync-system-backup` package is available on PyPI_ which means\ninstallation should be as simple as:\n\n.. code-block:: sh\n\n $ pip install rsync-system-backup\n\nThere's actually a multitude of ways to install Python packages (e.g. the `per\nuser site-packages directory`_, `virtual environments`_ or just installing\nsystem wide) and I have no intention of getting into that discussion here, so\nif this intimidates you then read up on your options before returning to these\ninstructions ;-).\n\nUsage\n-----\n\nThere are two ways to use the `rsync-system-backup` package: As the command\nline program ``rsync-system-backup`` and as a Python API. For details about the\nPython API please refer to the API documentation available on `Read the Docs`_.\nThe command line interface is described below.\n\nCommand line\n~~~~~~~~~~~~\n\n.. A DRY solution to avoid duplication of the `rsync-system-backup --help' text:\n..\n.. [[[cog\n.. from humanfriendly.usage import inject_usage\n.. inject_usage('rsync_system_backup.cli')\n.. ]]]\n\n**Usage:** `rsync-system-backup [OPTIONS] [SOURCE] DESTINATION`\n\nUse rsync to create full system backups.\n\nThe required DESTINATION argument specifies the (possibly remote) location\nwhere the backup is stored, in the syntax of rsync's command line interface.\nThe optional SOURCE argument defaults to '/' which means the complete root\nfilesystem will be included in the backup (other filesystems are excluded).\n\nPlease use the ``--dry-run`` option when getting familiar with this program and\ndon't remove it until you're confident that you have the right command line,\nbecause using this program in the wrong way can cause data loss (for example\nby accidentally swapping the SOURCE and DESTINATION arguments).\n\nSupported locations include:\n\n- Local disks (possibly encrypted using LUKS).\n- Remote systems that allow SSH connections.\n- Remote systems that are running an rsync daemon.\n- Connections to rsync daemons tunneled over SSH.\n\nThe backup process consists of several steps:\n\n1. First rsync is used to transfer all (relevant) files to a destination\n directory (whether on the local system or a remote system). Every time\n a backup is made, this same destination directory is updated.\n\n2. After the files have been transferred a 'snapshot' of the destination\n directory is taken and stored in a directory with a timestamp in its\n name. These snapshots are created using 'cp ``--archive`` ``--link``'.\n\n3. Finally the existing snapshots are rotated to purge old backups\n according to a rotation scheme that you can customize.\n\n**Supported options:**\n\n.. csv-table::\n :header: Option, Description\n :widths: 30, 70\n\n\n \"``-b``, ``--backup``\",\"Create a backup using rsync but don't create a snapshot and don't rotate\n old snapshots unless the ``--snapshot`` and/or ``--rotate`` options are also given.\"\n \"``-s``, ``--snapshot``\",\"Create a snapshot of the destination directory but don't create a backup\n and don't rotate old snapshots unless the ``--backup`` and/or ``--rotate`` options\n are also given.\n\n This option can be used to create snapshots of an rsync daemon module using\n a 'post-xfer exec' command. If DESTINATION isn't given it defaults to the\n value of the environment variable ``$RSYNC_MODULE_PATH``.\"\n \"``-r``, ``--rotate``\",\"Rotate old snapshots but don't create a backup and snapshot unless the\n ``--backup`` and/or ``--snapshot`` options are also given.\n\n This option can be used to rotate old snapshots of an rsync daemon module\n using a 'post-xfer exec' command. If DESTINATION isn't given it defaults to\n the value of the environment variable ``$RSYNC_MODULE_PATH``.\"\n \"``-m``, ``--mount=DIRECTORY``\",\"Automatically mount the filesystem to which backups are written.\n\n When this option is given and ``DIRECTORY`` isn't already mounted, the\n 'mount' command is used to mount the filesystem to which backups are\n written before the backup starts. When 'mount' was called before the\n backup started, 'umount' will be called when the backup finishes.\n\n An entry for the mount point needs to be\n defined in /etc/fstab for this to work.\"\n \"``-c``, ``--crypto=NAME``\",\"Automatically unlock the encrypted filesystem to which backups are written.\n\n When this option is given and the ``NAME`` device isn't already unlocked, the\n cryptdisks_start command is used to unlock the encrypted filesystem to\n which backups are written before the backup starts. When cryptdisks_start\n was called before the backup started, cryptdisks_stop will be called\n when the backup finishes.\n\n An entry for the encrypted filesystem needs to be defined in /etc/crypttab\n for this to work. If the device of the encrypted filesystem is missing and\n rsync-system-backup is being run non-interactively, it will exit gracefully\n and not show any desktop notifications.\n\n If you want the backup process to run fully unattended you can configure a\n key file in /etc/crypttab, otherwise you will be asked for the password\n each time the encrypted filesystem is unlocked.\"\n \"``-t``, ``--tunnel=TUNNEL_SPEC``\",\"Connect to an rsync daemon through an SSH tunnel. This provides encryption\n for rsync client to daemon connections that are not otherwise encrypted.\n The value of ``TUNNEL_SPEC`` is expected to be an SSH alias, host name or IP\n address. Optionally a username can be prefixed (followed by '@') and/or a\n port number can be suffixed (preceded by ':').\"\n \"``-i``, ``--ionice=CLASS``\",\"Use the 'ionice' program to set the I/O scheduling class and priority of\n the 'rm' invocations used to remove backups. ``CLASS`` is expected to be one of\n the values 'idle', 'best-effort' or 'realtime'. Refer to the man page of\n the 'ionice' program for details about these values.\"\n \"``-u``, ``--no-sudo``\",\"By default backup and snapshot creation is performed with superuser\n privileges, to ensure that all files are readable and filesystem\n metadata is preserved. The ``-u``, ``--no-sudo`` option disables\n the use of 'sudo' during these operations.\"\n \"``-n``, ``--dry-run``\",\"Don't make any changes, just report what would be done. This doesn't\n create a backup or snapshot but it does run rsync with the ``--dry-run``\n option.\"\n ``--multi-fs``,\"Allow rsync to cross filesystem boundaries. This option has the opposite\n effect of the rsync option ``--one-file-system`` because rsync-system-backup\n defaults to running rsync with ``--one-file-system`` and must be instructed\n not to using ``--multi-fs``.\"\n \"``-x``, ``--exclude=PATTERN``\",\"Selectively exclude certain files from being included in the backup.\n Refer to the rsync documentation for allowed ``PATTERN`` syntax. Note that\n rsync-system-backup always uses the 'rsync ``--one-file-system``' option.\"\n \"``-f``, ``--force``\",\"By default rsync-system-backup refuses to run on non-Linux systems because\n it was designed specifically for use on Linux. The use of the ``-f``, ``--force``\n option sidesteps this sanity check. Please note that you are on your own if\n things break!\"\n ``--disable-notifications``,\"By default a desktop notification is shown (using notify-send) before the\n system backup starts and after the backup finishes. The use of this option\n disables the notifications (notify-send will not be called at all).\"\n \"``-v``, ``--verbose``\",Make more noise (increase logging verbosity). Can be repeated.\n \"``-q``, ``--quiet``\",Make less noise (decrease logging verbosity). Can be repeated.\n \"``-h``, ``--help``\",Show this message and exit.\n\n.. [[[end]]]\n\nHow it works\n------------\n\nI've been finetuning my approach to Linux system backups for years now and\nduring that time rsync_ has become my swiss army knife of choice :-). I also\nbelieve that comprehensive documentation can be half the value of an open\nsource project. The following sections attempt to provide a high level\noverview of my system backup strategy:\n\n.. contents::\n :depth: 1\n :local:\n\nThe (lack of) backup format\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nEach backup is a full copy of the filesystem tree, stored in the form of\nindividual files and directories on the destination. This \"backup format\" makes\nit really easy to navigate through and recover from backups because you can use\nwhatever method you are comfortable with, whether that is a file browser,\nterminal, Python_ script or even chroot_ :-).\n\n.. note:: You may want to configure updatedb_ to exclude the directory\n containing your system backups, otherwise the locate_ database\n will grow enormously.\n\nSnapshots and hard links\n~~~~~~~~~~~~~~~~~~~~~~~~\n\nEvery time a backup is made the same destination directory is updated with\nadditions, updates and deletions since the last backup. After the backup is\ndone a snapshot of the destination directory is created using the command ``cp\n--archive --link`` with the current date and time encoded in the name.\n\nDue to the use of `hard links`_ each \"version\" of a file is only stored once.\nBecause rsync_ by default doesn't modify files inplace it breaks `hard links`_\nand thereby avoids modifying existing inodes_. This ensures that the contents\nof snapshots don't change when a new backup updates existing files. The\ncombination of hard links and the avoidance of inplace modifications\neffectively provides a limited form of deduplication_. Each snapshot requires a\ncouple of megabytes to store the directory names and hard links but the\ncontents of files aren't duplicated.\n\nThe article `Easy Automated Snapshot-Style Backups with Linux and Rsync`_\ncontains more details about this technique.\n\nRotation of snapshots\n~~~~~~~~~~~~~~~~~~~~~\n\nSnapshots can be rotated according to a flexible rotation scheme, for example\nI've configured my laptop backup rotation to preserve the most recent 24 hourly\nbackups, 30 daily backups and endless monthly backups.\n\nBackup destinations\n~~~~~~~~~~~~~~~~~~~\n\nWhile developing, maintaining and evolving backup scripts for various Linux\nlaptops and servers I've learned that backups for different systems require\ndifferent backup destinations and connection methods:\n\n.. contents::\n :local:\n\nEncrypted USB disks\n+++++++++++++++++++\n\nThere's a LUKS_ encrypted USB disk on my desk at work that I use to keep\nhourly, daily and monthly backups of my work laptop. The disk is connected\nthrough the same USB hub that also connects my keyboard and mouse so I can't\nreally forget about it :-).\n\nAutomatic mounting\n^^^^^^^^^^^^^^^^^^\n\nBefore the backup starts, the encrypted disk is automatically unlocked and\nmounted. The use of a key file enables this process to run unattended in the\nbackground. Once the backup is done the disk will be unmounted and locked\nagain, so that it can be unplugged at any time (as long as a backup isn't\nrunning of course).\n\nLocal server (rsync daemon)\n+++++++++++++++++++++++++++\n\nMy personal laptop transfers hourly backups to the `rsync daemon`_ running on\nthe server in my home network using a direct TCP connection without SSH. Most\nof the time the laptop has an USB Ethernet adapter connected but the backup\nruns fine over a wireless connection as well.\n\nRemote server (rsync daemon over SSH tunnel)\n++++++++++++++++++++++++++++++++++++++++++++\n\nMy VPS (virtual private server) transfers nightly backups to the `rsync\ndaemon`_ running on the server in my home network over an `SSH tunnel`_ in\norder to encrypt the traffic and restrict access. The SSH account is configured\nto allow tunneling but disallow command execution. This setup enables the rsync\nclient and server to run with root privileges without allowing the client to\nrun arbitrary commands on the server.\n\nAlternative connection methods\n------------------------------\n\nBacking up to a local disk limits the effectiveness of backups but using SSH\naccess between systems gives you more than you bargained for, because you're\nallowing arbitrary command execution. The `rsync daemon`_ provides an\nalternative that does not allow arbitrary command execution. The following\nsections discuss this option in more detail.\n\nUsing rsync daemon\n~~~~~~~~~~~~~~~~~~\n\nTo be able to write files as root and preserve all filesystem metadata, rsync\nmust be running with root privileges. However most of my backups are stored on\nremote systems and opening up remote root access over SSH just to transfer\nbackups feels like a very blunt way to solve the problem :-).\n\nFortunately another solution is available: Configure an rsync daemon on the\ndestination and instruct your rsync client to connect to the rsync daemon\ninstead of connecting to the remote system over SSH. The rsync daemon\nconfiguration can restrict the access of the rsync client so that it can only\nwrite to the directory that contains the backup tree.\n\nIn this setup no SSH connections are used and the traffic between the rsync\nclient and server is not encrypted. If this is a problem for you then continue\nreading the next section.\n\nEnabling rsync daemon\n+++++++++++++++++++++\n\nOn Debian and derivatives like Ubuntu you can enable and configure an `rsync\ndaemon`_ quite easily:\n\n1. Make sure that rsync is installed:\n\n .. code-block:: sh\n\n $ sudo apt-get install rsync\n\n2. Enable the rsync daemon by editing ``/etc/default/rsync`` and changing the\n line ``RSYNC_ENABLE=false`` to ``RSYNC_ENABLE=true``. Here's a one liner\n that accomplishes the task:\n\n .. code-block:: sh\n\n $ sudo sed -i 's/RSYNC_ENABLE=false/RSYNC_ENABLE=true/' /etc/default/rsync\n\n3. Create the configuration file ``/etc/rsyncd.conf`` and define at least\n one module. Here's an example based on my rsync daemon configuration:\n\n .. code-block:: ini\n\n # Global settings.\n max connections = 4\n log file = /var/log/rsyncd.log\n\n # Defaults for modules.\n read only = no\n uid = 0\n gid = 0\n\n # Daily backups of my VPS.\n [vps_backups]\n path = /mnt/backups/vps/latest\n post-xfer exec = /usr/sbin/process-vps-backups\n\n # Hourly backups of my personal laptop.\n [laptop_backups]\n path = /mnt/backups/laptop/latest\n post-xfer exec = /usr/sbin/process-laptop-backups\n\n The ``post-xfer exec`` directives configure the rsync daemon to create a\n snapshot once the backup is done and rotate old snapshots afterwards.\n\n4. Once you've created ``/etc/rsyncd.conf`` you can start the rsync daemon:\n\n .. code-block:: sh\n\n $ sudo service rsync start\n\n5. If you're using a firewall you should make sure that the rsync daemon port\n is whitelisted to allow incoming connections. The rsync daemon port number\n defaults to 873. Here's an iptables command to accomplish this:\n\n .. code-block:: sh\n\n $ sudo iptables -A INPUT -p tcp -m tcp --dport 873 -m comment --comment \"rsync daemon\" -j ACCEPT\n\nTunneling rsync daemon connections\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nWhen your backups are transferred over the public internet you should\ndefinitely use SSH to encrypt the traffic, but if you're at all security\nconscious then you probably won't like having to open up remote root access\nover SSH just to transfer backups :-).\n\nThe alternative is to use a non privileged SSH account to set up an `SSH\ntunnel`_ that redirects network traffic to the rsync daemon. The login shell of\nthe SSH account can be set to ``/usr/sbin/nologin`` (or something similar like\n``/bin/false``) to `disable command execution`_, in this case you need to pass\n``-N`` to the SSH client.\n\nContact\n-------\n\nThe latest version of `rsync-system-backup` is available on PyPI_ and GitHub_.\nThe documentation is hosted on `Read the Docs`_ and includes a changelog_. For\nbug reports please create an issue on GitHub_. If you have questions,\nsuggestions, etc. feel free to send me an e-mail at `peter@peterodding.com`_.\n\nLicense\n-------\n\nThis software is licensed under the `MIT license`_.\n\n\u00a9 2018 Peter Odding.\n\n.. External references:\n\n.. _changelog: https://rsync-system-backup.readthedocs.org/en/latest/changelog.html\n.. _chroot: https://manpages.debian.org/chroot\n.. _deduplication: https://en.wikipedia.org/wiki/Data_deduplication\n.. _disable command execution: https://unix.stackexchange.com/questions/155139/does-usr-sbin-nologin-as-a-login-shell-serve-a-security-purpose\n.. _Easy Automated Snapshot-Style Backups with Linux and Rsync: http://www.mikerubel.org/computers/rsync_snapshots/\n.. _GitHub: https://github.com/xolox/python-rsync-system-backup\n.. _hard links: https://en.wikipedia.org/wiki/Hard_link\n.. _inodes: https://en.wikipedia.org/wiki/Inode\n.. _Linux: https://en.wikipedia.org/wiki/Linux\n.. _locate: https://manpages.debian.org/mlocate\n.. _LUKS: https://en.wikipedia.org/wiki/Linux_Unified_Key_Setup\n.. _MIT license: http://en.wikipedia.org/wiki/MIT_License\n.. _per user site-packages directory: https://www.python.org/dev/peps/pep-0370/\n.. _peter@peterodding.com: peter@peterodding.com\n.. _PyPI: https://pypi.python.org/pypi/rsync-system-backup\n.. _Python Package Index: https://pypi.python.org/pypi/rsync-system-backup\n.. _Python: https://www.python.org/\n.. _Read the Docs: https://rsync-system-backup.readthedocs.org\n.. _rsync daemon: https://manpages.debian.org/rsyncd.conf\n.. _rsync: http://en.wikipedia.org/wiki/rsync\n.. _SSH tunnel: https://en.wikipedia.org/wiki/Tunneling_protocol#Secure_Shell_tunneling\n.. _SSH: https://en.wikipedia.org/wiki/Secure_Shell\n.. _updatedb: https://manpages.debian.org/updatedb\n.. _virtual environments: http://docs.python-guide.org/en/latest/dev/virtualenvs/\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/xolox/python-rsync-system-backup", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "rsync-system-backup", "package_url": "https://pypi.org/project/rsync-system-backup/", "platform": "", "project_url": "https://pypi.org/project/rsync-system-backup/", "project_urls": { "Homepage": "https://github.com/xolox/python-rsync-system-backup" }, "release_url": "https://pypi.org/project/rsync-system-backup/1.1/", "requires_dist": [ "coloredlogs (>=6.1)", "executor (>=19.3)", "humanfriendly (>=3.4)", "linux-utils (>=0.4)", "proc (>=0.14)", "property-manager (>=2.3)", "rotate-backups (>=4.4)" ], "requires_python": "", "summary": "Linux system backups powered by rsync", "version": "1.1" }, "last_serial": 5623007, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "4555ef49b5cb4782b7566ce92b1bfdb3", "sha256": "22485c30ccf5f7ec190dd1400397ab01c85a8d62e2446eb90e294cbf14e18c5a" }, "downloads": -1, "filename": "rsync_system_backup-0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "4555ef49b5cb4782b7566ce92b1bfdb3", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 34216, "upload_time": "2017-04-13T23:47:54", "url": "https://files.pythonhosted.org/packages/37/2e/6d7b2cad425eb195f0333d080e1c4dab6ad314227a34bad02ad901493c64/rsync_system_backup-0.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d4ba2cb695baa8f3215b673bf147c815", "sha256": "948b4f091e0653e861db33582e209559f1ca97711c2a4dfb1c7814ddd6ebfd32" }, "downloads": -1, "filename": "rsync-system-backup-0.1.tar.gz", "has_sig": false, "md5_digest": "d4ba2cb695baa8f3215b673bf147c815", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 31183, "upload_time": "2017-04-13T23:47:56", "url": "https://files.pythonhosted.org/packages/f5/e1/3bcc7932c188022d466d01818a4e67e9000b88a9b520ba545d21e4761697/rsync-system-backup-0.1.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "2e0166aa700516870b7c3a245966995d", "sha256": "8d730c066b089451f6299f6ce88b2b5db4513c1afaf832c32ea31ffeef610671" }, "downloads": -1, "filename": "rsync_system_backup-0.1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "2e0166aa700516870b7c3a245966995d", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 34245, "upload_time": "2017-04-17T20:58:22", "url": "https://files.pythonhosted.org/packages/32/3d/ade9cb00693d778afa4cb75edd2e082a38b0d3f0a44cc1fa171070d183a5/rsync_system_backup-0.1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ab11fd283a1cef261808137a8a8f5f6a", "sha256": "561af0fa75ab877b243f4846be849b222ff9647fab61968925d247320dd4c610" }, "downloads": -1, "filename": "rsync-system-backup-0.1.1.tar.gz", "has_sig": false, "md5_digest": "ab11fd283a1cef261808137a8a8f5f6a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 31169, "upload_time": "2017-04-17T20:58:25", "url": "https://files.pythonhosted.org/packages/21/1e/e2c843fef0f062c68ae3fc95abd7f2eb5dea32a393ff840bf70dde4bd947/rsync-system-backup-0.1.1.tar.gz" } ], "0.10": [ { "comment_text": "", "digests": { "md5": "fca304cb82cd940184baad2286078ca2", "sha256": "b55942773ddcd67eb934b4e1f245d77e78dff76c67277c020ddbc1ac653d2682" }, "downloads": -1, "filename": "rsync_system_backup-0.10-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "fca304cb82cd940184baad2286078ca2", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 35216, "upload_time": "2018-04-30T20:40:54", "url": "https://files.pythonhosted.org/packages/0e/1a/7a840cdfff045ddc8bce2e43e2e488b3330a9c6500f3cf40034c183d8731/rsync_system_backup-0.10-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "371d90bd2f6a348acdcb7219aa77fe02", "sha256": "fd0760adc295f623393757625cfa004d1a74496a7367e2b4d43c8ea11fe25f2d" }, "downloads": -1, "filename": "rsync-system-backup-0.10.tar.gz", "has_sig": false, "md5_digest": "371d90bd2f6a348acdcb7219aa77fe02", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32950, "upload_time": "2018-04-30T20:40:56", "url": "https://files.pythonhosted.org/packages/1e/69/8d57ffe5f78478be984f12753e9612ec657ca6491b57c2b15f621ce2db2a/rsync-system-backup-0.10.tar.gz" } ], "0.11": [ { "comment_text": "", "digests": { "md5": "aa64defa3883531a81bc2271a39260c6", "sha256": "d145cedb32a20b9d6ef0ab900b8bc07ff7f5cd64a9fd484b35e6c34495d909f9" }, "downloads": -1, "filename": "rsync_system_backup-0.11-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "aa64defa3883531a81bc2271a39260c6", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 35565, "upload_time": "2018-04-30T21:43:05", "url": "https://files.pythonhosted.org/packages/6d/8a/d660836f8dd0f57e1625703199fa565817cfca2f56741ae904aad2114cc9/rsync_system_backup-0.11-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "27c14f1ecededd492bd9ce9fd5fe37f6", "sha256": "26cfe3eba578b2e317af27e03cb90480aeb56791934eb870dcf3d2ec2d4bd1fe" }, "downloads": -1, "filename": "rsync-system-backup-0.11.tar.gz", "has_sig": false, "md5_digest": "27c14f1ecededd492bd9ce9fd5fe37f6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 33442, "upload_time": "2018-04-30T21:43:06", "url": "https://files.pythonhosted.org/packages/be/82/659311d97fa2f2b828989623617131f5af27ebab5580c73a44bd4b965b2c/rsync-system-backup-0.11.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "691eb677fbb82cbfb2196b158ca4c8f1", "sha256": "7bbfda925cf556dc2c957259f4314e25015afa3ae67a5e3d7e004986dc37f7cf" }, "downloads": -1, "filename": "rsync_system_backup-0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "691eb677fbb82cbfb2196b158ca4c8f1", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 34299, "upload_time": "2017-05-06T04:08:23", "url": "https://files.pythonhosted.org/packages/2e/f3/39fb92ab58acb685d87805abdfc32c90efc3692c9813d23efb868ed2f24a/rsync_system_backup-0.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b6f899bd39fe7eaa0815d482b7d1b911", "sha256": "357ad37cb1d87606c00869f7a3c9a16674b04cd7b4d53be88e779119bbd30591" }, "downloads": -1, "filename": "rsync-system-backup-0.2.tar.gz", "has_sig": false, "md5_digest": "b6f899bd39fe7eaa0815d482b7d1b911", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 29594, "upload_time": "2017-05-06T04:08:26", "url": "https://files.pythonhosted.org/packages/83/a4/fa700e0839945c0cc03382f95d9656edcfb517e5e371b76f10bb9ab75a76/rsync-system-backup-0.2.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "168de349f3474148f47d67d48e49ed84", "sha256": "36939a195b87b28f11a8d72f0c2723a13ce986811553bc5822f53cc14e193c61" }, "downloads": -1, "filename": "rsync_system_backup-0.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "168de349f3474148f47d67d48e49ed84", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 34577, "upload_time": "2017-06-06T14:25:21", "url": "https://files.pythonhosted.org/packages/59/f8/1789c7b1db062eae745c5c0730fb925fd355c84cbe1f8f1d5927c82619c5/rsync_system_backup-0.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bebe616ca46cac7e0a4a0c8a88742f4a", "sha256": "ac1d9e6a971b1cfc7480bc651f5371df84f4ba61bb66f6f90437172d7a0f6a35" }, "downloads": -1, "filename": "rsync-system-backup-0.3.tar.gz", "has_sig": false, "md5_digest": "bebe616ca46cac7e0a4a0c8a88742f4a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 31517, "upload_time": "2017-06-06T14:25:24", "url": "https://files.pythonhosted.org/packages/37/31/46eab72028291c5c678542bac2225743c4e4f84248290b8b37b69d7f9c90/rsync-system-backup-0.3.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "cd89c42696ccccaf5fa3451daabd65e8", "sha256": "64eb37834517db5328b3122b176bb5c64e94b71c3d8e4567f1a24a0e8cf40849" }, "downloads": -1, "filename": "rsync_system_backup-0.4-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "cd89c42696ccccaf5fa3451daabd65e8", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 35190, "upload_time": "2017-06-21T05:35:26", "url": "https://files.pythonhosted.org/packages/3a/9f/59c44799c74c945ed7a76aa812c1ca39ef69fd53fce4d747cf378e3fc3f4/rsync_system_backup-0.4-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6e21b1aa277bf59266f923e1dafb1b03", "sha256": "0157cae7901d7975497083ff1c93788ef1cbc4911ccc9ada56fc0d4b59094122" }, "downloads": -1, "filename": "rsync-system-backup-0.4.tar.gz", "has_sig": false, "md5_digest": "6e21b1aa277bf59266f923e1dafb1b03", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32101, "upload_time": "2017-06-21T05:35:27", "url": "https://files.pythonhosted.org/packages/cf/76/06e74a0c099095660451d0d3dd003b856e4a2565db9140751a1f1044c86c/rsync-system-backup-0.4.tar.gz" } ], "0.5": [ { "comment_text": "", "digests": { "md5": "5201b8df3dfa2a042e14d046980c0f6a", "sha256": "4a3f89884833e870df04c5a5d1f644e2786b0174039082a007044bea18a0b1c6" }, "downloads": -1, "filename": "rsync_system_backup-0.5-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "5201b8df3dfa2a042e14d046980c0f6a", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 35299, "upload_time": "2017-06-21T14:54:47", "url": "https://files.pythonhosted.org/packages/a9/31/06c9fe2e612371d65b66dde59e06a7d990168a3d1edc4189bad1e4c17e29/rsync_system_backup-0.5-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a6d9bb3b6809e2a70a9e1283483e3efc", "sha256": "ba6c8ae48db97c9102a5e141b2136daae6a5cfb106232181e8bcc4cefaa6a987" }, "downloads": -1, "filename": "rsync-system-backup-0.5.tar.gz", "has_sig": false, "md5_digest": "a6d9bb3b6809e2a70a9e1283483e3efc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32151, "upload_time": "2017-06-21T14:54:49", "url": "https://files.pythonhosted.org/packages/2f/e2/9cc1bab46a60f586564ab3b790575f40e546cf8bbc646d4422f97378eb98/rsync-system-backup-0.5.tar.gz" } ], "0.6": [ { "comment_text": "", "digests": { "md5": "f576f9db6bd72a1833105605bcf0857a", "sha256": "cfd06a7b6b4b35d96ed271dbae29c2cfb5d7b25a4ea69e6b66d3f3541f70fd12" }, "downloads": -1, "filename": "rsync_system_backup-0.6-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "f576f9db6bd72a1833105605bcf0857a", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 35294, "upload_time": "2017-06-23T11:35:34", "url": "https://files.pythonhosted.org/packages/09/a0/eeb780bcd12b98b24a1c4b3e0372f05c333a21c4b2a241ff0e299a9b1541/rsync_system_backup-0.6-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7d29563068165ef2ced32e1c03160ae2", "sha256": "398578807ec41d563c8f2d2efa1e3ea461d7978b721f09e5d3b2b3b9fbc18842" }, "downloads": -1, "filename": "rsync-system-backup-0.6.tar.gz", "has_sig": false, "md5_digest": "7d29563068165ef2ced32e1c03160ae2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30466, "upload_time": "2017-06-23T11:35:36", "url": "https://files.pythonhosted.org/packages/11/43/4a65f2a99c928b3ffa83706614834e09914b6293ccf6a5511c96f4e927cc/rsync-system-backup-0.6.tar.gz" } ], "0.7": [ { "comment_text": "", "digests": { "md5": "ab20f8215d36276a3f80587e3a50f9f5", "sha256": "1ff73177cf0cf1b06a856b55fa94dd1bc646e0208b13ef696f6ed15662b5a74e" }, "downloads": -1, "filename": "rsync_system_backup-0.7-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "ab20f8215d36276a3f80587e3a50f9f5", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 35605, "upload_time": "2017-06-23T14:08:26", "url": "https://files.pythonhosted.org/packages/83/81/a62ffb16f75d8dae4634e5622444a9ca9358fb746756e77f466595d55092/rsync_system_backup-0.7-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "eb0d1d867b904bf53b3856e5df96c81e", "sha256": "af2bbe2a35a85fdccc15940aed78cf2160aea860f3587c5557797b30607bfa29" }, "downloads": -1, "filename": "rsync-system-backup-0.7.tar.gz", "has_sig": false, "md5_digest": "eb0d1d867b904bf53b3856e5df96c81e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 30805, "upload_time": "2017-06-23T14:08:28", "url": "https://files.pythonhosted.org/packages/2f/58/d55df2ea902e2a89119b92ca30f5cbb23c18a4bfaf35df54689bc28d1730/rsync-system-backup-0.7.tar.gz" } ], "0.8": [ { "comment_text": "", "digests": { "md5": "0e525e6de7970ab5d46ac7d3db87304b", "sha256": "9c02fc6907f594ca4c0ba32f1777deffeafdd19a5b57f1bc7ab799af857778cb" }, "downloads": -1, "filename": "rsync_system_backup-0.8-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "0e525e6de7970ab5d46ac7d3db87304b", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 34599, "upload_time": "2017-06-24T04:55:15", "url": "https://files.pythonhosted.org/packages/38/a4/9edf42222214a5eec0f3bcc2bd70d37838276253cf34a216a780140c225f/rsync_system_backup-0.8-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b5b8d2cba2c5aafd47f0a5bfe85221bc", "sha256": "9385561afdf9e4e5cc61f4edbda24dfc6206e537089aaf4cb48b5a306541d633" }, "downloads": -1, "filename": "rsync-system-backup-0.8.tar.gz", "has_sig": false, "md5_digest": "b5b8d2cba2c5aafd47f0a5bfe85221bc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 29899, "upload_time": "2017-06-24T04:55:17", "url": "https://files.pythonhosted.org/packages/63/0a/39839c00de1fd9b929bc778876e92ad021ea53a307cdf115d9f5c900bd6d/rsync-system-backup-0.8.tar.gz" } ], "0.9": [ { "comment_text": "", "digests": { "md5": "7242ad913ad487ee7b100dd7b94ee94b", "sha256": "3294e431ee68122d850d7a70cde7ac30229f1a63e7d3fbcc2a74a3e7eba495e2" }, "downloads": -1, "filename": "rsync_system_backup-0.9-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "7242ad913ad487ee7b100dd7b94ee94b", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 35098, "upload_time": "2017-07-10T22:22:57", "url": "https://files.pythonhosted.org/packages/a3/ec/3e7de7e5dfedc0d4dd82fa2f93c64f0c9225c74fc552be9448cfe8b47a54/rsync_system_backup-0.9-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c69c98f651682d86722931ac14548d4f", "sha256": "552290ea1f7fb886f70fe3be096199146a5d8a01242ef1ea10ce4ee9b7e55cf5" }, "downloads": -1, "filename": "rsync-system-backup-0.9.tar.gz", "has_sig": false, "md5_digest": "c69c98f651682d86722931ac14548d4f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32061, "upload_time": "2017-07-10T22:23:01", "url": "https://files.pythonhosted.org/packages/79/ed/6b1634ec3020fed129aefc70529a9bf0903037b9689888934bbf09085480/rsync-system-backup-0.9.tar.gz" } ], "1.0": [ { "comment_text": "", "digests": { "md5": "d4fbebc3c94c2e872dec3b0ef4e5cdb2", "sha256": "0ccea104241188e51dcd5c3434a50fef64844b5f8606edacada673662f6aac14" }, "downloads": -1, "filename": "rsync_system_backup-1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "d4fbebc3c94c2e872dec3b0ef4e5cdb2", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 36266, "upload_time": "2018-05-04T22:11:05", "url": "https://files.pythonhosted.org/packages/80/12/3edc76105e176a545bf2a49b3f9f3f7a3a23e506f57db6e9505eb6e41abd/rsync_system_backup-1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bc4bb758cadd80a3202cfbc66da9c0d6", "sha256": "ae17aeb27380d41ce291dc1f4a64c1e257349810be782dc4cbc6db2c4f06e48f" }, "downloads": -1, "filename": "rsync-system-backup-1.0.tar.gz", "has_sig": false, "md5_digest": "bc4bb758cadd80a3202cfbc66da9c0d6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 34284, "upload_time": "2018-05-04T22:11:07", "url": "https://files.pythonhosted.org/packages/07/aa/e190a36f0378df593d5bee188456172346e69856ed85d4402051d67d7973/rsync-system-backup-1.0.tar.gz" } ], "1.1": [ { "comment_text": "", "digests": { "md5": "2a8b1a54b28839a0251f97f1249cd076", "sha256": "96727367725f81f5cb23c46ec0ceae113753afe243fdd80e3d3db47704339ff9" }, "downloads": -1, "filename": "rsync_system_backup-1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "2a8b1a54b28839a0251f97f1249cd076", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 29270, "upload_time": "2019-08-02T10:05:53", "url": "https://files.pythonhosted.org/packages/9f/ca/c72a7c21b060efb4343c488bed8a2febd213c7bfd6caa75af90d61de7af7/rsync_system_backup-1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "77a9fb6ebf82385419321f81a8acd79b", "sha256": "8919f2bd0e86351dfa2e942b2f9f0f3882cea35a8b79e99e79b164b308e10824" }, "downloads": -1, "filename": "rsync-system-backup-1.1.tar.gz", "has_sig": false, "md5_digest": "77a9fb6ebf82385419321f81a8acd79b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 34705, "upload_time": "2019-08-02T10:05:55", "url": "https://files.pythonhosted.org/packages/76/5a/59bb5aca0ddf4b00a1670b777fe029d8b2f7cce1836269a463bc769182f1/rsync-system-backup-1.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "2a8b1a54b28839a0251f97f1249cd076", "sha256": "96727367725f81f5cb23c46ec0ceae113753afe243fdd80e3d3db47704339ff9" }, "downloads": -1, "filename": "rsync_system_backup-1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "2a8b1a54b28839a0251f97f1249cd076", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 29270, "upload_time": "2019-08-02T10:05:53", "url": "https://files.pythonhosted.org/packages/9f/ca/c72a7c21b060efb4343c488bed8a2febd213c7bfd6caa75af90d61de7af7/rsync_system_backup-1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "77a9fb6ebf82385419321f81a8acd79b", "sha256": "8919f2bd0e86351dfa2e942b2f9f0f3882cea35a8b79e99e79b164b308e10824" }, "downloads": -1, "filename": "rsync-system-backup-1.1.tar.gz", "has_sig": false, "md5_digest": "77a9fb6ebf82385419321f81a8acd79b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 34705, "upload_time": "2019-08-02T10:05:55", "url": "https://files.pythonhosted.org/packages/76/5a/59bb5aca0ddf4b00a1670b777fe029d8b2f7cce1836269a463bc769182f1/rsync-system-backup-1.1.tar.gz" } ] }