Mini Shell

Direktori : /lib/python3.6/site-packages/blivet/__pycache__/
Upload File :
Current File : //lib/python3.6/site-packages/blivet/__pycache__/devicetree.cpython-36.opt-1.pyc

3

{)c_��@sdddlZddlZddlZddlZddlZejdd�ddlmZddl	m
Z
ddlmZddlm
Z
mZmZmZmZdd	lmZmZdd
lmZmZmZddlmZmZddlmZdd
lmZddlm Z ddl!m"Z"ddlm#Z#ddl$m%Z%ddl&m'Z'm(Z(ddl)m*Z*ddl+m,Z,ddl-Z-e-j.d�Z/eefZ0ej1e*�Gdd�de2��Z3Gdd�de3e%e"�Z4dS)�N�BlockDevz2.0)r�)�
ActionList)�	callbacks)�DeviceError�DeviceTreeError�StorageError�DuplicateUUIDError�InvalidMultideviceSelection)�ActionDestroyDevice�ActionDestroyFormat)�BTRFSDevice�NoDevice�PartitionDevice)�LVMLogicalVolumeDevice�LVMVolumeGroupDevice)�Tags)�formats)�lvm)�EventHandlerMixin)�util)�PopulatorMixin)�log_method_call�log_method_return)�SynchronizedMeta)�lvs_infoZblivetc@sleZdZdZdMdd�ZdNdd�Zdd�Zed	d
��Zedd��Z	dOdd�Z
dPdd�ZdQdd�Zedd��Z
dd�Zdd�Zdd�Zdd�ZdRdd �Zd!d"�Zd#d$�Zd%d&�ZdSd'd(�ZdTd)d*�ZdUd+d,�ZdVd-d.�ZdWd/d0�ZdXd1d2�ZdYd3d4�ZdZd5d6�Zed7d8��Zed9d:��Zed;d<��Z ed=d>��Z!ed?d@��Z"dAdB�Z#dCdD�Z$dEdF�Z%dGdH�Z&dIdJ�Z'dKdL�Z(dS)[�DeviceTreeBasea� A quasi-tree that represents the devices in the system.

        The tree contains a list of :class:`~.devices.StorageDevice` instances,
        which does not necessarily reflect the actual state of the system's
        devices. :class:`~.deviceaction.DeviceAction` is used to perform
        modifications to the tree, except when initially populating the tree.

        :class:`~.deviceaction.DeviceAction` instances are registered, possibly
        causing the addition or removal of :class:`~.devices.StorageDevice`
        instances to/from the tree. A :class:`~.deviceaction.DeviceAction`
        is reversible up to the time its 'execute' method is called.

        Only one action of any given type/object pair should exist for
        any given device at any given time.

        :class:`~.deviceaction.DeviceAction` instances can only be registered
        for leaf devices, except for resize actions.
    NcCs|j||�dS)z�
            :keyword ignored_disks: ignored disks
            :type ignored_disks: list
            :keyword exclusive_disks: exclusive didks
            :type exclusive_disks: list
        N)�reset)�self�
ignored_disks�exclusive_disks�r!� /usr/lib/python3.6/devicetree.py�__init__KszDeviceTreeBase.__init__cCsDg|_t|j|jd�|_g|_tj�|p,g|_|p6g|_	i|_
dS)z� Reset the instance to its initial state.

            :keyword ignored_disks: ignored disks
            :type ignored_disks: list
            :keyword exclusive_disks: exclusive didks
            :type exclusive_disks: list
        )ZaddfuncZ
removefuncN)�_devicesr�_register_action�_cancel_action�_actions�_hiddenrZlvm_devices_resetr r�edd_dict)rrr r!r!r"rTs	

