diff --git a/.travis.yml b/.travis.yml index 5b5608a6a..51b99236b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,4 +7,4 @@ install: - "pip install --use-mirrors Cython" - "pip install -e ." # command to run tests -script: fakeroot python -m darc.testsuite.run -vb +script: fakeroot python -m attic.testsuite.run -vb diff --git a/README.rst b/README.rst index 14ac4e3ac..13f906f50 100644 --- a/README.rst +++ b/README.rst @@ -1,16 +1,16 @@ -What is darc? -------------- -Darc is a Deduplicating ARChiver written in Python. The main goal of darc is -to provide an efficient and secure way to backup data. The data deduplication -technique used makes darc suitable for daily backups since only actual changes +What is Attic? +-------------- +Attic is a deduplicating backup program. The main goal of attic is to provide +an efficient and secure way to backup data. The data deduplication +technique used makes Attic suitable for daily backups since only actual changes are stored. Easy to use ~~~~~~~~~~~ Initialze backup repository and create a backup archive:: - $ darc init /usbdrive/my-backup.darc - $ darc create -v /usbdrive/my-backup.darc::documents ~/Documents + $ attic init /usbdrive/my-backup.attic + $ attic create -v /usbdrive/my-backup.attic::documents ~/Documents Main features ~~~~~~~~~~~~~ @@ -25,36 +25,36 @@ Optional data encryption and authenticity is verified using HMAC-SHA256. Off-site backups - darc can store data on any remote host accessible over SSH as long as - darc is installed. + attic can store data on any remote host accessible over SSH as long as + attic is installed. What do I need? --------------- -Darc requires Python 3.2 or above to work. Besides Python darc also requires +Attic requires Python 3.2 or above to work. Besides Python attic also requires msgpack-python and sufficiently recent OpenSSL (>= 1.0.0). How do I install it? -------------------- :: - $ pip install darc + $ pip install Attic Where are the docs? ------------------- -Go to https://pythonhosted.org/darc/ for a prebuilt version of the docs. You +Go to https://pythonhosted.org/Attic/ for a prebuilt version of the docs. You can also build them yourself form the docs folder. Where are the tests? -------------------- -The tests are in the darc/testsuite package. To run the test suite use the +The tests are in the attic/testsuite package. To run the test suite use the following command:: - $ python -m darc.testsuite.run + $ python -m attic.testsuite.run Contribute ---------- -Found a bug? Have any ideas to improve darc? Add bug reports and feature -requests to the `issue tracker `_. +Found a bug? Have any ideas to improve attic? Add bug reports and feature +requests to the `issue tracker `_. You can also ask the author a question directly by `email `_. diff --git a/darc/__init__.py b/attic/__init__.py similarity index 100% rename from darc/__init__.py rename to attic/__init__.py diff --git a/darc/_chunker.c b/attic/_chunker.c similarity index 100% rename from darc/_chunker.c rename to attic/_chunker.c diff --git a/darc/_hashindex.c b/attic/_hashindex.c similarity index 99% rename from darc/_hashindex.c rename to attic/_hashindex.c index dd2caa486..b481c381f 100644 --- a/darc/_hashindex.c +++ b/attic/_hashindex.c @@ -35,7 +35,7 @@ typedef struct { int upper_limit; } HashIndex; -#define MAGIC "DARCHASH" +#define MAGIC "ATTICIDX" #define EMPTY ((int32_t)-1) #define DELETED ((int32_t)-2) #define MAX_BUCKET_SIZE 512 diff --git a/darc/archive.py b/attic/archive.py similarity index 100% rename from darc/archive.py rename to attic/archive.py diff --git a/darc/archiver.py b/attic/archiver.py similarity index 99% rename from darc/archiver.py rename to attic/archiver.py index 7bf99520e..47e8bb252 100644 --- a/darc/archiver.py +++ b/attic/archiver.py @@ -32,7 +32,7 @@ class Archiver: def print_error(self, msg, *args): msg = args and msg % args or msg self.exit_code = 1 - print('darc: ' + msg, file=sys.stderr) + print('attic: ' + msg, file=sys.stderr) def print_verbose(self, msg, *args, **kw): if self.verbose: @@ -76,7 +76,7 @@ class Archiver: archive = Archive(repository, key, manifest, args.archive.archive, cache=cache, create=True, checkpoint_interval=args.checkpoint_interval, numeric_owner=args.numeric_owner) - # Add darc cache dir to inode_skip list + # Add Attic cache dir to inode_skip list skip_inodes = set() try: st = os.stat(get_cache_dir()) @@ -314,7 +314,7 @@ class Archiver: default=False, help='verbose output') - parser = argparse.ArgumentParser(description='Darc - Deduplicating Archiver') + parser = argparse.ArgumentParser(description='Attic - Deduplicated Backups') subparsers = parser.add_subparsers(title='Available subcommands') subparser = subparsers.add_parser('serve', parents=[common_parser]) diff --git a/darc/cache.py b/attic/cache.py similarity index 97% rename from darc/cache.py rename to attic/cache.py index c871d544b..aaa0515f7 100644 --- a/darc/cache.py +++ b/attic/cache.py @@ -35,7 +35,7 @@ class Cache(object): """ os.makedirs(self.path) with open(os.path.join(self.path, 'README'), 'w') as fd: - fd.write('This is a DARC cache') + fd.write('This is an Attic cache') config = RawConfigParser() config.add_section('cache') config.set('cache', 'version', '1') @@ -49,14 +49,14 @@ class Cache(object): def open(self): if not os.path.isdir(self.path): - raise Exception('%s Does not look like a darc cache' % self.path) + raise Exception('%s Does not look like an Attic cache' % self.path) self.lock_fd = open(os.path.join(self.path, 'README'), 'r+') fcntl.flock(self.lock_fd, fcntl.LOCK_EX) self.rollback() self.config = RawConfigParser() self.config.read(os.path.join(self.path, 'config')) if self.config.getint('cache', 'version') != 1: - raise Exception('%s Does not look like a darc cache') + raise Exception('%s Does not look like an Attic cache') self.id = self.config.get('cache', 'repository') self.manifest_id = unhexlify(self.config.get('cache', 'manifest')) self.chunks = ChunkIndex(os.path.join(self.path, 'chunks').encode('utf-8')) diff --git a/darc/chunker.pyx b/attic/chunker.pyx similarity index 100% rename from darc/chunker.pyx rename to attic/chunker.pyx diff --git a/darc/crypto.py b/attic/crypto.py similarity index 100% rename from darc/crypto.py rename to attic/crypto.py diff --git a/darc/hashindex.pyx b/attic/hashindex.pyx similarity index 100% rename from darc/hashindex.pyx rename to attic/hashindex.pyx diff --git a/darc/helpers.py b/attic/helpers.py similarity index 98% rename from darc/helpers.py rename to attic/helpers.py index ce7848fd7..1e3cfccd6 100644 --- a/darc/helpers.py +++ b/attic/helpers.py @@ -82,14 +82,14 @@ class Statistics: def get_keys_dir(): """Determine where to repository keys and cache""" - return os.environ.get('DARC_KEYS_DIR', - os.path.join(os.path.expanduser('~'), '.darc', 'keys')) + return os.environ.get('ATTIC_KEYS_DIR', + os.path.join(os.path.expanduser('~'), '.attic', 'keys')) def get_cache_dir(): """Determine where to repository keys and cache""" - return os.environ.get('DARC_CACHE_DIR', - os.path.join(os.path.expanduser('~'), '.cache', 'darc')) + return os.environ.get('ATTIC_CACHE_DIR', + os.path.join(os.path.expanduser('~'), '.cache', 'attic')) def to_localtime(ts): diff --git a/darc/key.py b/attic/key.py similarity index 97% rename from darc/key.py rename to attic/key.py index ef234854c..4b39e723f 100644 --- a/darc/key.py +++ b/attic/key.py @@ -137,7 +137,7 @@ class PassphraseKey(AESKeyBase): @classmethod def create(cls, repository, args): key = cls() - passphrase = os.environ.get('DARC_PASSPHRASE') + passphrase = os.environ.get('ATTIC_PASSPHRASE') if passphrase is not None: passphrase2 = passphrase else: @@ -159,7 +159,7 @@ class PassphraseKey(AESKeyBase): def detect(cls, repository, manifest_data): prompt = 'Enter passphrase for %s: ' % repository._location.orig key = cls() - passphrase = os.environ.get('DARC_PASSPHRASE') + passphrase = os.environ.get('ATTIC_PASSPHRASE') if passphrase is None: passphrase = getpass(prompt) while True: @@ -177,7 +177,7 @@ class PassphraseKey(AESKeyBase): class KeyfileKey(AESKeyBase): - FILE_ID = 'DARC KEY' + FILE_ID = 'ATTIC KEY' TYPE = 0x00 @classmethod @@ -185,7 +185,7 @@ class KeyfileKey(AESKeyBase): key = cls() path = cls.find_key_file(repository) prompt = 'Enter passphrase for key file %s: ' % path - passphrase = os.environ.get('DARC_PASSPHRASE', '') + passphrase = os.environ.get('ATTIC_PASSPHRASE', '') while not key.load(path, passphrase): passphrase = getpass(prompt) key.init_ciphers(PREFIX + long_to_bytes(key.extract_iv(manifest_data) + 1000)) @@ -199,7 +199,7 @@ class KeyfileKey(AESKeyBase): filename = os.path.join(keys_dir, name) with open(filename, 'r') as fd: line = fd.readline().strip() - if line and line.startswith(cls.FILE_ID) and line[9:] == id: + if line and line.startswith(cls.FILE_ID) and line[10:] == id: return filename raise Exception('Key file for repository with ID %s not found' % id) @@ -278,7 +278,7 @@ class KeyfileKey(AESKeyBase): while os.path.exists(path): i += 1 path = filename + '.%d' % i - passphrase = os.environ.get('DARC_PASSPHRASE') + passphrase = os.environ.get('ATTIC_PASSPHRASE') if passphrase is not None: passphrase2 = passphrase else: diff --git a/darc/lrucache.py b/attic/lrucache.py similarity index 100% rename from darc/lrucache.py rename to attic/lrucache.py diff --git a/darc/remote.py b/attic/remote.py similarity index 98% rename from darc/remote.py rename to attic/remote.py index 0ea50d3c6..8228d6359 100644 --- a/darc/remote.py +++ b/attic/remote.py @@ -81,9 +81,9 @@ class RemoteRepository(object): self.msgid = 0 self.received_msgid = 0 if location.host == '__testsuite__': - args = [sys.executable, '-m', 'darc.archiver', 'serve'] + args = [sys.executable, '-m', 'attic.archiver', 'serve'] else: - args = ['ssh', '-p', str(location.port), '%s@%s' % (location.user or getpass.getuser(), location.host), 'darc', 'serve'] + args = ['ssh', '-p', str(location.port), '%s@%s' % (location.user or getpass.getuser(), location.host), 'attic', 'serve'] self.p = Popen(args, bufsize=0, stdin=PIPE, stdout=PIPE) self.stdin_fd = self.p.stdin.fileno() self.stdout_fd = self.p.stdout.fileno() diff --git a/darc/repository.py b/attic/repository.py similarity index 98% rename from darc/repository.py rename to attic/repository.py index 28ac7a425..e5a0bd3c0 100644 --- a/darc/repository.py +++ b/attic/repository.py @@ -5,8 +5,6 @@ import os import re import shutil import struct -import tempfile -import unittest from zlib import crc32 from .hashindex import NSIndex @@ -14,7 +12,7 @@ from .helpers import IntegrityError, read_msgpack, write_msgpack, unhexlify from .lrucache import LRUCache MAX_OBJECT_SIZE = 20 * 1024 * 1024 - +MAGIC = b'ATTICSEG' TAG_PUT = 0 TAG_DELETE = 1 TAG_COMMIT = 2 @@ -57,7 +55,7 @@ class Repository(object): if not os.path.exists(path): os.mkdir(path) with open(os.path.join(path, 'README'), 'w') as fd: - fd.write('This is a DARC repository\n') + fd.write('This is an Attic repository\n') os.mkdir(os.path.join(path, 'data')) config = RawConfigParser() config.add_section('repository') @@ -78,7 +76,7 @@ class Repository(object): self.config = RawConfigParser() self.config.read(os.path.join(self.path, 'config')) if self.config.getint('repository', 'version') != 1: - raise Exception('%s Does not look like a darc repository') + raise Exception('%s Does not look like an Attic repository') self.max_segment_size = self.config.getint('repository', 'max_segment_size') self.segments_per_dir = self.config.getint('repository', 'segments_per_dir') self.id = unhexlify(self.config.get('repository', 'id').strip()) @@ -325,7 +323,7 @@ class LoggedIO(object): if not os.path.exists(dirname): os.mkdir(dirname) self._write_fd = open(self.segment_filename(self.segment), 'ab') - self._write_fd.write(b'DSEGMENT') + self._write_fd.write(MAGIC) self.offset = 8 return self._write_fd @@ -346,7 +344,7 @@ class LoggedIO(object): def iter_objects(self, segment, lookup=None, include_data=False): fd = self.get_fd(segment) fd.seek(0) - if fd.read(8) != b'DSEGMENT': + if fd.read(8) != MAGIC: raise IntegrityError('Invalid segment header') offset = 8 header = fd.read(self.header_fmt.size) diff --git a/darc/testsuite/__init__.py b/attic/testsuite/__init__.py similarity index 89% rename from darc/testsuite/__init__.py rename to attic/testsuite/__init__.py index 459ef4ccf..b69a37c9c 100644 --- a/darc/testsuite/__init__.py +++ b/attic/testsuite/__init__.py @@ -1,7 +1,7 @@ import unittest -class DarcTestCase(unittest.TestCase): +class AtticTestCase(unittest.TestCase): """ """ assert_equal = unittest.TestCase.assertEqual @@ -25,7 +25,7 @@ class TestLoader(unittest.TestLoader): """A customzied test loader that properly detects and filters our test cases """ def loadTestsFromName(self, pattern, module=None): - suite = self.discover('darc.testsuite', '*.py') + suite = self.discover('attic.testsuite', '*.py') tests = unittest.TestSuite() for test in get_tests(suite): if pattern.lower() in test.id().lower(): diff --git a/darc/testsuite/archiver.py b/attic/testsuite/archiver.py similarity index 69% rename from darc/testsuite/archiver.py rename to attic/testsuite/archiver.py index f6e1bd642..506c40752 100644 --- a/darc/testsuite/archiver.py +++ b/attic/testsuite/archiver.py @@ -5,10 +5,10 @@ import stat import sys import shutil import tempfile -from darc import xattr -from darc.archiver import Archiver -from darc.repository import Repository -from darc.testsuite import DarcTestCase +from attic import xattr +from attic.archiver import Archiver +from attic.repository import Repository +from attic.testsuite import AtticTestCase has_mtime_ns = sys.version >= '3.3' utime_supports_fd = os.utime in getattr(os, 'supports_fd', {}) @@ -27,7 +27,7 @@ class changedir: os.chdir(self.old) -class ArchiverTestCase(DarcTestCase): +class ArchiverTestCase(AtticTestCase): prefix = '' @@ -40,8 +40,8 @@ class ArchiverTestCase(DarcTestCase): self.output_path = os.path.join(self.tmpdir, 'output') self.keys_path = os.path.join(self.tmpdir, 'keys') self.cache_path = os.path.join(self.tmpdir, 'cache') - os.environ['DARC_KEYS_DIR'] = self.keys_path - os.environ['DARC_CACHE_DIR'] = self.cache_path + os.environ['ATTIC_KEYS_DIR'] = self.keys_path + os.environ['ATTIC_CACHE_DIR'] = self.cache_path os.mkdir(self.input_path) os.mkdir(self.output_path) os.mkdir(self.keys_path) @@ -53,7 +53,7 @@ class ArchiverTestCase(DarcTestCase): shutil.rmtree(self.tmpdir) os.chdir(self._old_wd) - def darc(self, *args, **kwargs): + def attic(self, *args, **kwargs): exit_code = kwargs.get('exit_code', 0) args = list(args) try: @@ -70,8 +70,8 @@ class ArchiverTestCase(DarcTestCase): sys.stdout, sys.stderr = stdout, stderr def create_src_archive(self, name): - self.darc('init', self.repository_location) - self.darc('create', self.repository_location + '::' + name, src_dir) + self.attic('init', self.repository_location) + self.attic('create', self.repository_location + '::' + name, src_dir) def create_regual_file(self, name, size=0): filename = os.path.join(self.input_path, name) @@ -132,91 +132,91 @@ class ArchiverTestCase(DarcTestCase): os.symlink('somewhere', os.path.join(self.input_path, 'link1')) # FIFO node os.mkfifo(os.path.join(self.input_path, 'fifo1')) - self.darc('init', self.repository_location) - self.darc('create', self.repository_location + '::test', 'input') - self.darc('create', self.repository_location + '::test.2', 'input') + self.attic('init', self.repository_location) + self.attic('create', self.repository_location + '::test', 'input') + self.attic('create', self.repository_location + '::test.2', 'input') with changedir('output'): - self.darc('extract', self.repository_location + '::test') - self.assert_equal(len(self.darc('list', self.repository_location).splitlines()), 2) - self.assert_equal(len(self.darc('list', self.repository_location + '::test').splitlines()), 9) + self.attic('extract', self.repository_location + '::test') + self.assert_equal(len(self.attic('list', self.repository_location).splitlines()), 2) + self.assert_equal(len(self.attic('list', self.repository_location + '::test').splitlines()), 9) self.diff_dirs('input', 'output/input') - info_output = self.darc('info', self.repository_location + '::test') + info_output = self.attic('info', self.repository_location + '::test') shutil.rmtree(self.cache_path) - info_output2 = self.darc('info', self.repository_location + '::test') + info_output2 = self.attic('info', self.repository_location + '::test') # info_output2 starts with some "initializing cache" text but should # end the same way as info_output assert info_output2.endswith(info_output) def test_extract_include_exclude(self): - self.darc('init', self.repository_location) + self.attic('init', self.repository_location) self.create_regual_file('file1', size=1024 * 80) self.create_regual_file('file2', size=1024 * 80) self.create_regual_file('file3', size=1024 * 80) self.create_regual_file('file4', size=1024 * 80) - self.darc('create', '--exclude=input/file4', self.repository_location + '::test', 'input') + self.attic('create', '--exclude=input/file4', self.repository_location + '::test', 'input') with changedir('output'): - self.darc('extract', self.repository_location + '::test', 'input/file1', ) + self.attic('extract', self.repository_location + '::test', 'input/file1', ) self.assert_equal(sorted(os.listdir('output/input')), ['file1']) with changedir('output'): - self.darc('extract', '--exclude=input/file2', self.repository_location + '::test') + self.attic('extract', '--exclude=input/file2', self.repository_location + '::test') self.assert_equal(sorted(os.listdir('output/input')), ['file1', 'file3']) def test_overwrite(self): self.create_regual_file('file1', size=1024 * 80) self.create_regual_file('dir2/file2', size=1024 * 80) - self.darc('init', self.repository_location) - self.darc('create', self.repository_location + '::test', 'input') + self.attic('init', self.repository_location) + self.attic('create', self.repository_location + '::test', 'input') # Overwriting regular files and directories should be supported os.mkdir('output/input') os.mkdir('output/input/file1') os.mkdir('output/input/dir2') with changedir('output'): - self.darc('extract', self.repository_location + '::test') + self.attic('extract', self.repository_location + '::test') self.diff_dirs('input', 'output/input') # But non-empty dirs should fail os.unlink('output/input/file1') os.mkdir('output/input/file1') os.mkdir('output/input/file1/dir') with changedir('output'): - self.darc('extract', self.repository_location + '::test', exit_code=1) + self.attic('extract', self.repository_location + '::test', exit_code=1) def test_delete(self): self.create_regual_file('file1', size=1024 * 80) self.create_regual_file('dir2/file2', size=1024 * 80) - self.darc('init', self.repository_location) - self.darc('create', self.repository_location + '::test', 'input') - self.darc('create', self.repository_location + '::test.2', 'input') - self.darc('verify', self.repository_location + '::test') - self.darc('verify', self.repository_location + '::test.2') - self.darc('delete', self.repository_location + '::test') - self.darc('verify', self.repository_location + '::test.2') - self.darc('delete', self.repository_location + '::test.2') + self.attic('init', self.repository_location) + self.attic('create', self.repository_location + '::test', 'input') + self.attic('create', self.repository_location + '::test.2', 'input') + self.attic('verify', self.repository_location + '::test') + self.attic('verify', self.repository_location + '::test.2') + self.attic('delete', self.repository_location + '::test') + self.attic('verify', self.repository_location + '::test.2') + self.attic('delete', self.repository_location + '::test.2') # Make sure all data except the manifest has been deleted repository = Repository(self.repository_path) self.assert_equal(repository._len(), 1) def test_corrupted_repository(self): self.create_src_archive('test') - self.darc('verify', self.repository_location + '::test') + self.attic('verify', self.repository_location + '::test') name = sorted(os.listdir(os.path.join(self.tmpdir, 'repository', 'data', '0')), reverse=True)[0] fd = open(os.path.join(self.tmpdir, 'repository', 'data', '0', name), 'r+') fd.seek(100) fd.write('X') fd.close() - self.darc('verify', self.repository_location + '::test', exit_code=1) + self.attic('verify', self.repository_location + '::test', exit_code=1) def test_prune_repository(self): - self.darc('init', self.repository_location) - self.darc('create', self.repository_location + '::test1', src_dir) - self.darc('create', self.repository_location + '::test2', src_dir) - self.darc('prune', self.repository_location, '--daily=2') - output = self.darc('list', self.repository_location) + self.attic('init', self.repository_location) + self.attic('create', self.repository_location + '::test1', src_dir) + self.attic('create', self.repository_location + '::test2', src_dir) + self.attic('prune', self.repository_location, '--daily=2') + output = self.attic('list', self.repository_location) assert 'test1' not in output assert 'test2' in output def test_usage(self): - self.assert_raises(SystemExit, lambda: self.darc()) - self.assert_raises(SystemExit, lambda: self.darc('-h')) + self.assert_raises(SystemExit, lambda: self.attic()) + self.assert_raises(SystemExit, lambda: self.attic('-h')) class RemoteArchiverTestCase(ArchiverTestCase): diff --git a/darc/testsuite/chunker.py b/attic/testsuite/chunker.py similarity index 93% rename from darc/testsuite/chunker.py rename to attic/testsuite/chunker.py index bb17fefcc..62002626b 100644 --- a/darc/testsuite/chunker.py +++ b/attic/testsuite/chunker.py @@ -1,9 +1,9 @@ -from darc.chunker import chunkify, buzhash, buzhash_update -from darc.testsuite import DarcTestCase +from attic.chunker import chunkify, buzhash, buzhash_update +from attic.testsuite import AtticTestCase from io import BytesIO -class ChunkerTestCase(DarcTestCase): +class ChunkerTestCase(AtticTestCase): def test_chunkify(self): data = b'0' * 1024 * 1024 * 15 + b'Y' diff --git a/darc/testsuite/crypto.py b/attic/testsuite/crypto.py similarity index 89% rename from darc/testsuite/crypto.py rename to attic/testsuite/crypto.py index 71cd3aa99..0abddfa8c 100644 --- a/darc/testsuite/crypto.py +++ b/attic/testsuite/crypto.py @@ -1,9 +1,9 @@ from binascii import hexlify -from darc.testsuite import DarcTestCase -from darc.crypto import AES, bytes_to_long, bytes_to_int, long_to_bytes, pbkdf2_sha256, get_random_bytes +from attic.testsuite import AtticTestCase +from attic.crypto import AES, bytes_to_long, bytes_to_int, long_to_bytes, pbkdf2_sha256, get_random_bytes -class CryptoTestCase(DarcTestCase): +class CryptoTestCase(AtticTestCase): def test_bytes_to_int(self): self.assert_equal(bytes_to_int(b'\0\0\0\1'), 1) diff --git a/darc/testsuite/hashindex.py b/attic/testsuite/hashindex.py similarity index 79% rename from darc/testsuite/hashindex.py rename to attic/testsuite/hashindex.py index 461e3ced5..d8cd19a37 100644 --- a/darc/testsuite/hashindex.py +++ b/attic/testsuite/hashindex.py @@ -1,10 +1,10 @@ import hashlib import tempfile -from darc.hashindex import NSIndex, ChunkIndex -from darc.testsuite import DarcTestCase +from attic.hashindex import NSIndex, ChunkIndex +from attic.testsuite import AtticTestCase -class HashIndexTestCase(DarcTestCase): +class HashIndexTestCase(AtticTestCase): def _generic_test(self, cls, make_value, sha): idx_name = tempfile.NamedTemporaryFile() @@ -41,8 +41,8 @@ class HashIndexTestCase(DarcTestCase): self.assert_equal(len(cls(idx_name.name)), 0) def test_nsindex(self): - self._generic_test(NSIndex, lambda x: (x, x), '9a6f9cb3c03d83ed611265eeef1f9a9d69c2f0417a35ac14d56ce573d0c8b356') + self._generic_test(NSIndex, lambda x: (x, x), '369a18ae6a52524eb2884a3c0fdc2824947edd017a2688c5d4d7b3510c245ab9') def test_chunkindex(self): - self._generic_test(ChunkIndex, lambda x: (x, x, x), '9c35f237e533b6d2533d2646da127052d615ab9b66de65a795cd922b337741ca') + self._generic_test(ChunkIndex, lambda x: (x, x, x), 'ed22e8a883400453c0ee79a06c54df72c994a54eeefdc6c0989efdc5ee6d07b7') diff --git a/darc/testsuite/helpers.py b/attic/testsuite/helpers.py similarity index 85% rename from darc/testsuite/helpers.py rename to attic/testsuite/helpers.py index d0801cac1..61c56c6d3 100644 --- a/darc/testsuite/helpers.py +++ b/attic/testsuite/helpers.py @@ -1,9 +1,9 @@ from datetime import datetime -from darc.helpers import Location, format_timedelta, IncludePattern, ExcludePattern -from darc.testsuite import DarcTestCase +from attic.helpers import Location, format_timedelta, IncludePattern, ExcludePattern +from attic.testsuite import AtticTestCase -class LocationTestCase(DarcTestCase): +class LocationTestCase(AtticTestCase): def test(self): self.assert_equal( @@ -19,8 +19,8 @@ class LocationTestCase(DarcTestCase): "Location(proto='ssh', user='user', host='host', port=22, path='/some/path', archive='archive')" ) self.assert_equal( - repr(Location('mybackup.darc::archive')), - "Location(proto='file', user=None, host=None, port=None, path='mybackup.darc', archive='archive')" + repr(Location('mybackup.attic::archive')), + "Location(proto='file', user=None, host=None, port=None, path='mybackup.attic', archive='archive')" ) self.assert_equal( repr(Location('/some/absolute/path::archive')), @@ -32,7 +32,7 @@ class LocationTestCase(DarcTestCase): ) -class FormatTimedeltaTestCase(DarcTestCase): +class FormatTimedeltaTestCase(AtticTestCase): def test(self): t0 = datetime(2001, 1, 1, 10, 20, 3, 0) @@ -43,7 +43,7 @@ class FormatTimedeltaTestCase(DarcTestCase): ) -class PatternTestCase(DarcTestCase): +class PatternTestCase(AtticTestCase): def test(self): self.assert_equal(IncludePattern('/usr').match('/usr'), True) diff --git a/darc/testsuite/key.py b/attic/testsuite/key.py similarity index 83% rename from darc/testsuite/key.py rename to attic/testsuite/key.py index 417314def..a23e495f3 100644 --- a/darc/testsuite/key.py +++ b/attic/testsuite/key.py @@ -3,19 +3,19 @@ import re import shutil import tempfile from binascii import hexlify -from darc.crypto import bytes_to_long -from darc.testsuite import DarcTestCase -from darc.key import PlaintextKey, PassphraseKey, KeyfileKey -from darc.helpers import Location, unhexlify +from attic.crypto import bytes_to_long +from attic.testsuite import AtticTestCase +from attic.key import PlaintextKey, PassphraseKey, KeyfileKey +from attic.helpers import Location, unhexlify -class KeyTestCase(DarcTestCase): +class KeyTestCase(AtticTestCase): class MockArgs(object): repository = Location(tempfile.mkstemp()[1]) keyfile2_key_file = """ - DARC KEY 0000000000000000000000000000000000000000000000000000000000000000 + ATTIC KEY 0000000000000000000000000000000000000000000000000000000000000000 hqppdGVyYXRpb25zzgABhqCkaGFzaNoAIMyonNI+7Cjv0qHi0AOBM6bLGxACJhfgzVD2oq bIS9SFqWFsZ29yaXRobaZzaGEyNTakc2FsdNoAINNK5qqJc1JWSUjACwFEWGTdM7Nd0a5l 1uBGPEb+9XM9p3ZlcnNpb24BpGRhdGHaANAYDT5yfPpU099oBJwMomsxouKyx/OG4QIXK2 @@ -32,7 +32,7 @@ class KeyTestCase(DarcTestCase): def setUp(self): self.tmppath = tempfile.mkdtemp() - os.environ['DARC_KEYS_DIR'] = self.tmppath + os.environ['ATTIC_KEYS_DIR'] = self.tmppath def tearDown(self): shutil.rmtree(self.tmppath) @@ -44,13 +44,6 @@ class KeyTestCase(DarcTestCase): _location = _Location() id = bytes(32) - def setUp(self): - self.tmpdir = tempfile.mkdtemp() - os.environ['DARC_KEYS_DIR'] = self.tmpdir - - def tearDown(self): - shutil.rmtree(self.tmpdir) - def test_plaintext(self): key = PlaintextKey.create(None, None) data = b'foo' @@ -58,7 +51,7 @@ class KeyTestCase(DarcTestCase): self.assert_equal(data, key.decrypt(key.id_hash(data), key.encrypt(data))) def test_keyfile(self): - os.environ['DARC_PASSPHRASE'] = 'test' + os.environ['ATTIC_PASSPHRASE'] = 'test' key = KeyfileKey.create(self.MockRepository(), self.MockArgs()) self.assert_equal(bytes_to_long(key.enc_cipher.iv, 8), 0) manifest = key.encrypt(b'') @@ -72,14 +65,14 @@ class KeyTestCase(DarcTestCase): self.assert_equal(data, key2.decrypt(key.id_hash(data), key.encrypt(data))) def test_keyfile2(self): - with open(os.path.join(os.environ['DARC_KEYS_DIR'], 'keyfile'), 'w') as fd: + with open(os.path.join(os.environ['ATTIC_KEYS_DIR'], 'keyfile'), 'w') as fd: fd.write(self.keyfile2_key_file) - os.environ['DARC_PASSPHRASE'] = 'passphrase' + os.environ['ATTIC_PASSPHRASE'] = 'passphrase' key = KeyfileKey.detect(self.MockRepository(), self.keyfile2_cdata) self.assert_equal(key.decrypt(self.keyfile2_id, self.keyfile2_cdata), b'payload') def test_passphrase(self): - os.environ['DARC_PASSPHRASE'] = 'test' + os.environ['ATTIC_PASSPHRASE'] = 'test' key = PassphraseKey.create(self.MockRepository(), None) self.assert_equal(bytes_to_long(key.enc_cipher.iv, 8), 0) self.assert_equal(hexlify(key.id_key), b'793b0717f9d8fb01c751a487e9b827897ceea62409870600013fbc6b4d8d7ca6') diff --git a/darc/testsuite/lrucache.py b/attic/testsuite/lrucache.py similarity index 90% rename from darc/testsuite/lrucache.py rename to attic/testsuite/lrucache.py index 7ae23f1eb..9b51a7aab 100644 --- a/darc/testsuite/lrucache.py +++ b/attic/testsuite/lrucache.py @@ -1,8 +1,8 @@ -from darc.lrucache import LRUCache -from darc.testsuite import DarcTestCase +from attic.lrucache import LRUCache +from attic.testsuite import AtticTestCase -class LRUCacheTestCase(DarcTestCase): +class LRUCacheTestCase(AtticTestCase): def test(self): c = LRUCache(2) diff --git a/darc/testsuite/repository.py b/attic/testsuite/repository.py similarity index 94% rename from darc/testsuite/repository.py rename to attic/testsuite/repository.py index 73a91c51b..d7b33d1ba 100644 --- a/darc/testsuite/repository.py +++ b/attic/testsuite/repository.py @@ -1,13 +1,13 @@ import os import shutil import tempfile -from darc.helpers import Location -from darc.remote import RemoteRepository -from darc.repository import Repository -from darc.testsuite import DarcTestCase +from attic.helpers import Location +from attic.remote import RemoteRepository +from attic.repository import Repository +from attic.testsuite import AtticTestCase -class RepositoryTestCase(DarcTestCase): +class RepositoryTestCase(AtticTestCase): def open(self, create=False): return Repository(os.path.join(self.tmppath, 'repository'), create=create) diff --git a/darc/testsuite/run.py b/attic/testsuite/run.py similarity index 76% rename from darc/testsuite/run.py rename to attic/testsuite/run.py index 2fed312f6..9231d3677 100644 --- a/darc/testsuite/run.py +++ b/attic/testsuite/run.py @@ -1,5 +1,5 @@ import unittest -from darc.testsuite import TestLoader +from attic.testsuite import TestLoader def main(): diff --git a/darc/testsuite/xattr.py b/attic/testsuite/xattr.py similarity index 89% rename from darc/testsuite/xattr.py rename to attic/testsuite/xattr.py index 2fd824ec1..123995d5a 100644 --- a/darc/testsuite/xattr.py +++ b/attic/testsuite/xattr.py @@ -1,12 +1,12 @@ import os import tempfile import unittest -from darc.testsuite import DarcTestCase -from darc.xattr import lsetxattr, llistxattr, lgetxattr, get_all, set, flistxattr, fgetxattr, fsetxattr, is_enabled +from attic.testsuite import AtticTestCase +from attic.xattr import lsetxattr, llistxattr, lgetxattr, get_all, set, flistxattr, fgetxattr, fsetxattr, is_enabled @unittest.skipUnless(is_enabled(), 'xattr not enabled on filesystem') -class XattrTestCase(DarcTestCase): +class XattrTestCase(AtticTestCase): def setUp(self): self.tmpfile = tempfile.NamedTemporaryFile() diff --git a/darc/xattr.py b/attic/xattr.py similarity index 100% rename from darc/xattr.py rename to attic/xattr.py diff --git a/docs/Makefile b/docs/Makefile index 02c94644a..77369e5ab 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -73,17 +73,17 @@ qthelp: @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Darc.qhcp" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/attic.qhcp" @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Darc.qhc" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/attic.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/Darc" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Darc" + @echo "# mkdir -p $$HOME/.local/share/devhelp/attic" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/attic" @echo "# devhelp" epub: diff --git a/docs/conf.py b/docs/conf.py index 788e8b35d..59ab492c7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Darc documentation build configuration file, created by +# Attic documentation build configuration file, created by # sphinx-quickstart on Sat Sep 10 18:18:25 2011. # # This file is execfile()d with the current directory set to its containing dir. @@ -11,7 +11,7 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys, os, darc +import sys, os, attic # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -40,7 +40,7 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = 'Darc - Deduplicating Archiver' +project = 'Attic - Deduplicating Archiver' copyright = '2010-2013, Jonas Borgström' # The version info for the project you're documenting, acts as replacement for @@ -48,9 +48,9 @@ copyright = '2010-2013, Jonas Borgström' # built documents. # # The short X.Y version. -version = darc.__version__ +version = attic.__version__ # The full version, including alpha/beta/rc tags. -release = darc.__release__ +release = attic.__release__ # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -164,7 +164,7 @@ html_static_path = ['_static'] #html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'Darcdoc' +htmlhelp_basename = 'atticdoc' # -- Options for LaTeX output -------------------------------------------------- @@ -178,7 +178,7 @@ htmlhelp_basename = 'Darcdoc' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'Darc.tex', 'Darc Documentation', + ('index', 'Attic.tex', 'Attic Documentation', 'Jonas Borgström', 'manual'), ] @@ -211,6 +211,6 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'darc', 'Darc Documentation', + ('index', 'attic', 'Attic Documentation', ['Jonas Borgström'], 1) ] diff --git a/docs/faq.rst b/docs/faq.rst index f3bbcf2bb..6e40989b3 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -12,8 +12,8 @@ Currently Linux and MacOS X are supported. Can I backup VM disk images? ---------------------------- -Yes, the :ref:`deduplication ` technique used by darc will -make sure only the modified parts of the file is stored. +Yes, the :ref:`deduplication ` technique used by |project_name| +makes sure only the modified parts of the file are stored. Which file attributes are preserved? ------------------------------------ diff --git a/docs/generalusage.rst b/docs/generalusage.rst index 71ad0b314..f37c33d84 100644 --- a/docs/generalusage.rst +++ b/docs/generalusage.rst @@ -12,39 +12,39 @@ Initialize a local :ref:`repository ` to store backup :ref:`archives ` in (See :ref:`encrypted_repos` and :ref:`remote_repos` for more details):: - $ darc init /somewhere/my-backup.darc + $ attic init /somewhere/my-backup.attic Create an archive containing the ``~/src`` and ``~/Documents`` directories:: - $ darc create -v /somwhere/my-backup.darc::first-backup ~/src ~/Documents + $ attic create -v /somwhere/my-backup.attic::first-backup ~/src ~/Documents Create another archive the next day. This backup will be a lot quicker since only new data is stored. The ``--stats`` option tells |project_name| to print statistics about the newly created archive such as the amount of unique data (not shared with other archives):: - $ darc create -v --stats /somwhere/my-backup.darc::second-backup ~/src ~/Documents + $ attic create -v --stats /somwhere/my-backup.attic::second-backup ~/src ~/Documents List all archives in the repository:: - $ darc list /somewhere/my-backup.darc + $ attic list /somewhere/my-backup.attic List the files in the *first-backup* archive:: - $ darc list /somewhere/my-backup.darc::first-backup + $ attic list /somewhere/my-backup.attic::first-backup Restore the *first-backup* archive:: - $ darc extract -v /somwhere/my-backup.darc::first-backup + $ attic extract -v /somwhere/my-backup.attic::first-backup Recover disk space by manually deleting the *first-backup* archive:: - $ darc delete /somwhere/my-backup.darc::first-backup + $ attic delete /somwhere/my-backup.attic::first-backup Use the ``prune`` subcommand to delete all archives except a given number of *daily*, *weekly*, *monthly* and *yearly* archives:: - $ darc prune /somwhere/my-backup.darc --daily=7 --weekly=2 --monthly=6 + $ attic prune /somwhere/my-backup.attic --daily=7 --weekly=2 --monthly=6 .. _encrypted_repos: @@ -54,7 +54,7 @@ Repository encryption Repository encryption is enabled at repository encryption time:: - $ darc init --passphrase | --key-file + $ attic init --passphrase | --key-file When repository encryption is enabled all data is encrypted using 256-bit AES_ encryption and the integrity and authenticity is verified using `HMAC-SHA256`_. @@ -68,7 +68,7 @@ Passphrase based encryption Key file based encryption This method generates random keys at repository initialization time that - are stored in a password protected file in the ``~/.darc/keys/`` directory. + are stored in a password protected file in the ``~/.attic/keys/`` directory. This method is secure and suitable for automated backups. .. Note:: @@ -86,8 +86,8 @@ host is accessible using SSH and |project_name| is installed. The following syntax is used to address remote repositories:: - $ darc init user@hostname:repository.darc + $ attic init user@hostname:repository.attic or:: - $ darc init ssh://user@hostname:port/repository.darc + $ attic init ssh://user@hostname:port/repository.attic diff --git a/docs/global.rst.inc b/docs/global.rst.inc index 87cc77e94..ec927d177 100644 --- a/docs/global.rst.inc +++ b/docs/global.rst.inc @@ -1,17 +1,17 @@ -.. |project_name| replace:: ``darc`` +.. |project_name| replace:: ``Attic`` .. |project_version| replace:: 0.6 -.. |package_dirname| replace:: darc-|project_version| +.. |package_dirname| replace:: Attic-|project_version| .. |package_filename| replace:: |package_dirname|.tar.gz -.. |package_url| replace:: https://pypi.python.org/packages/source/d/darc/darc-0.6.tar.gz - +.. |package_url| replace:: https://pypi.python.org/packages/source/A/Attic/Attic-0.6.tar.gz +.. |git_url| replace:: https://github.com/jborg/attic.git .. _deduplication: https://en.wikipedia.org/wiki/Data_deduplication .. _AES: https://en.wikipedia.org/wiki/Advanced_Encryption_Standard .. _HMAC-SHA256: http://en.wikipedia.org/wiki/HMAC .. _PBKDF2: https://en.wikipedia.org/wiki/PBKDF2 .. _ACL: https://en.wikipedia.org/wiki/Access_control_list -.. _github: https://github.com/jborg/darc +.. _github: https://github.com/jborg/attic .. _OpenSSL: https://www.openssl.org/ .. _Python: http://www.python.org/ .. _`msgpack-python`: https://pypi.python.org/pypi/msgpack-python/ .. _homebrew: http://mxcl.github.io/homebrew/ -.. _issue tracker: https://github.com/jborg/darc/issues +.. _issue tracker: https://github.com/jborg/attic/issues diff --git a/docs/index.rst b/docs/index.rst index 423dcf525..7754802d4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,8 +1,8 @@ .. include:: global.rst.inc -Darc -==== -|project_name| is a Deduplicating ARChiver written in Python. +Attic +===== +|project_name| is a deduplicating backup program written in Python. The main goal of |project_name| is to provide an efficient and secure way to backup data. The data deduplication technique used makes |project_name| suitable for daily backups since only actual changes are stored. @@ -28,8 +28,8 @@ Easy to use Initialize a new backup :ref:`repository ` and create your first backup :ref:`archive ` in two lines:: - $ darc init /usbdrive/my-backup.darc - $ darc create -v /usbdrive/my-backup.darc::documents ~/Documents + $ attic init /usbdrive/my-backup.attic + $ attic create -v /usbdrive/my-backup.attic::documents ~/Documents See the :ref:`generalusage` section for more detailed examples. @@ -37,7 +37,7 @@ Easy installation ----------------- You can use pip to install |project_name| quickly and easily:: - $ pip install darc + $ pip install attic Need more help with installing? See :ref:`installation` diff --git a/docs/installation.rst b/docs/installation.rst index 52e0258ed..9301dd90d 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -20,21 +20,21 @@ Installing from PyPI using pip ------------------------------ :: - $ pip install darc + $ pip install Attic Installing from source tarballs ------------------------------- .. parsed-literal:: $ curl -O |package_url| - $ tar -xvzf darc-|package_filename| + $ tar -xvzf |package_filename| $ cd |package_dirname| $ python setup.py install Installing from git ------------------- -:: +.. parsed-literal:: - $ git clone https://github.com/jborg/darc.git - $ cd darc + $ git clone |git_url| + $ cd attic $ python setup.py install diff --git a/docs/update_usage.sh b/docs/update_usage.sh index e3e3c79a2..f979a5381 100755 --- a/docs/update_usage.sh +++ b/docs/update_usage.sh @@ -1,7 +1,7 @@ #!/usr/bin/bash echo -n > usage.rst for cmd in init create extract delete prune verify change-passphrase; do - LINE=`echo -n darc $cmd | tr 'a-z ' '~'` - echo -e ".. _usage_darc_$cmd:\n\ndarc $cmd\n$LINE\n::\n" >> usage.rst - darc $cmd -h >> usage.rst + LINE=`echo -n attic $cmd | tr 'a-z ' '~'` + echo -e ".. _usage_attic_$cmd:\n\nattic $cmd\n$LINE\n::\n" >> usage.rst + attic $cmd -h >> usage.rst done diff --git a/docs/usage.rst b/docs/usage.rst index 696b4d789..36c3666b2 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -1,10 +1,10 @@ -.. _usage_darc_init: +.. _usage_attic_init: -darc init -~~~~~~~~~ +attic init +~~~~~~~~~~ :: -usage: darc init [-h] [-v] [--key-file] [--passphrase] repository +usage: attic init [-h] [-v] [--key-file] [--passphrase] repository Initialize a new repository @@ -16,15 +16,15 @@ optional arguments: -v, --verbose verbose output --key-file enable key file based encryption --passphrase enable passphrase based encryption -.. _usage_darc_create: +.. _usage_attic_create: -darc create -~~~~~~~~~~~ +attic create +~~~~~~~~~~~~ :: -usage: darc create [-h] [-v] [-s] [-e PATTERN] [-c SECONDS] - [--do-not-cross-mountpoints] [--numeric-owner] - ARCHIVE PATH [PATH ...] +usage: attic create [-h] [-v] [-s] [-e PATTERN] [-c SECONDS] + [--do-not-cross-mountpoints] [--numeric-owner] + ARCHIVE PATH [PATH ...] Create new archive @@ -43,14 +43,14 @@ optional arguments: --do-not-cross-mountpoints do not cross mount points --numeric-owner only store numeric user and group identifiers -.. _usage_darc_extract: +.. _usage_attic_extract: -darc extract -~~~~~~~~~~~~ +attic extract +~~~~~~~~~~~~~ :: -usage: darc extract [-h] [-v] [-e PATTERN] [--numeric-owner] - ARCHIVE [PATH [PATH ...]] +usage: attic extract [-h] [-v] [-e PATTERN] [--numeric-owner] + ARCHIVE [PATH [PATH ...]] Extract archive contents @@ -64,13 +64,13 @@ optional arguments: -e PATTERN, --exclude PATTERN exclude paths matching PATTERN --numeric-owner only obey numeric user and group identifiers -.. _usage_darc_delete: +.. _usage_attic_delete: -darc delete -~~~~~~~~~~~ +attic delete +~~~~~~~~~~~~ :: -usage: darc delete [-h] [-v] ARCHIVE +usage: attic delete [-h] [-v] ARCHIVE Delete archive @@ -80,15 +80,15 @@ positional arguments: optional arguments: -h, --help show this help message and exit -v, --verbose verbose output -.. _usage_darc_prune: +.. _usage_attic_prune: -darc prune -~~~~~~~~~~ +attic prune +~~~~~~~~~~~ :: -usage: darc prune [-h] [-v] [-H HOURLY] [-d DAILY] [-w WEEKLY] [-m MONTHLY] - [-y YEARLY] [-p PREFIX] - REPOSITORY +usage: attic prune [-h] [-v] [-H HOURLY] [-d DAILY] [-w WEEKLY] [-m MONTHLY] + [-y YEARLY] [-p PREFIX] + REPOSITORY Prune repository archives according to specified rules @@ -110,13 +110,13 @@ optional arguments: number of yearly archives to keep -p PREFIX, --prefix PREFIX only consider archive names starting with this prefix -.. _usage_darc_verify: +.. _usage_attic_verify: -darc verify -~~~~~~~~~~~ +attic verify +~~~~~~~~~~~~ :: -usage: darc verify [-h] [-v] [-e PATTERN] ARCHIVE [PATH [PATH ...]] +usage: attic verify [-h] [-v] [-e PATTERN] ARCHIVE [PATH [PATH ...]] Verify archive consistency @@ -129,13 +129,13 @@ optional arguments: -v, --verbose verbose output -e PATTERN, --exclude PATTERN exclude paths matching PATTERN -.. _usage_darc_change-passphrase: +.. _usage_attic_change-passphrase: -darc change-passphrase -~~~~~~~~~~~-~~~~~~~~~~ +attic change-passphrase +~~~~~~~~~~~~-~~~~~~~~~~ :: -usage: darc change-passphrase [-h] [-v] repository +usage: attic change-passphrase [-h] [-v] repository Change passphrase on repository key file diff --git a/scripts/attic b/scripts/attic new file mode 100644 index 000000000..01ace036e --- /dev/null +++ b/scripts/attic @@ -0,0 +1,4 @@ +#!/usr/bin/env python +from attic.archiver import main +main() + diff --git a/scripts/darc b/scripts/darc deleted file mode 100644 index 1b1b793f7..000000000 --- a/scripts/darc +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env python -from darc.archiver import main -main() - diff --git a/setup.py b/setup.py index 0c403b5bc..c65e6e5be 100644 --- a/setup.py +++ b/setup.py @@ -2,11 +2,11 @@ import os import sys from glob import glob -import darc +import attic min_python = (3, 2) if sys.version_info < min_python: - print("Darc requires Python %d.%d or later" % min_python) + print("Attic requires Python %d.%d or later" % min_python) sys.exit(1) try: @@ -15,8 +15,8 @@ except ImportError: from distutils.core import setup, Extension from distutils.command.sdist import sdist -chunker_source = 'darc/chunker.pyx' -hashindex_source = 'darc/hashindex.pyx' +chunker_source = 'attic/chunker.pyx' +hashindex_source = 'attic/hashindex.pyx' try: from Cython.Distutils import build_ext @@ -24,13 +24,13 @@ try: class Sdist(sdist): def __init__(self, *args, **kwargs): - for src in glob('darc/*.pyx'): - cython_compiler.compile(glob('darc/*.pyx'), + for src in glob('attic/*.pyx'): + cython_compiler.compile(glob('attic/*.pyx'), cython_compiler.default_options) sdist.__init__(self, *args, **kwargs) def make_distribution(self): - self.filelist.extend(['darc/chunker.c', 'darc/_chunker.c', 'darc/hashindex.c', 'darc/_hashindex.c']) + self.filelist.extend(['attic/chunker.c', 'attic/_chunker.c', 'attic/hashindex.c', 'attic/_hashindex.c']) super(Sdist, self).make_distribution() except ImportError: @@ -42,18 +42,18 @@ except ImportError: hashindex_source = hashindex_source.replace('.pyx', '.c') from distutils.command.build_ext import build_ext if not os.path.exists(chunker_source) or not os.path.exists(hashindex_source): - raise ImportError('The GIT version of darc needs Cython. Install Cython or use a released version') + raise ImportError('The GIT version of attic needs Cython. Install Cython or use a released version') with open('README.rst', 'r') as fd: long_description = fd.read() setup( - name='darc', - version=darc.__release__, + name='Attic', + version=attic.__release__, author='Jonas Borgström', author_email='jonas@borgstrom.se', - url='http://github.com/jborg/darc/', - description='Deduplicating ARChiver written in Python', + url='http://github.com/jborg/attic/', + description='Deduplicated backups', long_description=long_description, license='BSD', platforms=['Linux', 'MacOS X'], @@ -68,12 +68,12 @@ setup( 'Topic :: Security :: Cryptography', 'Topic :: System :: Archiving :: Backup', ], - packages=['darc', 'darc.testsuite'], - scripts=['scripts/darc'], + packages=['attic', 'attic.testsuite'], + scripts=['scripts/attic'], cmdclass={'build_ext': build_ext, 'sdist': Sdist}, ext_modules=[ - Extension('darc.chunker', [chunker_source]), - Extension('darc.hashindex', [hashindex_source]) + Extension('attic.chunker', [chunker_source]), + Extension('attic.hashindex', [hashindex_source]) ], install_requires=['msgpack-python'] ) diff --git a/tox.ini b/tox.ini index 8258bd0de..0b3f990fc 100644 --- a/tox.ini +++ b/tox.ini @@ -4,4 +4,4 @@ envlist = py32, py33 [testenv] # Change dir to avoid import problem changedir = docs -commands = {envpython} -m darc.testsuite.run -bv [] +commands = {envpython} -m attic.testsuite.run -bv []