WereSync-1.0.9/ 0000755 0001750 0001750 00000000000 13315166025 013774 5 ustar daniel daniel 0000000 0000000 WereSync-1.0.9/PKG-INFO 0000644 0001750 0001750 00000015574 13315166025 015105 0 ustar daniel daniel 0000000 0000000 Metadata-Version: 1.0
Name: WereSync
Version: 1.0.9
Summary: Incrementally clones Linux drives
Home-page: https://github.com/DonyorM/weresync
Author: Daniel Manila
Author-email: dmv@springwater7.org
License: Apache 2.0
Description: ########
WereSync
########
`Installation <#installation>`__ | `Basic Usage <#basic-usage>`__ | `Documentation `__ | `Contributing <#contributing-and-bug-reports>`__
.. image:: https://github.com/DonyorM/weresync/raw/master/docs/source/img/weresync-logo.png
:align: center
:alt: WereSync Logo
A lone hard drive stands atop a data heap, staring at the full moon. Suddenly, it
transforms...into a bootable clone of your drive, whirring hungrily at the digital
moon.
WereSync takes a Linux hard drive and effectively clones it, but works incrementally
so you don't have to spend so long backing up each time. Additionally, WereSync
can clone to a smaller drive, if your data will fit on the smaller drive. Because WereSync
uses rsync to copy, it can copy a running drive, though certain parts of state may not be
preserved.
Why Use WereSync?
=================
Hopefully, you think this project looks amazing and you want to try it right away.
However, you may be skeptical about the usefulness of WereSync. You may be
thinking, I can do this exact same thing using gparted or ddrescue. Hear me out!
There are a few reasons to use WereSync over the other tools.
- **WereSync is accessible to less-technical users.** It comes with a simple
interface and clone a drive with a single command while your computer is
running. No booting to a live disk or pushing through a long initiation
process. Unlike `dd` or CloneZilla, WereSync requires a low level of
technical skill and has an easy learning curve
- WereSync can run while the your main drive is being used, instead of blocking your computer up for hours at a time
- WereSync will incrementally update clones, making subsequent clones much faster.
- WereSync works quickly, a single command copies your entire drive, no booting to live CDs or managing MBRs.
- WereSync can copy to a smaller drive, provided your drive's data will fit.
- WereSync creates new UUIDs for the new partitions, allowing you to use the old and new drives alongside each other.
Full documentation may be found `here `__.
Installation
============
WereSync can be installed using the `setup.py` file.
.. code-block:: bash
$ ./setup.py install
If you have `pip `__ installed, you can easily install WereSync with the following command::
$ pip install weresync
For more in-depth instructions, see the `installation documentation `__.
Basic Usage
===========
**Note:** WereSync requires root capabilities to run because it has to access block devices.
The gui can be launched with the command::
$ sudo weresync-gui
Which generates the following GUI, though generally the advanced options are unneeded:
.. image:: https://github.com/DonyorM/weresync/raw/master/docs/source/img/gui-example.png
:align: left
:alt: Picture of WereSync GUI
To see the options for the terminal command use::
$ weresync -h
To copy from /dev/sda to /dev/sdb (the two drives must have the same partition scheme) use::
$ sudo weresync /dev/sda /dev/sdb
For more information, including how to copy the partition table from drive to
another, see the `Basic Usage `__
documentation page.
Documentation
=============
Documentation can be found on the `Read the Docs `__.
Contributing and Bug Reports
============================
First, take a look at our `contribution guidelines `__.
To contribute simply fork this repository, make your changes, and submit a pull
request. Bugs can be reported on the `issue tracker `__
WereSync currently has huge need of people testing the program on complex drive setups. In order to do this please:
1. Install WereSync from pip::
pip install weresync
#. Run it on your system::
sudo weresync -C source_drive target_drive
#. Report any errors to the `issue tracker `__. Please be sure to post the contents of ``/var/log/weresync/weresync.log`` and ``fdisk -l``.
All contributions will be greatly appreciated!
Distributions Capability for Drive Copying
------------------------------------------
|ubuntu| |debian| |arch| |centos| |fedora| |opensuse|
.. |ubuntu| image:: https://img.shields.io/badge/ubuntu-stable-brightgreen.svg
.. |arch| image:: https://img.shields.io/badge/Arch%20Linux-stable-brightgreen.svg
.. |centos| image:: https://img.shields.io/badge/CentOS-not%20tested-red.svg
.. |fedora| image:: https://img.shields.io/badge/Fedora-not%20tested-red.svg
.. |opensuse| image:: https://img.shields.io/badge/openSUSE-not%20tested-red.svg
.. |debian| image:: https://img.shields.io/badge/Debian-stable-brightgreen.svg
If you are able to test any of these systems, please report your exprience at the `issue tracker `__. Any help will be much appreciated.
Licensing
=========
This project is licensed under the `Apache 2.0 License `__. Licensing is in the **LICENSE.txt** file in this directory.
Acknowledgments
===============
Huge thanks to the creators of:
* `rsync `__, whose software allowed this project to be possible.
* `GNU Parted `__
* And `GPT fdisk `__
Keywords: clone,linux,backup,smaller drive
Platform: UNKNOWN
WereSync-1.0.9/README.rst 0000644 0001750 0001750 00000012766 13120341354 015471 0 ustar daniel daniel 0000000 0000000 ########
WereSync
########
`Installation <#installation>`__ | `Basic Usage <#basic-usage>`__ | `Documentation `__ | `Contributing <#contributing-and-bug-reports>`__
.. image:: https://github.com/DonyorM/weresync/raw/master/docs/source/img/weresync-logo.png
:align: center
:alt: WereSync Logo
A lone hard drive stands atop a data heap, staring at the full moon. Suddenly, it
transforms...into a bootable clone of your drive, whirring hungrily at the digital
moon.
WereSync takes a Linux hard drive and effectively clones it, but works incrementally
so you don't have to spend so long backing up each time. Additionally, WereSync
can clone to a smaller drive, if your data will fit on the smaller drive. Because WereSync
uses rsync to copy, it can copy a running drive, though certain parts of state may not be
preserved.
Why Use WereSync?
=================
Hopefully, you think this project looks amazing and you want to try it right away.
However, you may be skeptical about the usefulness of WereSync. You may be
thinking, I can do this exact same thing using gparted or ddrescue. Hear me out!
There are a few reasons to use WereSync over the other tools.
- **WereSync is accessible to less-technical users.** It comes with a simple
interface and clone a drive with a single command while your computer is
running. No booting to a live disk or pushing through a long initiation
process. Unlike `dd` or CloneZilla, WereSync requires a low level of
technical skill and has an easy learning curve
- WereSync can run while the your main drive is being used, instead of blocking your computer up for hours at a time
- WereSync will incrementally update clones, making subsequent clones much faster.
- WereSync works quickly, a single command copies your entire drive, no booting to live CDs or managing MBRs.
- WereSync can copy to a smaller drive, provided your drive's data will fit.
- WereSync creates new UUIDs for the new partitions, allowing you to use the old and new drives alongside each other.
Full documentation may be found `here `__.
Installation
============
WereSync can be installed using the `setup.py` file.
.. code-block:: bash
$ ./setup.py install
If you have `pip `__ installed, you can easily install WereSync with the following command::
$ pip install weresync
For more in-depth instructions, see the `installation documentation `__.
Basic Usage
===========
**Note:** WereSync requires root capabilities to run because it has to access block devices.
The gui can be launched with the command::
$ sudo weresync-gui
Which generates the following GUI, though generally the advanced options are unneeded:
.. image:: https://github.com/DonyorM/weresync/raw/master/docs/source/img/gui-example.png
:align: left
:alt: Picture of WereSync GUI
To see the options for the terminal command use::
$ weresync -h
To copy from /dev/sda to /dev/sdb (the two drives must have the same partition scheme) use::
$ sudo weresync /dev/sda /dev/sdb
For more information, including how to copy the partition table from drive to
another, see the `Basic Usage `__
documentation page.
Documentation
=============
Documentation can be found on the `Read the Docs `__.
Contributing and Bug Reports
============================
First, take a look at our `contribution guidelines `__.
To contribute simply fork this repository, make your changes, and submit a pull
request. Bugs can be reported on the `issue tracker `__
WereSync currently has huge need of people testing the program on complex drive setups. In order to do this please:
1. Install WereSync from pip::
pip install weresync
#. Run it on your system::
sudo weresync -C source_drive target_drive
#. Report any errors to the `issue tracker `__. Please be sure to post the contents of ``/var/log/weresync/weresync.log`` and ``fdisk -l``.
All contributions will be greatly appreciated!
Distributions Capability for Drive Copying
------------------------------------------
|ubuntu| |debian| |arch| |centos| |fedora| |opensuse|
.. |ubuntu| image:: https://img.shields.io/badge/ubuntu-stable-brightgreen.svg
.. |arch| image:: https://img.shields.io/badge/Arch%20Linux-stable-brightgreen.svg
.. |centos| image:: https://img.shields.io/badge/CentOS-not%20tested-red.svg
.. |fedora| image:: https://img.shields.io/badge/Fedora-not%20tested-red.svg
.. |opensuse| image:: https://img.shields.io/badge/openSUSE-not%20tested-red.svg
.. |debian| image:: https://img.shields.io/badge/Debian-stable-brightgreen.svg
If you are able to test any of these systems, please report your exprience at the `issue tracker `__. Any help will be much appreciated.
Licensing
=========
This project is licensed under the `Apache 2.0 License `__. Licensing is in the **LICENSE.txt** file in this directory.
Acknowledgments
===============
Huge thanks to the creators of:
* `rsync `__, whose software allowed this project to be possible.
* `GNU Parted `__
* And `GPT fdisk `__
WereSync-1.0.9/setup.cfg 0000644 0001750 0001750 00000000447 13315166025 015622 0 ustar daniel daniel 0000000 0000000 [tool:pytest]
testpaths = tests
[metadata]
license_file = LICENSE.txt
[build_sphinx]
source-dir = docs/source
build-dir = docs/build
all_files = 1
[upload_sphinx]
upload-dir = docs/build/html
[flake8]
ignore =
W503,
builtins = _
[egg_info]
tag_build =
tag_date = 0
tag_svn_revision = 0
WereSync-1.0.9/LICENSE.txt 0000644 0001750 0001750 00000021707 13006623417 015626 0 ustar daniel daniel 0000000 0000000 Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the
copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other
entities that control, are controlled by, or are under common control with
that entity. For the purposes of this definition, "control" means (i) the
power, direct or indirect, to cause the direction or management of such
entity, whether by contract or otherwise, or (ii) ownership of fifty percent
(50%) or more of the outstanding shares, or (iii) beneficial ownership of such
entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising
permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation source, and
configuration files.
"Object" form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object
code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form,
made available under the License, as indicated by a copyright notice that is
included in or attached to the work (an example is provided in the Appendix
below).
"Derivative Works" shall mean any work, whether in Source or Object form, that
is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative
Works shall not include works that remain separable from, or merely link (or
bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original
version of the Work and any modifications or additions to that Work or
Derivative Works thereof, that is intentionally submitted to Licensor for
inclusion in the Work by the copyright owner or by an individual or Legal
Entity authorized to submit on behalf of the copyright owner. For the purposes
of this definition, "submitted" means any form of electronic, verbal, or
written communication sent to the Licensor or its representatives, including
but not limited to communication on electronic mailing lists, source code
control systems, and issue tracking systems that are managed by, or on behalf
of, the Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise designated
in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this
License, each Contributor hereby grants to You a perpetual, worldwide,
non-exclusive, no-charge, royalty-free, irrevocable copyright license to
reproduce, prepare Derivative Works of, publicly display, publicly perform,
sublicense, and distribute the Work and such Derivative Works in Source or
Object form.
3. Grant of Patent License. Subject to the terms and conditions of this
License, each Contributor hereby grants to You a perpetual, worldwide,
non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this
section) patent license to make, have made, use, offer to sell, sell, import,
and otherwise transfer the Work, where such license applies only to those
patent claims licensable by such Contributor that are necessarily infringed by
their Contribution(s) alone or by combination of their Contribution(s) with
the Work to which such Contribution(s) was submitted. If You institute patent
litigation against any entity (including a cross-claim or counterclaim in a
lawsuit) alleging that the Work or a Contribution incorporated within the Work
constitutes direct or contributory patent infringement, then any patent
licenses granted to You under this License for that Work shall terminate as of
the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or
Derivative Works thereof in any medium, with or without modifications, and in
Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy
of this License; and
You must cause any modified files to carry prominent notices stating that
You changed the files; and
You must retain, in the Source form of any Derivative Works that You
distribute, all copyright, patent, trademark, and attribution notices from the
Source form of the Work, excluding those notices that do not pertain to any
part of the Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution,
then any Derivative Works that You distribute must include a readable copy of
the attribution notices contained within such NOTICE file, excluding those
notices that do not pertain to any part of the Derivative Works, in at least
one of the following places: within a NOTICE text file distributed as part of
the Derivative Works; within the Source form or documentation, if provided
along with the Derivative Works; or, within a display generated by the
Derivative Works, if and wherever such third-party notices normally appear.
The contents of the NOTICE file are for informational purposes only and do not
modify the License. You may add Your own attribution notices within Derivative
Works that You distribute, alongside or as an addendum to the NOTICE text from
the Work, provided that such additional attribution notices cannot be
construed as modifying the License.
You may add Your own copyright statement to Your modifications and may
provide additional or different license terms and conditions for use,
reproduction, or distribution of Your modifications, or for any such
Derivative Works as a whole, provided Your use, reproduction, and distribution
of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any
Contribution intentionally submitted for inclusion in the Work by You to the
Licensor shall be under the terms and conditions of this License, without any
additional terms or conditions. Notwithstanding the above, nothing herein
shall supersede or modify the terms of any separate license agreement you may
have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names,
trademarks, service marks, or product names of the Licensor, except as
required for reasonable and customary use in describing the origin of the Work
and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in
writing, Licensor provides the Work (and each Contributor provides its
Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied, including, without limitation, any warranties
or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any risks
associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in
tort (including negligence), contract, or otherwise, unless required by
applicable law (such as deliberate and grossly negligent acts) or agreed to in
writing, shall any Contributor be liable to You for damages, including any
direct, indirect, special, incidental, or consequential damages of any
character arising as a result of this License or out of the use or inability
to use the Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all other
commercial damages or losses), even if such Contributor has been advised of
the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work
or Derivative Works thereof, You may choose to offer, and charge a fee for,
acceptance of support, warranty, indemnity, or other liability obligations
and/or rights consistent with this License. However, in accepting such
obligations, You may act only on Your own behalf and on Your sole
responsibility, not on behalf of any other Contributor, and only if You agree
to indemnify, defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason of your
accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
WereSync-1.0.9/MANIFEST.in 0000644 0001750 0001750 00000000671 13131127717 015537 0 ustar daniel daniel 0000000 0000000 include README.rst
include LICENSE.txt
include COPYING
include AUTHORS
include docs/Makefile
recursive-include src *.py
recursive-include tests *.py
recursive-include docs *.rst
recursive-include docs *.py
recursive-include docs *.inc
recursive-include docs/source *.html
recursive-include docs/source *.png
recursive-include src *.svg
recursive-include src *.png
recursive-include src *.po
include src/weresync/resources/locale/weresync.pot WereSync-1.0.9/setup.py 0000775 0001750 0001750 00000004721 13314722051 015513 0 ustar daniel daniel 0000000 0000000 #! /usr/bin/env python3
import os
from setuptools import setup, find_packages
import subprocess
import shutil
class InvalidSetupError(Exception):
pass
def create_mo_files():
"""Converts .po templates to readble .mo files using msgfmt."""
# Avoids this code running on read the docs, since gettext is not installed
# there
if os.environ.get("READTHEDOCS") == "True":
return []
if shutil.which("msgfmt") is None:
# If gettext isn't installed, skip this
raise InvalidSetupError("gettext not installed but is required.")
localedir = 'src/weresync/resources/locale'
po_dirs = []
langs = next(os.walk(localedir))[1]
po_dirs = [localedir + '/' + l + '/LC_MESSAGES/'
for l in langs]
for d in po_dirs:
po_files = [f
for f in next(os.walk(d))[2]
if os.path.splitext(f)[1] == '.po']
for po_file in po_files:
filename, extension = os.path.splitext(po_file)
mo_file = filename + '.mo'
msgfmt_cmd = 'msgfmt {} -o {}'.format(d + po_file, d + mo_file)
subprocess.call(msgfmt_cmd, shell=True)
return ["locale/" + l + "/LC_MESSAGES/*.mo" for l in langs]
def read(fname):
with open(os.path.join(os.path.dirname(__file__), fname)) as file:
return file.read()
target_icon_loc = "share/icons/hicolor/scalable/apps"
if os.getuid() == 0: # Install is running as root
target_icon_loc = "/usr/" + target_icon_loc
if __name__ == "__main__":
setup(
name="WereSync",
version="1.0.9",
package_dir={"": "src"},
packages=find_packages("src"),
install_requires=["parse>=1.6.6", "yapsy>=1.11.223"],
entry_points={
'console_scripts': [
"weresync = weresync.interface:main"
],
'gui_scripts': [
"weresync-gui = weresync.gui:start_gui"
]
},
package_data={
"weresync.resources": ["*.svg", "*.png"] + create_mo_files()
},
data_files=[(target_icon_loc,
["src/weresync/resources/weresync.svg"])],
# Metadata
author="Daniel Manila",
author_email="dmv@springwater7.org",
description="Incrementally clones Linux drives",
long_description=read("README.rst"),
license="Apache 2.0",
keywords="clone, linux, backup, smaller drive",
url="https://github.com/DonyorM/weresync",
)
WereSync-1.0.9/tests/ 0000755 0001750 0001750 00000000000 13315166025 015136 5 ustar daniel daniel 0000000 0000000 WereSync-1.0.9/tests/test_device.py 0000644 0001750 0001750 00000061555 13216442734 020026 0 ustar daniel daniel 0000000 0000000 # Copyright 2016 Daniel Manila
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# flake8: noqa
import sys
import os
myPath = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, myPath + "/../src/")
import pytest
import unittest.mock as mock
import weresync.device as device
from weresync.exception import DeviceError, UnsupportedDeviceError
def generateStandardMock(monkeypatch,
return_value_output,
return_value_error,
return_code,
type="gpt"):
"""Generates a mock for the Popen class that allows easy testing of device methods that use Popen."""
mock_popen = mock.MagicMock()
if return_value_error != None:
return_value_output += return_value_error # Simulates combining the stdout and stderr
mock_popen.communicate.return_value = (return_value_output, None)
mock_popen.returncode = return_code
def popen_constructor(*args, **kargs):
return mock_popen
def mock_table_type(*args, **kargs):
return type
monkeypatch.setattr("subprocess.Popen", popen_constructor)
if type != None:
monkeypatch.setattr(
"weresync.device.DeviceManager.get_partition_table_type",
mock_table_type)
def test_get_partitions_valid(monkeypatch):
generateStandardMock(monkeypatch, b"""Model: Unknown (unknown)
Disk /dev/nbd0: 8590MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Number Start End Size File system Name Flags
4 1049kB 500MB 499MB bios_grub
1 500MB 6000MB 5500MB ext4
2 6000MB 7400MB 1400MB ext4
3 7400MB 8589MB 1189MB linux-swap(v1)\n """, None,
0) # standard return from sgdisk -p
manager = device.DeviceManager("/dev/sdd")
result = manager.get_partitions()
assert result == [4, 1, 2, 3]
def test_get_partitions_none_zero_returncode(monkeypatch):
generateStandardMock(monkeypatch, b"", b"Error.", 1)
manager = device.DeviceManager("/dev/sda")
with pytest.raises(DeviceError) as execinfo:
manager.get_partitions()
assert "Error." in str(execinfo.value)
def test_get_partitions_no_partitions(monkeypatch):
generateStandardMock(monkeypatch, b"Nope\nvery\nvery\nbad\ndata", None, 0)
manager = device.DeviceManager("/dev/sda")
result = manager.get_partitions()
assert result == []
def test_mount_point_normal(monkeypatch):
generateStandardMock(monkeypatch,
b"""TARGET SOURCE FSTYPE OPTIONS
/mnt /dev/sda11 fuseblk rw,nosuid,nodev,relatime,user_id=0,group_id=0,def
""", None, 0)
manager = device.DeviceManager("/dev/sda")
result = manager.mount_point(3)
assert "/mnt" == result
def test_mount_point_non_zero_return_code(monkeypatch):
generateStandardMock(monkeypatch,
b"""TARGET SOURCE FSTYPE OPTIONS\n
/mnt /dev/sda11 fuseblk rw,nosuid,nodev,relatime,user_id=0,group_id=0,def\n
""", b"Error.", 2)
manager = device.DeviceManager("/dev/sda")
with pytest.raises(DeviceError) as execinfo:
result = manager.mount_point(5)
assert "Error." in str(execinfo.value)
def test_mount_point_no_mount_point(monkeypatch):
generateStandardMock(monkeypatch, b"", None,
1) # findmnt returns 1 when there is no mount point
manager = device.DeviceManager("/dev/sda")
result = manager.mount_point(5)
assert result == None
def test_mount_partition(monkeypatch):
generateStandardMock(monkeypatch, b"", None, 0)
manager = device.DeviceManager("/dev/sda")
manager.mount_partition(3, "/mnt")
def test_mount_partition_non_zero_return_code(monkeypatch):
generateStandardMock(monkeypatch, b"", b"Error.", 1)
manager = device.DeviceManager("/dev/sda")
with pytest.raises(DeviceError) as execinfo:
manager.mount_partition(3, "/mnt")
assert "Error." in str(execinfo.value)
def test_unmount_partition(monkeypatch):
generateStandardMock(monkeypatch, b"", b"", 0)
manager = device.DeviceManager("/dev/sda")
manager.unmount_partition(5)
def test_unmount_partition_non_zero(monkeypatch):
generateStandardMock(monkeypatch, b"", b"Error.", 1)
manager = device.DeviceManager("/dev/sda")
with pytest.raises(DeviceError) as execinfo:
manager.unmount_partition(5)
assert "Error." in str(execinfo.value)
def test_get_partition_table_type_gpt(monkeypatch):
generateStandardMock(monkeypatch, b"""/dev/sda: gpt partitions 1 2 3 4 5 11 8 9 10 6 7""", b"", 0, None)
manager = device.DeviceManager("/dev/sda")
result = manager.get_partition_table_type()
assert "gpt" == result
def test_get_partition_table_type_non_zero_return_code(monkeypatch):
generateStandardMock(monkeypatch, b"", b"Error.", 1, None)
manager = device.DeviceManager("/dev/sda")
with pytest.raises(DeviceError) as execinfo:
manager.get_partition_table_type()
assert "Error." in str(execinfo.value)
def test_get_partition_table_type_mbr(monkeypatch):
generateStandardMock(monkeypatch, b"""/dev/sda: msdos partitions 1 2 3 4 5 11 8 9 10 6 7""", b"", 0, None)
manager = device.DeviceManager("mbr.img")
result = manager.get_partition_table_type()
assert result == "msdos"
def test_get_partition_table_type_unsupported(monkeypatch):
generateStandardMock(monkeypatch, b""" dddd """, b"", 0, None)
manager = device.DeviceManager("/dev/sda")
with pytest.raises(UnsupportedDeviceError) as execinfo:
manager.get_partition_table_type()
assert "Partition table type of /dev/sda not supported" in str(execinfo)
def test_get_drive_size(monkeypatch):
generateStandardMock(monkeypatch, b"192", b"", 0)
manager = device.DeviceManager("/dev/sda")
result = manager.get_drive_size()
assert 192 == result
def test_get_drive_size_non_zero_return_code(monkeypatch):
generateStandardMock(monkeypatch, b"", b"Error.", 1)
manager = device.DeviceManager("/dev/sda")
with pytest.raises(DeviceError) as execinfo:
manager.get_drive_size()
assert "Error." in str(execinfo.value)
def test_get_drive_size_bytes(monkeypatch):
generateStandardMock(monkeypatch, b"190", b"", 0)
manager = device.DeviceManager("/dev/sda")
result = manager.get_drive_size_bytes()
assert 190 == result
def test_get_drive_size_bytes_non_zero_return_code(monkeypatch):
generateStandardMock(monkeypatch, b"", b"Error.", 1)
manager = device.DeviceManager("/dev/sda")
with pytest.raises(DeviceError) as execinfo:
manager.get_drive_size()
assert "Error." in str(execinfo.value)
def test_get_partition_used(monkeypatch):
generateStandardMock(
monkeypatch,
b"/dev/sda11 676276220 179697120 496579100 27% /media/Data", b"",
0)
manager = device.DeviceManager("/dev/sda")
result = manager.get_partition_used(5)
assert 179697120 == result
def test_get_partition_used_non_zero_return(monkeypatch):
generateStandardMock(monkeypatch, b" ", b"Error.", 1)
manager = device.DeviceManager("/dev/sda")
with pytest.raises(DeviceError) as execinfo:
manager.get_partition_used(4)
assert "Error." in str(execinfo.value)
def test_get_drive_empty_space(monkeypatch):
generateStandardMock(monkeypatch,
b"""Disk gpt.img: 1024000 sectors, 500.0 MiB
Logical sector size: 512 bytes
Disk identifier (GUID): 6FCE9962-D7B0-4BF3-B7BC-5E5CE8A5B0B0
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 1023966
Partitions will be aligned on 2-sector boundaries
Total free space is 647 sectors (323.5 KiB)
Number Start (sector) End (sector) Size Code Name
1 34 97656 47.7 MiB 8300 test
2 98304 145407 23.0 MiB 8300 cool
3 145408 391167 120.0 MiB 8300 nice
4 391168 684031 143.0 MiB 8300 great
5 684032 976895 143.0 MiB 8300 sweet
6 976896 1023966 23.0 MiB 8300
""", b"", 0)
manager = device.DeviceManager("gpt.img")
result = manager.get_empty_space()
assert result == 34
def test_get_empty_space_non_zero_return(monkeypatch):
generateStandardMock(monkeypatch, b"", b"Error.", 2)
manager = device.DeviceManager("gpt.img")
with pytest.raises(DeviceError) as execinfo:
manager.get_empty_space()
assert "Error." in str(execinfo.value)
def test_get_empty_space_mbr(monkeypatch):
generateStandardMock(monkeypatch, b"""Disk mbr.img: 524 MB, 524288000 bytes
63 heads, 37 sectors/track, 439 cylinders, total 1024000 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xd9e3a78c
Device Boot Start End Blocks Id System
mbr.img1 2050 3942 946+ 83 Linux
""", b"", 0, "msdos")
manager = device.DeviceManager("mbr.img")
result = manager.get_empty_space()
assert result == 1020058
def test_get_empty_space_mbr_boot(monkeypatch):
generateStandardMock(monkeypatch, b"""Disk mbr.img: 524 MB, 524288000 bytes
63 heads, 37 sectors/track, 439 cylinders, total 1024000 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xd9e3a78c
Device Boot Start End Blocks Id System
mbr.img1 2050 3942 946+ 83 Linux
Disk mbr.img: 524 MB, 524288000 bytes
255 heads, 63 sectors/track, 63 cylinders, total 1024000 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xd9e3a78c
Device Boot Start End Blocks Id System
mbr.img1 2050 3942 946+ 83 Linux
mbr.img2 2048 2049 1 83 Linux
mbr.img3 3943 255846 125952 5 Extended
mbr.img5 5991 104244 49127 83 Linux
mbr.img6 * 106293 255846 74777 83 Linux
""", b"", 0, "msdos")
manager = device.DeviceManager("mbr.img")
result = manager.get_empty_space()
def test_get_partition_size(monkeypatch):
generateStandardMock(monkeypatch,
b"""Disk /dev/loop0: 1024000 sectors, 500.0 MiB
Logical sector size: 512 bytes
Disk identifier (GUID): 4EB07926-DFE2-4D18-A2F4-75FB23616F71
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 1023966
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)
Number Start (sector) End (sector) Size Code Name
1 2048 309247 150.0 MiB 8300 Linux filesystem
2 309248 821247 250.0 MiB 8300 Linux filesystem
3 821248 972799 74.0 MiB 8300 Linux filesystem
4 972800 1019903 23.0 MiB 8300 Linux filesystem
5 1019904 1023966 2.0 MiB 8300 Linux filesystem
""", None, 0)
monkeypatch.setattr(
"weresync.device.DeviceManager.get_partition_table_type",
lambda x: "gpt")
manager = device.DeviceManager("gpt.img")
result = manager.get_partition_size(5)
assert 4062 == result
def test_get_partition_size_non_zero_return_code(monkeypatch):
generateStandardMock(monkeypatch, b"", b"Error.", 2)
manager = device.DeviceManager("gpt.img")
with pytest.raises(DeviceError) as execinfo:
manager.get_partition_size(1)
assert "Error." in str(execinfo)
def test_get_partition_size_mbr_non_zero_return_code(monkeypatch):
generateStandardMock(monkeypatch, b"", b"Error.", 2, "msdos")
manager = device.DeviceManager("mbr.img")
with pytest.raises(DeviceError) as execinfo:
manager.get_partition_size(3)
assert "Error." in str(execinfo)
def test_get_partition_size_mbr(monkeypatch):
generateStandardMock(monkeypatch, b"204800", b"", 0, "msdos")
manager = device.DeviceManager("mbr.img")
result = manager.get_partition_size(4)
assert result == 204800
def test_get_partition_size_unknown_table_type(monkeypatch):
generateStandardMock(monkeypatch, b"", b"", 0, "blah")
manager = device.DeviceManager("blah.img")
with pytest.raises(ValueError) as execinfo:
manager.get_partition_size(5)
assert "Unsupported" in str(execinfo)
def test_get_sector_alignment_number(monkeypatch):
generateStandardMock(monkeypatch,
b"""Disk /dev/loop1: 512000 sectors, 250.0 MiB
Logical sector size: 512 bytes
Disk identifier (GUID): 4EB07926-DFE2-4D18-A2F4-75FB23616F71
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 511966
Partitions will be aligned on 2048-sector boundaries
Total free space is 5558 sectors (2.7 MiB)
Number Start (sector) End (sector) Size Code Name
1 2048 309247 150.0 MiB 8300 Linux filesystem
2 309248 508422 97.3 MiB 8300 Linux filesystem
""", b"", 0)
manager = device.DeviceManager("gpt.img")
result = manager.get_partition_alignment()
assert result == 2048
def test_get_sector_alignment_number_non_zero_return(monkeypatch):
generateStandardMock(monkeypatch, b"", b"Error.", 1)
manager = device.DeviceManager("gpt.img")
with pytest.raises(DeviceError) as execinfo:
result = manager.get_partition_alignment()
assert "Error." in str(execinfo.value)
def test_get_sector_alignment_number_invalid_return(monkeypatch):
generateStandardMock(monkeypatch, b"No alignment", b"", 0)
manager = device.DeviceManager("gpt.img")
with pytest.raises(DeviceError) as execinfo:
result = manager.get_partition_alignment()
def test_get_partition_alignment_msdos(monkeypatch):
generateStandardMock(monkeypatch,
b"""Disk /dev/loop0: 7516 MB, 7516192768 bytes
255 heads, 63 sectors/track, 913 cylinders, total 14680064 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x524f0bf8
Device Boot Start End Blocks Id System
""", b"", 0, "msdos")
manager = device.DeviceManager("msdos.img")
result = manager.get_partition_alignment()
# Basically, this is testing if the physical partition is different then the logical partition. If so, then sectors will need to be aligned properly. That isn't the case here.
assert result == 1
def test_get_partition_alignment_msdos_non_zero_return_code(monkeypatch):
generateStandardMock(monkeypatch, b"", b"Error msdos", 1, "msdos")
manager = device.DeviceManager("msdos.img")
with pytest.raises(DeviceError) as exceinfo:
result = manager.get_partition_alignment()
def test_get_partition_file_system(monkeypatch):
generateStandardMock(monkeypatch, b"ext4", b"", 0)
manager = device.DeviceManager("gpt.img")
result = manager.get_partition_file_system(4)
assert result == "ext4"
def test_get_partition_file_system_empty_return(monkeypatch):
generateStandardMock(monkeypatch, b"", b"", 0)
manager = device.DeviceManager("gpt.img")
result = manager.get_partition_file_system(4)
assert result == None
def test_get_partition_file_system_unsupported_type(monkeypatch):
generateStandardMock(monkeypatch, b"completelyimpossiblefilesystemtype",
b"", 0)
manager = device.DeviceManager("gpt.img")
result = manager.get_partition_file_system(4)
assert result == None
def test_get_partition_file_system_non_zero_return(monkeypatch):
generateStandardMock(monkeypatch, b"", b"Error.", 1)
manager = device.DeviceManager("gpt.img")
with pytest.raises(DeviceError) as execinfo:
manager.get_partition_file_system(3)
assert "Error." in str(execinfo.value)
def test_set_partition_file_system_non_zero_return(monkeypatch):
generateStandardMock(monkeypatch, b"", b"Error.", 1)
manager = device.DeviceManager("gpt.img")
with pytest.raises(DeviceError) as execinfo:
manager.set_partition_file_system(3, "ext4")
assert "new file system" in str(execinfo.value)
assert "Error." in str(execinfo.value)
def test_partition_code(monkeypatch):
generateStandardMock(monkeypatch,
b"""Disk /dev/nbd0: 16777216 sectors, 8.0 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): 13E1C95B-5AC6-412B-930B-8F119760B86E
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 16777182
Partitions will be aligned on 2048-sector boundaries
Total free space is 4029 sectors (2.0 MiB)
Number Start (sector) End (sector) Size Code Name
1 976896 11718655 5.1 GiB 8300
2 11718656 14452735 1.3 GiB 8300
3 14452736 16775167 1.1 GiB 8200
4 2048 976895 476.0 MiB EF02
""", b"", 0)
manager = device.DeviceManager("gpt.img")
result = manager.get_partition_code(3)
assert "8200" == result
def test_get_partition_code_non_zero_return_code(monkeypatch):
generateStandardMock(monkeypatch, b"", b"Error.", 2, "gpt")
with pytest.raises(DeviceError) as execinfo:
manager = device.DeviceManager("gpt.img")
manager.get_partition_code(3)
assert "Error." in str(execinfo)
def test_get_partition_code_newer_format(monkeypatch):
generateStandardMock(monkeypatch, b"""Disk /dev/sdb: 5 GiB, 5368709120 bytes, 10485760 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x0ee18f9a
Device Boot Start End Sectors Size Id Type
/dev/sdb1 * 2048 350300 348253 170M 83 Linux
/dev/sdb2 352347 10485759 10133413 4,9G 5 Extended
/dev/sdb5 352349 10485759 10133411 4,9G 8e Linux LVM""",
b"", 0, "msdos")
manager = device.DeviceManager("/dev/sdb")
result = manager.get_partition_code(5)
assert "8e" == result
def test_get_partition_code_mbr(monkeypatch):
generateStandardMock(monkeypatch,
b"""Disk /dev/loop0: 524 MB, 524288000 bytes
255 heads, 63 sectors/track, 63 cylinders, total 1024000 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x01517e72
Device Boot Start End Blocks Id System
/dev/loop0p1 * 2048 411647 204800 83 Linux
/dev/loop0p2 411648 718847 153600 83 Linux
/dev/loop0p3 * 718848 819199 50176 83 Linux
/dev/loop0p4 819200 1023999 102400 83 Linux
""", b"", 0, "msdos")
manager = device.DeviceManager("/dev/loop0", partition_mask="{0}p{1}")
result = manager.get_partition_code(2)
assert result == "83"
def test_get_partition_code_mbr_bootable(monkeypatch):
generateStandardMock(monkeypatch,
b"""Disk /dev/loop0: 524 MB, 524288000 bytes
255 heads, 63 sectors/track, 63 cylinders, total 1024000 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x01517e72
Device Boot Start End Blocks Id System
/dev/loop0p1 * 2048 411647 204800 83 Linux
/dev/loop0p2 411648 718847 153600 83 Linux
/dev/loop0p3 * 718848 819199 50176 83 Linux
/dev/loop0p4 819200 1023999 102400 83 Linux
""", b"", 0, "msdos")
manager = device.DeviceManager("/dev/loop0", partition_mask="{0}p{1}")
result = manager.get_partition_code(3)
assert result == "83"
def test_get_partition_code_mbr_invalid_value_passed(monkeypatch):
generateStandardMock(monkeypatch,
b"""Disk /dev/loop0: 524 MB, 524288000 bytes
255 heads, 63 sectors/track, 63 cylinders, total 1024000 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x01517e72
Device Boot Start End Blocks Id System
/dev/loop0p1 * 2048 411647 204800 83 Linux
/dev/loop0p2 411648 718847 153600 83 Linux
/dev/loop0p3 * 718848 819199 50176 83 Linux
/dev/loop0p4 819200 1023999 102400 83 Linux
""", b"", 0, "msdos")
with pytest.raises(ValueError) as execinfo:
manager = device.DeviceManager("/dev/loop0", "{0}p{1}")
manager.get_partition_code(5)
def test_get_partition_code_mbr_non_zero_return_code(monkeypatch):
generateStandardMock(monkeypatch, b"", b"Test error.", 2, "msdos")
manager = device.DeviceManager("mbr.img")
with pytest.raises(DeviceError) as execinfo:
manager.get_partition_code(4)
assert "Test error." in str(execinfo)
def test_lvm_get_partitions_standard(monkeypatch):
generateStandardMock(
monkeypatch,
b"""LV:VG:Attr:LSize:Pool:Origin:Data%:Meta%:Move:Log:Cpy%Sync:Convert
backup:fileserver:-wi-a-----:5,00g::::::::
media:fileserver:-wi-a-----:1,00g::::::::
share:fileserver:-wi-a-----:50,00g::::::::
root:ubuntu-vg:-wi-ao----:6,52g::::::::
swap_1:ubuntu-vg:-wi-ao----:1,00g::::::::
""", b"", 0, "lvm")
manager = device.LVMDeviceManager("/dev/fileserver")
parts = manager.get_partitions()
assert ["backup", "media", "share"] == parts
def test_lvm_get_partitions_bad_return_code(monkeypatch):
generateStandardMock(monkeypatch, b"Test error.", b"", 1, "lvm")
manager = device.LVMDeviceManager("/dev/fileserver")
with pytest.raises(DeviceError) as execinfo:
manager.get_partitions()
assert "Test error." in str(execinfo)
def test_lvm_get_drive_size_standard(monkeypatch):
generateStandardMock(monkeypatch, b" 12566528S", b"", 0, "lvm")
manager = device.LVMDeviceManager("/dev/fileserver")
result = manager.get_drive_size()
assert 12566528 == result
def test_lvm_get_drive_size_bytes_standard(monkeypatch):
generateStandardMock(monkeypatch, b" 6434062336B", b"", 0, "lvm")
manager = device.LVMDeviceManager("/dev/fileserver")
result = manager.get_drive_size_bytes()
assert 6434062336 == result
def test_lvm_get_drive_size_bytes_bad_return_code(monkeypatch):
generateStandardMock(monkeypatch, b"Test error", b"", 1, "lvm")
manager = device.LVMDeviceManager("/dev/fileserver")
with pytest.raises(DeviceError) as execinfo:
manager.get_drive_size_bytes()
assert "Test error" in str(execinfo)
def test_lvm_get_partition_size(monkeypatch):
generateStandardMock(
monkeypatch,
b"/dev/fileserver/media:fileserver:3:1:-1:0:2097152:256:-1:0:-1:252:3",
b"", 0, "lvm")
manager = device.LVMDeviceManager("/dev/fileserver")
result = manager.get_partition_size("media")
assert result == 2097152
def test_lvm_get_partition_size_bad_return_code(monkeypatch):
generateStandardMock(monkeypatch, b"Didn't work.", b"", 1, "lvm")
manager = device.LVMDeviceManager("/dev/fileserver")
with pytest.raises(DeviceError) as execinfo:
manager.get_partition_size("media")
assert "Didn't work." in str(execinfo)
def test_lvm_get_partition_code_unsupported():
manager = device.LVMDeviceManager("/dev/fileserver")
with pytest.raises(UnsupportedDeviceError) as execinfo:
manager.get_partition_code("media")
def test_lvm_get_partition_alignment_unssported():
manager = device.LVMDeviceManager("/dev/fileserver")
with pytest.raises(UnsupportedDeviceError) as execinfo:
manager.get_partition_alignment()
def test_get_empty_space(monkeypatch):
generateStandardMock(monkeypatch, b" 70921486336B", b"", 0, "lvm")
manager = device.LVMDeviceManager("/dev/fileserver")
result = manager.get_empty_space()
assert result == 70921486336
def test_get_empty_space_non_zero_return_code(monkeypatch):
generateStandardMock(monkeypatch, b"Error.", b"", 1, "lvm")
manager = device.LVMDeviceManager("/dev/fileserver")
with pytest.raises(DeviceError) as execinfo:
manager.get_empty_space()
assert "Error." in str(execinfo)
WereSync-1.0.9/tests/test_interface.py 0000644 0001750 0001750 00000000241 13013034506 020475 0 ustar daniel daniel 0000000 0000000 import os
import sys
myPath = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, myPath + "/../src/")
import pytest
import weresync.interface
pass
WereSync-1.0.9/docs/ 0000755 0001750 0001750 00000000000 13315166025 014724 5 ustar daniel daniel 0000000 0000000 WereSync-1.0.9/docs/Makefile 0000644 0001750 0001750 00000016707 13006633324 016375 0 ustar daniel daniel 0000000 0000000 # Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
.PHONY: help
help:
@echo "Please use \`make ' where is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " applehelp to make an Apple Help Book"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " epub3 to make an epub3"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " coverage to run coverage check of the documentation (if enabled)"
@echo " dummy to check syntax errors of document sources"
.PHONY: clean
clean:
rm -rf $(BUILDDIR)/*
.PHONY: html
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
.PHONY: dirhtml
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
.PHONY: singlehtml
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
.PHONY: pickle
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
.PHONY: json
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
.PHONY: htmlhelp
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
.PHONY: qthelp
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/WereSync.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/WereSync.qhc"
.PHONY: applehelp
applehelp:
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
@echo
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
@echo "N.B. You won't be able to view it unless you put it in" \
"~/Library/Documentation/Help or install it in your application" \
"bundle."
.PHONY: devhelp
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/WereSync"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/WereSync"
@echo "# devhelp"
.PHONY: epub
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
.PHONY: epub3
epub3:
$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
@echo
@echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."
.PHONY: latex
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
.PHONY: latexpdf
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
.PHONY: latexpdfja
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
.PHONY: text
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
.PHONY: man
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
.PHONY: texinfo
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
.PHONY: info
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
.PHONY: gettext
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
.PHONY: changes
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
.PHONY: linkcheck
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
.PHONY: doctest
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
.PHONY: coverage
coverage:
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
@echo "Testing of coverage in the sources finished, look at the " \
"results in $(BUILDDIR)/coverage/python.txt."
.PHONY: xml
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
.PHONY: pseudoxml
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
.PHONY: dummy
dummy:
$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
@echo
@echo "Build finished. Dummy builder generates no files."
WereSync-1.0.9/docs/weresync.1.rst 0000644 0001750 0001750 00000013426 13134020603 017450 0 ustar daniel daniel 0000000 0000000 .. Manpage documentation for WereSync. This should be converted to the groff format using rst2man.py
========
weresync
========
--------------------------------
clone linux drives incrementally
--------------------------------
:Author: Daniel Manila
:Date: June 30th, 2017
:Version: 1.0
:Manual Section: 1
:Manual group: admin
weresync-gui - GUI interface for the weresync program.
SYNOPSIS
--------
weresync [ options ] [**-g** *ROOT_PARTITION*] [**-B** *BOOT_PARTITION*]
[**-E** *EFI_PARTITION*] [**-L** *BOOTLOADER*]
[**-l** *LVM_SOURCE* [*LVM_TARGET*]]
source target
**weresync-gui**
DESCRIPTION
-----------
WereSync clones linux drives incrementally producing a bootable clone. Clones produced by WereSync will have different UUIDs than the original drive, but WereSync will update the fstab and bootloader to allow the clone to properly boot. Clones can be created with one command or one button click, using *weresync* or *weresync-gui* respectively.
OPTIONS
-------
The *weresync-gui* command takes no arguments. These arguments apply to the *weresync* command.
--h, --help
Displays help message.
-C, --check-and-partition
Checks if all partitions are large enough and formatted correctly to allow drive to be copied. If the partitions are not valid, the target drive will be re-partitioned and reformatted. If unset, no checking occurs.
-s, --source-mask *MASK*
A string to be passed to format() that will produce a partition identifier (/dev/sda1 or such) of the source drive when passed two arguments: the identifier ("/dev/sda") and a partition number in that order. Defaults to "{0}{1}"
-t, --target-mask *MASK*
A string to be passed to format() that will produce a partition identifier (/dev/sda1 or such) of the source drive when passed two arguments: the identifier ("/dev/sda") and a partition number in that order. Defaults to "{0}{1}".
-e, --excluded-partitions *LIST*
A list of comma separated partition numbers that should not be searched or copied at any time. These partitions will still be formatted if -C is passed. Defaults to empty.
-b, --break-on-error
If passed the program will halt if there are any errors copying. This flag is not recommended because it will halt even if encountering a normal issue, like a swap partition.
-g, --root-partition *PART_NUM*
The partition mounted on /. It is recommended to pass this always, but WereSync will attempt to find the main partition even if it is not passed.
-B, --boot-partition *PART_NUM*
The partition that should be mounted on /boot of the grub_partition. If you have a separate boot partition, you must use this flag.
-E, --efi-partition *PART_NUM*
The partition that should be mounted on /boot/efi of the grub_partition. If passed this will create the /boot/efi folder if it does not exist and pass it to grub. Required if you have an EFI partition.
-m, --source-mount *DIR*
The directory to mount partitions from the source drive on. Cannot be the same as --target-mount. If unset, WereSync generates a randomly named directory in the /tmp dir.
-M, --target-mount *DIR*
The directory to mount partitions from the target drive on. Cannot be the same as --source-mount. If unset, WereSync generates a randomly named directory in the /tmp dir.
-r, --rsync-args *RSYNC_ARGS*
The arguments to be passed to the rsync instance used to copy files. Defaults to "-aAXxH --delete"
-l, --lvm *SOURCE* [*TARGET*]
This argument expects either one or two arguments specifying the logical volume groups to copy from and to, respectively. If no target VG is passed, WereSync will use the VG SOURCE-copy. If the target does not exist, WereSync will create it.
-L, --bootloader *BOOTLOADER*
The plugin to use to install the bootloader. Such plugins can be found
at the bottom of the help message. Defaults to using the "uuid_copy"
plugin.
-v, --verbose
Makes WereSync increase output and include more minor details.
-d, --debug
Causes a huge amount of output, useful for debugging the program. Usually not needed for casual use.
COPYRIGHT
---------
Copyright 2016 Daniel Manila
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
|
| ``_
|
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
EXAMPLES
--------
To copy /dev/sda to /dev/sdb on a UEFI system use::
sudo weresync -C -L grub2 -E 1 -g 2 /dev/sda /dev/sdb
This example uses grub2 as the bootloader (for most other UEFI bootloaders use
``-L uuid_copy`` or omit the ``-L`` option all together)
with the efi partition on /dev/sda1, and the root partition on /dev/sda2.
Subsequent copies should omit the ``-C`` option, since it could cause weresync
to repartition /dev/sdb again, thus deleting existing data and making weresync's
incremental abilities useless.
To copy /dev/sda to /dev/sdb on a BIOS/Legacy system use::
sudo weresync -C -L grub2 -g 1 /dev/sda /dev/sdb
This example uses grub2 as the bootloader (other bootloaders, such as syslinux,
may be passed to the ``-L`` option) and has the root partition on /dev/sda1.
The omittance of the ``-E`` option signals to WereSync that this is not a
a UEFI drive.
As above, subsequent copies should be initiated without the ``-C`` option.
The gui can simply be run with::
sudo weresync-gui
SEE ALSO
--------
Full documentation can be found at WereSync's documentation on Read The Docs:
``_
WereSync-1.0.9/docs/source/ 0000755 0001750 0001750 00000000000 13315166025 016224 5 ustar daniel daniel 0000000 0000000 WereSync-1.0.9/docs/source/weresync.rst 0000644 0001750 0001750 00000017765 13126624003 020630 0 ustar daniel daniel 0000000 0000000 .. WereSync command documentation.
######################
Command Line Interface
######################
For help using the weresync command when you are on the command line, use the
help flag on the weresync command::
$ weresync -h
Basic Usage
===========
Requirements
------------
.. IMPORTANT::
WereSync requires root permissions to run, because it has to access block devices. Standard linux permissions restrict access to block devices to ordinary users.
WereSync will copy GPT, MBR, and LVM drives. The source drive
must have a valid disk label (such a disk label can be created with the gdisk or
fdisk command). All `dependencies `_ must be installed.
Commands
--------
WereSync always requires a source drive and a target drive. The source drive comes
first. WereSync requires root permissions in order to access hard drive data. So to copy from /dev/sda to /dev/sdb, use this command::
$ sudo weresync /dev/sda /dev/sdb
This will simply copy data from one partition to the another, and if the partitions
are different, you will encounter an error. To have WereSync fix your target drives
partitions, use the ``-C`` flag::
$ sudo weresync -C /dev/sda /dev/sdb
On subsequent backups, you may not want to include the -C flag, since this can
sometimes trigger unnecessary repartitioning.
LVM
+++
WereSync supports the copying of LVM drives with the `-l` flag::
$ sudo weresync -C -l -B 1 volume-group /dev/sda /dev/sdb
It is highly recommended to pass which partition of the drive your boot
partition is stored on, if you have a boot partition seperate from the VG.
If you have your /boot folder inside the VG, your bootloader installation
mileage may vary.
Bootloader Installation
-----------------------
WereSync will attempt to update the target drive's system to it will boot up
properly. By default this simply changes the UUIDs in the files of the /boot
folder and EFI system partition, but specific bootloader installation plugins
can also be specified.
For this to work, it is highly recommended that you pass the root partition
with the ``-g`` flag::
$ sudo weresync -g 1 /dev/sda /dev/sdb
If this is not passed, WereSync will attempt to discover the root filesystem on
its own, but this is unreliable.
In order for a drive on an EFI system to be made bootable, the partition number
of the EFI system partition
to be passed to WereSync with the ``-E`` flag. In this case, the root
filesystem should be installed on (``-g`` flag) should also be passed,
especially if the efi partition comes before the grub partition on the
partition list, as the efi partition can trigger the mechanisms used to find
the grub partition.
.. code-block:: bash
$ sudo weresync -E 2 -g 3 /dev/sda /dev/sdb
If you have your boot folder on a seperate partition, be sure to let WereSync know which partition that folder is on with the ``-B`` flag::
$ sudo weresync -E 1 -g 2 -B 3 /dev/sda /dev/sdb
Obviously replace the numbers with the proper values for your system.
Bootloader Plugins
++++++++++++++++++
Some bootloaders, especially those for MBR booting, require a more specific
process. Bootloader plugins allow such a process to occur. All plugins
available will be displayed at the end of the help message displayed with the
``-h`` flag. The specific plugin to use may be passed with the ``-L`` flag::
$ sudo weresync -L grub2 -E 1 -g 2 /dev/sda /dev/sdb
For more information on installing and creating bootloader plugins see the
`bootloader plugin page `_
Image Files
-----------
WereSync supports image files normally. If either the target or the source ends in
".img" WereSync will automatically consider it an image file and mount it as such.
Currently there is no way to mark files not ending in .img as image files.
To create an image file on linux, use::
$ dd if=/dev/zero of=my_image.img bs=1M count=
$ sgdisk my_image.img -o
The second command creates a partition table on the command, which is currently
needed by WereSync to start analyzing a drive.
In-Depth Parameter Definitions
==============================
Usage::
weresync [-h] [-C] [-s SOURCE_MASK] [-t TARGET_MASK]
[-e EXCLUDED_PARTITIONS] [-b] [-g ROOT_PARTITION]
[-B BOOT_PARTITION] [-E EFI_PARTITION] [-m SOURCE_MOUNT]
[-M TARGET_MOUNT] [-r RSYNC_ARGS] [-l] [-L BOOTLOADER]
[-v] [-d] source target
.. list-table:: Parameters
:widths: 15 10 30 10
:header-rows: 1
* - Long Option
- Short Option
- Description
- Default
* - --help
- -h
- Displays the help message
- N/A
* - --check-and-partition
- -C
- Checks if all partitions are large enough and formatted correctly to allow
drive to be copied. If the partitions are not valid, the target drive will
be re-partitioned and reformatted.
- If unset, no checking occurs.
* - --source-mask MASK
- -s MASK
- A string to be passed to :py:func:`format` that will produce a partition
identifier (/dev/sda1 or such) of the source drive when passed two
arguments: the identifier ("/dev/sda") and a partition number in that order.
- "{0}{1}"
* - --target-mask MASK
- -t MASK
- Same as --source-mask, but applied to the target drive.
- "{0}{1}"
* - --excluded-partitions LIST
- -e LIST
- A list of comma separated partition numbers that should not be searched or
copied at any time. These partitions will still be formatted if `-C` is
passed.
- []
* - --break-on-error
- -b
- If passed the program will halt if there are any errors copying. This
flag is not recommended because it will halt even if encountering a normal
issue, like a swap partition.
- False
* - --root-partition PART_NUM
- -g PART_NUM
- The partition mounted on /. It is recommended to
pass this always, but WereSync will attempt to find the main partition
even if it is not passed.
- None, WereSync searches for the partition.
* - --boot-partition PART_NUM
- -B PART_NUM
- The partition that should be mounted on /boot of the grub_partition. If you
have a separate boot partition, you must use this flag.
- None, no partition mounted.
* - --efi-partition PART_NUM
- -E PART_NUM
- The partition that should be mounted on /boot/efi of the grub_partition. If passed this will create the /boot/efi folder if it does not exist and pass
it to grub. Required if you have an EFI partition.
- None
* - --source-mount DIR
- -m DIR
- The directory to mount partitions from the source drive on. Cannot be the
same as --target-mount.
- None, randomly generated directory in the /tmp folder.
* - --target-mount DIR
- -M DIR
- The directory to mount partitions from the target drive on. Cannot be the
same as --source-mount.
- None, randomly generated directory in the /tmp folder.
* - --rsync-args RSYNC_ARGS
- -r RSYNC_ARGS
- The arguments to be passed to the rsync instance used to copy files.
- -aAXxvH --delete
* - --lvm SOURCE [TARGET]
- -l
- This argument expects either one or two arguments specifying the
logical volume groups to copy from and to, respectively. If no target
VG is passed, WereSync will use the VG SOURCE-copy. If the target does
not exist, WereSync will create it.
- No Volume Groups are copied
* - --bootloader BOOTLOADER
- -L BOOTLOADER
- The plugin to use to install the bootloader. Such plugins can be found
at the bottom of the help message.
- The "uuid_copy" plugin.
* - --verbose
- -v
- Makes WereSync increase output and include more minor details.
- Only Warnings, more serious issues, and basic info are printed.
* - --debug
- -d
- Causes a huge amount of output, useful for debugging the program. Usually
not needed for casual use.
- Only Warnings, more serious issues, and basic info are printed.
WereSync-1.0.9/docs/source/issues.rst 0000644 0001750 0001750 00000000665 13117327354 020304 0 ustar daniel daniel 0000000 0000000 .. Known Issues Page
Known Issues
============
* Due to the complexity of boot loader installations, bootloading may not always install correctly depending on the nature of your setup
* Occasionally, installing the boot loader can change the order of boot on the parent drive, especially for a dual-boot drive
If you have found anymore issues, please report them to the `issue tracker `_.
WereSync-1.0.9/docs/source/global.rst.inc 0000644 0001750 0001750 00000000112 13117327354 020764 0 ustar daniel daniel 0000000 0000000 .. Global includes and various things
.. |project_version| replace:: 0.3
WereSync-1.0.9/docs/source/bootloader.rst 0000644 0001750 0001750 00000010446 13125115721 021111 0 ustar daniel daniel 0000000 0000000 .. Documentaion on bootloader plugins
.. include:: global.rst.inc
==================
Bootloader Plugins
==================
Bootloader plugins allow WereSync to have special process to install specific
bootloaders, allowing support for a wider variety of bootloaders.
The default bootloader plugin, UUID Copy, simply changes the UUIDs in each
file in the /boot folder. UUIDs in /etc/fstab are always updated, regardless
of boot plugin.
Installing
----------
Bootloader plugins can be installed to two different locations:
``/usr/local/weresync/plugins`` and the python site-packages directory. This
means that plugins can be installed as pip packages or installed manually.
Creating Bootloader Plugins
---------------------------
Bootloader plugins are very simple files. They must be a single python file
that fits the form "weresync_.py". Inside this file, a class
must extend :py:class:`~weresync.plugins.IBootPlugin` and at least implement
the method :py:func:`~weresync.plugins.IBootPlugin.install_bootloader`.
No other files are necessary, but other files may be packaged with a plugin
for it to call within its process.
For an example plugin see the `Grub2 Plugin `_.
Method Implementations
++++++++++++++++++++++
All plugins should extend :py:func:`~weresync.plugins.IBootPlugin`, as
mentioned above (signature: ``class MyPlugin(IBootPlugin)``). They should all
call ``super().__init__(name, prettyName)`` where ``name`` is the portion
of the file name after the "weresync\_" prefix but before the ".py" extension
(weresync_.py). ``prettyName`` can be anything, but should be human
readable. Currently this is only displayed by the GUI.
For any given bootloader plugin, the following methods are called in this
order:
* :py:func:`~weresync.plugins.IBootPlugin.activate` is called before bootloader
installation. All files will be exactly the same as the source drive at this
point. Implementing this method is not required.
* :py:func:`~weresync.plugins.IBootPlugin.install_bootloader` is called to
install the bootloader. This should do the majority of the work. Implementing
this method is required.
* :py:func:`~weresync.plugins.IBootPlugin.deactivate` is called after
bootloader installation is complete. Implementing this method is not
required.
:py:class:`~weresync.plugins.IBootPlugin` contains one more method,
:py:func:`~weresync.plugins.IBootPlugin.get_help`, this is an optional method
that should return a string describing what the plugin accomplishes (i.e. what
bootloader it installs).
Helpful Functions
+++++++++++++++++
Several important methods are available to plugin developers. The ``copier``
parameter of :py:func:`~weresync.plugins.IBootPlugin.install_bootloader`
provides access to a
:py:class:`~weresync.device.DeviceCopier` instance. This instance then provides
access to :py:class:`~weresync.device.DeviceManager` instances through the
``copier.source`` and ``copier.target`` fields. These instances allow a plugin
to mount and umnount partitions and get information about the drives in
question.
The method :py:func:`~weresync.device.DeviceCopier.get_uuid_dict` of the
``copier`` parameter returns a dictionary
relating the UUIDs of the source drive with those of the target drive.
This can be used in conjunction with :py:func:`weresync.device.multireplace`
to update the UUIDs of any given string, for example one from a file.
The function :py:func:`weresync.plugins.translate_uuid` makes use of the
above two functions to step recursively through the passed folder and update
the UUIDs of every text file.
LVM
+++
Your bootloader will be expected to support LVM systems as well. One can test
if Logical Volume Groups are being copied by testing if the ``lvm_source`` field
of the ``copier`` object is not ``None``::
if copier.lvm_source is not None:
# Handle copying VG
The ``lvm_source`` and ``lvm_target`` fields will be
:py:class:`~weresync.device.LVMDeviceManager` objects, but can generally be
treated like ordinary DeviceManager objects.
Builtin Bootloaders
-------------------
UUID Copy
+++++++++
.. automodule:: weresync.plugins.weresync_uuid_copy
Grub2
+++++
.. automodule:: weresync.plugins.weresync_grub2
Syslinux
++++++++
.. automodule:: weresync.plugins.weresync_syslinux
WereSync-1.0.9/docs/source/translation.rst 0000644 0001750 0001750 00000003032 13125115721 021306 0 ustar daniel daniel 0000000 0000000 .. Documentation on translating WereSync
.. include:: global.rst.inc
====================
Translating WereSync
====================
WereSync supports translation via Pythons
`gettext `_
module. For end users, if your language is supported, it will simply change
based on your system locale and requires no further configuration.
More languages are always welcome. If know another language besides English
your contribution would be most welcome. You can follow these steps in order
to translate WereSync.
1. Clone WereSync to your computer::
$ git clone https://github.com/DonyorM/weresync.git
2. Enter the WereSync source directory::
$ cd weresync/src
3. Generate the `weresync.pot` file with the `pygettext` command from within
the "src" directory::
$ pygettext -d weresync weresync/*.py weresync/plugins/*.py
4. Translate the file. I recommend using a tool, such as
`poedit `_ to edit the translation. Be sure to choose
the UTF-8 encoding.
5. Place your translation files in the proper folder. `gettext` expects
specific path for language files::
$ mkdir -p resources/locale//LC_MESSAGES/weresync.po
You can find your language code `here `_.
6. Add your language code to the `LANGUAGES` list of the `interface` module.
7. Stage and commit your new language folder and the `interface.py` file.
Then create and submit a pull request.
WereSync-1.0.9/docs/source/_templates/ 0000755 0001750 0001750 00000000000 13315166025 020361 5 ustar daniel daniel 0000000 0000000 WereSync-1.0.9/docs/source/_templates/homepage.html 0000644 0001750 0001750 00000000170 13117327354 023036 0 ustar daniel daniel 0000000 0000000
WereSync-1.0.9/docs/source/index.rst 0000644 0001750 0001750 00000003441 13125115721 020063 0 ustar daniel daniel 0000000 0000000 .. WereSync documentation master file, created by
sphinx-quickstart on Thu Nov 3 19:08:36 2016.
.. include:: global.rst.inc
========
WereSync
========
.. image:: img/weresync-logo.png
:align: center
Making your backup drives into were-drives, transforming them into clones at will.
WereSync incrementally backups up hard drives using rsync. Backups can be run while
you use your computer. As icing on the cake, you can boot your clone just like your
normal computer.
Installation
------------
WereSync can easily be installed with pip. Simply use::
$ pip install weresync
For more in depth information see the `installation guide `_.
Basic Usage
-----------
.. IMPORTANT::
WereSync requires root permissions to run, because it has to access block devices. Standard linux permissions restrict access to block devices to ordinary users.
To start the gui use::
$ sudo weresync-gui
For help on how the terminal command works, run::
$ weresync -h
For a basic setup, you could use a version of the following command::
$ sudo weresync -C --efi-partition /dev/sda /dev/sdb
=========
Contents:
=========
.. toctree::
:maxdepth: 2
installation
gui
weresync
api
bootloader
translation
issues
============
Contributing
============
First, take a look at our `contribution guidelines `_.
Then, if you would like to submit a new feature or fix a bug, please submit a Pull Request at the `project repository `_.
You can submit a bug report on the `issue tracker `_.
==================
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
WereSync-1.0.9/docs/source/gui.rst 0000644 0001750 0001750 00000003721 13125115721 017541 0 ustar daniel daniel 0000000 0000000 .. gui information
########################
Graphical User Interface
########################
Provides a simple user interface in order to produce clones. Each field provided by
the GUI has a "What's This?" link which opens a dialog explaining the field.
By default WereSync outputs all log files to ``/var/log/weresync``. If any errors or problems occur, please be sure to include the output of the most recent file in your report.
To start the gui run the command::
$ sudo weresync-gui
.. IMPORTANT::
WereSync requires root permissions to run, because it has to access block devices. Standard linux permissions restrict access to block devices to ordinary users.
.. image:: img/gui-example.png
:align: left
LVM
===
WereSync supports cloning logical volume groups as well. Simply check the
"Copy Logical Volume Groups" option and select your source group from the
dropdown.
If the target group name is left as "Default" then WereSync will simply use
the name of the source group with "-copy" appended to it. WereSync will create
the target volume group if it does not already exist.
Bootloader Installation
=======================
WereSync will attempt to install a bootloader onto your drive, based on your
choice in the "Bootloader Plugin" entry. If you are unsure which to pick,
use the default "UUID Copy" plugin. WereSync cannot properly install all
bootloaders. You may have to manually adjust some settings after the clone
finishes.
If you have your /boot directory on another partition, be sure to pass that partition number to the "Boot Partition" field under advanced options.
Dependencies
============
The WereSync GUI runs using GTK and requires the `PyGObject `_ bindings to be installed. On Ubuntu these can be installed with::
$ sudo apt install python3-gi
API Reference
=============
The GUI can be started from the ``gui`` module with the method ``start_gui()``::
>>> import weresync.gui
>>> weresync.gui.start_gui()
WereSync-1.0.9/docs/source/img/ 0000755 0001750 0001750 00000000000 13315166025 017000 5 ustar daniel daniel 0000000 0000000 WereSync-1.0.9/docs/source/img/weresync-logo.png 0000644 0001750 0001750 00000104656 13117327354 022323 0 ustar daniel daniel 0000000 0000000 ‰PNG
IHDR ô j 캨¹ sBIT|dˆ pHYs Z ZÉžû tEXtSoftware www.inkscape.org›î< tEXtAuthor Jakub Steineræû÷/ !tEXtSource http://jimmac.musichall.czifã^ XtEXtCopyright CC0 Public Domain Dedication http://creativecommons.org/publicdomain/zero/1.0/Æã½ù IDATxœì½yt\×}çù}KíU(ì @;.â
P¢H‰”ijáª-ɲ©ÈÑÄ™9“Μ¤{¦§gŽÒ}:§sNgzb'™žÄ™DØÓsä-IŸØ–íHŠE²S”Q”Ìâ"ì@jïÎÔ}~(T½w«êÕÜÏ9u$VݺïW…z÷w¿û[pÖ'Nœ¨—$i€{>yô¨àÿä¿î
ŠÇápª‡$€« ® ¸à"€oã߸\I¡8…#TZ NñƒA—¢(ÇAxÀ öJËÄápjàÇ„].×K_ýêW—*-‡®Ðk˜³gÏ:—––~[„…»8‡ÃáXÅ!ä_oݺõ/_xáµÒÂpÌá
½FyüñÇ?Cù z*-‡ÃYÓüŒòßüæ7ß©´ c¸B¯1ž~úéºD"ñׄc•–…Ãá¬Ò‚ ü›¯ýëPiA8¹á
½†8uêT ß°£Ò²p8œuÉnjjúÿìÏþ,UiA8«‘*- ‡S§Nõˆ¢øS ƒ•–…Ãá¬[vE£Ñ3gÎ|ëÕW_%•†³®Ðk€`0ØàŸ tWZ‡³¾aljjªïÌ™3Ë•zuÁz•sôèQ‡,Ëß°¥Ò²p8Î'lššJ…B¡UZίàgèUÎéÓ§ÿO ¿eÅ\^¯›6m‚×ë…ÇãÇã Xó $÷FÝèµrÏ™Ï{Ëq|ÞWŒ<¥¾F¥ÿVÅÌQÉÏ\nÙÒé4–––°´´„ééi$‰‚æÿUUÕ‡¾õoýc1“p¬ƒ+ô*&Þ§ªêk Ä|ßÛÜ܌ݻwcûöíðz½°ÙlÌï·JyTëõ*y}«¯UÙKqrlP*=g¥ç1Ût,,,àúõëxå•Wpþüy¨jÞéæWEQÜþÒK/-$ ÇR¸B¯RŽ=êp»Ý¿ ЗÏû:;;ñØcaçΨ««ƒ(æ·¨„b]Oʼ×+¥ü¥š»ÒŠ®sVzž|Þ§ª*>úè#¼øâ‹¸|9ïʯ_úÆ7¾a‰‘Sü½JÙ¾}ûo8Ã:^E<òÈ#xöÙg1<<\;½RŠUË\ÿùRëʼ”¬eYŠy+ýyŸ ðûý˜˜˜€¢(¸téR>oß5<<ü·.\ø8ïs,…+ô*$z !ÿ ËxI’ð…/|<ð ššš IæVBÈ
%ZiE³k©®YŠÍÐzSæÕ&[9•¹I’022‚úúz¼÷Þ{¬oEQ윜üjQçMÞg³œÒCù
¬ãÏœ9ƒññq4440-îú›žRQe^‰ë¯%e^
ªUa–ê·Ri%œ9G¥”9EEÜÿýxê©§ò¹ö§Ož<¹Í8Ãzõ!B~“uð½÷Þ‹C‡Áçó™ŽÕ/‚ T\ɬÅZŽ
K¥ÿŽFXõùK¥È+„3ç)+=5‚ àÁÄÁƒ™ß#Šâ¿°L NAp…^eœ:uj€ ËØúúzœ9suuu¦cõ‹ÅzTækÕPé¿c¹°úX¡š¬r+ç±AðÄO ¡¡õ-g‚Á`K)eâÃzõñëÀ“'O¢Ít\æbÁ]쥿^9¬òjv?S*ìhÄZVÂVãt:ñÜsÌK’KQ”gK)ǮЫˆÇ{Ì-Âi–±ÍÍ͸ÿþû
ÓÒ*}>žÉzq±×â5jeƒPMTãf¥ŒŒŒ`Ó¦MLcA8[Zi8FÈ•€ó+l6Û Ìýç Ž9'w|®…”‚d2 UU«Ná—‚jNo*Å\å¼F-YºÕ&+ë}úsÏ~øa- ÅÌM¶¼¼EQ X¿€Õê‚X«rçÃzøŒëˆD"Ìc>Ì:t÷©S§v$§`¸B¯!gYÇÒÊM,n²p8\¨HFÖºÛ½Úàß‘õ¤Ói¦øB™ªR~s;ǸB¯0'Nœ¨áËØ¾¾>4773)óx<®YçVSë‹jË_‹ðZ‰F£†¯Ó5G–ef+]„§{ì1wÑÂq˜á
½ÂH’ô ËØ“'O2Ïkvƒ®w¸eÍÆZþlk•Bþfñxªª®z>Û±Þøø8ë´~‡ÃñxÞÂp
†+ô
ÃênE‘9 EUUæ@ÎÚ„+âòQR@a^3š››1<<Ì:/w»—®Ð+ÈÉ“'GA˜`ûàƒÂét2ÍFkª÷v¶k”ë:ÕF5Ê´V©–ïÚf³ÁívÃï÷ÃåbrÖ•„|¼zyÇÝòäÉ‘‚âä
¯WA>É=gâÈ‘#Ìó.//¯øwµ,\Fd“Qÿ\µ—¨†vë…Zþ®iÙU›Í»ÝI’´ßy<¯¨gÇÙívÓ±£££p:ˆÇã¦c%I:à_- Çn¡Wˆ`0( ‚ðËØ¦¦&lܸ‘iÞd2‰T*U”lå„Õ/—ÕÎ)ëñïçp8àõzÑÐЀ––477Ãï÷ÃívC–eí;I§ÓX\\¬°´ìVºÃáȧWúçŸþùÜÅã9–Áz… „|ŠÒÁ2öĉ†]ÕôÔ’u^ˆl<Ÿ¾üðïˆ
Y–áv»Q__ææf´µµ¡¡¡^¯‡’$å|ïââbUx‰DÖà¸lÜ{ï½Lã!m333#‡
îr¯„æ¾Á¬Q¥Ù[$I²,}ZöZv¹–þ=•Qa³Ù4ºÝngº?h¹ÕÙÙYÌÌÌ ¿¿N§³*¼jÔýÇáv»M;6l@ À•+WLçEñ9 ß²HTN¸B¯ O>ùds2™<Î2vÛ¶mY±d#‹Ø]Ó´öb7Õø™¬b-¶ZE–eØívM‰gv)Ë!˜žžÆìì,æçç±´´¤ými‘–R¸Úù
‰¢AF™‚óAÀ¡C‡ð•¯|Åt,!äh0ì~饗®ç%'/¸B¯ Édò3 Ì#O ;vŒyÞLw;uÓsQø÷¼6 Ö7µ¼õgÝFÄãqLMMazzóó󘟟׺™eÒÒÒ‚±±1,,,X-~ÁÐÍ:F:fÚ´lÛ¶
6›Åà B>àßY!+';\¡W†³,ƒìv;FFØ2>Òé4‰„öoý$Š"ó¹Øz„+âõ‹ +"Ïm6›áY7%Nc~~ÓÓÓšgPw¹\Ø·oß
k]/O%~‹Ô:îzö¢Ñ(êêÌ; ºÝnìÛ·¯½öšéXBȯ½ðÂÿþ…^à‹Q‰à
½Ìœ