zDeviceTreeBase.resetcsFg���fdd��dd�|jD�}d}x|D]}|�|d�7}q,W|S)Ncsd|�k}dd||f}�j|�|r>|dd|df7}n"x |jD]}|�||d�7}qFW|S)Nz%s%s
z  z%s...
r)�append�children)�root�depthZabbreviate_subtree�sZchild)�done�show_subtreer!r"r0ms
z,DeviceTreeBase.__str__.<locals>.show_subtreecSsg|]}|js|�qSr!)�parents)�.0�dr!r!r"�
<listcomp>xsz*DeviceTreeBase.__str__.<locals>.<listcomp>�r)r$)r�rootsZtreer,r!)r/r0r"�__str__js
zDeviceTreeBase.__str__cCs^g}xT|jD]J}t|dd�sq|jrL|jdd�|D�krLt|t�rLtd��|j|�qW|S)z' List of devices currently in the tree �completeTcSsg|]
}|j�qSr!)�uuid)r2r3r!r!r"r4�sz*DeviceTreeBase.devices.<locals>.<listcomp>zduplicate uuids in device tree)r$�getattrr9�
isinstancerrr*)r�devices�devicer!r!r"r<�szDeviceTreeBase.devicescs�ttjj��}g�xL|j|jD]<}|jdks<|jjd�r |jdkr |j�kr �j	|j�q Wdd�|j
jddd�D���j��fd	d
�|D���S)z List of devices names �	partitionZreqzbtrfs volumecSsg|]}|jj�qSr!)r=�name)r2Zacr!r!r"r4�sz(DeviceTreeBase.names.<locals>.<listcomp>Zdestroyr=)Zaction_typeZobject_typec3s"|]}|�kr|�kr|VqdS)Nr!)r2�n)�names�
removed_namesr!r"�	<genexpr>�sz'DeviceTreeBase.names.<locals>.<genexpr>)
�listr�cache�keysr$r(�typer?�
startswithr*�actions�find�extend)rZlv_info�devr!)rArBr"rA�s

zDeviceTreeBase.namesTcCs�|jrh|jdd�|jD�krht|t�rh|j|jddd�}|j|jkrPtd��ntd|j|j|jf��x |jD]}||jkrptd��qpW|j	|d�|jj
|�tj|d	�t
jd
|j|j|j�dS)z� Add a device to the tree.

            :param newdev: the device to add
            :type newdev: a subclass of :class:`~.devices.StorageDevice`

            Raise DeviceTreeError if the device's identifier is already
            in the list.
        cSsg|]
}|j�qSr!)r9)r2r3r!r!r"r4�sz.DeviceTreeBase._add_device.<locals>.<listcomp>T)�
incomplete�hiddenz&Trying to add already existing device.z5Duplicate UUID '%s' found for devices: '%s' and '%s'.zparent device not in tree)�new)r=z"added %s %s (id %d) to device treeN)r9r$r;r�get_device_by_uuidr?rr	r1�add_hookr*rZdevice_added�log�inforG�id)rZnewdevrOrL�parentr!r!r"�_add_device�s 	


zDeviceTreeBase._add_devicecCs�||jkrtd|j��|jrV|rVtjd|jtjdd�|jD���td|j��|j	|d�|r�t
|t�r�|jdk	r�x,|jD]"}t
|t�r�|j|jkr�|j
�q�W|jj|�tj|d�tjd	|j|j|j�dS)
a� Remove a device from the tree.

            :param dev: the device to remove
            :type dev: a subclass of :class:`~.devices.StorageDevice`
            :keyword force: whether to force removal of a non-leaf device
            :type force: bool
            :keyword modparent: update parent device to account for removal
            :type modparent: bool

            .. note::

                Only leaves may be removed.
        zDevice '%s' not in treez%s has children %scss|]}|jVqdS)N)r?)r2�cr!r!r"rC�sz0DeviceTreeBase._remove_device.<locals>.<genexpr>z"Cannot remove non-leaf device '%s')�	modparentN)r=z&removed %s %s (id %d) from device tree)r$�
ValueErrorr?�isleafrR�debug�pprintZpformatr+Zremove_hookr;r�diskZupdate_name�removerZdevice_removedrSrGrT)rrL�forcerXr=r!r!r"�_remove_device�s"
"

