Repository: borgbackup/borg

Issue:
Create repo a bit later
Currently if `init` was interrupted, borg leave repo folder and some files inside repo. So we need delete repo folder manually. Maybe possible create repo at end of repo init process?



Discussion:
Well, creating and populating the repo folder is the main thing what init does.
So I'ld suggest not to interrupt it and just use borg delete repo afterwards if you change your mind.

`borg delete` not work for incomplete repo

Object with key b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' not found in repository /backup/opt.repo.
Traceback (most recent call last):
  File "/usr/lib64/python3.4/site-packages/borg/archiver.py", line 1466, in main
    exit_code = archiver.run(args)
  File "/usr/lib64/python3.4/site-packages/borg/archiver.py", line 1420, in run
    return args.func(args)
  File "/usr/lib64/python3.4/site-packages/borg/archiver.py", line 371, in do_delete
    manifest, key = Manifest.load(repository)
  File "/usr/lib64/python3.4/site-packages/borg/helpers.py", line 93, in load
    cdata = repository.get(cls.MANIFEST_ID)
  File "/usr/lib64/python3.4/site-packages/borg/repository.py", line 421, in get
    raise self.ObjectNotFound(id_, self.path) from None
borg.repository.ObjectNotFound: (b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', '/backup/opt.repo')

You can create and populate the repo folder after `Do you want your passphrase to be displayed for verification? [yN]:`

Certainly the process could be modified to first ask and verify the passphrase before doing anything else.

Ah, now it makes sense to me. I read this before and wondered: _what's the use case for interrupting `borg init`?_
Typo in the passphrase (although you could change-passphrase... if it was shown or you know it), or wrong encryption options, that makes sense.

> Certainly the process could be modified to first ask and verify the passphrase before doing anything else.

Sounds good. Or destroy the repo if no key/manifest etc. was created.


Resolving patch:
diff --git a/borg/archiver.py b/borg/archiver.py
--- a/borg/archiver.py
+++ b/borg/archiver.py
@@ -161,7 +161,11 @@ def do_serve(self, args):
     def do_init(self, args, repository):
         """Initialize an empty repository"""
         logger.info('Initializing repository at "%s"' % args.location.canonical_path())
-        key = key_creator(repository, args)
+        try:
+            key = key_creator(repository, args)
+        except (EOFError, KeyboardInterrupt):
+            repository.destroy()
+            return EXIT_WARNING
         manifest = Manifest(key, repository)
         manifest.key = key
         manifest.write()
diff --git a/borg/testsuite/archiver.py b/borg/testsuite/archiver.py
--- a/borg/testsuite/archiver.py
+++ b/borg/testsuite/archiver.py
@@ -22,6 +22,7 @@
 from ..cache import Cache
 from ..crypto import bytes_to_long, num_aes_blocks
 from ..helpers import Manifest, EXIT_SUCCESS, EXIT_WARNING, EXIT_ERROR
+from ..key import KeyfileKeyBase
 from ..remote import RemoteRepository, PathNotAllowed
 from ..repository import Repository
 from . import BaseTestCase, changedir, environment_variable
@@ -1127,12 +1128,24 @@ def test_debug_put_get_delete_obj(self):
         output = self.cmd('debug-delete-obj', self.repository_location, 'invalid')
         assert "is invalid" in output
 
+    def test_init_interrupt(self):
+        def raise_eof(*args):
+            raise EOFError
+
+        with patch.object(KeyfileKeyBase, 'create', raise_eof):
+            self.cmd('init', self.repository_location, exit_code=1)
+        assert not os.path.exists(self.repository_location)
+
 
 @unittest.skipUnless('binary' in BORG_EXES, 'no borg.exe available')
 class ArchiverTestCaseBinary(ArchiverTestCase):
     EXE = 'borg.exe'
     FORK_DEFAULT = True
 
+    @unittest.skip('patches objects')
+    def test_init_interrupt(self):
+        pass
+
 
 class ArchiverCheckTestCase(ArchiverTestCaseBase):
 


Test patch: