Patches 1-3 are for switch to python-pyudev.
Patch 4 splits devices.py into devices package.
Patch 5 switches from transifex to zanata.
Patches 6-10 are for rc-release builds.
Patches 11,12 are required changes.
Patch 13 is just low-hanging pylint fruit.
bcl, clumens, do we want/need the rc-release/mock stuff on rhel7-branch?
I have tested this by installing a scratch build in a freshly- installed 7.1 vm and running the examples shipped with blivet.
There are two major differences in how we use the module. Each device is represented by a pyudev.Device instance, which is based on collections.abc.Mapping. That means we can no longer change the data to do things like set a "multipath_member" format type or inject LVM or MD metadata.
The other difference is that sysfs paths now include the "/sys", which is great since it's always mounted in the same place.
(cherry picked from commit 8ff97169daa3fe529e4849e3431d9ec9147c2c20) --- blivet/devices.py | 96 +++++++--------------- blivet/devicetree.py | 64 +++++++-------- blivet/pyudev.py | 226 --------------------------------------------------- blivet/udev.py | 142 +++++++++----------------------- blivet/util.py | 2 +- python-blivet.spec | 1 + tests/udev_test.py | 130 +---------------------------- 7 files changed, 107 insertions(+), 554 deletions(-) delete mode 100644 blivet/pyudev.py
diff --git a/blivet/devices.py b/blivet/devices.py index 6724071..d78ff5b 100644 --- a/blivet/devices.py +++ b/blivet/devices.py @@ -27,6 +27,7 @@ import tempfile import abc from decimal import Decimal import re +import pyudev
from six import add_metaclass
@@ -107,7 +108,7 @@ def deviceNameToDiskByPath(deviceName=None): return ""
ret = None - for dev in udev.get_block_devices(): + for dev in udev.get_devices(): if udev.device_get_name(dev) == deviceName: ret = udev.device_get_by_path(dev) break @@ -523,7 +524,6 @@ class StorageDevice(Device):
_type = "blivet" _devDir = "/dev" - sysfsBlockDir = "class/block" _formatImmutable = False _partitionable = False _isDisk = False @@ -789,11 +789,22 @@ class StorageDevice(Device):
def updateSysfsPath(self): """ Update this device's sysfs path. """ - log_method_call(self, self.name, status=self.status) - sysfsName = self.name.replace("/", "!") - path = os.path.join("/sys", self.sysfsBlockDir, sysfsName) - self.sysfsPath = os.path.realpath(path)[4:] - log.debug("%s sysfsPath set to %s", self.name, self.sysfsPath) + # We're using os.path.exists as a stand-in for status. We can't use + # the status property directly because MDRaidArrayDevice.status calls + # this method. + log_method_call(self, self.name, status=os.path.exists(self.path)) + if not self.exists: + raise errors.DeviceError("device has not been created", self.name) + + try: + udev_device = pyudev.Device.from_device_file(udev.global_udev, + self.path) + except pyudev.DeviceNotFoundError as e: + log.error("failed to update sysfs path for %s: %s", self.name, e) + self.sysfsPath = '' + else: + self.sysfsPath = udev_device.sys_path + log.debug("%s sysfsPath set to %s", self.name, self.sysfsPath)
@property def formatArgs(self): @@ -818,7 +829,7 @@ class StorageDevice(Device): log.debug("not sending change uevent for inactive device") return
- path = os.path.normpath("/sys/%s" % self.sysfsPath) + path = os.path.normpath(self.sysfsPath) try: util.notify_kernel(path, action="change") except (ValueError, IOError) as e: @@ -1093,7 +1104,7 @@ class StorageDevice(Device):
@property def removable(self): - devpath = os.path.normpath("/sys/%s" % self.sysfsPath) + devpath = os.path.normpath(self.sysfsPath) remfile = os.path.normpath("%s/removable" % devpath) return (self.sysfsPath and os.path.exists(devpath) and os.access(remfile, os.R_OK) and @@ -1668,23 +1679,6 @@ class PartitionDevice(StorageDevice): weight = property(lambda d: d._getWeight(), lambda d,w: d._setWeight(w))
- def updateSysfsPath(self): - """ Update this device's sysfs path. """ - log_method_call(self, self.name, status=self.status) - if not self.parents: - self.sysfsPath = '' - - elif isinstance(self.parents[0], DMDevice): - dm_node = dm.dm_node_from_name(self.name) - path = os.path.join("/sys", self.sysfsBlockDir, dm_node) - self.sysfsPath = os.path.realpath(path)[4:] - elif isinstance(self.parents[0], MDRaidArrayDevice): - md_node = mdraid.md_node_from_name(self.name) - path = os.path.join("/sys", self.sysfsBlockDir, md_node) - self.sysfsPath = os.path.realpath(path)[4:] - else: - StorageDevice.updateSysfsPath(self) - def _setName(self, value): self._name = value # actual name setting is done by parted
@@ -2252,19 +2246,6 @@ class DMDevice(StorageDevice): None) return (match.live_table and not match.suspended) if match else False
- def updateSysfsPath(self): - """ Update this device's sysfs path. """ - log_method_call(self, self.name, status=self.status) - if not self.exists: - raise errors.DeviceError("device has not been created", self.name) - - if self.status: - dm_node = self.getDMNode() - path = os.path.join("/sys", self.sysfsBlockDir, dm_node) - self.sysfsPath = os.path.realpath(path)[4:] - else: - self.sysfsPath = '' - #def getTargetType(self): # return dm.getDmTarget(name=self.name)
@@ -4098,22 +4079,6 @@ class MDRaidArrayDevice(ContainerDevice):
spares = property(_getSpares, _setSpares)
- def updateSysfsPath(self): - """ Update this device's sysfs path. """ - # don't include self.status here since this method is called by - # MDRaidArrayDevice.status - log_method_call(self, self.name) - if not self.exists: - raise errors.DeviceError("device has not been created", self.name) - - # We don't use self.status here because self.status requires a valid - # sysfs path to function correctly. - if os.path.exists(self.path): - md_node = mdraid.md_node_from_name(self.name) - self.sysfsPath = "/devices/virtual/block/%s" % md_node - else: - self.sysfsPath = '' - def _addParent(self, member): super(MDRaidArrayDevice, self)._addParent(member)
@@ -4174,7 +4139,7 @@ class MDRaidArrayDevice(ContainerDevice): self.updateSysfsPath()
# make sure the active array is the one we expect - info = udev.get_block_device(self.sysfsPath) + info = udev.get_device(self.sysfsPath) uuid = udev.device_get_md_uuid(info) if uuid and uuid != self.uuid: log.warning("md array %s is active, but has UUID %s -- not %s", @@ -4182,7 +4147,7 @@ class MDRaidArrayDevice(ContainerDevice): self.sysfsPath = "" return status
- state_file = "/sys/%s/md/array_state" % self.sysfsPath + state_file = "%s/md/array_state" % self.sysfsPath try: state = open(state_file).read().strip() if state in ("clean", "active", "active-idle", "readonly", "read-auto"): @@ -4212,7 +4177,7 @@ class MDRaidArrayDevice(ContainerDevice): def degraded(self): """ Return True if the array is running in degraded mode. """ rc = False - degraded_file = "/sys/%s/md/degraded" % self.sysfsPath + degraded_file = "%s/md/degraded" % self.sysfsPath if os.access(degraded_file, os.R_OK): val = open(degraded_file).read().strip() if val == "1": @@ -4270,7 +4235,7 @@ class MDRaidArrayDevice(ContainerDevice): # mdadm reuses minors indiscriminantly when there is no mdadm.conf, so # we need to clear the sysfs path now so our status method continues to # give valid results - self.updateSysfsPath() + self.sysfsPath = ''
def teardown(self, recursive=None): """ Close, or tear down, a device. """ @@ -4312,15 +4277,14 @@ class MDRaidArrayDevice(ContainerDevice):
def _postCreate(self): # this is critical since our status method requires a valid sysfs path - md_node = mdraid.md_node_from_name(self.name) - self.sysfsPath = "/devices/virtual/block/%s" % md_node - self.exists = True # I think we can remove this. - + self.exists = True # this is needed to run updateSysfsPath + self.updateSysfsPath() StorageDevice._postCreate(self)
# update our uuid attribute with the new array's UUID - info = udev.get_block_device(self.sysfsPath) - self.uuid = udev.device_get_md_uuid(info) + # XXX this won't work for containers since no UUID is reported for them + info = mdraid.mddetail(self.path) + self.uuid = info.get("UUID") for member in self.devices: member.format.mdUuid = self.uuid
@@ -5568,7 +5532,7 @@ class BTRFSVolumeDevice(BTRFSDevice, ContainerDevice):
def _postCreate(self): super(BTRFSVolumeDevice, self)._postCreate() - info = udev.get_block_device(self.sysfsPath) + info = udev.get_device(self.sysfsPath) if not info: log.error("failed to get updated udev info for new btrfs volume") else: diff --git a/blivet/devicetree.py b/blivet/devicetree.py index 9f1aa9e..4ba4640 100644 --- a/blivet/devicetree.py +++ b/blivet/devicetree.py @@ -645,7 +645,7 @@ class DeviceTree(object):
if self.udevDeviceIsDisk(info): # Ignore any readonly disks - if util.get_sysfs_attr(info["sysfs_path"], 'ro') == '1': + if util.get_sysfs_attr(udev.device_get_sysfs_path(info), 'ro') == '1': log.debug("Ignoring read only device %s", name) # FIXME: We have to handle this better, ie: not ignore these. self.addIgnoredDisk(name) @@ -691,10 +691,10 @@ class DeviceTree(object): if not device: # initiate detection of all PVs and hope that it leads to us having # the VG and LVs in the tree - for pv_name in os.listdir("/sys" + sysfs_path + "/slaves"): - link = os.readlink("/sys" + sysfs_path + "/slaves/" + pv_name) + for pv_name in os.listdir(sysfs_path + "/slaves"): + link = os.readlink(sysfs_path + "/slaves/" + pv_name) pv_sysfs_path = os.path.normpath(sysfs_path + '/slaves/' + link) - pv_info = udev.get_block_device(pv_sysfs_path) + pv_info = udev.get_device(pv_sysfs_path) self.addUdevDevice(pv_info)
vg_name = udev.device_get_lv_vg_name(info) @@ -737,7 +737,7 @@ class DeviceTree(object): if device is None: # we couldn't find it, so create it # first, get a list of the slave devs and look them up - slave_dir = os.path.normpath("/sys/%s/slaves" % sysfs_path) + slave_dir = os.path.normpath("%s/slaves" % sysfs_path) slave_names = os.listdir(slave_dir) for slave_name in slave_names: # if it's a dm-X name, resolve it to a map name first @@ -747,7 +747,7 @@ class DeviceTree(object): dev_name = slave_name.replace("!", "/") # handles cciss slave_dev = self.getDeviceByName(dev_name) path = os.path.normpath("%s/%s" % (slave_dir, slave_name)) - new_info = udev.get_block_device(os.path.realpath(path)[4:]) + new_info = udev.get_device(os.path.realpath(path)) if not slave_dev: # we haven't scanned the slave yet, so do it now if new_info: @@ -807,7 +807,7 @@ class DeviceTree(object): # TODO: look for this device by dm-uuid?
# first, get a list of the slave devs and look them up - slave_dir = os.path.normpath("/sys/%s/slaves" % sysfs_path) + slave_dir = os.path.normpath("%s/slaves" % sysfs_path) slave_names = os.listdir(slave_dir) for slave_name in slave_names: # if it's a dm-X name, resolve it to a map name first @@ -817,7 +817,7 @@ class DeviceTree(object): dev_name = slave_name.replace("!", "/") # handles cciss slave_dev = self.getDeviceByName(dev_name) path = os.path.normpath("%s/%s" % (slave_dir, slave_name)) - new_info = udev.get_block_device(os.path.realpath(path)[4:]) + new_info = udev.get_device(os.path.realpath(path)) if not slave_dev: # we haven't scanned the slave yet, so do it now if new_info: @@ -850,7 +850,7 @@ class DeviceTree(object): log_method_call(self, name=name) sysfs_path = udev.device_get_sysfs_path(info)
- slave_dir = os.path.normpath("/sys/%s/slaves" % sysfs_path) + slave_dir = os.path.normpath("%s/slaves" % sysfs_path) slave_names = os.listdir(slave_dir) for slave_name in slave_names: # if it's a dm-X name, resolve it to a map name @@ -862,7 +862,7 @@ class DeviceTree(object): if not slave_dev: # we haven't scanned the slave yet, so do it now path = os.path.normpath("%s/%s" % (slave_dir, slave_name)) - new_info = udev.get_block_device(os.path.realpath(path)[4:]) + new_info = udev.get_device(os.path.realpath(path)) if new_info: self.addUdevDevice(new_info) if self.getDeviceByName(dev_name) is None: @@ -921,7 +921,7 @@ class DeviceTree(object):
if disk is None: # create a device instance for the disk - new_info = udev.get_block_device(os.path.dirname(sysfs_path)) + new_info = udev.get_device(os.path.dirname(sysfs_path)) if new_info: self.addUdevDevice(new_info) disk = self.getDeviceByName(disk_name) @@ -1018,8 +1018,8 @@ class DeviceTree(object): container = self.getDeviceByName(parentName) if not container: parentSysName = mdraid.md_node_from_name(parentName) - container_sysfs = "/class/block/" + parentSysName - container_info = udev.get_block_device(container_sysfs) + container_sysfs = "/sys/class/block/" + parentSysName + container_info = udev.get_device(container_sysfs) if not container_info: log.error("failed to find md container %s at %s", parentName, container_sysfs) @@ -1064,9 +1064,6 @@ class DeviceTree(object): minor=udev.device_get_minor(info), sysfsPath=sysfs_path, **kwargs)
- if mpath.is_multipath_member(device.path): - info["ID_FS_TYPE"] = "multipath_member" - if diskType == DASDDevice: self.dasd.append(device)
@@ -1091,7 +1088,7 @@ class DeviceTree(object): name = udev.device_get_name(info) log_method_call(self, name=name) sysfs_path = udev.device_get_sysfs_path(info) - sys_file = "/sys/%s/loop/backing_file" % sysfs_path + sys_file = "%s/loop/backing_file" % sysfs_path backing_file = open(sys_file).read().strip() file_device = self.getDeviceByName(backing_file) if not file_device: @@ -1111,7 +1108,7 @@ class DeviceTree(object):
def addUdevDevice(self, info): name = udev.device_get_name(info) - log_method_call(self, name=name, info=pprint.pformat(info)) + log_method_call(self, name=name, info=pprint.pformat(dict(info))) uuid = udev.device_get_uuid(info) sysfs_path = udev.device_get_sysfs_path(info)
@@ -1152,8 +1149,6 @@ class DeviceTree(object):
if device and device.isDisk and \ mpath.is_multipath_member(device.path): - # mark as multipath_member also when repopulating devicetree - info["ID_FS_TYPE"] = "multipath_member" # newly added device (eg iSCSI) could make this one a multipath member if device.format and device.format.type != "multipath_member": log.debug("%s newly detected as multipath member, dropping old format and removing kids", device.name) @@ -1481,7 +1476,7 @@ class DeviceTree(object):
if lv_device.status: lv_device.updateSysfsPath() - lv_info = udev.get_block_device(lv_device.sysfsPath) + lv_info = udev.get_device(lv_device.sysfsPath) if not lv_info: log.error("failed to get udev data for lv %s", lv_device.name) return @@ -1578,7 +1573,7 @@ class DeviceTree(object):
# check the list of devices udev knows about to see if the array # this device belongs to is already active - for dev in udev.get_block_devices(): + for dev in udev.get_devices(): if not udev.device_is_md(dev): continue
@@ -1681,13 +1676,13 @@ class DeviceTree(object): self._addDevice(dm_array)
# Wait for udev to scan the just created nodes, to avoid a race - # with the udev.get_block_device() call below. + # with the udev.get_device() call below. udev.settle()
# Get the DMRaidArrayDevice a DiskLabel format *now*, in case # its partitions get scanned before it does. dm_array.updateSysfsPath() - dm_array_info = udev.get_block_device(dm_array.sysfsPath) + dm_array_info = udev.get_device(dm_array.sysfsPath) self.handleUdevDiskLabelFormat(dm_array_info, dm_array)
# Use the rs's object on the device. @@ -1773,11 +1768,15 @@ class DeviceTree(object): format_type = udev.device_get_format(info) serial = udev.device_get_serial(info)
+ is_multipath_member = mpath.is_multipath_member(device.path) + if is_multipath_member: + format_type = "multipath_member" + # Now, if the device is a disk, see if there is a usable disklabel. # If not, see if the user would like to create one. # XXX ignore disklabels on multipath or biosraid member disks if not udev.device_is_biosraid_member(info) and \ - not udev.device_is_multipath_member(info) and \ + not is_multipath_member and \ format_type != "iso9660": self.handleUdevDiskLabelFormat(info, device) if device.partitioned or self.isIgnored(info) or \ @@ -1890,7 +1889,7 @@ class DeviceTree(object): def updateDeviceFormat(self, device): log.info("updating format of device: %s", device) try: - util.notify_kernel("/sys%s" % device.sysfsPath) + util.notify_kernel(device.sysfsPath) except (ValueError, IOError) as e: log.warning("failed to notify kernel of change: %s", e)
@@ -2022,7 +2021,7 @@ class DeviceTree(object): loop_name = loop.get_loop_name(filedev.path) loop_sysfs = None if loop_name: - loop_sysfs = "/class/block/%s" % loop_name + loop_sysfs = "/sys/class/block/%s" % loop_name loopdev = LoopDevice(name=loop_name, parents=[filedev], sysfsPath=loop_sysfs, @@ -2042,7 +2041,7 @@ class DeviceTree(object): self._addDevice(filedev) self._addDevice(loopdev) self._addDevice(dmdev) - info = udev.get_block_device(dmdev.sysfsPath) + info = udev.get_device(dmdev.sysfsPath) self.addUdevDevice(info)
def backupConfigs(self, restore=False): @@ -2156,18 +2155,19 @@ class DeviceTree(object): # blocks or since previous iterations. while True: devices = [] - new_devices = udev.get_block_devices() + new_devices = udev.get_devices()
for new_device in new_devices: - if new_device['name'] not in old_devices: - old_devices[new_device['name']] = new_device + new_name = udev.device_get_name(new_device) + if new_name not in old_devices: + old_devices[new_name] = new_device devices.append(new_device)
if len(devices) == 0: # nothing is changing -- we are finished building devices break
- log.info("devices to scan: %s", [d['name'] for d in devices]) + log.info("devices to scan: %s", [udev.device_get_name(d) for d in devices]) for dev in devices: self.addUdevDevice(dev)
diff --git a/blivet/pyudev.py b/blivet/pyudev.py deleted file mode 100644 index fa0846f..0000000 --- a/blivet/pyudev.py +++ /dev/null @@ -1,226 +0,0 @@ -from __future__ import print_function - -import sys -import os -import fnmatch -from ctypes import CDLL, c_char_p, c_int, c_void_p - - -# XXX this one may need some tweaking... -def find_library(name, somajor=0): - env = os.environ.get("LD_LIBRARY_PATH") - common = ["/lib64", "/lib"] - - if env: - libdirs = env.split(":") + common - else: - libdirs = common - - for ldir in filter(os.path.isdir, libdirs): - files = fnmatch.filter(os.listdir(ldir), "lib%s.so.%d" % (name, somajor)) - if files: - return next(os.path.join(ldir, lfile) for lfile in files) - - return None - -def get_library(): - name = "udev" - somajor = 1 - lib = find_library(name=name, somajor=somajor) - - if not lib or not os.path.exists(lib): - raise ImportError("No library named %s.%d" % (name, somajor)) - return lib - -# load the udev library -libudev = CDLL(get_library()) - - -# create aliases for needed functions and set the return types where needed -libudev_udev_new = libudev.udev_new -libudev_udev_new.argtypes = [] -libudev_udev_new.restype = c_void_p -libudev_udev_unref = libudev.udev_unref -libudev_udev_unref.argtypes = [ c_void_p ] - -libudev_udev_device_new_from_syspath = libudev.udev_device_new_from_syspath -libudev_udev_device_new_from_syspath.restype = c_void_p -libudev_udev_device_new_from_syspath.argtypes = [ c_void_p, c_char_p ] -libudev_udev_device_unref = libudev.udev_device_unref -libudev_udev_device_unref.argtypes = [ c_void_p ] - -libudev_udev_device_get_syspath = libudev.udev_device_get_syspath -libudev_udev_device_get_syspath.restype = c_char_p -libudev_udev_device_get_syspath.argtypes = [ c_void_p ] -libudev_udev_device_get_sysname = libudev.udev_device_get_sysname -libudev_udev_device_get_sysname.restype = c_char_p -libudev_udev_device_get_sysname.argtypes = [ c_void_p ] -libudev_udev_device_get_devpath = libudev.udev_device_get_devpath -libudev_udev_device_get_devpath.restype = c_char_p -libudev_udev_device_get_devpath.argtypes = [ c_void_p ] -libudev_udev_device_get_devtype = libudev.udev_device_get_devtype -libudev_udev_device_get_devtype.restype = c_char_p -libudev_udev_device_get_devtype.argtypes = [ c_void_p ] -libudev_udev_device_get_devnode = libudev.udev_device_get_devnode -libudev_udev_device_get_devnode.restype = c_char_p -libudev_udev_device_get_devnode.argtypes = [ c_void_p ] -libudev_udev_device_get_subsystem = libudev.udev_device_get_subsystem -libudev_udev_device_get_subsystem.restype = c_char_p -libudev_udev_device_get_subsystem.argtypes = [ c_void_p ] -libudev_udev_device_get_sysnum = libudev.udev_device_get_sysnum -libudev_udev_device_get_sysnum.restype = c_char_p -libudev_udev_device_get_sysnum.argtypes = [ c_void_p ] - -libudev_udev_device_get_properties_list_entry = libudev.udev_device_get_properties_list_entry -libudev_udev_device_get_properties_list_entry.restype = c_void_p -libudev_udev_device_get_properties_list_entry.argtypes = [ c_void_p ] -libudev_udev_list_entry_get_next = libudev.udev_list_entry_get_next -libudev_udev_list_entry_get_next.restype = c_void_p -libudev_udev_list_entry_get_next.argtypes = [ c_void_p ] - -libudev_udev_list_entry_get_name = libudev.udev_list_entry_get_name -libudev_udev_list_entry_get_name.restype = c_char_p -libudev_udev_list_entry_get_name.argtypes = [ c_void_p ] -libudev_udev_list_entry_get_value = libudev.udev_list_entry_get_value -libudev_udev_list_entry_get_value.restype = c_char_p -libudev_udev_list_entry_get_value.argtypes = [ c_void_p ] - -libudev_udev_enumerate_new = libudev.udev_enumerate_new -libudev_udev_enumerate_new.restype = c_void_p -libudev_udev_enumerate_new.argtypes = [ c_void_p ] -libudev_udev_enumerate_unref = libudev.udev_enumerate_unref -libudev_udev_enumerate_unref.argtypes = [ c_void_p ] - -libudev_udev_enumerate_add_match_subsystem = libudev.udev_enumerate_add_match_subsystem -libudev_udev_enumerate_add_match_subsystem.restype = c_int -libudev_udev_enumerate_add_match_subsystem.argtypes = [ c_void_p, c_char_p ] -libudev_udev_enumerate_scan_devices = libudev.udev_enumerate_scan_devices -libudev_udev_enumerate_scan_devices.restype = c_int -libudev_udev_enumerate_scan_devices.argtypes = [ c_void_p ] -libudev_udev_enumerate_get_list_entry = libudev.udev_enumerate_get_list_entry -libudev_udev_enumerate_get_list_entry.restype = c_void_p -libudev_udev_enumerate_get_list_entry.argtypes = [ c_void_p ] - -libudev_udev_device_get_devlinks_list_entry = libudev.udev_device_get_devlinks_list_entry -libudev_udev_device_get_devlinks_list_entry.restype = c_void_p -libudev_udev_device_get_devlinks_list_entry.argtypes = [ c_void_p ] - - -class UdevDevice(dict): - - def __init__(self, udev, sysfs_path): - dict.__init__(self) - - # create new udev device from syspath - udev_device = libudev_udev_device_new_from_syspath(udev, sysfs_path) - if not udev_device: - # device does not exist - return - - # set syspath and sysname properties - self.syspath = libudev_udev_device_get_syspath(udev_device) - self.sysname = libudev_udev_device_get_sysname(udev_device) - - # get the devlinks list - devlinks = [] - devlinks_entry = libudev_udev_device_get_devlinks_list_entry(udev_device) - - while devlinks_entry: - path = libudev_udev_list_entry_get_name(devlinks_entry) - devlinks.append(path) - - devlinks_entry = libudev_udev_list_entry_get_next(devlinks_entry) - - # add devlinks list to the dictionary - self["symlinks"] = devlinks - - # get the first property entry - property_entry = libudev_udev_device_get_properties_list_entry(udev_device) - - while property_entry: - name = libudev_udev_list_entry_get_name(property_entry) - value = libudev_udev_list_entry_get_value(property_entry) - - # lvm outputs values for multiple lvs in one line - # we want to split them and make a list - # if the first lv's value is empty we end up with a value starting - # with name=, prepend a space that our split does the right thing - if value.startswith("%s=" % name): - value = " " + value - - if value.count(" %s=" % name): - value = value.split(" %s=" % name) - - self[name] = value - - # get next property entry - property_entry = libudev_udev_list_entry_get_next(property_entry) - - # set additional properties - self.devpath = libudev_udev_device_get_devpath(udev_device) - self.subsystem = libudev_udev_device_get_subsystem(udev_device) - self.devtype = libudev_udev_device_get_devtype(udev_device) - self.sysnum = libudev_udev_device_get_sysnum(udev_device) - self.devnode = libudev_udev_device_get_devnode(udev_device) - - # cleanup - libudev_udev_device_unref(udev_device) - - -class Udev(object): - - def __init__(self): - self.udev = libudev_udev_new() - - def create_device(self, sysfs_path): - return UdevDevice(self.udev, sysfs_path) - - def enumerate_devices(self, subsystem=None): - context = libudev_udev_enumerate_new(self.udev) - - # add the match subsystem - if subsystem is not None: - rc = libudev_udev_enumerate_add_match_subsystem(context, subsystem) - if not rc == 0: - print("error: unable to add the match subsystem", file=sys.stderr) - libudev_udev_enumerate_unref(context) - return [] - - # scan the devices - rc = libudev_udev_enumerate_scan_devices(context) - if not rc == 0: - print("error: unable to enumerate the devices", file=sys.stderr) - libudev_udev_enumerate_unref(context) - return [] - - # create the list of sysfs paths - sysfs_paths = [] - - # get the first list entry - list_entry = libudev_udev_enumerate_get_list_entry(context) - - while list_entry: - sysfs_path = libudev_udev_list_entry_get_name(list_entry) - sysfs_paths.append(sysfs_path) - - # get next list entry - list_entry = libudev_udev_list_entry_get_next(list_entry) - - # cleanup - libudev_udev_enumerate_unref(context) - - return sysfs_paths - - def scan_devices(self, sysfs_paths=None): - if sysfs_paths is None: - sysfs_paths = self.enumerate_devices() - - for sysfs_path in sysfs_paths: - device = self.create_device(sysfs_path) - - if device: - yield device - - def unref(self): - libudev_udev_unref(self.udev) - self.udev = None diff --git a/blivet/udev.py b/blivet/udev.py index 5e8c527..44c2aac 100644 --- a/blivet/udev.py +++ b/blivet/udev.py @@ -28,8 +28,8 @@ from . import util from .size import Size from .flags import flags
-from . import pyudev -global_udev = pyudev.Udev() +import pyudev +global_udev = pyudev.Context()
import logging log = logging.getLogger("blivet") @@ -37,51 +37,19 @@ log = logging.getLogger("blivet") INSTALLER_BLACKLIST = (r'^mtd', r'^mmcblk.+boot', r'^mmcblk.+rpmb', r'^zram') """ device name regexes to ignore when flags.installer_mode is True """
-def enumerate_devices(deviceClass="block"): - devices = global_udev.enumerate_devices(subsystem=deviceClass) - return [path[4:] for path in devices] - def get_device(sysfs_path): - if not os.path.exists("/sys%s" % sysfs_path): - log.debug("%s does not exist", sysfs_path) - return None - - # XXX we remove the /sys part when enumerating devices, - # so we have to prepend it when creating the device - dev = global_udev.create_device("/sys" + sysfs_path) - - if dev: - dev["name"] = dev.sysname - dev["sysfs_path"] = sysfs_path - - # now add in the contents of the uevent file since they're handy - dev = parse_uevent_file(dev) + try: + dev = pyudev.Device.from_sys_path(global_udev, sysfs_path) + except pyudev.DeviceNotFoundError as e: + log.error(e) + dev = None
return dev
-def get_devices(deviceClass="block"): +def get_devices(subsystem="block"): settle() - entries = [] - for path in enumerate_devices(deviceClass): - entry = get_device(path) - if entry: - entries.append(entry) - return entries - -def parse_uevent_file(dev): - path = os.path.normpath("/sys/%s/uevent" % dev['sysfs_path']) - if not os.access(path, os.R_OK): - return dev - - with open(path) as f: - for line in f.readlines(): - (key, equals, value) = line.strip().partition("=") - if not equals: - continue - - dev[key] = value - - return dev + return [d for d in global_udev.list_devices(subsystem=subsystem) + if not __is_blacklisted_blockdev(d.sys_name)]
def settle(): # wait maximal 300 seconds for udev to be done running blkid, lvm, @@ -107,7 +75,7 @@ def resolve_devspec(devspec): from . import devices
ret = None - for dev in get_block_devices(): + for dev in get_devices(): if devspec.startswith("LABEL="): if device_get_label(dev) == devspec[6:]: ret = dev @@ -124,7 +92,7 @@ def resolve_devspec(devspec): if not spec.startswith("/dev/"): spec = os.path.normpath("/dev/" + spec)
- for link in dev["symlinks"]: + for link in device_get_symlinks(dev): if spec == link: ret = dev break @@ -139,37 +107,18 @@ def resolve_glob(glob): if not glob: return ret
- for dev in get_block_devices(): + for dev in get_devices(): name = device_get_name(dev)
if fnmatch.fnmatch(name, glob): ret.append(name) else: - for link in dev["symlinks"]: + for link in device_get_symlinks(dev): if fnmatch.fnmatch(link, glob): ret.append(name)
return ret
-def get_block_devices(): - settle() - entries = [] - for path in enumerate_block_devices(): - entry = get_block_device(path) - if entry: - if entry["name"].startswith("md"): - # mdraid is really braindead, when a device is stopped - # it is no longer usefull in anyway (and we should not - # probe it) yet it still sticks around, see bug rh523387 - state = None - state_file = "/sys/%s/md/array_state" % entry["sysfs_path"] - if os.access(state_file, os.R_OK): - state = open(state_file).read().strip() - if state == "clear": - continue - entries.append(entry) - return entries - def __is_blacklisted_blockdev(dev_name): """Is this a blockdev we never want for an install?""" if dev_name.startswith("ram") or dev_name.startswith("fd"): @@ -188,17 +137,6 @@ def __is_blacklisted_blockdev(dev_name):
return False
-def enumerate_block_devices(): - return [d for d in enumerate_devices(deviceClass="block") if not __is_blacklisted_blockdev(os.path.basename(d))] - -def get_block_device(sysfs_path): - dev = get_device(sysfs_path) - if not dev or 'name' not in dev: - return None - else: - return dev - - # These are functions for retrieving specific pieces of information from # udev database entries. def device_get_name(udev_info): @@ -206,7 +144,7 @@ def device_get_name(udev_info): if "DM_NAME" in udev_info: name = udev_info["DM_NAME"] else: - name = udev_info["name"] + name = udev_info.sys_name
return name
@@ -245,7 +183,7 @@ def device_is_md(info):
# The udev information keeps shifting around. Only md arrays have a # /sys/class/block/<name>/md/ subdirectory. - md_dir = "/sys" + device_get_sysfs_path(info) + "/md" + md_dir = device_get_sysfs_path(info) + "/md" return os.path.exists(md_dir)
def device_is_cciss(info): @@ -254,18 +192,15 @@ def device_is_cciss(info):
def device_is_dasd(info): """ Return True if the device is a dasd device. """ - devname = info.get("DEVNAME") - if devname: - return devname.startswith("dasd") - else: - return False + devname = info.get("DEVNAME", '').split("/")[-1] + return devname.startswith("dasd")
def device_is_zfcp(info): """ Return True if the device is a zfcp device. """ if info.get("DEVTYPE") != "disk": return False
- subsystem = "/sys" + info.get("sysfs_path") + subsystem = device_get_sysfs_path(info)
while True: topdir = os.path.realpath(os.path.dirname(subsystem)) @@ -293,7 +228,7 @@ def device_get_zfcp_attribute(info, attr=None): log.debug("device_get_zfcp_attribute() called with attr=None") return None
- attribute = "/sys%s/device/%s" % (info.get("sysfs_path"), attr,) + attribute = "%s/device/%s" % (device_get_sysfs_path(info), attr) attribute = os.path.realpath(attribute)
if not os.path.isfile(attribute): @@ -304,14 +239,14 @@ def device_get_zfcp_attribute(info, attr=None):
def device_get_dasd_bus_id(info): """ Return the CCW bus ID of the dasd device. """ - return info.get("sysfs_path").split("/")[-3] + return device_get_sysfs_path(info).split("/")[-3]
def device_get_dasd_flag(info, flag=None): """ Return the specified flag for the dasd device. """ if flag is None: return None
- path = "/sys" + info.get("sysfs_path") + "/device/" + flag + path = device_get_sysfs_path(info) + "/device/" + flag if not os.path.isfile(path): return None
@@ -327,17 +262,17 @@ def device_is_disk(info): """ Return True is the device is a disk. """ if device_is_cdrom(info): return False - has_range = os.path.exists("/sys/%s/range" % info['sysfs_path']) + has_range = os.path.exists("%s/range" % device_get_sysfs_path(info)) return info.get("DEVTYPE") == "disk" or has_range
def device_is_partition(info): - has_start = os.path.exists("/sys/%s/start" % info['sysfs_path']) + has_start = os.path.exists("%s/start" % device_get_sysfs_path(info)) return info.get("DEVTYPE") == "partition" or has_start
def device_is_loop(info): """ Return True if the device is a configured loop device. """ return (device_get_name(info).startswith("loop") and - os.path.isdir("/sys/%s/loop" % info['sysfs_path'])) + os.path.isdir("%s/loop" % device_get_sysfs_path(info)))
def device_get_serial(udev_info): """ Get the serial number/UUID from the device as reported by udev. """ @@ -365,7 +300,7 @@ def device_get_path(info): return info["ID_PATH"]
def device_get_symlinks(info): - return info.get("symlinks", []) + return info.get("DEVLINKS", [])
def device_get_by_path(info): for link in device_get_symlinks(info): @@ -375,7 +310,7 @@ def device_get_by_path(info): return device_get_name(info)
def device_get_sysfs_path(info): - return info['sysfs_path'] + return info.sys_path
def device_get_major(info): return int(info["MAJOR"]) @@ -683,7 +618,7 @@ def device_get_iscsi_session(info): # The position of sessionX part depends on device # (e.g. offload vs. sw; also varies for different offload devs) session = None - match = re.match(r'/.*/(session\d+)', info["sysfs_path"]) + match = re.match(r'/.*/(session\d+)', device_get_sysfs_path(info)) if match: session = match.groups()[0] else: @@ -702,7 +637,7 @@ def device_get_iscsi_nic(info): def device_get_iscsi_initiator(info): initiator = None if device_is_partoff_iscsi(info): - host = re.match(r'.*/(host\d+)', info["sysfs_path"]).groups()[0] + host = re.match(r'.*/(host\d+)', device_get_sysfs_path(info)).groups()[0] if host: initiator_file = "/sys/class/iscsi_host/%s/initiatorname" % host if os.access(initiator_file, os.R_OK): @@ -746,10 +681,10 @@ def device_get_iscsi_initiator(info):
def _detect_broadcom_fcoe(info): re_pci_host=re.compile(r'/(.*)/(host\d+)') - match = re_pci_host.match(info["sysfs_path"]) + match = re_pci_host.match(device_get_sysfs_path(info)) if match: sysfs_pci, host = match.groups() - if os.access('/sys/%s/%s/fc_host' %(sysfs_pci, host), os.X_OK) and \ + if os.access('%s/%s/fc_host' %(sysfs_pci, host), os.X_OK) and \ 'net' in sysfs_pci: return (sysfs_pci, host) return (None, None) @@ -765,7 +700,7 @@ def device_is_fcoe(info): path_components[2] == "fc": return True
- if path.startswith("fc-") and "fcoe" in info["sysfs_path"]: + if path.startswith("fc-") and "fcoe" in device_get_sysfs_path(info): return True
if _detect_broadcom_fcoe(info) != (None, None): @@ -776,20 +711,21 @@ def device_is_fcoe(info): def device_get_fcoe_nic(info): path = info.get("ID_PATH", "") path_components = path.split("-") + sysfs_path = device_get_sysfs_path(info)
if path.startswith("pci-eth") and len(path_components) >= 4 and \ path_components[2] == "fc": return path_components[1]
- if path.startswith("fc-") and "fcoe" in info["sysfs_path"]: - return info["sysfs_path"].split("/")[4].split(".")[0] + if path.startswith("fc-") and "fcoe" in sysfs_path: + return sysfs_path.split("/")[5].split(".")[0]
(sysfs_pci, host) = _detect_broadcom_fcoe(info) if (sysfs_pci, host) != (None, None): - net, iface = info['sysfs_path'].split("/")[5:7] + net, iface = sysfs_path.split("/")[6:8] if net != "net": - log.warning("unexpected sysfs_path of bnx2fc device: %s", info['sysfs_path']) - match = re.compile(r'.*/net/([^/]*)').match(info['sysfs_path']) + log.warning("unexpected sysfs_path of bnx2fc device: %s", sysfs_path) + match = re.compile(r'.*/net/([^/]*)').match(sysfs_path) if match: return match.groups()[0].split(".")[0] else: @@ -803,7 +739,7 @@ def device_get_fcoe_identifier(info): path_components[2] == "fc": return path_components[3]
- if path.startswith("fc-") and "fcoe" in info["sysfs_path"]: + if path.startswith("fc-") and "fcoe" in device_get_sysfs_path(info): return path_components[1]
if device_is_fcoe(info) and len(path_components) >= 4 and \ diff --git a/blivet/util.py b/blivet/util.py index 4160a5c..90b8515 100644 --- a/blivet/util.py +++ b/blivet/util.py @@ -179,7 +179,7 @@ def get_sysfs_attr(path, attr): log.debug("get_sysfs_attr() called with attr=None") return None
- attribute = "/sys%s/%s" % (path, attr) + attribute = "%s/%s" % (path, attr) attribute = os.path.realpath(attribute)
if not os.path.isfile(attribute) and not os.path.islink(attribute): diff --git a/python-blivet.spec b/python-blivet.spec index 134fba1..f14b6ef 100644 --- a/python-blivet.spec +++ b/python-blivet.spec @@ -29,6 +29,7 @@ Requires: python Requires: python-six Requires: pykickstart >= %{pykickstartver} Requires: util-linux >= %{utillinuxver} +Requires: python-pyudev Requires: parted >= %{partedver} Requires: pyparted >= %{pypartedver} Requires: device-mapper >= %{dmver} diff --git a/tests/udev_test.py b/tests/udev_test.py index a7b09ab..a930031 100644 --- a/tests/udev_test.py +++ b/tests/udev_test.py @@ -2,7 +2,6 @@
import unittest import mock -import os
class UdevTest(unittest.TestCase):
@@ -11,132 +10,11 @@ class UdevTest(unittest.TestCase): blivet.udev.os = mock.Mock() blivet.udev.log = mock.Mock()
- def test_udev_enumerate_devices(self): + def test_udev_get_device(self): import blivet.udev - ENUMERATE_LIST = [ - '/sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda', - '/sys/devices/virtual/block/loop0', - '/sys/devices/virtual/block/loop1', - '/sys/devices/virtual/block/ram0', - '/sys/devices/virtual/block/ram1', - '/sys/devices/virtual/block/dm-0', - ] - blivet.udev.global_udev.enumerate_devices = mock.Mock(return_value=ENUMERATE_LIST) - ret = blivet.udev.enumerate_devices() - self.assertEqual(set(ret), - set(['/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda', - '/devices/virtual/block/loop0', '/devices/virtual/block/loop1', - '/devices/virtual/block/ram0', '/devices/virtual/block/ram1', - '/devices/virtual/block/dm-0']) - ) - - def test_udev_get_device_1(self): - import blivet.udev - - class Device(object): - def __init__(self): - self.sysname = 'loop1' - self.dict = {'symlinks': ['/dev/block/7:1'], - 'SUBSYSTEM': 'block', - 'MAJOR': '7', - 'DEVPATH': '/devices/virtual/block/loop1', - 'UDISKS_PRESENTATION_NOPOLICY': '1', - 'UDEV_LOG': '3', - 'DEVNAME': '/dev/loop1', - 'DEVTYPE': 'disk', - 'DEVLINKS': '/dev/block/7:1', - 'MINOR': '1' - } - - def __getitem__(self, key): - return self.dict[key] - - def __setitem__(self, key, value): - self.dict[key] = value - - blivet.udev.os.path.exists.return_value = True - DEV_PATH = '/devices/virtual/block/loop1' - dev = Device() - blivet.udev.global_udev = mock.Mock() - blivet.udev.global_udev.create_device.return_value = dev - - saved = blivet.udev.parse_uevent_file - blivet.udev.parse_uevent_file = mock.Mock(return_value=dev) - - ret = blivet.udev.get_device(DEV_PATH) - self.assertTrue(isinstance(ret, Device)) - self.assertEqual(ret['name'], ret.sysname) - self.assertEqual(ret['sysfs_path'], DEV_PATH) - self.assertTrue(blivet.udev.parse_uevent_file.called) - - blivet.udev.parse_uevent_file = saved - - def test_udev_get_device_2(self): - import blivet.udev - blivet.udev.os.path.exists.return_value = False - ret = blivet.udev.get_device('') - self.assertEqual(ret, None) - - def test_udev_get_device_3(self): - import blivet.udev - blivet.udev.os.path.exists.return_value = True - blivet.udev.global_udev = mock.Mock() - blivet.udev.global_udev.create_device.return_value = None - ret = blivet.udev.get_device('') - self.assertEqual(ret, None) - - def test_udev_get_devices(self): - import blivet.udev - saved = blivet.udev.settle - blivet.udev.settle = mock.Mock() - DEVS = \ - ['/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda', - '/devices/virtual/block/loop0', '/devices/virtual/block/loop1', - '/devices/virtual/block/ram0', '/devices/virtual/block/ram1', - '/devices/virtual/block/dm-0'] - blivet.udev.enumerate_devices = mock.Mock(return_value=DEVS) - blivet.udev.get_device = lambda x: x - ret = blivet.udev.get_devices() - self.assertEqual(ret, DEVS) - blivet.udev.settle = saved - - def test_udev_parse_uevent_file_1(self): - import blivet.udev - # For this one we're accessing the real uevent file (twice). - path = '/devices/virtual/block/loop1' - if not os.path.exists("/sys" + path): - self.skipTest("this test requires the presence of /dev/loop1") - - info = {'sysfs_path': path} - for line in open('/sys' + path + '/uevent').readlines(): - (name, equals, value) = line.strip().partition("=") - if not equals: - continue - - info[name] = value - - dev = {'sysfs_path': path} - blivet.udev.os.path.normpath = os.path.normpath - blivet.udev.os.access = os.access - blivet.udev.os.R_OK = os.R_OK - ret = blivet.udev.parse_uevent_file(dev) - self.assertEqual(ret, info) - blivet.udev.os.path.normpath = mock.Mock() - blivet.udev.os.access = mock.Mock() - blivet.udev.os.R_OK = mock.Mock() - - def test_udev_parse_uevent_file_2(self): - import blivet.udev - blivet.udev.os.path.normpath = os.path.normpath - blivet.udev.os.access.return_value = False - path = '/devices/virtual/block/loop1' - if not os.path.exists("/sys" + path): - self.skipTest("this test requires the presence of /dev/loop1") - - dev = {'sysfs_path': path} - - ret = blivet.udev.parse_uevent_file(dev) - self.assertEqual(ret, {'sysfs_path': '/devices/virtual/block/loop1'}) + devices = blivet.udev.global_udev.list_devices(subsystem="block") + for device in devices: + self.assertNotEqual(blivet.udev.get_device(device.sys_path), None)
def udev_settle_test(self): import blivet.udev
On Wed, 2015-05-27 at 13:16 -0500, David Lehman wrote:
There are two major differences in how we use the module. Each device is represented by a pyudev.Device instance, which is based on collections.abc.Mapping. That means we can no longer change the data to do things like set a "multipath_member" format type or inject LVM or MD metadata.
The other difference is that sysfs paths now include the "/sys", which is great since it's always mounted in the same place.
(cherry picked from commit 8ff97169daa3fe529e4849e3431d9ec9147c2c20)
blivet/devices.py | 96 +++++++--------------- blivet/devicetree.py | 64 +++++++-------- blivet/pyudev.py | 226 --------------------------------------------------- blivet/udev.py | 142 +++++++++----------------------- blivet/util.py | 2 +- python-blivet.spec | 1 + tests/udev_test.py | 130 +---------------------------- 7 files changed, 107 insertions(+), 554 deletions(-) delete mode 100644 blivet/pyudev.py
diff --git a/blivet/devices.py b/blivet/devices.py index 6724071..d78ff5b 100644 --- a/blivet/devices.py +++ b/blivet/devices.py @@ -27,6 +27,7 @@ import tempfile import abc from decimal import Decimal import re +import pyudev
from six import add_metaclass
@@ -107,7 +108,7 @@ def deviceNameToDiskByPath(deviceName=None): return ""
ret = None
- for dev in udev.get_block_devices():
- for dev in udev.get_devices(): if udev.device_get_name(dev) == deviceName: ret = udev.device_get_by_path(dev) break
@@ -523,7 +524,6 @@ class StorageDevice(Device):
_type = "blivet" _devDir = "/dev"
- sysfsBlockDir = "class/block" _formatImmutable = False _partitionable = False _isDisk = False
@@ -789,11 +789,22 @@ class StorageDevice(Device):
def updateSysfsPath(self): """ Update this device's sysfs path. """
log_method_call(self, self.name, status=self.status)sysfsName = self.name.replace("/", "!")
This looks like something nasty needed for some weird storage HW. Do we really want to drop this line? IOW, does pyudev.Device.from_device_file() handle the '/'s and '!'s correctly?
We can't inject data into pyudev.Device instances like we could when the udev db entries were plain dicts.
(cherry picked from commit fd6d5ebf3f12d4cb2e82f848e6ce7d1c9a840efa) --- blivet/devicetree.py | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-)
diff --git a/blivet/devicetree.py b/blivet/devicetree.py index 4ba4640..38b729a 100644 --- a/blivet/devicetree.py +++ b/blivet/devicetree.py @@ -1505,11 +1505,13 @@ class DeviceTree(object): lv_dev.logSize, lv_dev.vgSpaceUsed)
def handleUdevLVMPVFormat(self, info, device): + # pylint: disable=unused-argument log_method_call(self, name=device.name, type=device.format.type) + pv_info = self.pvInfo.get(device.path, {}) # lookup/create the VG and LVs try: - vg_name = udev.device_get_vg_name(info) - vg_uuid = udev.device_get_vg_uuid(info) + vg_name = udev.device_get_vg_name(pv_info) + vg_uuid = udev.device_get_vg_uuid(pv_info) except KeyError: # no vg name means no vg -- we're done with this pv return @@ -1523,12 +1525,12 @@ class DeviceTree(object): vg_device.parents.append(device) else: try: - vg_size = udev.device_get_vg_size(info) - vg_free = udev.device_get_vg_free(info) - pe_size = udev.device_get_vg_extent_size(info) - pe_count = udev.device_get_vg_extent_count(info) - pe_free = udev.device_get_vg_free_extents(info) - pv_count = udev.device_get_vg_pv_count(info) + vg_size = udev.device_get_vg_size(pv_info) + vg_free = udev.device_get_vg_free(pv_info) + pe_size = udev.device_get_vg_extent_size(pv_info) + pe_count = udev.device_get_vg_extent_count(pv_info) + pe_free = udev.device_get_vg_free_extents(pv_info) + pv_count = udev.device_get_vg_pv_count(pv_info) except (KeyError, ValueError) as e: log.warning("invalid data for %s: %s", device.name, e) return @@ -1548,8 +1550,9 @@ class DeviceTree(object): self.handleVgLvs(vg_device)
def handleUdevMDMemberFormat(self, info, device): + # pylint: disable=unused-argument log_method_call(self, name=device.name, type=device.format.type) - + md_info = mdraid.mdexamine(device.path) md_array = self.getDeviceByUuid(device.format.mdUuid, incomplete=True) if device.format.mdUuid and md_array: md_array.parents.append(device) @@ -1557,9 +1560,9 @@ class DeviceTree(object): # create the array with just this one member try: # level is reported as, eg: "raid1" - md_level = udev.device_get_md_level(info) - md_devices = udev.device_get_md_devices(info) - md_uuid = udev.device_get_md_uuid(info) + md_level = udev.device_get_md_level(md_info) + md_devices = udev.device_get_md_devices(md_info) + md_uuid = udev.device_get_md_uuid(md_info) except (KeyError, ValueError) as e: log.warning("invalid data for %s: %s", device.name, e) return @@ -1602,10 +1605,10 @@ class DeviceTree(object):
# mdexamine yields MD_METADATA only for metadata version > 0.90 # if MD_METADATA is missing, assume metadata version is 0.90 - md_metadata = md_metadata or udev.device_get_md_metadata(info) or "0.90" + md_metadata = md_metadata or udev.device_get_md_metadata(md_info) or "0.90"
if not md_name: - md_path = info.get("DEVICE", "") + md_path = md_info.get("DEVICE", "") if md_path: md_name = devicePathToName(md_path) if re.match(r'md\d+$', md_name): @@ -1808,8 +1811,6 @@ class DeviceTree(object): # luks/dmcrypt kwargs["name"] = "luks-%s" % uuid elif format_type in formats.mdraid.MDRaidMember._udevTypes: - info.update(mdraid.mdexamine(device.path)) - # mdraid try: kwargs["mdUuid"] = udev.device_get_md_uuid(info) @@ -1823,18 +1824,18 @@ class DeviceTree(object): kwargs["biosraid"] = udev.device_is_biosraid_member(info) elif format_type == "LVM2_member": # lvm - info.update(self.pvInfo.get(device.path, {})) + pv_info = self.pvInfo.get(device.path, {})
try: - kwargs["vgName"] = udev.device_get_vg_name(info) + kwargs["vgName"] = udev.device_get_vg_name(pv_info) except KeyError: log.warning("PV %s has no vg_name", name) try: - kwargs["vgUuid"] = udev.device_get_vg_uuid(info) + kwargs["vgUuid"] = udev.device_get_vg_uuid(pv_info) except KeyError: log.warning("PV %s has no vg_uuid", name) try: - kwargs["peStart"] = udev.device_get_pv_pe_start(info) + kwargs["peStart"] = udev.device_get_pv_pe_start(pv_info) except KeyError: log.warning("PV %s has no pe_start", name) elif format_type == "vfat":
From: mulhern amulhern@redhat.com
Resolves: fed#1136214
pyudev library returns a string whereas blivet's pyudev library returned an array of string. Our udev code should persist in returning an array of strings.
Signed-off-by: mulhern amulhern@redhat.com (cherry picked from commit 4ea21ea9fa6bc0213ad5de0b164c00ffde4b5058) --- blivet/udev.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/blivet/udev.py b/blivet/udev.py index 44c2aac..dd9b2d9 100644 --- a/blivet/udev.py +++ b/blivet/udev.py @@ -300,7 +300,13 @@ def device_get_path(info): return info["ID_PATH"]
def device_get_symlinks(info): - return info.get("DEVLINKS", []) + """ Get an array of symbolic links for a device. + + :param info: a :class:`pyudev.Device` instance + :returns: list of symbolic links + :rtype: list of str + """ + return info.get("DEVLINKS", "").split()
def device_get_by_path(info): for link in device_get_symlinks(info):
From: "Brian C. Lane" bcl@redhat.com
Use https://fedora.zanata.org/project/view/blivet for translations. Also check to make sure zanata-python-client is installed before po-pull
Related: rhbz#1205285 --- Makefile | 9 +++--- zanata.xml | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 zanata.xml
diff --git a/Makefile b/Makefile index 6edac2a..1f7cc7a 100644 --- a/Makefile +++ b/Makefile @@ -5,14 +5,15 @@ RELEASE=$(shell awk '/Release:/ { print $$2 }' $(SPECFILE) | sed -e 's|%.*$$||g' RELEASE_TAG=$(PKGNAME)-$(VERSION)-$(RELEASE) VERSION_TAG=$(PKGNAME)-$(VERSION)
-TX_PULL_ARGS = -a --disable-overwrite -TX_PUSH_ARGS = -s +ZANATA_PULL_ARGS = --transdir ./po/ +ZANATA_PUSH_ARGS = --srcdir ./po/ --push-type source --force
all: $(MAKE) -C po
po-pull: - tx pull $(TX_PULL_ARGS) + rpm -q zanata-python-client &>/dev/null || ( echo "need to run: yum install zanata-python-client"; exit 1 ) + zanata pull $(ZANATA_PULL_ARGS)
test: @echo "*** Running unittests ***" @@ -91,6 +92,6 @@ bumpver: po-pull fi ; \ ( scripts/makebumpver $${opts} ) || exit 1 ; \ make -C po $(PKGNAME).pot ; \ - tx push $(TX_PUSH_ARGS) + zanata push $(ZANATA_PUSH_ARGS)
.PHONY: check clean install tag archive local diff --git a/zanata.xml b/zanata.xml new file mode 100644 index 0000000..3d66c7a --- /dev/null +++ b/zanata.xml @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<config xmlns="http://zanata.org/namespace/config/"> + <url>https://fedora.zanata.org/</url> + <project>blivet</project> + <project-version>rhel7-branch</project-version> + <project-type>gettext</project-type> + + <locales> + <locale>sq</locale> + <locale>ar</locale> + <locale>as</locale> + <locale>ast</locale> + <locale>bal</locale> + <locale>eu</locale> + <locale>bn</locale> + <locale>bn-IN</locale> + <locale>brx</locale> + <locale>bs</locale> + <locale>br</locale> + <locale>bg</locale> + <locale>ca</locale> + <locale>zh-CN</locale> + <locale>zh-HK</locale> + <locale>zh-TW</locale> + <locale>kw</locale> + <locale>kw-GB</locale> + <locale>cs</locale> + <locale>da</locale> + <locale>nl</locale> + <locale>en-GB</locale> + <locale>eo</locale> + <locale>et</locale> + <locale>fi</locale> + <locale>fr</locale> + <locale>gl</locale> + <locale>ka</locale> + <locale>de</locale> + <locale>el</locale> + <locale>gu</locale> + <locale>he</locale> + <locale>hi</locale> + <locale>hu</locale> + <locale>is</locale> + <locale>id</locale> + <locale>ia</locale> + <locale>it</locale> + <locale>ja</locale> + <locale>kn</locale> + <locale>kk</locale> + <locale>km</locale> + <locale>ky</locale> + <locale>ko</locale> + <locale>lt</locale> + <locale>nds</locale> + <locale>mk</locale> + <locale>mai</locale> + <locale>ms</locale> + <locale>ml</locale> + <locale>mr</locale> + <locale>mn</locale> + <locale>ne</locale> + <locale>nb</locale> + <locale>nn</locale> + <locale>or</locale> + <locale>pa</locale> + <locale>fa</locale> + <locale>pl</locale> + <locale>pt</locale> + <locale>pt-BR</locale> + <locale>ro</locale> + <locale>ru</locale> + <locale>sr</locale> + <locale>sr@latin</locale> + <locale>si</locale> + <locale>sk</locale> + <locale>sl</locale> + <locale>es</locale> + <locale>sv</locale> + <locale>tg</locale> + <locale>ta</locale> + <locale>te</locale> + <locale>bo</locale> + <locale>tr</locale> + <locale>uk</locale> + <locale>ur</locale> + <locale>wba</locale> + <locale>cy</locale> + <locale>lv</locale> + <locale>kw@uccor</locale> + <locale>kw@kkcor</locale> + <locale>af</locale> + <locale>am</locale> + <locale>be</locale> + <locale>hr</locale> + <locale>de-CH</locale> + <locale>th</locale> + <locale>vi</locale> + <locale>zu</locale> + <locale>ilo</locale> + <locale>nso</locale> + <locale>tw</locale> + <locale>yo</locale> + <locale>anp</locale> + </locales> + +</config>
From: "Brian C. Lane" bcl@redhat.com
(cherry picked from commit 7208b0bc80cee8fbbdbb649f008523335801d376) --- Makefile | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/Makefile b/Makefile index 1f7cc7a..f62771d 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,13 @@ po-pull: rpm -q zanata-python-client &>/dev/null || ( echo "need to run: yum install zanata-python-client"; exit 1 ) zanata pull $(ZANATA_PULL_ARGS)
+po-empty: + for lingua in $$(gawk 'match($$0, /locale>(.*)</locale/, ary) {print ary[1]}' ./zanata.xml) ; do \ + [ -f ./po/$$lingua.po ] || \ + msginit -i ./po/$(PKGNAME).pot -o ./po/$$lingua.po --no-translator || \ + exit 1 ; \ + done + test: @echo "*** Running unittests ***" PYTHONPATH=.:tests/ python -m unittest discover -v -s tests/ -p '*_test.py'
From: "Brian C. Lane" bcl@redhat.com
This is written to the changelog entries and the Release: field in the spec file. Defaults to the same release as it currently has.
(cherry picked from commit beaabaf49483c2087520819cc33797f3ae171cb1) --- scripts/makebumpver | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/scripts/makebumpver b/scripts/makebumpver index bb1d6e6..871fb5a 100755 --- a/scripts/makebumpver +++ b/scripts/makebumpver @@ -64,6 +64,7 @@ class MakeBumpVer: self.fixedin_name = kwargs.get('fixedin', self.name) self.version = kwargs.get('version') self.release = kwargs.get('release') + self.new_release = kwargs.get('new_release') or self.release self.ignore = kwargs.get('ignore')
self.bugmap = {} @@ -371,7 +372,7 @@ class MakeBumpVer: """ find first occurrence of search and replace it with replace """ for i, l in enumerate(lines): - if l.find(search) > -1: + if re.search(search, l): break else: print("!!! Failed to replace '%s' with '%s'" % (search, replace)) @@ -386,6 +387,8 @@ class MakeBumpVer:
self._replaceString(l, "Version: %s\n" % (self.version), "Version: %s\n" % (newVersion)) + self._replaceString(l, "Release: %s\n" % (self.release+r"%{?dist}"), + "Release: %s\n" % (self.new_release+r"%{?dist}"))
i = l.index('%changelog\n') top = l[:i] @@ -398,7 +401,7 @@ class MakeBumpVer: today = datetime.date.today() stamp = today.strftime("%a %b %d %Y") f.write("* %s %s <%s> - %s-%s\n" % (stamp, self.gituser, self.gitemail, - newVersion, self.release)) + newVersion, self.new_release))
for msg, rhbz in rpmlog: msg = re.sub('(?<!%)%%(?!%)|(?<!%%)%(?!%%)', '%%', msg) @@ -434,7 +437,7 @@ class MakeBumpVer:
def run(self): newVersion = self._incrementVersion() - fixedIn = "%s-%s-%s" % (self.fixedin_name, newVersion, self.release) + fixedIn = "%s-%s-%s" % (self.fixedin_name, newVersion, self.new_release) rpmlog = self._rpmLog(fixedIn)
self._writeNewSpec(newVersion, rpmlog) @@ -447,6 +450,7 @@ def usage(cmd): sys.stdout.write(" -n, --name Package name.\n") sys.stdout.write(" -v, --version Current package version number.\n") sys.stdout.write(" -r, --release Package release number.\n") + sys.stdout.write(" --newrelease Value for release in the .spec file.\n") sys.stdout.write(" -i, --ignore Comma separated list of git commits to ignore.\n") sys.stdout.write(" -m, --map Comma separated list of FEDORA_BZ=RHEL_BZ mappings.\n") sys.stdout.write(" -s, --skip-acks Skip checking for rhel-X.X.X ack flag\n") @@ -461,14 +465,14 @@ def main(argv): prog = os.path.basename(argv[0]) cwd = os.getcwd() spec = os.path.realpath(cwd + '/python-blivet.spec') - name, version, release = None, None, None + name, version, release, new_release = None, None, None, None ignore, bugmap = None, None show_help, unknown, skip_acks = False, False, False opts = []
try: opts, _args = getopt.getopt(argv[1:], 'n:v:r:i:m:d?', - ['name=', 'version=', 'release=', + ['name=', 'version=', 'release=', 'newrelease=', 'ignore=', 'map=', 'debug', 'help']) except getopt.GetoptError: show_help = True @@ -480,6 +484,8 @@ def main(argv): version = a elif o in ('-r', '--release'): release = a + elif o in ('--newrelease'): + new_release = a elif o in ('-i', '--ignore'): ignore = a elif o in ('-m', '--map'): @@ -525,7 +531,8 @@ def main(argv):
mbv = MakeBumpVer(name=name, version=version, release=release, ignore=ignore, bugmap=bugmap, spec=spec, skip_acks=skip_acks, - version_files=version_files, fixedin="python-"+name) + version_files=version_files, fixedin="python-"+name, + new_release=new_release) mbv.run()
if __name__ == "__main__":
From: "Brian C. Lane" bcl@redhat.com
Use these make targets for creating scratch rc builds that can be used before an official release. rc-release will run scratch-bumpver to bump the version and add a rc release with the current date and time to the specfile. scratch is then run to create the tar.gz file and then mock is used to build a rc rpm package.
No changes are committed to git, no zanata account is required and nothing is pushed to zanata.
(cherry picked from commit a352382e24ff8d3add1ae6c9076ccd12cbf9f7d1) --- Makefile | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
diff --git a/Makefile b/Makefile index f62771d..6d50550 100644 --- a/Makefile +++ b/Makefile @@ -2,12 +2,15 @@ PKGNAME=blivet SPECFILE=python-blivet.spec VERSION=$(shell awk '/Version:/ { print $$2 }' $(SPECFILE)) RELEASE=$(shell awk '/Release:/ { print $$2 }' $(SPECFILE) | sed -e 's|%.*$$||g') +RC_RELEASE ?= $(shell date -u +0.1.%Y%m%d%H%M%S) RELEASE_TAG=$(PKGNAME)-$(VERSION)-$(RELEASE) VERSION_TAG=$(PKGNAME)-$(VERSION)
ZANATA_PULL_ARGS = --transdir ./po/ ZANATA_PUSH_ARGS = --srcdir ./po/ --push-type source --force
+MOCKCHROOT ?= fedora-rawhide-x86_64 + all: $(MAKE) -C po
@@ -101,4 +104,37 @@ bumpver: po-pull make -C po $(PKGNAME).pot ; \ zanata push $(ZANATA_PUSH_ARGS)
+scratch-bumpver: po-empty + @opts="-n $(PKGNAME) -v $(VERSION) -r $(RELEASE) --newrelease $(RC_RELEASE)" ; \ + if [ ! -z "$(IGNORE)" ]; then \ + opts="$${opts} -i $(IGNORE)" ; \ + fi ; \ + if [ ! -z "$(MAP)" ]; then \ + opts="$${opts} -m $(MAP)" ; \ + fi ; \ + if [ ! -z "$(SKIP_ACKS)" ]; then \ + opts="$${opts} -s" ; \ + fi ; \ + if [ ! -z "$(BZDEBUG)" ]; then \ + opts="$${opts} -d" ; \ + fi ; \ + ( scripts/makebumpver $${opts} ) || exit 1 ; + +scratch: po-empty + @rm -f ChangeLog + @make ChangeLog + @rm -rf $(PKGNAME)-$(VERSION).tar.gz + @rm -rf /tmp/$(PKGNAME)-$(VERSION) /tmp/$(PKGNAME) + @dir=$$PWD; cp -a $$dir /tmp/$(PKGNAME)-$(VERSION) + @cd /tmp/$(PKGNAME)-$(VERSION) ; python setup.py -q sdist + @cp /tmp/$(PKGNAME)-$(VERSION)/dist/$(PKGNAME)-$(VERSION).tar.gz . + @rm -rf /tmp/$(PKGNAME)-$(VERSION) + @echo "The archive is in $(PKGNAME)-$(VERSION).tar.gz" + +rc-release: scratch-bumpver scratch + mock -r $(MOCKCHROOT) --buildsrpm --spec ./$(SPECFILE) --sources . || exit 1 + cp /var/lib/mock/$(MOCKCHROOT)/result/*src.rpm . || exit 1 + mock -r $(MOCKCHROOT) --rebuild *src.rpm || exit 1 + cp /var/lib/mock/$(MOCKCHROOT)/result/*.rpm . || exit 1 + .PHONY: check clean install tag archive local
From: Chris Lumens clumens@redhat.com
This allows us to capture the mock logs in jenkins, among other things.
(cherry picked from commit 7e8610874d11b9c45070a8e31d231d8dde6422d5) --- Makefile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/Makefile b/Makefile index 6d50550..0a81a9a 100644 --- a/Makefile +++ b/Makefile @@ -132,9 +132,7 @@ scratch: po-empty @echo "The archive is in $(PKGNAME)-$(VERSION).tar.gz"
rc-release: scratch-bumpver scratch - mock -r $(MOCKCHROOT) --buildsrpm --spec ./$(SPECFILE) --sources . || exit 1 - cp /var/lib/mock/$(MOCKCHROOT)/result/*src.rpm . || exit 1 - mock -r $(MOCKCHROOT) --rebuild *src.rpm || exit 1 - cp /var/lib/mock/$(MOCKCHROOT)/result/*.rpm . || exit 1 + mock -r $(MOCKCHROOT) --buildsrpm --spec ./$(SPECFILE) --sources . --resultdir $(PWD) || exit 1 + mock -r $(MOCKCHROOT) --rebuild *src.rpm --resultdir $(PWD) || exit 1
.PHONY: check clean install tag archive local
From: Chris Lumens clumens@redhat.com
Otherwise it'll get hung up failing to download some package that exists.
(cherry picked from commit 994c8a1550eea9bfbdcd39082a8a94ae45d92b12) --- Makefile | 1 + 1 file changed, 1 insertion(+)
diff --git a/Makefile b/Makefile index 0a81a9a..4629ca1 100644 --- a/Makefile +++ b/Makefile @@ -132,6 +132,7 @@ scratch: po-empty @echo "The archive is in $(PKGNAME)-$(VERSION).tar.gz"
rc-release: scratch-bumpver scratch + mock -r $(MOCKCHROOT) --scrub all || exit 1 mock -r $(MOCKCHROOT) --buildsrpm --spec ./$(SPECFILE) --sources . --resultdir $(PWD) || exit 1 mock -r $(MOCKCHROOT) --rebuild *src.rpm --resultdir $(PWD) || exit 1
--- blivet/devicelibs/raid.py | 7 ++----- blivet/devices/container.py | 4 +--- blivet/devices/lvm.py | 3 +-- blivet/formats/fs.py | 5 ----- blivet/formats/fslabel.py | 4 +--- blivet/formats/fslabeling.py | 4 +--- blivet/size.py | 22 ++++++---------------- blivet/util.py | 4 +--- python-blivet.spec | 1 - tests/formats_test/fslabeling.py | 4 +--- tests/size_test.py | 5 ----- 11 files changed, 14 insertions(+), 49 deletions(-)
diff --git a/blivet/devicelibs/raid.py b/blivet/devicelibs/raid.py index 50d19dc..2277669 100644 --- a/blivet/devicelibs/raid.py +++ b/blivet/devicelibs/raid.py @@ -23,8 +23,6 @@
import abc
-from six import add_metaclass - from ..errors import RaidError
def div_up(a,b): @@ -35,7 +33,6 @@ def div_up(a,b): """ return (a + (b - 1))//b
-@add_metaclass(abc.ABCMeta) class RAIDLevel(object): """An abstract class which is the parent of all classes which represent a RAID level. @@ -43,6 +40,7 @@ class RAIDLevel(object): It ensures that RAIDLevel objects will really be singleton objects by overriding copy methods. """ + __metaclass__ = abc.ABCMeta
name = abc.abstractproperty(doc="The canonical name for this level") names = abc.abstractproperty(doc="List of recognized names for this level.") @@ -65,7 +63,6 @@ class RAIDLevel(object): return self
-@add_metaclass(abc.ABCMeta) class RAIDn(RAIDLevel):
"""An abstract class which is the parent of classes which represent a @@ -91,7 +88,7 @@ class RAIDn(RAIDLevel): it is defined and using the same name, effectively yielding a singleton object of the class. """ - + __metaclass__ = abc.ABCMeta
# ABSTRACT PROPERTIES level = abc.abstractproperty(doc="A code representing the level") diff --git a/blivet/devices/container.py b/blivet/devices/container.py index df759e7..d8a1379 100644 --- a/blivet/devices/container.py +++ b/blivet/devices/container.py @@ -21,8 +21,6 @@
import abc
-from six import add_metaclass - from .. import errors from ..storage_log import log_method_call from ..formats import get_device_format_class @@ -32,7 +30,6 @@ log = logging.getLogger("blivet")
from .storage import StorageDevice
-@add_metaclass(abc.ABCMeta) class ContainerDevice(StorageDevice): """ A device that aggregates a set of member devices.
@@ -49,6 +46,7 @@ class ContainerDevice(StorageDevice): within :meth:`.deviceaction.ActionAddMember.execute` and :meth:`.deviceaction.ActionRemoveMember.execute`. """ + __metaclass__ = abc.ABCMeta
_formatClassName = abc.abstractproperty(lambda s: None, doc="The type of member devices' required format") diff --git a/blivet/devices/lvm.py b/blivet/devices/lvm.py index 3b4cd36..61e8e26 100644 --- a/blivet/devices/lvm.py +++ b/blivet/devices/lvm.py @@ -20,7 +20,6 @@ #
from decimal import Decimal -from six import add_metaclass import abc import pprint import re @@ -803,7 +802,6 @@ class LVMLogicalVolumeDevice(DMDevice):
return True
-@add_metaclass(abc.ABCMeta) class LVMSnapShotBase(object): """ Abstract base class for lvm snapshots
@@ -820,6 +818,7 @@ class LVMSnapShotBase(object): It is also impossible to set the format for a snapshot explicitly as it always has the same format as its origin. """ + __metaclass__ = abc.ABCMeta _type = "lvmsnapshotbase"
def __init__(self, origin=None, vorigin=False, exists=False): diff --git a/blivet/formats/fs.py b/blivet/formats/fs.py index 9c17470..5c3d81a 100644 --- a/blivet/formats/fs.py +++ b/blivet/formats/fs.py @@ -25,7 +25,6 @@ from decimal import Decimal import os import tempfile -import six
from . import fslabeling from ..errors import FormatCreateError, FSError, FSResizeError @@ -43,10 +42,6 @@ from .. import udev import logging log = logging.getLogger("blivet")
-if six.PY3: - long = int # pylint: disable=redefined-builtin - - fs_configs = {}
kernel_filesystems = [] diff --git a/blivet/formats/fslabel.py b/blivet/formats/fslabel.py index 2c6fce2..2d35f61 100644 --- a/blivet/formats/fslabel.py +++ b/blivet/formats/fslabel.py @@ -22,15 +22,13 @@ import abc import re
-from six import add_metaclass - from .. import errors
-@add_metaclass(abc.ABCMeta) class FSLabelApp(object): """An abstract class that represents actions associated with a filesystem's labeling application. """ + __metaclass__ = abc.ABCMeta
name = abc.abstractproperty( doc="The name of the filesystem labeling application.") diff --git a/blivet/formats/fslabeling.py b/blivet/formats/fslabeling.py index ef5b4ae..b9d8cf3 100644 --- a/blivet/formats/fslabeling.py +++ b/blivet/formats/fslabeling.py @@ -21,14 +21,12 @@
import abc
-from six import add_metaclass - from . import fslabel
-@add_metaclass(abc.ABCMeta) class FSLabeling(object): """An abstract class that represents filesystem labeling actions. """ + __metaclass__ = abc.ABCMeta
default_label = abc.abstractproperty( doc="Default label set on this filesystem at creation.") diff --git a/blivet/size.py b/blivet/size.py index e010a00..f313a98 100644 --- a/blivet/size.py +++ b/blivet/size.py @@ -27,7 +27,6 @@ from collections import namedtuple from decimal import Decimal from decimal import InvalidOperation from decimal import ROUND_DOWN, ROUND_UP, ROUND_HALF_UP -import six
from .errors import SizePlacesError from .i18n import _, P_, N_ @@ -136,14 +135,9 @@ def _parseSpec(spec): try: # This will raise UnicodeDecodeError if specifier contains non-ascii # characters - if six.PY2: - spec_ascii = specifier.decode("ascii") - # Convert back to a str type to match the _bytes and _prefixes arrays - spec_ascii = str(spec_ascii) - else: - # This will raise UnicodeEncodeError if specifier contains any non-ascii - # in Python3 `bytes` are new Python2 `str` - spec_ascii = bytes(specifier, 'ascii') + spec_ascii = specifier.decode("ascii") + # Convert back to a str type to match the _bytes and _prefixes arrays + spec_ascii = str(spec_ascii)
# Use the ASCII-only lowercase mapping spec_ascii = _lowerASCII(spec_ascii) @@ -164,11 +158,7 @@ def _parseSpec(spec):
# No English match found, try localized size specs. Accept any utf-8 # character and leave the result as a (unicode object. - if six.PY2: - spec_local = specifier.decode("utf-8") - else: - # str = unicode in Python3 - spec_local = specifier + spec_local = specifier.decode("utf-8")
# Use the locale-specific lowercasing spec_local = spec_local.lower() @@ -210,9 +200,9 @@ class Size(Decimal): If you want to use a spec value to represent a bytes value, you can use the letter 'b' or 'B' or omit the size specifier. """ - if isinstance(value, (six.string_types, bytes)): + if isinstance(value, str): size = _parseSpec(value) - elif isinstance(value, (six.integer_types, float, Decimal)): + elif isinstance(value, (int, long, float, Decimal)): size = Decimal(value) elif isinstance(value, Size): size = Decimal(value.convertTo("b")) diff --git a/blivet/util.py b/blivet/util.py index 90b8515..8c75e6f 100644 --- a/blivet/util.py +++ b/blivet/util.py @@ -12,8 +12,6 @@ import uuid from decimal import Decimal from contextlib import contextmanager
-import six - from .size import Size
import logging @@ -326,7 +324,7 @@ def numeric_type(num): """ if num is None: num = 0 - elif not isinstance(num, (six.integer_types, float, Size, Decimal)): + elif not isinstance(num, (int, long, float, Size, Decimal)): raise ValueError("value (%s) must be either a number or None" % num)
return num diff --git a/python-blivet.spec b/python-blivet.spec index f14b6ef..fb57f06 100644 --- a/python-blivet.spec +++ b/python-blivet.spec @@ -26,7 +26,6 @@ BuildRequires: gettext BuildRequires: python-setuptools
Requires: python -Requires: python-six Requires: pykickstart >= %{pykickstartver} Requires: util-linux >= %{utillinuxver} Requires: python-pyudev diff --git a/tests/formats_test/fslabeling.py b/tests/formats_test/fslabeling.py index 22d74ee..f7386b7 100644 --- a/tests/formats_test/fslabeling.py +++ b/tests/formats_test/fslabeling.py @@ -1,18 +1,16 @@ #!/usr/bin/python
import abc -from six import add_metaclass
from tests import loopbackedtestcase from blivet.errors import FSError
-@add_metaclass(abc.ABCMeta) class LabelingAsRoot(loopbackedtestcase.LoopBackedTestCase): """Tests various aspects of labeling a filesystem where there is no easy way to read the filesystem's label once it has been set and where the filesystem can not be relabeled. """ - + __metaclass__ = abc.ABCMeta
_fs_class = abc.abstractproperty( doc="The class of the filesystem being tested on.") diff --git a/tests/size_test.py b/tests/size_test.py index 0f2a733..c600083 100644 --- a/tests/size_test.py +++ b/tests/size_test.py @@ -23,14 +23,9 @@
import unittest
-import six - from blivet.errors import SizePlacesError from blivet.size import Size, _prefixes, ROUND_UP, ROUND_DOWN, ROUND_DEFAULT, ROUND_HALF_UP
-if six.PY3: - long = int # pylint: disable=redefined-builtin - class SizeTestCase(unittest.TestCase): def testExceptions(self): zero = Size(0)
--- python-blivet.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/python-blivet.spec b/python-blivet.spec index fb57f06..18a4997 100644 --- a/python-blivet.spec +++ b/python-blivet.spec @@ -14,7 +14,7 @@ Source0: http://github.com/dwlehman/blivet/archive/%%7Brealname%7D-%%7Bversion%7D.tar... %define dmver 1.02.17-6 %define pykickstartver 1.99.22 %define partedver 1.8.1 -%define pypartedver 1:3.9.5 +%define pypartedver 1:3.9 %define pythonpyblockver 0.45 %define e2fsver 1.41.0 %define pythoncryptsetupver 0.1.1
--- blivet/__init__.py | 2 -- blivet/devicetree.py | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/blivet/__init__.py b/blivet/__init__.py index 7051ecb..1f47add 100644 --- a/blivet/__init__.py +++ b/blivet/__init__.py @@ -132,8 +132,6 @@ def enable_installer_mode():
flags.installer_mode = True
- from . import deviceaction - def getSysroot(): """Returns the path to the target OS installation.
diff --git a/blivet/devicetree.py b/blivet/devicetree.py index 38b729a..360155f 100644 --- a/blivet/devicetree.py +++ b/blivet/devicetree.py @@ -53,7 +53,6 @@ from .platform import platform from . import tsort from .flags import flags from .storage_log import log_exception_info, log_method_call, log_method_return -import parted from .i18n import _ from .size import Size
@@ -172,6 +171,7 @@ class DeviceTree(object): @property def pvInfo(self): if self._pvInfo is None: + # pylint: disable=attribute-defined-outside-init self._pvInfo = lvm.pvinfo()
return self._pvInfo @@ -179,6 +179,7 @@ class DeviceTree(object): @property def lvInfo(self): if self._lvInfo is None: + # pylint: disable=attribute-defined-outside-init self._lvInfo = lvm.lvs()
return self._lvInfo
On Wed, May 27, 2015 at 01:16:01PM -0500, David Lehman wrote:
Patches 1-3 are for switch to python-pyudev.
Patch 4 splits devices.py into devices package.
Patch 5 switches from transifex to zanata.
Patches 6-10 are for rc-release builds.
Patches 11,12 are required changes.
Patch 13 is just low-hanging pylint fruit.
bcl, clumens, do we want/need the rc-release/mock stuff on rhel7-branch?
I have tested this by installing a scratch build in a freshly- installed 7.1 vm and running the examples shipped with blivet.
These all look good to me.
On Thu, 2015-05-28 at 17:06 -0700, Brian C. Lane wrote:
On Wed, May 27, 2015 at 01:16:01PM -0500, David Lehman wrote:
Patches 1-3 are for switch to python-pyudev.
Patch 4 splits devices.py into devices package.
Patch 5 switches from transifex to zanata.
Patches 6-10 are for rc-release builds.
Patches 11,12 are required changes.
Patch 13 is just low-hanging pylint fruit.
bcl, clumens, do we want/need the rc-release/mock stuff on rhel7-branch?
I have tested this by installing a scratch build in a freshly- installed 7.1 vm and running the examples shipped with blivet.
These all look good to me.
Same here, except for that one question/double-check-request for PATCH 01/13.
anaconda-patches@lists.fedorahosted.org