zDeviceTreeBase._remove_devicecCs0tjd|j�|j|�}|j�x�|r�tjddd�|D��dd�|D�}tjddd�|D��xn|D]f}|r�|jjr�|jr�|jr�|j	j
t|��|j	j
t|��n|js�d|_|j
||d	�|j|�qfWq"W|js�|r�|j	j
t|��nd|_|�r,|j�r,|�r|j	j
t|��n|j
||d	�dS)
a� Remove a device after removing its dependent devices.

            :param :class:`~.devices.StorageDevice` device: the device to remove
            :keyword bool actions: whether to schedule actions for the removal
            :keyword bool modparent: whether to update parent device upon removal
            :keyword bool remove_device: whether to remove the root device

            If the device is not a leaf, all of its dependents are removed
            recursively until it is a leaf device. At that point the device is
            removed, unless it is a disk. If the device is a disk, its
            formatting is removed but no attempt is made to actually remove the
            disk device.
        zremoving %szdevices to remove: %scSsg|]
}|j�qSr!)r?)r2r3r!r!r"r4sz3DeviceTreeBase.recursive_remove.<locals>.<listcomp>cSsg|]}|jr|�qSr!)rZ)r2r3r!r!r"r4szleaves to remove: %scSsg|]
}|j�qSr!)r?)r2r3r!r!r"r4sN)rX)rRr[r?�get_dependent_devices�reverse�format�exists�	protectedZformat_immutablerI�addrrr`r^�is_disk)rr=rIZ
remove_devicerXr<�leavesZleafr!r!r"�recursive_remove�s2

