Repository: borgbackup/borg

Issue:
Invoking "borg serve" compares None with int in version 1.0.11
```
$LOG ERROR Remote: Local Exception.
Traceback (most recent call last):
  File "/usr/lib64/python3.4/site-packages/borg/archiver.py", line 2168, in main
    exit_code = archiver.run(args)
  File "/usr/lib64/python3.4/site-packages/borg/archiver.py", line 2104, in run
    return set_ec(func(args))
  File "/usr/lib64/python3.4/site-packages/borg/helpers.py", line 85, in set_ec
    exit_code = max(exit_code, ec)
TypeError: unorderable types: NoneType() > int()

Platform: REDACTED
Linux: Gentoo Base System 2.3 
Borg: 1.0.11  Python: CPython 3.4.5
PID: 11348  CWD: /var/lib/borg
sys.argv: ['/usr/lib/python-exec/python3.4/borg', 'serve', '--append-only', '--restrict-to-path', '/var/lib/borg/REDACTED']
```

It looks like **Archiver.run** is calling **Archiver.do_serve**, which is expecting a return value from **RepositoryServer.serve**, but **RepositoryServer.serve** doesn't return anything.

The actual backup is completed successfully, prior to the exception being raised.



Discussion:

Patch:
diff --git a/src/borg/archiver.py b/src/borg/archiver.py
index ebb4b5e1..96a8eb25 100644
--- a/src/borg/archiver.py
+++ b/src/borg/archiver.py
@@ -231,12 +231,13 @@ def build_matcher(inclexcl_patterns, include_paths):
 
     def do_serve(self, args):
         """Start in server mode. This command is usually not used manually."""
-        return RepositoryServer(
+        RepositoryServer(
             restrict_to_paths=args.restrict_to_paths,
             restrict_to_repositories=args.restrict_to_repositories,
             append_only=args.append_only,
             storage_quota=args.storage_quota,
         ).serve()
+        return EXIT_SUCCESS
 
     @with_repository(create=True, exclusive=True, manifest=False)
     def do_init(self, args, repository):
@@ -1021,19 +1022,18 @@ def contents_changed(item1, item2):
         def compare_content(path, item1, item2):
             if contents_changed(item1, item2):
                 if item1.get('deleted'):
-                    return 'added {:>13}'.format(format_file_size(sum_chunk_size(item2)))
-                if item2.get('deleted'):
-                    return 'removed {:>11}'.format(format_file_size(sum_chunk_size(item1)))
-                if not can_compare_chunk_ids:
-                    return 'modified'
-                chunk_ids1 = {c.id for c in item1.chunks}
-                chunk_ids2 = {c.id for c in item2.chunks}
-                added_ids = chunk_ids2 - chunk_ids1
-                removed_ids = chunk_ids1 - chunk_ids2
-                added = sum_chunk_size(item2, added_ids)
-                removed = sum_chunk_size(item1, removed_ids)
-                return '{:>9} {:>9}'.format(format_file_size(added, precision=1, sign=True),
-                                            format_file_size(-removed, precision=1, sign=True))
+                    return ('added {:>13}'.format(format_file_size(sum_chunk_size(item2))))
+                elif item2.get('deleted'):
+                    return ('removed {:>11}'.format(format_file_size(sum_chunk_size(item1))))
+                else:
+                    chunk_ids1 = {c.id for c in item1.chunks}
+                    chunk_ids2 = {c.id for c in item2.chunks}
+                    added_ids = chunk_ids2 - chunk_ids1
+                    removed_ids = chunk_ids1 - chunk_ids2
+                    added = sum_chunk_size(item2, added_ids)
+                    removed = sum_chunk_size(item1, removed_ids)
+                    return ('{:>9} {:>9}'.format(format_file_size(added, precision=1, sign=True),
+                                                 format_file_size(-removed, precision=1, sign=True)))
 
         def compare_directory(item1, item2):
             if item2.get('deleted') and not item1.get('deleted'):


Test patch:
diff --git a/src/borg/testsuite/archiver.py b/src/borg/testsuite/archiver.py
index 0d28eb31..3d2783e1 100644
--- a/src/borg/testsuite/archiver.py
+++ b/src/borg/testsuite/archiver.py
@@ -3276,10 +3276,9 @@ def test_basic_functionality(self):
         self.cmd('create', self.repository_location + '::test1a', 'input')
         self.cmd('create', '--chunker-params', '16,18,17,4095', self.repository_location + '::test1b', 'input')
 
-        def do_asserts(output, can_compare_ids):
+        def do_asserts(output, archive):
             # File contents changed (deleted and replaced with a new file)
-            change = 'B' if can_compare_ids else '{:<19}'.format('modified')
-            assert '{} input/file_replaced'.format(change) in output
+            assert 'B input/file_replaced' in output
 
             # File unchanged
             assert 'input/file_unchanged' not in output
@@ -3308,10 +3307,9 @@ def do_asserts(output, can_compare_ids):
             # The inode has two links and the file contents changed. Borg
             # should notice the changes in both links. However, the symlink
             # pointing to the file is not changed.
-            change = '0 B' if can_compare_ids else '{:<19}'.format('modified')
-            assert '{} input/empty'.format(change) in output
+            assert '0 B input/empty' in output
             if are_hardlinks_supported():
-                assert '{} input/hardlink_contents_changed'.format(change) in output
+                assert '0 B input/hardlink_contents_changed' in output
             if are_symlinks_supported():
                 assert 'input/link_target_contents_changed' not in output
 
@@ -3338,9 +3336,9 @@ def do_asserts(output, can_compare_ids):
             if are_hardlinks_supported():
                 assert 'input/hardlink_target_replaced' not in output
 
-        do_asserts(self.cmd('diff', self.repository_location + '::test0', 'test1a'), True)
+        do_asserts(self.cmd('diff', self.repository_location + '::test0', 'test1a'), '1a')
         # We expect exit_code=1 due to the chunker params warning
-        do_asserts(self.cmd('diff', self.repository_location + '::test0', 'test1b', exit_code=1), False)
+        do_asserts(self.cmd('diff', self.repository_location + '::test0', 'test1b', exit_code=1), '1b')
 
     def test_sort_option(self):
         self.cmd('init', '--encryption=repokey', self.repository_location)