From: Vratislav Podzimek <vpodzime(a)redhat.com>
Except for the few things that are not provided by BlockDev.
---
blivet/devicelibs/btrfs.py | 167 ---------------------------------------------
blivet/devices/btrfs.py | 42 +++++++-----
blivet/devicetree.py | 8 +--
blivet/formats/fs.py | 4 +-
4 files changed, 32 insertions(+), 189 deletions(-)
diff --git a/blivet/devicelibs/btrfs.py b/blivet/devicelibs/btrfs.py
index a0a4ec8..65a6ca6 100644
--- a/blivet/devicelibs/btrfs.py
+++ b/blivet/devicelibs/btrfs.py
@@ -20,12 +20,7 @@
# Author(s): David Lehman <dlehman(a)redhat.com>
#
-import os
-import re
-
from . import raid
-from .. import util
-from ..errors import BTRFSError, BTRFSValueError
from ..size import Size
import logging
@@ -40,165 +35,3 @@
RAID_levels = raid.RAIDLevels(["raid0", "raid1", "raid10",
"single"])
metadata_levels = raid.RAIDLevels(["raid0", "raid1",
"raid10", "single", "dup"])
-
-def btrfs(args, capture=False):
- if capture:
- exec_func = util.capture_output
- else:
- exec_func = util.run_program
-
- argv = ["btrfs"] + args
-
- ret = exec_func(argv)
- if ret and not capture:
- raise BTRFSError(ret)
- return ret
-
-def create_volume(devices, label=None, data=None, metadata=None):
- """Create a btrfs filesystem on the list of devices specified by
devices.
-
- :param data: a raid level for data
- :type data: :class:`~.devicelibs.raid.RAIDLevel` or str
- :param metadata: a raid level for metadata
- :type metadata: :class:`~.devicelibs.raid.RAIDLevel` or str
-
- Note that if a level is specified as a string, rather than by means
- of a RAIDLevel object, it is not checked for validity. It is the
- responsibility of the invoking method to verify that mkfs.btrfs
- recognizes the string.
- """
- if not devices:
- raise BTRFSValueError("no devices specified")
- elif any([not os.path.exists(d) for d in devices]):
- raise BTRFSValueError("one or more specified devices not present")
-
- args = []
- if data:
- args.append("--data=%s" % data)
-
- if metadata:
- args.append("--metadata=%s" % metadata)
-
- if label:
- args.append("--label=%s" % label)
-
- args.extend(devices)
-
- ret = util.run_program(["mkfs.btrfs"] + args)
- if ret:
- raise BTRFSError(ret)
-
- return ret
-
-# destroy is handled using wipefs
-
-def add(mountpoint, device):
- if not os.path.ismount(mountpoint):
- raise BTRFSValueError("volume not mounted")
-
- return btrfs(["device", "add", device, mountpoint])
-
-def remove(mountpoint, device):
- if not os.path.ismount(mountpoint):
- raise BTRFSValueError("volume not mounted")
-
- return btrfs(["device", "delete", device, mountpoint])
-
-def create_subvolume(mountpoint, name):
- """Create a subvolume named name below mountpoint
mountpoint."""
- if not os.path.ismount(mountpoint):
- raise BTRFSValueError("volume not mounted")
-
- path = os.path.normpath("%s/%s" % (mountpoint, name))
- args = ["subvol", "create", path]
- return btrfs(args)
-
-def delete_subvolume(mountpoint, name):
- if not os.path.ismount(mountpoint):
- raise BTRFSValueError("volume not mounted")
-
- path = os.path.normpath("%s/%s" % (mountpoint, name))
- args = ["subvol", "delete", path]
- return btrfs(args)
-
-_SUBVOL_REGEX_STR = r'ID (?P<id>\d+) gen \d+ (cgen \d+ )?parent
(?P<parent>\d+) top level \d+ (otime \d{4}-\d{2}-\d{2} \d\d:\d\d:\d\d )?path
(?P<path>.+)\n'
-_SUBVOL_REGEX = re.compile(_SUBVOL_REGEX_STR)
-
-# get a list of subvolumes from a mounted btrfs filesystem
-def list_subvolumes(mountpoint, snapshots_only=False):
- if not os.path.ismount(mountpoint):
- raise BTRFSValueError("volume not mounted")
-
- args = ["subvol", "list", "-p", mountpoint]
- if snapshots_only:
- args.insert(2, "-s")
-
- buf = btrfs(args, capture=True)
- vols = []
- for m in _SUBVOL_REGEX.finditer(buf):
- vols.append({"id": int(m.group('id')), "parent":
int(m.group('parent')),
- "path": m.group('path')})
-
- return vols
-
-def get_default_subvolume(mountpoint):
- if not os.path.ismount(mountpoint):
- raise BTRFSValueError("volume not mounted")
-
- args = ["subvol", "get-default", mountpoint]
- buf = btrfs(args, capture=True)
- m = re.match(r'ID (\d+) .*', buf)
- try:
- default = int(m.groups()[0])
- except IndexError:
- raise BTRFSError("failed to get default subvolume from %s" %
mountpoint)
-
- return default
-
-def set_default_subvolume(mountpoint, subvol_id):
- """ Sets the subvolume of mountpoint which is mounted as default.
-
- :param str mountpoint: path of mountpoint
- :param int subvol_id: the subvolume id to set as the default
- """
- if not os.path.ismount(mountpoint):
- raise ValueError("volume not mounted")
-
- args = ["subvol", "set-default", str(subvol_id), mountpoint]
- return btrfs(args)
-
-def create_snapshot(source, dest, ro=False):
- """
- :param str source: path to source subvolume
- :param str dest: path to new snapshot subvolume
- :keyword bool ro: whether to create a read-only snapshot
- """
- if not os.path.ismount(source):
- raise BTRFSValueError("source is not a mounted subvolume")
-
- args = ["subvol", "snapshot"]
- if ro:
- args.append("-r")
-
- args.extend([source, dest])
- return btrfs(args)
-
-_DEVICE_REGEX_STR = r'devid[ \t]+(\d+)[ \t]+size[ \t]+(\S+)[ \t]+used[ \t]+(\S+)[
\t]+path[ \t]+(\S+)\n'
-_DEVICE_REGEX = re.compile(_DEVICE_REGEX_STR)
-
-def list_devices(device):
- """List the devices in the filesystem in which this device
participates. """
- args = ["filesystem", "show", device]
- buf = btrfs(args, capture=True)
- return [{"id" : g[0], "size" : g[1], "used" : g[2],
"path" : g[3] } for g in _DEVICE_REGEX.findall(buf)]
-
-_HEADER_REGEX_STR = r'Label: (?P<label>\S+)[ \t]+uuid:
(?P<uuid>\S+)\s+Total devices (?P<num_devices>\d+)[ \t]+FS bytes used
(?P<fs_bytes_used>\S+)\n'
-_HEADER_REGEX = re.compile(_HEADER_REGEX_STR)
-
-def summarize_filesystem(device):
- """Summarize some general information about the filesystem in which
this
- device participates.
- """
- args = ["filesystem", "show", device]
- buf = btrfs(args, capture=True)
- return _HEADER_REGEX.search(buf).groupdict()
diff --git a/blivet/devices/btrfs.py b/blivet/devices/btrfs.py
index b650854..674d3c4 100644
--- a/blivet/devices/btrfs.py
+++ b/blivet/devices/btrfs.py
@@ -22,6 +22,8 @@
import os
import copy
import tempfile
+from gi.repository import BlockDev as blockdev
+from gi.repository import GLib
from ..devicelibs import btrfs
from ..devicelibs import raid
@@ -326,9 +328,9 @@ def listSubVolumes(self, snapshotsOnly=False):
return subvols
try:
- subvols = btrfs.list_subvolumes(self.originalFormat._mountpoint,
- snapshots_only=snapshotsOnly)
- except errors.BTRFSError as e:
+ subvols = blockdev.btrfs_list_subvolumes(self.originalFormat._mountpoint,
+ snapshots_only=snapshotsOnly)
+ except GLib.GError as e:
log.debug("failed to list subvolumes: %s", e)
else:
self._getDefaultSubVolumeID()
@@ -353,8 +355,8 @@ def removeSubVolume(self, name):
def _getDefaultSubVolumeID(self):
subvolid = None
try:
- subvolid = btrfs.get_default_subvolume(self.originalFormat._mountpoint)
- except errors.BTRFSError as e:
+ subvolid =
blockdev.btrfs_get_default_subvolume_id(self.originalFormat._mountpoint)
+ except GLib.Error as e:
log.debug("failed to get default subvolume id: %s", e)
self._defaultSubVolumeID = subvolid
@@ -365,8 +367,8 @@ def _setDefaultSubVolumeID(self, vol_id):
This writes the change to the filesystem, which must be mounted.
"""
try:
- btrfs.set_default_subvolume(self.originalFormat._mountpoint, vol_id)
- except errors.BTRFSError as e:
+ blockdev.btrfs_set_default_subvolume(self.originalFormat._mountpoint,
vol_id)
+ except GLib.Error as e:
log.error("failed to set new default subvolume id (%s): %s",
vol_id, e)
# The only time we set a new default subvolume is so we can remove
@@ -398,10 +400,18 @@ def _preCreate(self):
def _create(self):
log_method_call(self, self.name, status=self.status)
- btrfs.create_volume(devices=[d.path for d in self.parents],
- label=self.format.label,
- data=self.dataLevel,
- metadata=self.metaDataLevel)
+ if self.dataLevel:
+ data_level = str(self.dataLevel)
+ else:
+ data_level = None
+ if self.metaDataLevel:
+ md_level = str(self.metaDataLevel)
+ else:
+ md_level = None
+ blockdev.btrfs_create_volume([d.path for d in self.parents],
+ label=self.format.label,
+ data_level=data_level,
+ md_level=md_level)
def _postCreate(self):
super(BTRFSVolumeDevice, self)._postCreate()
@@ -429,7 +439,7 @@ def _remove(self, member):
raise
try:
- btrfs.remove(self.originalFormat._mountpoint, member.path)
+ blockdev.btrfs_remove_device(self.originalFormat._mountpoint, member.path)
finally:
self._undo_temp_mount()
@@ -441,7 +451,7 @@ def _add(self, member):
raise
try:
- btrfs.add(self.originalFormat._mountpoint, member.path)
+ blockdev.btrfs_add_device(self.originalFormat._mountpoint, member.path)
finally:
self._undo_temp_mount()
@@ -531,7 +541,7 @@ def _create(self):
raise RuntimeError("btrfs subvol create requires mounted volume")
try:
- btrfs.create_subvolume(mountpoint, self.name)
+ blockdev.btrfs_create_subvolume(mountpoint, self.name)
finally:
self.volume._undo_temp_mount()
@@ -549,7 +559,7 @@ def _destroy(self):
mountpoint = self.volume.originalFormat._mountpoint
if not mountpoint:
raise RuntimeError("btrfs subvol destroy requires mounted volume")
- btrfs.delete_subvolume(mountpoint, self.name)
+ blockdev.btrfs_delete_subvolume(mountpoint, self.name)
self.volume._undo_temp_mount()
def removeHook(self, modparent=True):
@@ -633,7 +643,7 @@ def _create(self):
dest_path = "%s/%s" % (mountpoint, self.name)
try:
- btrfs.create_snapshot(source_path, dest_path, ro=self.readOnly)
+ blockdev.btrfs_create_snapshot(source_path, dest_path, ro=self.readOnly)
finally:
self.volume._undo_temp_mount()
diff --git a/blivet/devicetree.py b/blivet/devicetree.py
index 6b84fb9..c7ffd91 100644
--- a/blivet/devicetree.py
+++ b/blivet/devicetree.py
@@ -1716,11 +1716,11 @@ def handleBTRFSFormat(self, info, device):
if not btrfs_dev.subvolumes:
snapshots = btrfs_dev.listSubVolumes(snapshotsOnly=True)
- snapshot_ids = [s["id"] for s in snapshots]
+ snapshot_ids = [s.id for s in snapshots]
for subvol_dict in btrfs_dev.listSubVolumes():
- vol_id = subvol_dict["id"]
- vol_path = subvol_dict["path"]
- parent_id = subvol_dict["parent"]
+ vol_id = subvol_dict.id
+ vol_path = subvol_dict.path
+ parent_id = subvol_dict.parent_id
if vol_path in [sv.name for sv in btrfs_dev.subvolumes]:
continue
diff --git a/blivet/formats/fs.py b/blivet/formats/fs.py
index 69ead04..747493d 100644
--- a/blivet/formats/fs.py
+++ b/blivet/formats/fs.py
@@ -1125,11 +1125,11 @@ def __init__(self, **kwargs):
self.volUUID = kwargs.pop("volUUID", None)
def create(self, **kwargs):
- # filesystem creation is done in storage.devicelibs.btrfs.create_volume
+ # filesystem creation is done in blockdev.btrfs_create_volume
self.exists = True
def destroy(self, **kwargs):
- # filesystem creation is done in storage.devicelibs.btrfs.delete_volume
+ # filesystem deletion is done in blockdev.btrfs_delete_volume
self.exists = False
def setup(self, **kwargs):
--
To view this commit on github, visit
https://github.com/rhinstaller/blivet/commit/8af8c55d95b52ae310ddf44b10e4...