zDeviceTreeBase.recursive_removecCs|jS)N)r')rr!r!r"rI$szDeviceTreeBase.actionscCs&|jo
|jr$|j|jkr$td��n |jrD|jrD|j|jkrDtd��|jr�|jr�t|jt�r�|jjr�x$|jjD]}||jkrn|j|�qnW|j	|j�n�|j
r�|jr�|j|j�t|jt�r�|jjr�x\|jjD]}|j	|dd�q�Wn<|jo�|j�r"t|jjt
jj��r"|jjj|jk�r"td��dS)a Register an action to be performed at a later time.

            :param action: the action
            :type action: :class:`~.deviceaction.DeviceAction`

            Modifications to the Device instance are handled before we
            get here.
        zdevice is not in the treezdevice is already in the treeF)rOzmountpoint already in useN)�	is_create�	is_devicer=r$rr;r�from_lvsr`rV�
is_destroyZ	is_formatrcrZfsZFS�
mountpoint�filesystems)r�action�lvr!r!r"r%(s*	

zDeviceTreeBase._register_actioncCs�|jrN|jrN|j|j�t|jt�r�|jjr�xv|jjD]}|j|dd�q6WnV|jr�|jr�t|jt�r�|jjr�x$|jjD]}||j	krx|j|�qxW|j|jdd�dS)ai Cancel a registered action.

            :param action: the action
            :type action: :class:`~.deviceaction.DeviceAction`

            This will unregister the action and do any required
            modifications to the device list.

            Actions all operate on a Device, so we can use the devices
            to determine dependencies.
        F)rON)
rjrkr`r=r;rrlrVrmr$)rrprqr!r!r"r&Ls
zDeviceTreeBase._cancel_actioncCsfx`|jD]V}|jrqy|jdd�Wqttjfk
r\}ztjd|j|�WYdd}~XqXqWdS)z& Run teardown methods on all devices. T)�	recursivezteardown of %s failed: %sN)	rhreZteardownr�blockdevZ
BlockDevErrorrRrSr?)rr=�er!r!r"�teardown_allmszDeviceTreeBase.teardown_allcCsTxN|jD]D}y|j�Wqtk
rJ}ztjd|j|�WYdd}~XqXqWdS)z# Run setup methods on all devices. zsetup of %s failed: %sN)rhZsetuprrR�errorr?)rr=rtr!r!r"�	setup_allxs
zDeviceTreeBase.setup_allFcCs�g}t|||d�|jr,|r,tjd�|S|jdd�}|rJ|j|j�x2|D]*}tjd|j|j�|j|�rP|j	|�qPW|S)a= Return a list of devices that depend on dep.

            The list includes both direct and indirect dependents.

            :param dep: the device whose dependents we are looking for
            :type dep: :class:`~.devices.StorageDevice`
            :keyword bool hidden: include hidden devices in search
        )�deprNz
dep is a leafNzchecking if %s depends on %s)
rrZrRr[r$rKr(r?�
depends_onr*)rrxrNZ
dependentsr<r=r!r!r"ra�s	


z$DeviceTreeBase.get_dependent_devicescCstdd�|j|dd�D��S)a$ Return disks related to disk by container membership.

            :param :class:`~.devices.StorageDevice` disk: the disk
            :returns: related disks
            :rtype: set of :class:`~.devices.StorageDevice`

            .. note::

                The disk may be hidden.

        css|]}|jD]
}|VqqdS)N)�disks)r2rxr3r!r!r"rC�sz3DeviceTreeBase.get_related_disks.<locals>.<genexpr>T)rN)�setra)rr]r!r!r"�get_related_disks�sz DeviceTreeBase.get_related_diskscsRt��x2|jD](�t�fdd�|D��r�j�jj�qW�fdd�|jD�}|S)a� Return a list of actions related to the specified disk.

            :param disks: list of disks
            :type disk: list of :class:`~.devices.StorageDevices`
            :returns: list of related actions
            :rtype: list of :class:`~.deviceaction.DeviceAction`

            This includes all actions on the specified disks, plus all actions
            on disks that are in any way connected to the specified disk via
            container devices.
        c3s|]}�jj|�VqdS)N)r=ry)r2r3)rpr!r"rC�sz2DeviceTreeBase.get_disk_actions.<locals>.<genexpr>cs"g|]}t|jj�j��r|�qSr!)r{r=rz�intersection)r2�a)�
related_disksr!r"r4�sz3DeviceTreeBase.get_disk_actions.<locals>.<listcomp>)r{rI�any�updater=rz)rrzZrelated_actionsr!)rprr"�get_disk_actions�szDeviceTreeBase.get_disk_actionscCs,|j|�}xt|�D]}|jj|�qWdS)a Cancel all actions related to the specified disk.

            :param disks: list of disks
            :type disk: list of :class:`~.devices.StorageDevices`

            This includes actions related directly and indirectly (via container
            membership, for example).
        N)r��reversedrIr^)rrzrIrpr!r!r"�cancel_disk_actions�s	
z"DeviceTreeBase.cancel_disk_actionscCsZ|r,dd�|jdd�|jdd�D�}ndd�|jdd�D�}|sVdd�|D�}|S)a6 Return list of devices modified according to parameters.

            :param bool incomplete: include incomplete devices in result
            :param bool hidden: include hidden devices in result

            :returns: a generator of devices
            :rtype: generator of :class:`~.devices.Device`
        css|]
}|VqdS)Nr!)r2r3r!r!r"rC�sz1DeviceTreeBase._filter_devices.<locals>.<genexpr>Ncss|]
}|VqdS)Nr!)r2r3r!r!r"rC�scss|]}t|dd�r|VqdS)r8TN)r:)r2r3r!r!r"rC�s)r$r()rrMrNr<r!r!r"�_filter_devices�s	(zDeviceTreeBase._filter_devicescsNt|�||d�d}�r@|j||d�}tj�fdd�|D�d�}t||�|S)ab Return a list of devices with a matching sysfs path.

            :param str path: the sysfs path to match
            :param bool incomplete: include incomplete devices in search
            :param bool hidden: include hidden devices in search
            :returns: the first matching device found
            :rtype: :class:`~.devices.Device`
        )�pathrMrNN)rMrNc3s|]}|j�kr|VqdS)N)Z
sysfs_path)r2r3)r�r!r"rC�sz:DeviceTreeBase.get_device_by_sysfs_path.<locals>.<genexpr>)rr��six�nextr)rr�rMrN�resultr<r!)r�r"�get_device_by_sysfs_path�s	
z'DeviceTreeBase.get_device_by_sysfs_pathcsNt|�||d�d}�r@|j||d�}tj�fdd�|D�d�}t||�|S)aV Return a list of devices with a matching UUID.

            :param str uuid: the UUID to match
            :param bool incomplete: include incomplete devices in search
            :param bool hidden: include hidden devices in search
            :returns: the first matching device found
            :rtype: :class:`~.devices.Device`
        )r9rMrNN)rMrNc3s(|] }|j�ks|jj�kr|VqdS)N)r9rc)r2r3)r9r!r"rC	sz4DeviceTreeBase.get_device_by_uuid.<locals>.<genexpr>)rr�r�r�r)rr9rMrNr�r<r!)r9r"rP�s	
z!DeviceTreeBase.get_device_by_uuidcsNt|�||d�d}�r@|j||d�}tj�fdd�|D�d�}t||�|S)af Return a device with a matching filesystem label.

            :param str label: the filesystem label to match
            :param bool incomplete: include incomplete devices in search
            :param bool hidden: include hidden devices in search
            :returns: the first matching device found
            :rtype: :class:`~.devices.Device`
        )�labelrMrNN)rMrNc3s$|]}t|jdd��kr|VqdS)r�N)r:rc)r2r3)r�r!r"rCsz5DeviceTreeBase.get_device_by_label.<locals>.<genexpr>)rr�r�r�r)rr�rMrNr�r<r!)r�r"�get_device_by_label
s	
z"DeviceTreeBase.get_device_by_labelcsNt|�||d�d}�r@|j||d�}tj�fdd�|D�d�}t||�|S)aP Return a device with a matching name.

            :param str name: the name to look for
            :param bool incomplete: include incomplete devices in search
            :param bool hidden: include hidden devices in search
            :returns: the first matching device found
            :rtype: :class:`~.devices.Device`
        )r?rMrNN)rMrNc3s8|]0}|j�ks,t|t�r|j�jdd�kr|VqdS)z--�-N)r?r;�_LVM_DEVICE_CLASSES�replace)r2r3)r?r!r"rC+sz4DeviceTreeBase.get_device_by_name.<locals>.<genexpr>)rr�r�r�r)rr?rMrNr�r<r!)r?r"�get_device_by_names	
z!DeviceTreeBase.get_device_by_namecsVt|�||d�d}�rH|j||d�}tj�fdd�tt|��D�d�}t||�|S)a� Return a device with a matching path.

            If there is more than one device with a matching path,
            prefer a leaf device to a non-leaf device.

            :param str path: the path to match
            :param bool incomplete: include incomplete devices in search
            :param bool hidden: include hidden devices in search
            :returns: the first matching device found
            :rtype: :class:`~.devices.Device`
        )r�rMrNN)rMrNc3s8|]0}|j�ks,t|t�r|j�jdd�kr|VqdS)z--r�N)r�r;r�r�)r2r3)r�r!r"rCEsz4DeviceTreeBase.get_device_by_path.<locals>.<genexpr>)rr�r�r�r�rDr)rr�rMrNr�r<r!)r�r"�get_device_by_path1s
z!DeviceTreeBase.get_device_by_pathcsFt|�||d�|j||d�}tj�fdd�|D�d�}t||�|S)aT Return a device with specified device id.

            :param int id_num: the id to look for
            :param bool incomplete: include incomplete devices in search
            :param bool hidden: include hidden devices in search
            :returns: the first matching device found
            :rtype: :class:`~.devices.Device`
        )�id_numrMrN)rMrNc3s|]}|j�kr|VqdS)N)rT)r2r3)r�r!r"rCWsz2DeviceTreeBase.get_device_by_id.<locals>.<genexpr>N)rr�r�r�r)rr�rMrNr<r�r!)r�r"�get_device_by_idLs
	
zDeviceTreeBase.get_device_by_idc/Cs�d}|jd�r`|jd�d}|jd�r0|jd�sD|jd�rP|jd�rP|dd*�}|jj|�}�n~|jd�r�|jd�d}|jd�r�|jd�s�|jd�r�|jd�r�|dd+�}|jj|�}�n"|r�d	|jd
�kr�|j|�}|s�|j|�}�n�t	j
d|��rF|jd�\}}	}
t|d
�}x2|jj
�D]$\}}
|
|k�r|j||
�}P�qW|�rt|jd��rt|j|�}|�std|}|�sv|jd��r�tjj|�}|jd��r�ytjj|dd��}Wn8tjk
�r�}ztjd||�d}WYdd}~XnX|�r�d|}t	j
d|��rlytjj|dd��}Wn8tjk
�r\}ztjd||�d}WYdd}~XnX|�rld|}|j|�}|dk�r�|�r|j|�}|�rtjd|�|jd�}|�r�|j|�}|�r�|j}nd}tjd|�|�r|j�r|jjdk�r|jj}tjd|�|j|�}|�r|}|dk�r�|�r�|jd��r�|j|jd�d,�}|�r�|d}y|jd}Wn$t k
�r�}zWYdd}~XnXnL|dk�r�|dd�}|jd�\}}}|�r�d|k�r�d||f}|j|�}|�r�|jjd ��r�|�r�t!|d!|�}d}d"|k�r$d#}t"j#d$|�}n*d%|k�r@d&}t"j#d'|�}n|j$�rN|j$}|�r�|�r�x(|j%D]}t!||d�|k�rb|}P�qbW|�r�tjd(||j|j�ntjd)|�|S)-a� Return the device matching the provided device specification.

            The spec can be anything from a device name (eg: 'sda3') to a device
            node path (eg: '/dev/mapper/fedora-root' or '/dev/dm-2') to
            something like 'UUID=xyz-tuv-qrs' or 'LABEL=rootfs'.

            :param devspec: a string describing a block device
            :type devspec: str
            :keyword blkid_tab: blkid info
            :type blkid_tab: :class:`~.BlkidTab`
            :keyword crypt_tab: crypto info
            :type crypt_tab: :class:`~.CryptTab`
            :keyword options: mount options
            :type options: str
            :returns: the device
            :rtype: :class:`~.devices.StorageDevice` or None
        NzUUID=�=��"�'rzLABEL=Znodev�,z(0x)?[A-Fa-f0-9]{2}(p\d+)?$�p�z/dev/z
