Browse Source

Dropping support for Attic.

master
Dan Helfman 3 years ago
parent
commit
40a215802f

+ 6
- 0
NEWS View File

@@ -1,3 +1,9 @@
1
+1.0.0
2
+
3
+ * Attic is no longer supported, as there hasn't been any recent development on it.
4
+   This will allow faster iteration on Borg-specific configuration.
5
+ * Project renamed from atticmatic to borgmatic.
6
+
1 7
 0.1.8
2 8
 
3 9
  * Fix for handling of spaces in source_directories which resulted in backup up everything.

+ 24
- 37
README.md View File

@@ -1,9 +1,8 @@
1
-title: Atticmatic
1
+title: Borgmatic
2 2
 
3 3
 ## Overview
4 4
 
5
-atticmatic is a simple Python wrapper script for the
6
-[Attic](https://attic-backup.org/) and
5
+borgmatic (formerly atticmatic) is a simple Python wrapper script for the
7 6
 [Borg](https://borgbackup.readthedocs.org/en/stable/) backup software that
8 7
 initiates a backup, prunes any old backups according to a retention policy,
9 8
 and validates backups for consistency. The script supports specifying your
@@ -19,7 +18,7 @@ Here's an example config file:
19 18
 source_directories: /home /etc /var/log/syslog*
20 19
 
21 20
 # Path to local or remote backup repository.
22
-repository: user@backupserver:sourcehostname.attic
21
+repository: user@backupserver:sourcehostname.borg
23 22
 
24 23
 [retention]
25 24
 # Retention policy for how many backups to keep in each category.
@@ -35,37 +34,30 @@ checks: repository archives
35 34
 Additionally, exclude patterns can be specified in a separate excludes config
36 35
 file, one pattern per line.
37 36
 
38
-atticmatic is hosted at <https://torsion.org/atticmatic> with [source code
39
-available](https://torsion.org/hg/atticmatic). It's also mirrored on
40
-[GitHub](https://github.com/witten/atticmatic) and
41
-[BitBucket](https://bitbucket.org/dhelfman/atticmatic) for convenience.
37
+borgmatic is hosted at <https://torsion.org/borgmatic> with [source code
38
+available](https://torsion.org/hg/borgmatic). It's also mirrored on
39
+[GitHub](https://github.com/witten/borgmatic) and
40
+[BitBucket](https://bitbucket.org/dhelfman/borgmatic) for convenience.
42 41
 
43 42
 
44 43
 ## Setup
45 44
 
46
-To get up and running, follow the [Attic Quick
47
-Start](https://attic-backup.org/quickstart.html) or the [Borg Quick
48
-Start](https://borgbackup.readthedocs.org/en/latest/quickstart.html) to create a
49
-repository on a local or remote host. Note that if you plan to run atticmatic
50
-on a schedule with cron, and you encrypt your attic repository with a
51
-passphrase instead of a key file, you'll need to set the atticmatic
45
+To get up and running, follow the [Borg Quick
46
+Start](https://borgbackup.readthedocs.org/en/latest/quickstart.html) to create
47
+a repository on a local or remote host. Note that if you plan to run
48
+borgmatic on a schedule with cron, and you encrypt your Borg repository with
49
+a passphrase instead of a key file, you'll need to set the borgmatic
52 50
 `encryption_passphrase` configuration variable. See the repository encryption
53 51
 section of the Quick Start for more info.
54 52
 
55 53
 If the repository is on a remote host, make sure that your local root user has
56 54
 key-based ssh access to the desired user account on the remote host.
57 55
 
58
-To install atticmatic, run the following command to download and install it:
56
+To install borgmatic, run the following command to download and install it:
59 57
 
60
-    sudo pip install --upgrade atticmatic
58
+    sudo pip install --upgrade borgmatic
61 59
 
62
-If you are using Attic, copy the following configuration files:
63
-
64
-    sudo cp sample/atticmatic.cron /etc/cron.d/atticmatic
65
-    sudo mkdir /etc/atticmatic/
66
-    sudo cp sample/config sample/excludes /etc/atticmatic/
67
-
68
-If you are using Borg, copy the files like this instead:
60
+Then, copy the following configuration files:
69 61
 
70 62
     sudo cp sample/borgmatic.cron /etc/cron.d/borgmatic
71 63
     sudo mkdir /etc/borgmatic/
@@ -76,14 +68,9 @@ Lastly, modify the /etc files with your desired configuration.
76 68
 
77 69
 ## Usage
78 70
 
79
-You can run atticmatic and start a backup simply by invoking it without
71
+You can run borgmatic and start a backup simply by invoking it without
80 72
 arguments:
81 73
 
82
-    atticmatic
83
-
84
-Or, if you're using Borg, use this command instead to make use of the Borg
85
-backend:
86
-
87 74
     borgmatic
88 75
 
89 76
 This will also prune any old backups as per the configured retention policy,
@@ -93,15 +80,15 @@ By default, the backup will proceed silently except in the case of errors. But
93 80
 if you'd like to to get additional information about the progress of the
94 81
 backup as it proceeds, use the verbosity option:
95 82
 
96
-    atticmatic --verbosity 1
83
+    borgmatic --verbosity 1
97 84
 
98 85
 Or, for even more progress spew:
99 86
 
100
-    atticmatic --verbosity 2
87
+    borgmatic --verbosity 2
101 88
 
102 89
 If you'd like to see the available command-line arguments, view the help:
103 90
 
104
-    atticmatic --help
91
+    borgmatic --help
105 92
 
106 93
 
107 94
 ## Running tests
@@ -119,12 +106,12 @@ Then, to actually run tests, run:
119 106
 
120 107
 ### Broken pipe with remote repository
121 108
 
122
-When running atticmatic on a large remote repository, you may receive errors
123
-like the following, particularly while "attic check" is validating backups for
109
+When running borgmatic on a large remote repository, you may receive errors
110
+like the following, particularly while "borg check" is validating backups for
124 111
 consistency:
125 112
 
126 113
     Write failed: Broken pipe
127
-    attic: Error: Connection closed by remote host
114
+    borg: Error: Connection closed by remote host
128 115
 
129 116
 This error can be caused by an ssh timeout, which you can rectify by adding
130 117
 the following to the ~/.ssh/config file on the client:
@@ -138,8 +125,8 @@ backups.
138 125
 
139 126
 ## Issues and feedback
140 127
 
141
-Got an issue or an idea for a feature enhancement? Check out the [atticmatic
142
-issue tracker](https://tree.taiga.io/project/witten-atticmatic/issues). In
128
+Got an issue or an idea for a feature enhancement? Check out the [borgmatic
129
+issue tracker](https://tree.taiga.io/project/witten-borgmatic/issues). In
143 130
 order to create a new issue or comment on an issue, you'll need to [login
144 131
 first](https://tree.taiga.io/login).
145 132
 

+ 0
- 14
atticmatic/backends/attic.py View File

@@ -1,14 +0,0 @@
1
-from functools import partial
2
-
3
-from atticmatic.backends import shared
4
-
5
-# An atticmatic backend that supports Attic for actually handling backups.
6
-
7
-COMMAND = 'attic'
8
-CONFIG_FORMAT = shared.CONFIG_FORMAT
9
-
10
-
11
-initialize = partial(shared.initialize, command=COMMAND)
12
-create_archive = partial(shared.create_archive, command=COMMAND)
13
-prune_archives = partial(shared.prune_archives, command=COMMAND)
14
-check_archives = partial(shared.check_archives, command=COMMAND)

+ 0
- 41
atticmatic/backends/borg.py View File

@@ -1,41 +0,0 @@
1
-from functools import partial
2
-
3
-from atticmatic.config import Section_format, option
4
-from atticmatic.backends import shared
5
-
6
-# An atticmatic backend that supports Borg for actually handling backups.
7
-
8
-COMMAND = 'borg'
9
-CONFIG_FORMAT = (
10
-    Section_format(
11
-        'location',
12
-        (
13
-            option('source_directories'),
14
-            option('one_file_system', value_type=bool, required=False),
15
-            option('repository'),
16
-        ),
17
-    ),
18
-    Section_format(
19
-        'storage',
20
-        (
21
-            option('encryption_passphrase', required=False),
22
-            option('compression', required=False),
23
-            option('umask', required=False),
24
-        ),
25
-    ),
26
-    shared.CONFIG_FORMAT[2],  # retention
27
-    Section_format(
28
-        'consistency',
29
-        (
30
-            option('checks', required=False),
31
-            option('check_last', required=False),
32
-        ),
33
-    )
34
-)
35
-
36
-
37
-initialize = partial(shared.initialize, command=COMMAND)
38
-
39
-create_archive = partial(shared.create_archive, command=COMMAND)
40
-prune_archives = partial(shared.prune_archives, command=COMMAND)
41
-check_archives = partial(shared.check_archives, command=COMMAND)

+ 0
- 75
atticmatic/command.py View File

@@ -1,75 +0,0 @@
1
-from __future__ import print_function
2
-from argparse import ArgumentParser
3
-from importlib import import_module
4
-import os
5
-from subprocess import CalledProcessError
6
-import sys
7
-
8
-from atticmatic.config import parse_configuration
9
-
10
-
11
-DEFAULT_CONFIG_FILENAME_PATTERN = '/etc/{}/config'
12
-DEFAULT_EXCLUDES_FILENAME_PATTERN = '/etc/{}/excludes'
13
-
14
-
15
-def parse_arguments(command_name, *arguments):
16
-    '''
17
-    Given the name of the command with which this script was invoked and command-line arguments,
18
-    parse the arguments and return them as an ArgumentParser instance. Use the command name to
19
-    determine the default configuration and excludes paths.
20
-    '''
21
-    config_filename_default = DEFAULT_CONFIG_FILENAME_PATTERN.format(command_name)
22
-    excludes_filename_default = DEFAULT_EXCLUDES_FILENAME_PATTERN.format(command_name)
23
-
24
-    parser = ArgumentParser()
25
-    parser.add_argument(
26
-        '-c', '--config',
27
-        dest='config_filename',
28
-        default=config_filename_default,
29
-        help='Configuration filename',
30
-    )
31
-    parser.add_argument(
32
-        '--excludes',
33
-        dest='excludes_filename',
34
-        default=excludes_filename_default if os.path.exists(excludes_filename_default) else None,
35
-        help='Excludes filename',
36
-    )
37
-    parser.add_argument(
38
-        '-v', '--verbosity',
39
-        type=int,
40
-        help='Display verbose progress (1 for some, 2 for lots)',
41
-    )
42
-
43
-    return parser.parse_args(arguments)
44
-
45
-
46
-def load_backend(command_name):
47
-    '''
48
-    Given the name of the command with which this script was invoked, return the corresponding
49
-    backend module responsible for actually dealing with backups.
50
-    '''
51
-    backend_name = {
52
-        'atticmatic': 'attic',
53
-        'borgmatic': 'borg',
54
-    }.get(command_name, 'attic')
55
-
56
-    return import_module('atticmatic.backends.{}'.format(backend_name))
57
-
58
-
59
-def main():
60
-    try:
61
-        command_name = os.path.basename(sys.argv[0])
62
-        args = parse_arguments(command_name, *sys.argv[1:])
63
-        backend = load_backend(command_name)
64
-        config = parse_configuration(args.config_filename, backend.CONFIG_FORMAT)
65
-        repository = config.location['repository']
66
-
67
-        backend.initialize(config.storage)
68
-        backend.create_archive(
69
-            args.excludes_filename, args.verbosity, config.storage, **config.location
70
-        )
71
-        backend.prune_archives(args.verbosity, repository, config.retention)
72
-        backend.check_archives(args.verbosity, repository, config.consistency)
73
-    except (ValueError, IOError, CalledProcessError) as error:
74
-        print(error, file=sys.stderr)
75
-        sys.exit(1)

+ 0
- 0
atticmatic/tests/unit/__init__.py View File


+ 0
- 0
atticmatic/tests/unit/backends/__init__.py View File


+ 0
- 33
atticmatic/tests/unit/test_command.py View File

@@ -1,33 +0,0 @@
1
-from flexmock import flexmock
2
-
3
-from atticmatic import command as module
4
-
5
-
6
-def test_load_backend_with_atticmatic_command_should_return_attic_backend():
7
-    backend = flexmock()
8
-    (
9
-        flexmock(module).should_receive('import_module').with_args('atticmatic.backends.attic')
10
-        .and_return(backend).once()
11
-    )
12
-
13
-    assert module.load_backend('atticmatic') == backend
14
-
15
-
16
-def test_load_backend_with_unknown_command_should_return_attic_backend():
17
-    backend = flexmock()
18
-    (
19
-        flexmock(module).should_receive('import_module').with_args('atticmatic.backends.attic')
20
-        .and_return(backend).once()
21
-    )
22
-
23
-    assert module.load_backend('unknownmatic') == backend
24
-
25
-
26
-def test_load_backend_with_borgmatic_command_should_return_borg_backend():
27
-    backend = flexmock()
28
-    (
29
-        flexmock(module).should_receive('import_module').with_args('atticmatic.backends.borg')
30
-        .and_return(backend).once()
31
-    )
32
-
33
-    assert module.load_backend('borgmatic') == backend

atticmatic/__init__.py → borgmatic/__init__.py View File


atticmatic/backends/shared.py → borgmatic/borg.py View File

@@ -6,52 +6,16 @@ import subprocess
6 6
 from glob import glob
7 7
 from itertools import chain
8 8
 
9
-from atticmatic.config import Section_format, option
10
-from atticmatic.verbosity import VERBOSITY_SOME, VERBOSITY_LOTS
9
+from borgmatic.verbosity import VERBOSITY_SOME, VERBOSITY_LOTS
11 10
 
12 11
 
13
-# Common backend functionality shared by Attic and Borg. As the two backup
14
-# commands diverge, these shared functions will likely need to be replaced
15
-# with non-shared functions within atticmatic.backends.attic and
16
-# atticmatic.backends.borg.
12
+# Integration with Borg for actually handling backups.
17 13
 
18 14
 
19
-CONFIG_FORMAT = (
20
-    Section_format(
21
-        'location',
22
-        (
23
-            option('source_directories'),
24
-            option('repository'),
25
-        ),
26
-    ),
27
-    Section_format(
28
-        'storage',
29
-        (
30
-            option('encryption_passphrase', required=False),
31
-        ),
32
-    ),
33
-    Section_format(
34
-        'retention',
35
-        (
36
-            option('keep_within', required=False),
37
-            option('keep_hourly', int, required=False),
38
-            option('keep_daily', int, required=False),
39
-            option('keep_weekly', int, required=False),
40
-            option('keep_monthly', int, required=False),
41
-            option('keep_yearly', int, required=False),
42
-            option('prefix', required=False),
43
-        ),
44
-    ),
45
-    Section_format(
46
-        'consistency',
47
-        (
48
-            option('checks', required=False),
49
-        ),
50
-    )
51
-)
15
+COMMAND = 'borg'
52 16
 
53 17
 
54
-def initialize(storage_config, command):
18
+def initialize(storage_config, command=COMMAND):
55 19
     passphrase = storage_config.get('encryption_passphrase')
56 20
 
57 21
     if passphrase:
@@ -59,7 +23,7 @@ def initialize(storage_config, command):
59 23
 
60 24
 
61 25
 def create_archive(
62
-    excludes_filename, verbosity, storage_config, source_directories, repository, command,
26
+    excludes_filename, verbosity, storage_config, source_directories, repository, command=COMMAND,
63 27
     one_file_system=None
64 28
 ):
65 29
     '''
@@ -115,7 +79,7 @@ def _make_prune_flags(retention_config):
115 79
     )
116 80
 
117 81
 
118
-def prune_archives(verbosity, repository, retention_config, command):
82
+def prune_archives(verbosity, repository, retention_config, command=COMMAND):
119 83
     '''
120 84
     Given a verbosity flag, a local or remote repository path, a retention config dict, and a
121 85
     command to run, prune attic archives according the the retention policy specified in that
@@ -191,7 +155,7 @@ def _make_check_flags(checks, check_last=None):
191 155
     ) + last_flag
192 156
 
193 157
 
194
-def check_archives(verbosity, repository, consistency_config, command):
158
+def check_archives(verbosity, repository, consistency_config, command=COMMAND):
195 159
     '''
196 160
     Given a verbosity flag, a local or remote repository path, a consistency config dict, and a
197 161
     command to run, check the contained attic archives for consistency.

+ 57
- 0
borgmatic/command.py View File

@@ -0,0 +1,57 @@
1
+from __future__ import print_function
2
+from argparse import ArgumentParser
3
+import os
4
+from subprocess import CalledProcessError
5
+import sys
6
+
7
+from borgmatic import borg
8
+from borgmatic.config import parse_configuration, CONFIG_FORMAT
9
+
10
+
11
+DEFAULT_CONFIG_FILENAME = '/etc/borgmatic/config'
12
+DEFAULT_EXCLUDES_FILENAME = '/etc/borgmatic/excludes'
13
+
14
+
15
+def parse_arguments(*arguments):
16
+    '''
17
+    Given the name of the command with which this script was invoked and command-line arguments,
18
+    parse the arguments and return them as an ArgumentParser instance. Use the command name to
19
+    determine the default configuration and excludes paths.
20
+    '''
21
+    parser = ArgumentParser()
22
+    parser.add_argument(
23
+        '-c', '--config',
24
+        dest='config_filename',
25
+        default=DEFAULT_CONFIG_FILENAME,
26
+        help='Configuration filename',
27
+    )
28
+    parser.add_argument(
29
+        '--excludes',
30
+        dest='excludes_filename',
31
+        default=DEFAULT_EXCLUDES_FILENAME if os.path.exists(DEFAULT_EXCLUDES_FILENAME) else None,
32
+        help='Excludes filename',
33
+    )
34
+    parser.add_argument(
35
+        '-v', '--verbosity',
36
+        type=int,
37
+        help='Display verbose progress (1 for some, 2 for lots)',
38
+    )
39
+
40
+    return parser.parse_args(arguments)
41
+
42
+
43
+def main():
44
+    try:
45
+        args = parse_arguments(*sys.argv[1:])
46
+        config = parse_configuration(args.config_filename, CONFIG_FORMAT)
47
+        repository = config.location['repository']
48
+
49
+        borg.initialize(config.storage)
50
+        borg.create_archive(
51
+            args.excludes_filename, args.verbosity, config.storage, **config.location
52
+        )
53
+        borg.prune_archives(args.verbosity, repository, config.retention)
54
+        borg.check_archives(args.verbosity, repository, config.consistency)
55
+    except (ValueError, IOError, CalledProcessError) as error:
56
+        print(error, file=sys.stderr)
57
+        sys.exit(1)

atticmatic/config.py → borgmatic/config.py View File

@@ -20,6 +20,45 @@ def option(name, value_type=str, required=True):
20 20
     return Config_option(name, value_type, required)
21 21
 
22 22
 
23
+CONFIG_FORMAT = (
24
+    Section_format(
25
+        'location',
26
+        (
27
+            option('source_directories'),
28
+            option('one_file_system', value_type=bool, required=False),
29
+            option('repository'),
30
+        ),
31
+    ),
32
+    Section_format(
33
+        'storage',
34
+        (
35
+            option('encryption_passphrase', required=False),
36
+            option('compression', required=False),
37
+            option('umask', required=False),
38
+        ),
39
+    ),
40
+    Section_format(
41
+        'retention',
42
+        (
43
+            option('keep_within', required=False),
44
+            option('keep_hourly', int, required=False),
45
+            option('keep_daily', int, required=False),
46
+            option('keep_weekly', int, required=False),
47
+            option('keep_monthly', int, required=False),
48
+            option('keep_yearly', int, required=False),
49
+            option('prefix', required=False),
50
+        ),
51
+    ),
52
+    Section_format(
53
+        'consistency',
54
+        (
55
+            option('checks', required=False),
56
+            option('check_last', required=False),
57
+        ),
58
+    )
59
+)
60
+
61
+
23 62
 def validate_configuration_format(parser, config_format):
24 63
     '''
25 64
     Given an open RawConfigParser and an expected config file format, validate that the parsed

atticmatic/backends/__init__.py → borgmatic/tests/__init__.py View File


atticmatic/tests/builtins.py → borgmatic/tests/builtins.py View File


atticmatic/tests/__init__.py → borgmatic/tests/integration/__init__.py View File


atticmatic/tests/integration/test_command.py → borgmatic/tests/integration/test_command.py View File

@@ -4,26 +4,23 @@ import sys
4 4
 from flexmock import flexmock
5 5
 import pytest
6 6
 
7
-from atticmatic import command as module
8
-
9
-
10
-COMMAND_NAME = 'foomatic'
7
+from borgmatic import command as module
11 8
 
12 9
 
13 10
 def test_parse_arguments_with_no_arguments_uses_defaults():
14 11
     flexmock(os.path).should_receive('exists').and_return(True)
15 12
 
16
-    parser = module.parse_arguments(COMMAND_NAME)
13
+    parser = module.parse_arguments()
17 14
 
18
-    assert parser.config_filename == module.DEFAULT_CONFIG_FILENAME_PATTERN.format(COMMAND_NAME)
19
-    assert parser.excludes_filename == module.DEFAULT_EXCLUDES_FILENAME_PATTERN.format(COMMAND_NAME)
15
+    assert parser.config_filename == module.DEFAULT_CONFIG_FILENAME
16
+    assert parser.excludes_filename == module.DEFAULT_EXCLUDES_FILENAME
20 17
     assert parser.verbosity == None
21 18
 
22 19
 
23 20
 def test_parse_arguments_with_filename_arguments_overrides_defaults():
24 21
     flexmock(os.path).should_receive('exists').and_return(True)
25 22
 
26
-    parser = module.parse_arguments(COMMAND_NAME, '--config', 'myconfig', '--excludes', 'myexcludes')
23
+    parser = module.parse_arguments('--config', 'myconfig', '--excludes', 'myexcludes')
27 24
 
28 25
     assert parser.config_filename == 'myconfig'
29 26
     assert parser.excludes_filename == 'myexcludes'
@@ -33,9 +30,9 @@ def test_parse_arguments_with_filename_arguments_overrides_defaults():
33 30
 def test_parse_arguments_with_missing_default_excludes_file_sets_filename_to_none():
34 31
     flexmock(os.path).should_receive('exists').and_return(False)
35 32
 
36
-    parser = module.parse_arguments(COMMAND_NAME)
33
+    parser = module.parse_arguments()
37 34
 
38
-    assert parser.config_filename == module.DEFAULT_CONFIG_FILENAME_PATTERN.format(COMMAND_NAME)
35
+    assert parser.config_filename == module.DEFAULT_CONFIG_FILENAME
39 36
     assert parser.excludes_filename == None
40 37
     assert parser.verbosity == None
41 38
 
@@ -43,9 +40,9 @@ def test_parse_arguments_with_missing_default_excludes_file_sets_filename_to_non
43 40
 def test_parse_arguments_with_missing_overridden_excludes_file_retains_filename():
44 41
     flexmock(os.path).should_receive('exists').and_return(False)
45 42
 
46
-    parser = module.parse_arguments(COMMAND_NAME, '--excludes', 'myexcludes')
43
+    parser = module.parse_arguments('--excludes', 'myexcludes')
47 44
 
48
-    assert parser.config_filename == module.DEFAULT_CONFIG_FILENAME_PATTERN.format(COMMAND_NAME)
45
+    assert parser.config_filename == module.DEFAULT_CONFIG_FILENAME
49 46
     assert parser.excludes_filename == 'myexcludes'
50 47
     assert parser.verbosity == None
51 48
 
@@ -53,10 +50,10 @@ def test_parse_arguments_with_missing_overridden_excludes_file_retains_filename(
53 50
 def test_parse_arguments_with_verbosity_flag_overrides_default():
54 51
     flexmock(os.path).should_receive('exists').and_return(True)
55 52
 
56
-    parser = module.parse_arguments(COMMAND_NAME, '--verbosity', '1')
53
+    parser = module.parse_arguments('--verbosity', '1')
57 54
 
58
-    assert parser.config_filename == module.DEFAULT_CONFIG_FILENAME_PATTERN.format(COMMAND_NAME)
59
-    assert parser.excludes_filename == module.DEFAULT_EXCLUDES_FILENAME_PATTERN.format(COMMAND_NAME)
55
+    assert parser.config_filename == module.DEFAULT_CONFIG_FILENAME
56
+    assert parser.excludes_filename == module.DEFAULT_EXCLUDES_FILENAME
60 57
     assert parser.verbosity == 1
61 58
 
62 59
 
@@ -67,6 +64,6 @@ def test_parse_arguments_with_invalid_arguments_exits():
67 64
 
68 65
     try:
69 66
         with pytest.raises(SystemExit):
70
-            module.parse_arguments(COMMAND_NAME, '--posix-me-harder')
67
+            module.parse_arguments('--posix-me-harder')
71 68
     finally:
72 69
         sys.stderr = original_stderr

atticmatic/tests/integration/test_config.py → borgmatic/tests/integration/test_config.py View File

@@ -8,7 +8,7 @@ except ImportError:
8 8
 from collections import OrderedDict
9 9
 import string
10 10
 
11
-from atticmatic import config as module
11
+from borgmatic import config as module
12 12
 
13 13
 
14 14
 def test_parse_section_options_with_punctuation_should_return_section_options():

atticmatic/tests/integration/test_version.py → borgmatic/tests/integration/test_version.py View File


atticmatic/tests/integration/__init__.py → borgmatic/tests/unit/__init__.py View File


atticmatic/tests/unit/backends/test_shared.py → borgmatic/tests/unit/test_borg.py View File

@@ -4,9 +4,9 @@ import os
4 4
 
5 5
 from flexmock import flexmock
6 6
 
7
-from atticmatic.backends import shared as module
8
-from atticmatic.tests.builtins import builtins_mock
9
-from atticmatic.verbosity import VERBOSITY_SOME, VERBOSITY_LOTS
7
+from borgmatic import borg as module
8
+from borgmatic.tests.builtins import builtins_mock
9
+from borgmatic.verbosity import VERBOSITY_SOME, VERBOSITY_LOTS
10 10
 
11 11
 
12 12
 def test_initialize_with_passphrase_should_set_environment():

atticmatic/tests/unit/test_config.py → borgmatic/tests/unit/test_config.py View File

@@ -3,7 +3,7 @@ from collections import OrderedDict
3 3
 from flexmock import flexmock
4 4
 import pytest
5 5
 
6
-from atticmatic import config as module
6
+from borgmatic import config as module
7 7
 
8 8
 
9 9
 def test_option_should_create_config_option():

atticmatic/verbosity.py → borgmatic/verbosity.py View File


+ 0
- 3
sample/atticmatic.cron View File

@@ -1,3 +0,0 @@
1
-# You can drop this file into /etc/cron.d/ to run atticmatic nightly.
2
-
3
-0 3 * * * root PATH=$PATH:/usr/local/bin /usr/local/bin/atticmatic

+ 7
- 8
sample/config View File

@@ -8,22 +8,21 @@ source_directories: /home /etc /var/log/syslog*
8 8
 #one_file_system: True
9 9
 
10 10
 # Path to local or remote repository.
11
-repository: user@backupserver:sourcehostname.attic
11
+repository: user@backupserver:sourcehostname.borg
12 12
 
13 13
 [storage]
14 14
 # Passphrase to unlock the encryption key with. Only use on repositories that
15 15
 # were initialized with passphrase/repokey encryption.
16 16
 #encryption_passphrase: foo
17
-# For Borg only, you can specify the type of compression to use when creating
18
-# archives. See https://borgbackup.readthedocs.org/en/stable/usage.html#borg-create
17
+# Type of compression to use when creating archives. See
18
+# https://borgbackup.readthedocs.org/en/stable/usage.html#borg-create
19 19
 # for details. Defaults to no compression.
20 20
 #compression: lz4
21
-# For Borg only, you can specify the umask to be used for borg create.
21
+# Umask to be used for borg create.
22 22
 #umask: 0740
23 23
 
24 24
 [retention]
25 25
 # Retention policy for how many backups to keep in each category. See
26
-# https://attic-backup.org/usage.html#attic-prune or
27 26
 # https://borgbackup.readthedocs.org/en/stable/usage.html#borg-prune for details.
28 27
 #keep_within: 3H
29 28
 #keep_hourly: 24
@@ -36,8 +35,8 @@ keep_yearly: 1
36 35
 [consistency]
37 36
 # Space-separated list of consistency checks to run: "repository", "archives",
38 37
 # or both. Defaults to both. Set to "disabled" to disable all consistency
39
-# checks. See https://attic-backup.org/usage.html#attic-check or
40
-# https://borgbackup.readthedocs.org/en/stable/usage.html#borg-check for details.
38
+# checks. See https://borgbackup.readthedocs.org/en/stable/usage.html#borg-check
39
+# for details.
41 40
 checks: repository archives
42
-# For Borg only, you can restrict the number of checked archives to the last n.
41
+# Restrict the number of checked archives to the last n.
43 42
 #check_last: 3

+ 9
- 7
setup.py View File

@@ -1,17 +1,17 @@
1 1
 from setuptools import setup, find_packages
2 2
 
3 3
 
4
-VERSION = '0.1.8'
4
+VERSION = '1.0.0'
5 5
 
6 6
 
7 7
 setup(
8
-    name='atticmatic',
8
+    name='borgmatic',
9 9
     version=VERSION,
10
-    description='A wrapper script for Attic/Borg backup software that creates and prunes backups',
10
+    description='A wrapper script for Borg backup software that creates and prunes backups',
11 11
     author='Dan Helfman',
12 12
     author_email='witten@torsion.org',
13
-    url='https://torsion.org/atticmatic',
14
-    download_url='https://torsion.org/hg/atticmatic/archive/%s.tar.gz' % VERSION,
13
+    url='https://torsion.org/borgmatic',
14
+    download_url='https://torsion.org/hg/borgmatic/archive/%s.tar.gz' % VERSION,
15 15
     classifiers=(
16 16
         'Development Status :: 5 - Production/Stable',
17 17
         'Environment :: Console',
@@ -24,10 +24,12 @@ setup(
24 24
     packages=find_packages(),
25 25
     entry_points={
26 26
         'console_scripts': [
27
-            'atticmatic = atticmatic.command:main',
28
-            'borgmatic = atticmatic.command:main',
27
+            'borgmatic = borgmatic.command:main',
29 28
         ]
30 29
     },
30
+    obsoletes=(
31
+        'atticmatic',
32
+    ),
31 33
     tests_require=(
32 34
         'flexmock',
33 35
         'pytest',

Loading…
Cancel
Save