Răsfoiți Sursa

Merge branch '1.0-maint'

# Conflicts:
#	borg/platform.py
#	src/borg/archiver.py
#	src/borg/helpers.py
#	src/borg/platform/darwin.pyx
#	src/borg/platform/freebsd.pyx
#	src/borg/platform/linux.pyx
#	src/borg/testsuite/__init__.py
Thomas Waldmann 8 ani în urmă
părinte
comite
afab1cc9b0

+ 10 - 3
docs/development.rst

@@ -21,9 +21,16 @@ Some guidance for contributors:
 
 - choose the branch you base your changesets on wisely:
 
-  - choose x.y-maint for stuff that should go into next x.y release
-    (it usually gets merged into master branch later also)
-  - choose master if that does not apply
+  - choose x.y-maint for stuff that should go into next x.y.z release
+    (it usually gets merged into master branch later also), like:
+
+    - bug fixes (code or docs)
+    - missing *important* (and preferably small) features
+    - docs rearrangements (so stuff stays in-sync to avoid merge
+      troubles in future)
+  - choose master if that does not apply, like for:
+
+    - developing new features
 
 - do clean changesets:
 

+ 3 - 1
docs/usage.rst

@@ -575,6 +575,8 @@ Examples
 
 .. include:: usage/mount.rst.inc
 
+.. include:: usage/umount.rst.inc
+
 Examples
 ~~~~~~~~
 borg mount
@@ -584,7 +586,7 @@ borg mount
     $ borg mount /path/to/repo::root-2016-02-15 /tmp/mymountpoint
     $ ls /tmp/mymountpoint
     bin  boot  etc	home  lib  lib64  lost+found  media  mnt  opt  root  sbin  srv  tmp  usr  var
-    $ fusermount -u /tmp/mymountpoint
+    $ borg umount /tmp/mymountpoint
 
 ::
 

+ 40 - 0
docs/usage/umount.rst.inc

@@ -0,0 +1,40 @@
+.. IMPORTANT: this file is auto-generated from borg's built-in help, do not edit!
+
+.. _borg_umount:
+
+borg umount
+-----------
+::
+
+    usage: borg umount [-h] [--critical] [--error] [--warning] [--info] [--debug]
+                       [--lock-wait N] [--show-rc] [--no-files-cache] [--umask M]
+                       [--remote-path PATH]
+                       MOUNTPOINT
+    
+    un-mount the FUSE filesystem
+    
+    positional arguments:
+      MOUNTPOINT            mountpoint of the filesystem to umount
+    
+    optional arguments:
+      -h, --help            show this help message and exit
+      --critical            work on log level CRITICAL
+      --error               work on log level ERROR
+      --warning             work on log level WARNING (default)
+      --info, -v, --verbose
+                            work on log level INFO
+      --debug               work on log level DEBUG
+      --lock-wait N         wait for the lock, but max. N seconds (default: 1).
+      --show-rc             show/log the return code (rc)
+      --no-files-cache      do not load/update the file metadata cache used to
+                            detect unchanged files
+      --umask M             set umask to M (local and remote, default: 0077)
+      --remote-path PATH    set remote path to executable (default: "borg")
+    
+Description
+~~~~~~~~~~~
+
+This command un-mounts a FUSE filesystem that was mounted with ``borg mount``.
+
+This is a convenience wrapper that just calls the platform-specific shell
+command - usually this is either umount or fusermount -u.

+ 20 - 1
src/borg/archiver.py

@@ -47,7 +47,7 @@ from .helpers import ProgressIndicatorPercent
 from .item import Item
 from .key import key_creator, RepoKey, PassphraseKey
 from .keymanager import KeyManager
-from .platform import get_flags
+from .platform import get_flags, umount
 from .remote import RepositoryServer, RemoteRepository, cache_if_remote
 from .repository import Repository
 from .selftest import selftest
@@ -865,6 +865,10 @@ class Archiver:
                 self.exit_code = EXIT_ERROR
         return self.exit_code
 
+    def do_umount(self, args):
+        """un-mount the FUSE filesystem"""
+        return umount(args.mountpoint)
+
     @with_repository()
     def do_list(self, args, repository, manifest, key):
         """List archive or repository contents"""
@@ -2154,6 +2158,21 @@ class Archiver:
                                help='Extra mount options')
         self.add_archives_filters_args(subparser)
 