/dev/disk/z/dev/dm-�zfailed to resolve %s: %sz/dev/mapper/z/dev/md\d+(p\d+)?$z/dev/md/zfound blkid.tab entry for '%s'ZUUID�Nonezfound device '%s' in treeZlukszluks device; map name is '%s'�/r=rz%s-%s�btrfsZvolumezsubvol=r?�subvolz	subvolid=Zvol_idZsubvolidzresolved '%s' to '%s' (%s)zfailed to resolve '%s'���r�r�)&rHr>�endswith�uuids�get�labels�splitr�r��re�match�intr)�items�osr��realpathrsZdmZname_from_nodeZDMErrorrRrSZmdZMDRaidErrorr[rPr?rcrG�map_namer+�
IndexErrorr:rZget_option_valueZdefault_subvolumeZ
subvolumes)rZdevspecZ	blkid_tabZ	crypt_tabZoptionsr=r9r�ZdriveZ_pZpartnum�specZedd_nameZ
edd_numberZdm_namertZmd_nameZ
blkid_tab_entZdevstrr�Z
mapped_devZ
crypt_tab_entZluks_devr?Zvg_nameZ_slashZlv_namerq�attr�valr�r!r!r"�resolve_device[s�















zDeviceTreeBase.resolve_devicecCsdd�|jD�}|S)z8 List of all devices upon which no other devices exist. cSsg|]}|jr|�qSr!)rZ)r2r3r!r!r"r4�sz)DeviceTreeBase.leaves.<locals>.<listcomp>)r$)rrhr!r!r"rh�szDeviceTreeBase.leavescCs8g}x.|jD]$}|jrt|jdd�r|j|j�qW|S)z List of filesystems. rnN)rhrcr:r*)rrorLr!r!r"ro�s
zDeviceTreeBase.filesystemscCszi}xp|jD]f}y
|j}Wntk
r2d}YnX|r@|||<y|jj}Wntk
rdd}YnX|r|||<qW|S)z; Dict with uuid keys and :class:`~.devices.Device` values. N)r$r9�AttributeErrorrc)rr�rLr9r!r!r"r�s


