mount module
The mount API.
The high-level mount API is Mount
and handles mount,
umount, remount and checks for Back In Time. The low-level mount API
is MountControl
. The latter can be used to create own
mounting services via subclassing it. See the following example.
Example
See this template to create your own mounting service by inheriting
from MountControl
. All you need to do is:
Add your settings in
qt/settingsdialog.py
.Add settings in
common/config.py
.Use the following template class
MountDummy
, rename and modify it to your needs.Please use
self.currentMountpoint
as your local mountpoint.Your class should inherit from
mount.MountControl
.
As real usage example see the two classes sshtools.SSH
and
encfstools.EncFS_mount
.
This is the template:
class MountDummy(mount.MountControl):
def __init__(self, *args, **kwargs):
super(MountDummy, self).__init__(*args, **kwargs)
self.all_kwargs = {}
# First we need to map the settings.
# If <arg> is in kwargs (e.g. if this class is called with
# dummytools.Dummy(<arg> = <value>) this will map self.<arg> to
# kwargs[<arg>]; else self.<arg> = <default> from config
# e.g. self.setattrKwargs(<arg>, <default>, **kwargs)
self.setattrKwargs(
'user', self.config.get_dummy_user(self.profile_id), **kwargs)
self.setattrKwargs(
'host', self.config.get_dummy_host(self.profile_id), **kwargs)
self.setattrKwargs(
'port', self.config.get_dummy_port(self.profile_id), **kwargs)
self.setattrKwargs(
'password',
self.config.password(self.parent, self.profile_id),
store = False, **kwargs)
self.setDefaultArgs()
# If self.currentMountpoint is not the remote snapshot path
# you can specify a subfolder of self.currentMountpoint for
# the symlink
self.symlink_subfolder = None
self.mountproc = 'dummy'
self.log_command = '%s: %s@%s' % (self.mode, self.user, self.host)
def _mount(self):
# Mount the service
# Implement your mountprocess here.
pass
def _umount(self):
# Umount the service
# Implement your unmountprocess here.
pass
def preMountCheck(self, first_run = False):
# Check what ever conditions must be given for the mount to be
# done successful.
# Raise MountException('Error description') if service can not mount
# return True if everything is okay
# all pre|post_[u]mount_check can also be used to prepare
# things or clean up
return True
def postMountCheck(self):
# Check if mount was successful
# Raise MountException('Error description') if not
return True
def preUmountCheck(self):
# Check if service is safe to umount
# Raise MountException('Error description') if not
return True
def postUmountCheck(self):
# Check if umount successful
# Raise MountException('Error description') if not
return True
- class mount.Mount(cfg=None, profile_id=None, tmp_mount=False, parent=None)[source]
Bases:
object
This is the high-level mount API. This will handle mount, umount, remount and checks on the low-level
MountControl
subclass backends for BackInTime.If
cfg
isNone
this will load the default config. Ifprofile_id
isNone
it will useconfigfile.ConfigFileWithProfiles.currentProfile()
.If the current profile uses Password-Cache and the Password-Cache is not running this will try to start it.
- Parameters:
cfg (config.Config) – current config
profile_id (str) – profile ID that should be used
tmp_mount (bool) – if
True
mount to a temporary destinationparent (QWidget) – parent widget for QDialogs or
None
if there is no parent
- mount(mode=None, check=True, **kwargs)[source]
High-level mount. Check if the selected
mode
need to be mounted, select the low-level backend and mount it.- Parameters:
mode (str) – mode to use. One of ‘local’, ‘ssh’, ‘local_encfs’ or ‘ssh_encfs’
check (bool) – if
True
runMountControl.preMountCheck()
before mounting**kwargs – keyword arguments paste to low-level
MountControl
subclass backend
- Returns:
Hash ID used as mountpoint
- Return type:
- Raises:
exceptions.MountException – if a check failed
exceptions.HashCollision – if Hash ID was used before but umount info wasn’t identical
- preMountCheck(mode=None, first_run=False, **kwargs)[source]
High-level check. Run
MountControl.preMountCheck()
to check if all conditions forMount.mount()
are set.Should be called with
first_run = True
to check if new settings are correct before saving them.- Parameters:
mode (str) – mode to use. One of ‘local’, ‘ssh’, ‘local_encfs’ or ‘ssh_encfs’
first_run (bool) – run intense checks that only need to run after changing settings but not every time before mounting
**kwargs – keyword arguments paste to low-level
MountControl
subclass backend
- Returns:
True
if all checks where okay- Return type:
- Raises:
exceptions.MountException – if a check failed
- remount(new_profile_id, mode=None, hash_id=None, **kwargs)[source]
High-level remount. Unmount the old profile presented by
hash_id
and mount new profilenew_profile_id
with modemode
. If old and new mounts are the same just add new symlinks and keep the mount.Args map to profiles:
new_profile_id <= new profile mode <= new profile kwargs <= new profile hash_id <= old profile self.profile_id <= old profile
- Parameters:
new_profile_id (str) – Profile ID that should get mounted
mode (str) – mode to use for new mount. One of ‘local’, ‘ssh’, ‘local_encfs’ or ‘ssh_encfs’
hash_id (str) – Hash ID used as mountpoint on the old mount, that should get unmounted
**kwargs – keyword arguments paste to low-level
MountControl
subclass backend for the new mount
- Returns:
Hash ID used as mountpoint
- Return type:
- Raises:
exceptions.MountException – if a check failed
exceptions.HashCollision – if Hash ID was used before but umount info wasn’t identical
- umount(hash_id=None)[source]
High-level unmount. Unmount the low-level backend. This will read unmount infos written next to the mountpoint identified by
hash_id
and unmount it.- Parameters:
hash_id (bool) – Hash ID used as mountpoint before that should get unmounted
- Raises:
exceptions.MountException – if a check failed
- class mount.MountControl(cfg=None, profile_id=None, hash_id=None, tmp_mount=False, parent=None, symlink=True, *args, **kwargs)[source]
Bases:
object
This is the low-level mount API. This should be subclassed by backends.
Subclasses should have its own
__init__
but must also call the inherited__init__
. See module description (mount
) for a detailed example.You must overwrite methods:
You can overwrite methods:
These arguments (all of type
str
) must be defined inself
namespace by subclassing__init__
method:mountproc
: process used to mountlog_command
: shortened form of mount command used in logssymlink_subfolder
: mountpoint-subfolder which should be linked
- Parameters:
cfg (config.Config) – current config
profile_id (str) – profile ID that should be used
hash_id (str) – crc32 hash used to identify identical mountpoints
tmp_mount (bool) – if
True
mount to a temporary destinationparent (QWidget) – parent widget for QDialogs or
None
if there is no parentsymlink (bool) – if
True
set symlink to mountpointmode (str) – one of
local
,local_encfs
,ssh
orssh_encfs
hash_collision (int) – global value used to prevent hash collisions on mountpoints
- _mount()[source]
Backend mount method. This must be overwritten in the backend which subclasses
MountControl
.
- _umount()[source]
Unmount with
fusermount -u
for fuse based backends. This can be overwritten by backends which subclassesMountControl
.- Raises:
exceptions.MountException – If unmount failed.
- checkFuse()[source]
Check if command in
self.mountproc
is installed.- Raises:
exceptions.MountException – If either command is not available.
- checkLocks(path, lockSuffix)[source]
Check if there are active locks ending with
lockSuffix
inpath
. If the process owning the lock doesn’t exist anymore this will remove the lock.
- compareRemount(old_hash_id)[source]
Compare mount arguments between current and
old_hash_id
. If they are identical we could reuse the mount and don’t need to remount.
- compareUmountInfo(umount_info=None)[source]
Compare current
self.all_kwargs
with those from fileumount_info
.This should prevent hash collisions of two different mounts.
- createMountStructure()[source]
Create folders that are necessary for mounting.
Folder structure in
~/.local/share/backintime/mnt/
(self.mount_root
):. ├── <pid>.lock <= mountprocess lock that will prevent │ different processes modifying │ mountpoints at one time │ ├── <hash_id>/ <= ``self.hash_id_path`` will be │ │ shared by all profiles with the │ │ same mount settings │ │ │ ├── mountpoint/ <= ``self.currentMountpoint`` real │ │ mountpoint │ │ │ ├── umount <= ``self.umount_info`` json file with │ │ all necessary args for unmount │ │ │ └── locks/ <= ``self.lock_path`` for each process │ you have a ``<pid>.lock`` file │ ├── <profile id>_<pid>/ <= sym-link to the right path. return │ by config.snapshotsPath (can be │ ../mnt/<hash_id>/mount_point for ssh │ or ../mnt/<hash_id>/<HOST>/<SHARE> │ for fusesmb ...) │ └── tmp_<profile id>_<pid>/ <= sym-link for testing mountpoints in settingsdialog
- mount(check=True)[source]
Low-level mount. Set mountprocess lock and prepare mount, run checks and than call
_mount()
for the subclassed backend. Finally set mount lock and symlink and release mountprocess lock.- Parameters:
check (bool) – if
True
runpreMountCheck()
before mounting- Returns:
Hash ID used as mountpoint
- Return type:
- Raises:
exceptions.MountException – if a check failed
exceptions.HashCollision – if Hash ID was used before but umount info wasn’t identical
- mountLockAquire()[source]
Create a lock for a mountpoint to prevent unmounting as long as this process is still running.
- mountLockCheck()[source]
Check for locks on the current mountpoint.
- Returns:
True
if there are any locks- Return type:
- mountProcessLockAcquire(timeout=60)[source]
Create a short term lock only for blocking other processes changing mounts at the same time.
- Parameters:
timeout (int) – wait
timeout
seconds before fail acquiring the lock- Raises:
exceptions.MountException – if timed out
- mounted()[source]
Check if the mountpoint is already mounted.
- Returns:
True
if mountpoint is mounted- Return type:
- Raises:
exceptions.MountException – if mountpoint is not mounted but also not empty
- postMountCheck()[source]
Check if the mount was successful. This can be overwritten in backends which subclasses
MountControl
.- Returns:
True
if all checks where okay- Return type:
- Raises:
exceptions.MountException – if backend wasn’t mount successful
Note
This can also be used to clean up after running
_mount()
- postUmountCheck()[source]
Check if unmount was successful. This can be overwritten in backends which subclasses
MountControl
.- Returns:
True
if all checks where okay- Return type:
- Raises:
exceptions.MountException – if backend wasn’t unmounted successful
Note
This can also be used to clean up after running
_umount()
- preMountCheck(first_run=False)[source]
Check what ever conditions must be given for the mount to be done successful. This can be overwritten in backends which subclasses
MountControl
.- Returns:
True
if all checks where okay- Return type:
- Raises:
exceptions.MountException – if backend can not mount
Note
This can also be used to prepare things before running
_mount()
- preUmountCheck()[source]
Check if backend is safe to umount. This can be overwritten in backends which subclasses
MountControl
.- Returns:
True
if all checks where okay- Return type:
- Raises:
exceptions.MountException – if backend can not umount
Note
This can also be used to prepare things before running
_umount()
- removeSymlink(profile_id=None, tmp_mount=None)[source]
Remove symlink
~/.local/share/backintime/mnt/<profile id>_<pid>
- setDefaultArgs()[source]
Set some arguments which are necessary for all backends.
self.all_kwargs
need to be filled throughsetattrKwargs()
before calling this.
- setSymlink(profile_id=None, hash_id=None, tmp_mount=None)[source]
If
self.symlink
isTrue
set symlink~/.local/share/backintime/mnt/<profile id>_<pid>
. Target will be either the mountpoint or a subfolder of the mountpoint ifself.symlink_subfolder
is set.
- setattrKwargs(arg, default, store=True, **kwargs)[source]
Set attribute
arg
in local namespace (self.arg). Also collect all args inself.all_kwargs
which will be hashed later and used as mountpoint name and also be written as unmount_info.
- umount()[source]
Low-level umount. Set mountprocess lock, run umount checks and call
_umount()
for the subclassed backend. Finally release mount lock, remove symlink and release mountprocess lock.- Raises:
exceptions.MountException – if a check failed