diff --git a/assimilate/command.py b/assimilate/command.py index 4b5bd38..398bda1 100644 --- a/assimilate/command.py +++ b/assimilate/command.py @@ -2216,6 +2216,11 @@ def run(cls, command, args, settings, options): cmd="repo-create", assimilate_opts = cmdline ) + out = (borg.stderr or borg.stdout).rstrip() + if out: + out = out.replace('borg repo-space', 'assimilate repo-space') + out = out.replace('borg key export -r REPOSITORY', 'assimilate borg key export -r @repo') + output(out) if borg.status: return borg.status @@ -2234,6 +2239,7 @@ def run(cls, command, args, settings, options): borg_opts = [f"--reserve={space}"], assimilate_opts = cmdline ) + out = borg.stderr or borg.stdout if out: output(out.rstrip()) diff --git a/assimilate/overdue.py b/assimilate/overdue.py index ffe806a..d487e07 100644 --- a/assimilate/overdue.py +++ b/assimilate/overdue.py @@ -193,7 +193,7 @@ def get_remote_data(name, host, config, cmd): display(f"\n{name}:") config = ['--config', config] if config else [] try: - ssh = Run(['ssh', host] + config + cmd.split() + ['--nt'], 'sOEW1') + ssh = Run(['ssh', host] + config + cmd.split() + ['--nt', '--local'], 'sOEW1') for repo_data in nt.loads(ssh.stdout, top=list): if 'description' not in repo_data: repo_data['description'] = repo_data.get('host', '') diff --git a/assimilate/preferences.py b/assimilate/preferences.py index 0687abb..66e39f2 100644 --- a/assimilate/preferences.py +++ b/assimilate/preferences.py @@ -85,8 +85,16 @@ command aliases: repo-list: - archives + - a - recent --last=20 - list: paths + list: + - paths + - l + - ln -N + - ls -S + - ld -D + overdue: od + umount: unmount # composite log file logging: @@ -109,20 +117,17 @@ overdue: max age: 36 h message: {description}: {updated} ago{locked: (currently active)}{overdue: — PAST DUE} - # repositories: - # # local - # cache@❬host❭ (/home/❬user❭): - # config: cache - # max age: 15m - # home@❬host❭ (/home/❬user❭): - # config: home2 - # root@❬host❭ (/): - # config: root - # sentinel dir: ~root/.local/share/assimilate - # - # # remote - # ❬remote-host❭: - # host: ❬remote-host❭ + repositories: + # local + cache@❬host❭ (/home/❬user❭): + config: cache + max age: 15m + home@❬host❭ (/home/❬user❭): + config: home + + # remote + ❬remote-host❭: + host: ❬remote-host❭ """, strip_nl='l') # Root settings {{{3 @@ -187,13 +192,15 @@ # directories to be backed up - R ~ - # directories/files to be excluded - - - ~/.cache + # patterns are applied in order + # get rid of some always uninteresting files early so they do not get + # pulled back in by inclusions later - - **/*~ - - **/__pycache__ - - - **/*.pyc - - - **/.*.swp - - - **/.*.swo + - - **/.*.sw[ponml] + + # directories/files to be excluded + - - .cache # prune settings keep within: 1d @@ -223,16 +230,19 @@ # directories to be backed up - R ~ - # directories/files to be excluded - - - ~/music - - - ~/videos - - - ~/photos - - - ~/.cache + # patterns are applied in order + # get rid of some always uninteresting files early so they do not get + # pulled back in by inclusions later - - **/*~ - - **/__pycache__ - - - **/*.pyc - - - **/.*.swp - - - **/.*.swo + - - **/.*.sw[ponml] + - - **/.sw[ponml] + + # directories/files to be excluded + - - Music + - - Videos + - - Pictures + - - .cache # prune settings keep within: 1d diff --git a/doc/configuring.rst b/doc/configuring.rst index 4c7265e..f8bb1ef 100644 --- a/doc/configuring.rst +++ b/doc/configuring.rst @@ -140,13 +140,15 @@ suffix. It might look like the following: # directories to be backed up - R ~ - # directories/files to be excluded - - - ~/.cache + # patterns are applied in order + # get rid of some always uninteresting files early so they do not get + # pulled back in by inclusions later - - **/*~ - - **/__pycache__ - - - **/*.pyc - - - **/.*.swp - - - **/.*.swo + - - **/.*.sw[ponml] + + # specific directories/files to be excluded + - - ~/.cache # prune settings keep within: 2d @@ -399,7 +401,10 @@ Patterns are an alternate way of specifying which files are backed up, and which are not. Patterns can be specified in conjunction with, or instead of, :ref:`src_dirs` and :ref:`excludes`. One powerful feature of patterns is that they allow you to specify that a directory or file should be backed up even if -it is contained within a directory that is being excluded. +it is contained within a directory that is being excluded. The patterns are +processed in the order given, so in this example the pattern that matches the +file to be included should be given before the pattern that matches the +containing directory that is to be excluded. An example that uses :ref:`patterns` in lieu of :ref:`src_dirs` and :ref:`excludes` is: @@ -441,8 +446,7 @@ and ``-`` specifies a path that should be excluded. With this example, /usr/local is included while all other files and directories in /usr are not. The subdirectory to include must be specified before the directory that contains it is excluded. This is a relatively simple example, additional features are -described in the `Borg patterns documentation -`_. +described in BorgPatterns_. .. _retention: diff --git a/doc/examples.rst b/doc/examples.rst index 5e93150..bdb3186 100644 --- a/doc/examples.rst +++ b/doc/examples.rst @@ -94,7 +94,7 @@ And here is the contents of the *root* configuration file: > R /opt > R /usr/local - # directories/files to be excluded + # specific directories/files to be excluded > - /var/cache > - /var/lock > - /var/run @@ -242,13 +242,16 @@ be run interactively, perhaps once per day. # directories to be backed up - R ~ - # directories/files to be excluded - - - ~/.cache + # patterns are applied in order + # get rid of some always uninteresting files early so they do not get + # pulled back in by inclusions later - - **/*~ - - **/__pycache__ - - - **/*.pyc - - - **/.*.swp - - - **/.*.swo + - - **/.*.sw[ponml] + + # specific directories/files to be excluded + - - ~/.cache + - - ~/tmp # prune settings keep within: 1d @@ -320,16 +323,18 @@ And finally, here is the contents of the *snapshots* configuration file: # directories to be backed up - R ~ - # directories/files to be excluded - - - ~/music - - - ~/videos - - - ~/photos - - - ~/.cache + # patterns are applied in order + # get rid of some always uninteresting files early so they do not get + # pulled back in by inclusions later - - **/*~ - - **/__pycache__ - - - **/*.pyc - - - **/.*.swp - - - **/.*.swo + - - **/.*.sw[ponml] + + # specific directories/files to be excluded + - - ~/Music + - - ~/Videos + - - ~/Pictures + - - ~/.cache # prune settings keep within: 1d diff --git a/doc/links.rst b/doc/links.rst index d4d5243..2b53076 100644 --- a/doc/links.rst +++ b/doc/links.rst @@ -5,6 +5,7 @@ .. _BorgBackup: https://borgbackup.readthedocs.io .. _BorgBase: https://www.borgbase.com .. _BorgMatic: https://torsion.org/borgmatic +.. _BorgPatterns: https://borgbackup.readthedocs.io/en/master/usage/help.html#borg-help-patterns .. _Duplicity: http://duplicity.nongnu.org .. _Emborg: https://emborg.readthedocs.io/en/stable .. _GitHub: https://github.com/KenKundert/assimilate/issues diff --git a/doc/migrating.rst b/doc/migrating.rst index e574b14..31c9409 100644 --- a/doc/migrating.rst +++ b/doc/migrating.rst @@ -233,6 +233,10 @@ Before starting, it is useful to carefully read the documentation for the *Borg and related settings. *archive* should be chosen to match the archives in your *Borg 1* repository. + You should choose *archive* or *match_archives* settings to match the + archive naming of your old repository. In addition, you should choose + *working_dir* to maintain the same root paths. + **Step 2**: Now create the new *Borg 2* repository diff --git a/tests/assimilate.nt b/tests/assimilate.nt index 84c32e9..8942dae 100644 --- a/tests/assimilate.nt +++ b/tests/assimilate.nt @@ -33,7 +33,14 @@ assimilate: - repo-list: - - archives - - recent --last=20 - - list: paths + - list: + - - paths + - - l + - - ln -N + - - ls -S + - - ld -D + - overdue: od + - umount: unmount - logging: - keep for: 1w - max entries: 20 @@ -50,6 +57,14 @@ assimilate: - overdue: - max age: 36 h - message: ⟪description⟫: ⟪updated⟫ ago⟪locked: (currently active)⟫⟪overdue: — PAST DUE⟫ + - repositories: + - cache@❬host❭ (/home/❬user❭): + - config: cache + - max age: 15m + - home@❬host❭ (/home/❬user❭): + - config: home + - ❬remote-host❭: + - host: ❬remote-host❭ ~/.config/assimilate/root.conf.nt: contains lines in order: @@ -85,12 +100,10 @@ assimilate: > pass command: ❬command❭ > patterns: > - R ~ - > - - ~/.cache > - - **/*~ > - - **/__pycache__ - > - - **/*.pyc - > - - **/.*.swp - > - - **/.*.swo + > - - **/.*.sw[ponml] + > - - .cache > keep within: 1d > keep daily: 7 > keep weekly: 4 @@ -103,15 +116,13 @@ assimilate: > encryption: none > patterns: > - R ~ - > - - ~/music - > - - ~/videos - > - - ~/photos - > - - ~/.cache > - - **/*~ > - - **/__pycache__ - > - - **/*.pyc - > - - **/.*.swp - > - - **/.*.swo + > - - **/.*.sw[ponml] + > - - .cache + > - - Music + > - - Videos + > - - Pictures > keep within: 1d > keep hourly: 48 @@ -241,6 +252,12 @@ assimilate: binding — repo-create {{{2: run: assimilate repo-create checks: + stdout: + matches text: + > + > Reserve some repository storage space now for emergencies like 'disk full' + > by running: + > assimilate repo-space --reserve 1G ~/.local/share/assimilate/test.log: contains text: > running: @@ -907,6 +924,12 @@ assimilate: albino — repo-create {{{2: run: assimilate repo-create checks: + stdout: + matches text: + > + > Reserve some repository storage space now for emergencies like 'disk full' + > by running: + > assimilate repo-space --reserve 1G ~/.local/share/assimilate/test.log: contains text: > running: @@ -1693,6 +1716,9 @@ assimilate: epicenter — repo-create {{{2: run: assimilate repo-create checks: + stdout: + contains text: assimilate borg key export -r @repo + contains text: assimilate repo-space ~/.local/share/assimilate/test.log: contains text: > Borg-related environment variables: ⟪ @@ -2418,6 +2444,9 @@ assimilate: > === test1 === > > === test2 === + stdout: + contains text: assimilate borg key export -r @repo + contains text: assimilate repo-space ~/.local/share/assimilate/test1.log: contains text: @@ -3294,6 +3323,12 @@ assimilate: pantry — repo-create {{{2: run: assimilate repo-create checks: + stdout: + matches text: + > + > Reserve some repository storage space now for emergencies like 'disk full' + > by running: + > assimilate repo-space --reserve 1G ~/.local/share/assimilate/test.log: contains text: > running: @@ -3953,6 +3988,12 @@ assimilate: annual — repo-create {{{2: run: assimilate repo-create checks: + stdout: + matches text: + > + > Reserve some repository storage space now for emergencies like 'disk full' + > by running: + > assimilate repo-space --reserve 1G ~/.local/share/assimilate/test.log: contains text: > running: @@ -4838,6 +4879,12 @@ assimilate: megaphone — repo-create {{{2: run: assimilate repo-create checks: + stdout: + matches text: + > + > Reserve some repository storage space now for emergencies like 'disk full' + > by running: + > assimilate repo-space --reserve 1G ~/.local/share/assimilate/test1.log: contains text: > running: @@ -5065,7 +5112,7 @@ assimilate: > Choose from: test, test1, or test2. status: 2 - agent — repo-create -ctest {{{2: + ebony — repo-create -ctest {{{2: run: assimilate -ctest repo-create checks: stderr: @@ -5074,6 +5121,17 @@ assimilate: > > === test2 === + stdout: + matches text: + > + > Reserve some repository storage space now for emergencies like 'disk full' + > by running: + > assimilate repo-space --reserve 1G + > + > Reserve some repository storage space now for emergencies like 'disk full' + > by running: + > assimilate repo-space --reserve 1G + ~/.local/share/assimilate/test1.log: contains text: > running: @@ -5311,6 +5369,16 @@ assimilate: spinner — repo-create {{{2: run: assimilate -c test1 repo-create checks: + stdout: + matches text: + > + > Reserve some repository storage space now for emergencies like 'disk full' + > by running: + > assimilate repo-space --reserve 1G + + stderr: + matches text: assimilate warning: passphrase given but not needed as encryption set to none. + ~/.local/share/assimilate/test1.log: contains text: > running: @@ -5320,9 +5388,6 @@ assimilate: > --make-parent-dirs \ > --encryption=none - stderr: - matches text: assimilate warning: passphrase given but not needed as encryption set to none. - lemming — must specify config error {{{2: run: assimilate create checks: