fuxi/fuxi/common/mount.py

153 lines
5.2 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from fuxi import exceptions
from fuxi.i18n import _
from fuxi import utils
from oslo_concurrency import processutils
from oslo_log import log as logging
from oslo_utils import excutils
proc_mounts_path = '/proc/mounts'
LOG = logging.getLogger(__name__)
class MountInfo(object):
def __init__(self, device, mountpoint, fstype, opts):
self.device = device
self.mountpoint = mountpoint
self.fstype = fstype
self.opts = opts
def __repr__(self, *args, **kwargs):
return str(self.__dict__)
class Mounter(object):
def make_filesystem(self, devpath, fstype):
try:
utils.execute('mkfs', '-t', fstype, '-F', devpath,
run_as_root=True)
except processutils.ProcessExecutionError as e:
msg = _("Unexpected error while make filesystem. "
"Devpath: {0}, "
"Fstype: {1}"
"Error: {2}").format(devpath, fstype, e)
raise exceptions.MakeFileSystemException(msg)
def mount(self, devpath, mountpoint, fstype=None):
try:
if fstype:
utils.execute('mount', '-t', fstype, devpath, mountpoint,
run_as_root=True)
else:
utils.execute('mount', devpath, mountpoint,
run_as_root=True)
except processutils.ProcessExecutionError as e:
msg = _("Unexpected error while mount block device. "
"Devpath: {0}, "
"Mountpoint: {1} "
"Error: {2}").format(devpath, mountpoint, e)
raise exceptions.MountException(msg)
def unmount(self, mountpoint):
try:
utils.execute('umount', mountpoint, run_as_root=True)
except processutils.ProcessExecutionError as e:
msg = _("Unexpected err while unmount block device. "
"Mountpoint: {0}, "
"Error: {1}").format(mountpoint, e)
raise exceptions.UnmountException(msg)
def read_mounts(self, filter_device=(), filter_fstype=()):
"""Read all mounted filesystems.
Read all mounted filesystems except filtered option.
:param filter_device: Filter for device, the result will not contain
the mounts whose device argument in it.
:param filter_fstype: Filter for mount point.
:return: All mounts.
"""
try:
(out, err) = processutils.execute('cat', proc_mounts_path,
check_exit_code=0)
except processutils.ProcessExecutionError:
msg = _("Failed to read mounts.")
raise exceptions.FileNotFound(msg)
lines = out.split('\n')
mounts = []
for line in lines:
if not line:
continue
tokens = line.split()
if len(tokens) < 4:
continue
if tokens[0] in filter_device or tokens[1] in filter_fstype:
continue
mounts.append(MountInfo(device=tokens[0], mountpoint=tokens[1],
fstype=tokens[2], opts=tokens[3]))
return mounts
def get_mps_by_device(self, devpath):
"""Get all mountpoints that device mounted on.
:param devpath: The path of mount device.
:return: All mountpoints.
:rtype: list
"""
mps = []
mounts = self.read_mounts()
for m in mounts:
if devpath == m.device:
mps.append(m.mountpoint)
return mps
def check_already_mounted(devpath, mountpoint):
"""Check that the mount device is mounted on the specific mount point.
:param devpath: The path of mount deivce.
:param mountpoint: The path of mount point.
:rtype: bool
"""
mounts = Mounter().read_mounts()
for m in mounts:
if devpath == m.device and mountpoint == m.mountpoint:
return True
return False
def do_mount(devpath, mountpoint, fstype):
"""Execute device mount operation.
:param devpath: The path of mount device.
:param mountpoint: The path of mount point.
:param fstype: The file system type.
"""
try:
if check_already_mounted(devpath, mountpoint):
return
mounter = Mounter()
mounter.mount(devpath, mountpoint, fstype)
except exceptions.MountException:
try:
mounter.make_filesystem(devpath, fstype)
mounter.mount(devpath, mountpoint, fstype)
except exceptions.FuxiException as e:
with excutils.save_and_reraise_exception():
LOG.error(str(e))