zDeviceTreeBase.uuidscCsHi}x>|jD]4}t|jdd�r|jjdks4t|t�r|||jj<qW|S)zh Dict with label keys and Device values.

            FIXME: duplicate labels are a possibility
        r�Nr�)r$r:rcrGr;r
r�)rr�rLr!r!r"r�szDeviceTreeBase.labelscCs4i}x*|jD] }|jjr|jjr|||jj<qW|S)z. Dict with mountpoint keys and Device values. )r<rcZ	mountablern)rror=r!r!r"�mountpoints.s
zDeviceTreeBase.mountpointscCs�||jkrdS|jr |j|g�x|jD]}|j|�q(Wtjd|�|jsPdS|j|ddd�|jj	|�|j
jdkr�tj
|j�dS)a� Hide the specified device.

            :param device: the device to hide
            :type device: :class:`~.devices.StorageDevice`

            Hiding a device will cancel all actions that involve the device and
            will remove the device from the device list.

            If the device is not a leaf device, all devices that depend on it
            will be hidden leaves-first until the device is a leaf device.

            If a device exists, performs some special actions and places
            it on a list of hidden devices.

            Mixes recursion and side effects, most significantly in the code
            that removes all the actions. However, this code is a null op
            in every case except the first base case that is reached,
            where all actions are removed. This means that when a device
            is removed explicitly in this function by means of a direct call to
            _remove_devices it is guaranteed that all actions have already
            been canceled.

            If a device does not exist then it must have been removed by the
            cancelation of all the actions, so it does not need to be removed
            explicitly.

            Most devices are considered leaf devices if they have no children,
            however, some devices must satisfy more stringent requirements.
            _remove_device() will raise an exception if the device it is
            removing is not a leaf device. hide() guarantees that any
            device that it removes will have no children, but it does not
            guarantee that the more stringent requirements will be enforced.
            Therefore, _remove_device() is invoked with the force parameter
            set to True, to skip the isleaf check.
        Nzhiding device %sTF)r_rX�lvmpv)r(rgr�r+�hiderRrSrdr`r*rcrGrZlvm_devices_remover�)rr=r3r!r!r"r�:s$
zDeviceTreeBase.hidecs�x�t�j�D]�}||ks<|j|�rt�fdd�|jD��rtjd|j|j|j	��jj
|��jj|�|j
dd�|jjdkrtj|j�qWdS)a! Restore a device's visibility.

            :param device: the device to restore/unhide
            :type device: :class:`~.devices.StorageDevice`

            .. note::

                Actions canceled while hiding the device are not rescheduled
                automatically.

        c3s|]}|�jkVqdS)N)r()r2rU)rr!r"rC�sz(DeviceTreeBase.unhide.<locals>.<genexpr>zunhiding device %s %s (id %d)F)rOr�N)r�r(ryr�r1rRrSrGr?rTr^r$r*rQrcrZlvm_devices_addr�)rr=rNr!)rr"�unhideus
zDeviceTreeBase.unhidecCs�t�}|jdd�}xh|D]`}|jd�rp|dd�}|tjkrJtd|��x.|D]}||jkrP|j|j�qPWq|j|�qW|S)a9 Expands tags in input list into devices.

            :param taglist: list of strings
            :returns: set of devices
            :rtype: set of strings

            Raise ValueError if unknown tag encountered in taglist

            .. note::

                Returns empty set if taglist is empty
        N�@rzunknown tag '@%s' encountered)	r{r$rHr�__members__rY�tagsrfr?)r�taglistr�r<�item�tagr=r!r!r"�expand_taglist�s