+        umount_epilog = textwrap.dedent("""
+        This command un-mounts a FUSE filesystem that was mounted with ``borg mount``.
+
+        This is a convenience wrapper that just calls the platform-specific shell
+        command - usually this is either umount or fusermount -u.
+        """)
+        subparser = subparsers.add_parser('umount', parents=[common_parser], add_help=False,
+                                          description=self.do_umount.__doc__,
+                                          epilog=umount_epilog,
+                                          formatter_class=argparse.RawDescriptionHelpFormatter,
+                                          help='umount repository')
+        subparser.set_defaults(func=self.do_umount)
+        subparser.add_argument('mountpoint', metavar='MOUNTPOINT', type=str,
+                               help='mountpoint of the filesystem to umount')
+
         info_epilog = textwrap.dedent("""
         This command displays detailed information about the specified archive or repository.
 

+ 1 - 1
src/borg/helpers.py

@@ -95,7 +95,7 @@ def check_extension_modules():
         raise ExtensionModuleError
     if crypto.API_VERSION != 3:
         raise ExtensionModuleError
-    if platform.API_VERSION != platform.OS_API_VERSION != 4:
+    if platform.API_VERSION != platform.OS_API_VERSION != 5:
         raise ExtensionModuleError
 
 

+ 4 - 4
src/borg/platform/__init__.py

@@ -9,7 +9,7 @@ Public APIs are documented in platform.base.
 from .base import acl_get, acl_set
 from .base import set_flags, get_flags
 from .base import SaveFile, SyncFile, sync_dir, fdatasync
-from .base import swidth, API_VERSION
+from .base import swidth, umount, API_VERSION
 from .posix import process_alive, get_process_id, local_pid_alive
 
 
@@ -19,12 +19,12 @@ if sys.platform.startswith('linux'):  # pragma: linux only
     from .linux import acl_get, acl_set
     from .linux import set_flags, get_flags
     from .linux import SyncFile
-    from .linux import swidth
+    from .linux import swidth, umount
 elif sys.platform.startswith('freebsd'):  # pragma: freebsd only
     from .freebsd import API_VERSION as OS_API_VERSION
     from .freebsd import acl_get, acl_set
-    from .freebsd import swidth
+    from .freebsd import swidth, umount
 elif sys.platform == 'darwin':  # pragma: darwin only
     from .darwin import API_VERSION as OS_API_VERSION
     from .darwin import acl_get, acl_set
-    from .darwin import swidth
+    from .darwin import swidth, umount

+ 6 - 1
src/borg/platform/base.py

@@ -13,7 +13,7 @@ platform API: that way platform APIs provided by the platform-specific support m
 are correctly composed into the base functionality.
 """
 
-API_VERSION = 4
+API_VERSION = 5
 
 fdatasync = getattr(os, 'fdatasync', os.fsync)
 
@@ -157,3 +157,8 @@ def swidth(s):
     For western scripts, this is just len(s), but for cjk glyphs, 2 cells are used.
     """
     return len(s)
+
+
+def umount(mountpoint):
+    """un-mount the FUSE filesystem mounted at <mountpoint>"""
+    return 0  # dummy, see also posix module

+ 2 - 2
src/borg/platform/darwin.pyx

@@ -2,9 +2,9 @@ import os
 
 from ..helpers import user2uid, group2gid
 from ..helpers import safe_decode, safe_encode
-from .posix import swidth
+from .posix import swidth, umount
 
-API_VERSION = 4
+API_VERSION = 5
 
 cdef extern from "sys/acl.h":
     ctypedef struct _acl_t:

+ 2 - 2
src/borg/platform/freebsd.pyx

@@ -2,9 +2,9 @@ import os
 
 from ..helpers import posix_acl_use_stored_uid_gid
 from ..helpers import safe_encode, safe_decode
-from .posix import swidth
+from .posix import swidth, umount
 
-API_VERSION = 4
+API_VERSION = 5
 
 cdef extern from "errno.h":
     int errno

+ 6 - 1
src/borg/platform/linux.pyx

@@ -2,6 +2,7 @@ import os
 import re
 import resource
 import stat
+import subprocess
 
 from ..helpers import posix_acl_use_stored_uid_gid
 from ..helpers import user2uid, group2gid
@@ -12,7 +13,7 @@ from .posix import swidth
 from libc cimport errno
 from libc.stdint cimport int64_t
 
-API_VERSION = 4
+API_VERSION = 5
 
 cdef extern from "sys/types.h":
     int ACL_TYPE_ACCESS
@@ -251,3 +252,7 @@ class SyncFile(BaseSyncFile):
         self.fd.flush()
         os.fdatasync(self.fileno)
         os.posix_fadvise(self.fileno, 0, 0, os.POSIX_FADV_DONTNEED)
+
+
+def umount(mountpoint):
+    return subprocess.call(['fusermount', '-u', mountpoint])

+ 9 - 1
src/borg/platform/posix.pyx

@@ -1,7 +1,8 @@
-
 import errno
 import os
 import socket
+import subprocess
+
 
 cdef extern from "wchar.h":
     cdef int wcswidth(const Py_UNICODE *str, size_t n)
@@ -69,3 +70,10 @@ def local_pid_alive(pid):
             return False
         # Any other error (eg. permissions) means that the process ID refers to a live process.
         return True
+
+
+# most POSIX platforms (but not Linux)
+def umount(mountpoint):
+    return subprocess.call(['umount', mountpoint])
+
+

+ 2 - 6
src/borg/testsuite/__init__.py

@@ -12,7 +12,7 @@ import uuid
 import unittest
 
 from ..xattr import get_all
-from ..platform import get_flags
+from ..platform import get_flags, umount
 from .. import platform
 
 # Note: this is used by borg.selftest, do not use or import py.test functionality here.
@@ -200,11 +200,7 @@ class BaseTestCase(unittest.TestCase):
         self.cmd(*args, fork=True)
         self.wait_for_mount(mountpoint)
         yield
-        if sys.platform.startswith('linux'):
-            cmd = 'fusermount -u %s' % mountpoint
-        else:
-            cmd = 'umount %s' % mountpoint
-        os.system(cmd)
+        umount(mountpoint)
         os.rmdir(mountpoint)
         # Give the daemon some time to exit
         time.sleep(.2)