zDeviceTreeBase.expand_taglistcCsV|j|krdSdd�|D�}x4|D],}|tjkr<td|��t|�|jkr"dSq"WdS)NTcSs"g|]}|jd�r|dd��qS)r�rN)rH)r2�tr!r!r"r4�sz3DeviceTreeBase._disk_in_taglist.<locals>.<listcomp>z(unknown ignoredisk tag '@%s' encounteredF)r?rr�rYr�)rr]r�r�r�r!r!r"�_disk_in_taglist�s


zDeviceTreeBase._disk_in_taglistcCs*|jr|j||j�p(|jo(|j||j�S)z{ Checks config for lists of exclusive and ignored disks
            and returns if the given one should be ignored
        )rr�r )rr]r!r!r"�_is_ignored_disk�szDeviceTreeBase._is_ignored_diskcs2�x*dd��jD�D�]}�jo,�j|�j�}�jo@�j|�j�}|r�t|j�dkr�t�fdd�|jdjD��sztd���j	|jd�x|jD]}�j	|�q�W�j	|��jo�|rd}|jr�td	d�|jD��r�t
�fd
d�|jD��}n*|jj�rt|j�dk�r�j
|jd�}|r�j	|�qWdS)NcSsg|]}|jr|�qSr!)rg)r2r3r!r!r"r4�sz6DeviceTreeBase._hide_ignored_disks.<locals>.<listcomp>rc3s|]}�j|�VqdS)N)r�)r2r3)rr!r"rC�sz5DeviceTreeBase._hide_ignored_disks.<locals>.<genexpr>rzFIncluding only a subset of raid/multipath member disks is not allowed.Tcss|]}|jjVqdS)N)rcrN)r2r�r!r!r"rC�sc3s|]}�j|�VqdS)N)r�)r2r3)rr!r"rC�s)r$rr�r �lenr+�allr1r
r�r�rcrNr�)rr]Z
is_ignoredZis_exclusiver�Zignoredr!)rr"�_hide_ignored_disks�s&
z"DeviceTreeBase._hide_ignored_disks)NN)NN)T)NT)TTT)F)FF)FF)FF)FF)FF)FF)FF)NNN))�__name__�
__module__�__qualname__�__doc__r#rr7�propertyr<rArVr`rirIr%r&rurwrar|r�r�r�r�rPr�r�r�r�r�rhror�r�r�r�r�r�r�r�r�r!r!r!r"r7sL
	

 
'
8$!









;
rc@s eZdZddd�Zddd�ZdS)�
DeviceTreeNcCs,tj|||d�tj||d�tj|�dS)N)rr )�disk_images)rr#rr)rrr r�r!r!r"r#�szDeviceTree.__init__cCs"tj|||d�tj||d�dS)N)rr )r�)rrr)rrr r�r!r!r"r�szDeviceTree.reset)NNN)NNN)r�r�r�r#rr!r!r!r"r��s
r�)5r�r\r�r�ZgiZrequire_versionZ
gi.repositoryrrsZ
actionlistrr�errorsrrrr	r
Zdeviceactionrrr<r
rrrrZdevices.librr5rZ
devicelibsrZevents.handlerrrZ	populatorrZstorage_logrrZthreadsrZstatic_datarZloggingZ	getLoggerrRr�Z
add_metaclass�objectrr�r!r!r!r"�<module>sD
4