Mini Shell

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

3

�Mf���@s�ddlZddlZddlZddlZddlZddlZddlZddlZddlm	Z	m
Z
ddlmZm
Z
ddlmZmZddlmZmZmZmZddlmZmZddlmZmZmZdd	lmZmZmZdd
lmZddlm Z ddl!m"Z"dd
l#m$Z$m%Z%ddl&m'Z'ddl(m)Z)ddl*m+Z+ddl,m,Z,ddl*m-Z-ddl.m/Z/m0Z0ddl1m2Z2ddl1m3Z3ddl1m4Z4ddl1m5Z5ddl6m7Z7ddl8m9Z9ddl:Z:e:j;d�Z<ej=e7�Gdd�de>��Z?dS)�N�)�log_method_call�log_exception_info)�BTRFSSubVolumeDevice�BTRFSVolumeDevice)�LVMLogicalVolumeDevice�LVMVolumeGroupDevice)�MDRaidArrayDevice�PartitionDevice�TmpFSDevice�device_path_to_name)�StratisPoolDevice�StratisFilesystemDevice)�ActionCreateDevice�ActionCreateFormat�ActionDestroyDevice)�ActionDestroyFormat�ActionResizeDevice�ActionResizeFormat)�get_edd_dict)�MAIN_VOLUME_ID)�LUKS_METADATA_SIZE)�StorageError�DependencyError)�Size)�
DeviceTree)�get_default_filesystem_type)�flags)�
get_format)�capture_output�natural_sort_key)�arch)�
devicefactory)�__version__)�
devicelibs)�SynchronizedMeta)�	luks_data�blivetc@s�eZdZdZdd�Zedd��Zejdd��Zd�dd	�Zed
d��Z	d�d
d�Z
edd��Zedd��Zedd��Z
edd��Zedd��Zedd��Zedd��Zedd��Zedd ��Zed!d"��Zed#d$��Zed%d&��Zed'd(��Zed)d*��Zed+d,��Zed-d.��Zejd/d.��Zd0d1�Zd2d3�Zd4d5�Zd6d7�Zd�d8d9�Zed:d;��Z d<d=�Z!d>d?�Z"d@dA�Z#dBdC�Z$dDdE�Z%dFdG�Z&dHdI�Z'dJdK�Z(dLdM�Z)dNdO�Z*dPdQ�Z+dRdS�Z,dTdU�Z-dVdW�Z.dXdY�Z/dZd[�Z0d�d\d]�Z1d�d_d`�Z2d�dadb�Z3d�ddde�Z4d�dfdg�Z5dhdi�Z6djdk�Z7edldm��Z8dndo�Z9edpdq��Z:drds�Z;edtdu��Z<dvdw�Z=edxdy��Z>d�dzd{�Z?e@jAfd|d}�ZBd~d�ZCdS)��Blivetz5 Top-level class for managing storage configuration. c
Cs�i|_g|_g|_i|_g|_|jt��d|_d|_dt	j
�|_yd}tdddd|g�}Wnt
k
rrYnXtjd	|�t|j|j|jd
�|_g|_dS)Nr'rz%s/storage.statez@NAME,SIZE,OWNER,GROUP,MODE,FSTYPE,LABEL,UUID,PARTUUID,MOUNTPOINTZlsblkz--bytesz-az-ozlsblk output:
%s)�
ignored_disks�exclusive_disks�disk_images)�edd_dictr)r*r+�	size_sets�set_default_fstyper�_short_product_name�_next_id�tempfileZ
gettempdir�
_dump_filer�	Exception�log�debugr�
devicetree�roots)�selfZoptions�out�r:�/usr/lib/python3.6/blivet.py�__init__?s&zBlivet.__init__cCs|jS)N)r/)r8r:r:r;�short_product_name]szBlivet.short_product_namecCstjd|�||_dS)zl Change the (short) product name.
        :param name: The product name.
        :type name: string
        znew short product name: %sN)r4r5r/)r8�namer:r:r;r=asNcCs|jjj||jd�dS)z�
        Commit queued changes to disk.

        :param callbacks: callbacks to be invoked when actions are executed
        :type callbacks: return value of the :func:`~.callbacks.create_new_callbacks_register`

        )�	callbacks�devicesN)r6�actionsZprocessr@)r8r?r:r:r;�do_itjs	zBlivet.do_itcCs|j}|jd7_|S)z- Used for creating unique placeholder names. r)r0)r8Znewidr:r:r;�next_iduszBlivet.next_idFcCs^tjdt|�|jj|j|j|jd�|jj|d�t	|j
�|_|j|j_tj
rZ|jj�dS)a� Reset storage configuration to reflect actual system state.

            This will cancel any queued actions and rescan from scratch but not
            clobber user-obtained information like passphrases, iscsi config, &c

            :keyword cleanup_only: prepare the tree only to deactivate devices
            :type cleanup_only: bool

            See :meth:`devicetree.Devicetree.populate` for more information
            about the cleanup_only keyword argument.
        z)resetting Blivet (version %s) instance %s)r)r*r+)�cleanup_onlyN)r4�infor#r6�resetr)r*r+Zpopulater�partitionedr,rZ
include_nodevZhandle_nodev_filesystems)r8rDr:r:r;rF|s


zBlivet.resetcCs|jj}|jtd�|S)z/ A list of all the devices in the device tree. )�key)r6r@�sortr )r8r@r:r:r;r@�szBlivet.devicescCsNg}x6|jjD]*}|jr|js.tjd|j�q|j|�qW|j|j	d�|S)a* A list of the disks in the device tree.

            Ignored disks are excluded, as are disks with no media present.

            This is based on the current state of the device tree and
            does not necessarily reflect the actual on-disk state of the
            system's disks.
        z#Skipping disk: %s: No media present)rH)
r6r@Zis_disk�
media_presentr4rEr>�appendrI�compare_disks_key)r8�disks�devicer:r:r;rM�s
zBlivet.diskscCsRg}x8|jjD],}|jsq|js0tjd|j�q|j|�qW|jdd�d�|S)a� A list of the partitioned devices in the device tree.

            Ignored devices are not included, nor disks with no media present.

            Devices of types for which partitioning is not supported are also
            not included.

            This is based on the current state of the device tree and
            does not necessarily reflect the actual on-disk state of the
            system's disks.
        z%Skipping device: %s: No media presentcSs|jS)N)r>)�dr:r:r;�<lambda>�sz$Blivet.partitioned.<locals>.<lambda>)rH)	r6r@rGrJr4rEr>rKrI)r8rGrNr:r:r;rG�s
zBlivet.partitionedcCs$dd�|jD�}|jdd�d�|S)z� A list of the partitions in the device tree.

            This is based on the current state of the device tree and
            does not necessarily reflect the actual on-disk state of the
            system's disks.
        cSsg|]}t|t�r|�qSr:)�
isinstancer
)�.0rOr:r:r;�
<listcomp>�sz%Blivet.partitions.<locals>.<listcomp>cSs|jS)N)r>)rOr:r:r;rP�sz#Blivet.partitions.<locals>.<lambda>)rH)r@rI)r8�
partitionsr:r:r;rT�szBlivet.partitionscCs$dd�|jD�}|jdd�d�|S)z� A list of the LVM Volume Groups in the device tree.

            This is based on the current state of the device tree and
            does not necessarily reflect the actual on-disk state of the
            system's disks.
        cSsg|]}|jdkr|�qS)Zlvmvg)�type)rRrOr:r:r;rS�szBlivet.vgs.<locals>.<listcomp>cSs|jS)N)r>)rOr:r:r;rP�szBlivet.vgs.<locals>.<lambda>)rH)r@rI)r8�vgsr:r:r;rV�sz
Blivet.vgscCs dd�|jD�}t|dd�d�S)z� A list of the LVM Logical Volumes in the device tree.

            This is based on the current state of the device tree and
            does not necessarily reflect the actual on-disk state of the
            system's disks.
        css|]}|jdkr|VqdS)�lvmlv�lvmthinpool�	lvmthinlvN)rWrXrY)rU)rRrOr:r:r;�	<genexpr>�szBlivet.lvs.<locals>.<genexpr>cSs|jS)N)r>)rOr:r:r;rP�szBlivet.lvs.<locals>.<lambda>)rH)r@�sorted)r8�lvsr:r:r;r\�sz
Blivet.lvscCs$dd�|jD�}|jdd�d�|S)z� A list of the LVM Thin Logical Volumes in the device tree.

            This is based on the current state of the device tree and
            does not necessarily reflect the actual on-disk state of the
            system's disks.
        cSsg|]}|jdkr|�qS)rY)rU)rRrOr:r:r;rS�sz"Blivet.thinlvs.<locals>.<listcomp>cSs|jS)N)r>)rOr:r:r;rP�sz Blivet.thinlvs.<locals>.<lambda>)rH)r@rI)r8�thinr:r:r;�thinlvs�szBlivet.thinlvscCs$dd�|jD�}|jdd�d�|S)z� A list of the LVM Thin Pool Logical Volumes in the device tree.

            This is based on the current state of the device tree and
            does not necessarily reflect the actual on-disk state of the
            system's disks.
        cSsg|]}|jdkr|�qS)rX)rU)rRrOr:r:r;rSsz$Blivet.thinpools.<locals>.<listcomp>cSs|jS)N)r>)rOr:r:r;rPsz"Blivet.thinpools.<locals>.<lambda>)rH)r@rI)r8Zpoolsr:r:r;�	thinpools�szBlivet.thinpoolscCs*|jj}dd�|D�}|jdd�d�|S)z� A list of the LVM Physical Volumes in the device tree.

            This is based on the current state of the device tree and
            does not necessarily reflect the actual on-disk state of the
            system's disks.
        cSsg|]}|jjdkr|�qS)Zlvmpv)�formatrU)rRrOr:r:r;rSszBlivet.pvs.<locals>.<listcomp>cSs|jS)N)r>)rOr:r:r;rPszBlivet.pvs.<locals>.<lambda>)rH)r6r@rI)r8r@�pvsr:r:r;rasz
Blivet.pvscCs$dd�|jD�}|jdd�d�|S)z� A list of the MD arrays in the device tree.

            This is based on the current state of the device tree and
            does not necessarily reflect the actual on-disk state of the
            system's disks.
        cSsg|]}|jdkr|�qS)Zmdarray)rU)rRrOr:r:r;rSsz#Blivet.mdarrays.<locals>.<listcomp>cSs|jS)N)r>)rOr:r:r;rPsz!Blivet.mdarrays.<locals>.<lambda>)rH)r@rI)r8�arraysr:r:r;�mdarraysszBlivet.mdarrayscCs$dd�|jD�}|jdd�d�|S)z1 A list of the MD containers in the device tree. cSsg|]}|jdkr|�qS)Zmdcontainer)rU)rRrOr:r:r;rS!sz'Blivet.mdcontainers.<locals>.<listcomp>cSs|jS)N)r>)rOr:r:r;rP"sz%Blivet.mdcontainers.<locals>.<lambda>)rH)r@rI)r8rbr:r:r;�mdcontainersszBlivet.mdcontainerscCs*|jj}dd�|D�}|jdd�d�|S)z� A list of the MD member devices in the device tree.

            This is based on the current state of the device tree and
            does not necessarily reflect the actual on-disk state of the
            system's disks.
        cSsg|]}|jjdkr|�qS)Zmdmember)r`rU)rRrOr:r:r;rS.sz$Blivet.mdmembers.<locals>.<listcomp>cSs|jS)N)r>)rOr:r:r;rP/sz"Blivet.mdmembers.<locals>.<lambda>)rH)r6r@rI)r8r@�membersr:r:r;�	mdmembers%szBlivet.mdmemberscCstdd�|jD�dd�d�S)z� A list of the BTRFS volumes in the device tree.

            This is based on the current state of the device tree and
            does not necessarily reflect the actual on-disk state of the
            system's disks.
        css|]}|jdkr|VqdS)zbtrfs volumeN)rU)rRrOr:r:r;rZ:sz'Blivet.btrfs_volumes.<locals>.<genexpr>cSs|jS)N)r>)rOr:r:r;rP;sz&Blivet.btrfs_volumes.<locals>.<lambda>)rH)r[r@)r8r:r:r;�
btrfs_volumes2szBlivet.btrfs_volumescCstdd�|jD�dd�d�S)z� A list of the Stratis pools in the device tree.

            This is based on the current state of the device tree and
            does not necessarily reflect the actual on-disk state of the
            system's disks.
        css|]}|jdkr|VqdS)zstratis poolN)rU)rRrOr:r:r;rZEsz'Blivet.stratis_pools.<locals>.<genexpr>cSs|jS)N)r>)rOr:r:r;rPFsz&Blivet.stratis_pools.<locals>.<lambda>)rH)r[r@)r8r:r:r;�
stratis_pools=szBlivet.stratis_poolscCs*|jj}dd�|D�}|jdd�d�|S)z� A list of the swap devices in the device tree.

            This is based on the current state of the device tree and
            does not necessarily reflect the actual on-disk state of the
            system's disks.
        cSsg|]}|jjdkr|�qS)�swap)r`rU)rRrOr:r:r;rSQsz Blivet.swaps.<locals>.<listcomp>cSs|jS)N)r>)rOr:r:r;rPRszBlivet.swaps.<locals>.<lambda>)rH)r6r@rI)r8r@�swapsr:r:r;rjHszBlivet.swapscCstjS)N)r&�encryption_passphrase)r8r:r:r;rkUszBlivet.encryption_passphrasecCs
|t_dS)N)r&rk)r8�valuer:r:r;rkYscCstj|�dS)N)r&�save_passphrase)r8rNr:r:r;rm]szBlivet.save_passphrasecCs|jj|�dS)a� Remove a device after removing its dependent devices.

            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 by no attempt is made to actually remove the
            disk device.
        N)r6�recursive_remove)r8rNr:r:r;rn`s	zBlivet.recursive_removecCs�|jrl|jj}d}|rTd}x8|jD].}|jj|kr"tjd|j�|j	j
|dd�q"Wt|jj�|krlt
d��t|�}|j	jj|�td|jd�}t||d	�}|j	jj|�d
S)a� (Re)initialize a disk by creating a disklabel on it.

            The disk should not contain any partitions except perhaps for a
            magic partitions on mac and sun disklabels. If the disk does contain
            partitions other than the disklabel-type-specific "magic" partitions
            ValueError will be raised.

            :param disk: the disk to initialize
            :type disk: :class:`~.devices.StorageDevice`
            :returns None:
            :raises: ValueError
        rrzremoving %sF)Z	modparentz,cannot initialize a disk that has partitionsZ	disklabel)rN)�fmtN)rGr`Zmagic_partition_number�children�parted_partitionZnumberr4r5r>r6�_remove_device�lenrT�
ValueErrorrrA�addr�pathr)r8�disk�magicZexpected�partZdestroy_actionZ	new_labelZ
create_actionr:r:r;�initialize_diskks zBlivet.initialize_diskcCs�x~|jD]t}tjd|j�|jj}|jj}tjd|dd�|D��|r|rtjd|j�t|j��}|j	j
|�}|j|�qWdS)Nz.checking whether disk %s has an empty extendedzextended is %s ; logicals is %scSsg|]}|j��qSr:)�getDeviceNodeName)rR�pr:r:r;rS�sz;Blivet.remove_empty_extended_partitions.<locals>.<listcomp>z)removing empty extended partition from %s)rGr4r5r>r`Zextended_partitionZlogical_partitionsrr{r6Zget_device_by_name�destroy_device)r8rwZextendedZ
logical_partsZ
extended_namer:r:r;� remove_empty_extended_partitions�s
z'Blivet.remove_empty_extended_partitionscs�|dkr|j}|dkr|j}i}x�|D]��td�}td�}�jr��jj}xl�fdd�|D�D]$}|jjr\t|jd�r\||jj7}q\Wn0�jjr�t�jd�r��jj}n�jjdkr��j	}||f|�j
<q&W|S)a Return a dict with free space info for each disk.

            The dict values are 2-tuples: (disk_free, fs_free). fs_free is
            space available by shrinking filesystems. disk_free is space not
            allocated to any partition.

            disks and partitions allow specifying a set of disks other than
            self.disks and partition values other than self.parttions.

            :keyword disks: overrides :attr:`disks`
            :type disks: list
            :keyword partitions: overrides :attr:`partitions`
            :type partitions: list
            :returns: dict with disk name keys and tuple (disk, fs) free values
            :rtype: dict

            .. note::

                The free space values are :class:`~.size.Size` instances.

        Nrc3s|]}|j�kr|VqdS)N)rw)rRr|)rwr:r;rZ�sz(Blivet.get_free_space.<locals>.<genexpr>�free)rMrTrrGr`r�exists�hasattrrU�sizer>)r8rMrTrZ	disk_freeZfs_free�	partitionr:)rwr;�get_free_space�s&

zBlivet.get_free_spacecCs|jjS)z1 A list of all of the known in-use device names. )r6�names)r8r:r:r;r��szBlivet.namescCs|jj|�S)a Return a list of the devices that depend on the specified device.

            :param device: the subtree root device
            :type device: :class:`~.devices.StorageDevice`
            :returns: list of dependent devices
            :rtype: list
        )r6Zget_dependent_devices)r8rNr:r:r;�device_deps�szBlivet.device_depscOsdd|kr6t|jd�fd|jdd�i|jdi���|d<d|krJ|jd�}n
d|j}t|f|�|�S)a� Return a new (unallocated) PartitionDevice instance.

            :keyword fmt_type: format type
            :type fmt_type: str
            :keyword fmt_args: arguments for format constructor
            :type fmt_args: dict
            :keyword mountpoint: mountpoint for format (filesystem)
            :type mountpoint: str

            All other arguments are passed on to the
            :class:`~.devices.PartitionDevice` constructor.
        �fmt_type�
mountpointN�fmt_argsror>zreq%d)r�poprCr
)r8�args�kwargsr>r:r:r;�
new_partition�s

zBlivet.new_partitioncOs�d|kr6t|jd�fd|jdd�i|jdi���|d<|jdd�}|rp|j|tj�}||kr�tjd||�|}n:t|jd�dd�d	k}t|jd�dd�}|j	|j
||d
�}t|f|�|�S)a� Return a new MDRaidArrayDevice instance.

            :keyword fmt_type: format type
            :type fmt_type: str
            :keyword fmt_args: arguments for format constructor
            :type fmt_args: dict
            :keyword mountpoint: mountpoint for format (filesystem)
            :type mountpoint: str
            :returns: the new md array device
            :rtype: :class:`~.devices.MDRaidArrayDevice`

            All other arguments are passed on to the
            :class:`~.devices.MDRaidArrayDevice` constructor.

            If a name is not specified, one will be generated based on the
            format type, mountpoint, hostname, and/or product name.
        r�r�Nr�ror>z)using '%s' instead of specified name '%s'rUri)�prefixrir�)rr��safe_device_namer"�DEVICE_TYPE_MDr4�warning�getattr�get�suggest_device_namer=r	)r8r�r�r>�	safe_namerir�r:r:r;�new_mdarray�s$zBlivet.new_mdarraycOs�|jdg�}x|D]}||jkrtd��qW|jdd�}|rf|j|tj�}||krttjd||�|}n|jtjd�}||j	kr�td|��t
||f|�|�S)a� Return a new LVMVolumeGroupDevice instance.

            :returns: the new volume group device
            :rtype: :class:`~.devices.LVMVolumeGroupDevice`

            All arguments are passed on to the
            :class:`~.devices.LVMVolumeGroupDevice` constructor.

            If a name is not specified, one will be generated based on the
            hostname, and/or product name.
        �parentszpv is not in the device treer>Nz)using '%s' instead of specified name '%s')�container_typezname '%s' is already in use)r�r@rtr�r"�DEVICE_TYPE_LVMr4r��suggest_container_namer�r)r8r�r�raZpvr>r�r:r:r;�new_vgs


z
Blivet.new_vgcOs"|jdd�}|jdd�}|jdd�}|jdd�}|jdd�}|jddg�d	}|sV|rb|rb|j}	n|}	|rrd
|d<|r~d|d<|r�d
|d<|r�d|d<|r�d|d<|jdd�}
d|kr�|jdi�}|r�d|j�kr�d|d<t|jd�fd|
i|��|d<|jdd�}|�rf|j|	jtj�}
d|
|f}|j|tj�}||k�r�|t	|
�dd�}t
jd||�|}nR|jd��r�|djdk�r�d}nd}d}|�s�|�s�|�r�d}|j
|	||
|d�}d|	j|f|jk�r�td|��|�s�|�s�|�s�|�s�|�r|jdd�}|�rtd ��t|f|�|�S)!a Return a new LVMLogicalVolumeDevice instance.

            :keyword fmt_type: format type
            :type fmt_type: str
            :keyword fmt_args: arguments for format constructor
            :type fmt_args: dict
            :keyword mountpoint: mountpoint for format (filesystem)
            :type mountpoint: str
            :keyword thin_pool: whether to create a thin pool
            :type thin_pool: bool
            :keyword thin_volume: whether to create a thin volume
            :type thin_volume: bool
            :keyword vdo_pool: whether to create a vdo pool
            :type vdo_pool: bool
            :keyword vdo_lv: whether to create a vdo lv
            :type vdo_lv: bool
            :keyword cache_pool: whether to create a cache pool
            :type cache_pool: bool
            :returns: the new device
            :rtype: :class:`~.devices.LVMLogicalVolumeDevice`

            All other arguments are passed on to the appropriate
            :class:`~.devices.LVMLogicalVolumeDevice` constructor.

            If a name is not specified, one will be generated based on the
            format type and/or mountpoint.

            .. note::

                If you are creating a thin volume, the parents kwarg should
                contain the pool -- not the vg.
        �thin_volumeF�	thin_pool�vdo_pool�vdo_lv�
cache_poolr�Nrr]�seg_typez	thin-poolzvdo-poolZvdoz
cache-poolr�r�r�Z	nodiscardTror>z%s-%srz)using '%s' instead of specified name '%s'ri��pool)�parentrir�r�zname '%s' is already in useZ
cache_requestz?Creating cached thin and VDO volumes and pools is not supported)r�r��vg�keysrr�r>r"r�rsr4r�rUr�r�rtr)r8r�r�r�r�r�r�r�r�r�r�r�r>Zsafe_vg_name�	full_namer��new_namerir�Z	cache_reqr:r:r;�new_lv>sl!
z
Blivet.new_lvcKsHx.|D]&}||jjkr$|jj|�qtd��qWt|f|||d�|��S)a� Return a new LVMLogicalVolumeDevice created from other LVs

            :param vg: VG to create the new LV in
            :type vg: :class:`~.devices.lvm.LVMVolumeGroupDevice`
            :param str name: name of the new LV
            :param str seg_type: segment type of the new LV
            :param from_lvs: LVs to create the new LV from (in the (data_lv, metadata_lv) order)
            :type from_lvs: tuple of :class:`~.devices.lvm.LVMLogicalVolumeDevice`
            :rtype: :class:`~.devices.lvm.LVMLogicalVolumeDevice`

            All other arguments are passed on to the :class:`~.devices.lvm.LVMLogicalVolumeDevice`
            constructor.

        z@All LVs to construct a new one from have to be in the devicetree)r�r��from_lvs)r6r@rrrtr)r8r�r>r�r�r�Zlvr:r:r;�new_lv_from_lvs�s

zBlivet.new_lv_from_lvscOs�tjd||�|jdd�}|r&|d}|jdd�}|jdi�}|jd|i�|jdd�r�t}|sl|j|d	�}d
||d<||d<|jd
d�|jdd�|jdd�n.t}|s�|jtj	d�}d|kr�||d<t
|d<|jdd�||f|�}td|�|_|S)a� Return a new BTRFSVolumeDevice or BRFSSubVolumeDevice.

            :keyword fmt_args: arguments for format constructor
            :type fmt_args: dict
            :keyword mountpoint: mountpoint for format (filesystem)
            :type mountpoint: str
            :keyword subvol: whether this is a subvol (as opposed to a volume)
            :type subvol: bool
            :returns: the new device
            :rtype: :class:`~.devices.BTRFSDevice`

            All other arguments are passed on to the appropriate
            :class:`~.devices.BTRFSDevice` constructor.

            For volumes, the label is the same as the name. If a name/label is
            not specified, one will be generated based on the hostname and/or
            product name.

            .. note::

                If you are creating a subvolume, the parents kwarg should
                contain the volume you want to contain the subvolume.

        z"new_btrfs: args = %s ; kwargs = %sr>Nrr�r��subvolF)r�z	subvol=%sZ	mountoptsZ
subvolspecZmetadata_levelZ
data_levelZcreate_options)r�Zlabelr��btrfs)r�)
r4r5r��updaterr�rr�r"�DEVICE_TYPE_BTRFSrrr`)r8r�r�r>r�r�Z	dev_classrNr:r:r;�	new_btrfs�s4zBlivet.new_btrfscOsd|d<|j||�S)aw Return a new BRFSSubVolumeDevice.

            :keyword fmt_args: arguments for format constructor
            :type fmt_args: dict
            :keyword mountpoint: mountpoint for format (filesystem)
            :type mountpoint: str
            :returns: the new device
            :rtype: :class:`~.devices.BTRFSSubVolumeDevice`

            All other arguments are passed on to the
            :class:`~.devices.BTRFSSubVolumeDevice` constructor.

            .. note::

                Since you are creating a subvolume, the parents kwarg should
                contain the volume you want to contain the subvolume.

        Tr�)r�)r8r�r�r:r:r;�new_btrfs_sub_volumeszBlivet.new_btrfs_sub_volumecOs�|jdg�}|jdd�}|rF|j|tj�}||krTtjd||�|}n|jtjd�}||jkrjtd|��t	|f|�d|i|��S)a� Return a new StratisPoolDevice instance.

            :returns: the new Stratis pool device
            :rtype: :class:`~.devices.StratisPoolDevice`

            All arguments are passed on to the
            :class:`~.devices.StratisPoolDevice` constructor.

            If a name is not specified, one will be generated based on the
            hostname, and/or product name.
        r�r>Nz)using '%s' instead of specified name '%s')r�zname '%s' is already in use)
r�r�r"�DEVICE_TYPE_STRATISr4r�r�r�rtr
)r8r�r�Z	blockdevsr>r�r:r:r;�new_stratis_pools
zBlivet.new_stratis_poolc
Os�|jddg�d}|jdd�}|jdd�}|r|d|j|f}|j|tj�}||kr�|t|j�dd�}tjd||�|}n|j	||tjd	�}d|j|f|j
kr�td
|��t|f|�|�}	t
d|d�|	_|	S)
a� Return a new StratisFilesystemDevice instance.

            :keyword mountpoint: mountpoint for filesystem
            :type mountpoint: str
            :returns: the new device
            :rtype: :class:`~.devices.StratisFilesystemDevice`

            All other arguments are passed on to the appropriate
            :class:`~.devices.StratisFilesystemDevice` constructor.

            If a name is not specified, one will be generated based on the
            format type and/or mountpoint.
        r�Nrr�r>z%s/%srz)using '%s' instead of specified name '%s')r�r��device_typezname '%s' is already in usezstratis xfs)r�)r�r�r>r�r"r�rsr4r�r�r�rtrrr`)
r8r�r�r�r�r>r�r�r�rNr:r:r;�new_stratis_filesystem3s&
zBlivet.new_stratis_filesystemcOs
t||�S)z Return a new TmpFSDevice. )r)r8r�r�r:r:r;�
new_tmp_fs]szBlivet.new_tmp_fscCs�t|�}|jjj|�t|t�o$|j}|jjr�|j	r�|r�d}yt
|�}Wn8ttfk
r�}z|jjj
|�|�WYdd}~XnX|jjj|�dS)z� Schedule creation of a device.

            :param device: the device to schedule creation of
            :type device: :class:`~.devices.StorageDevice`
            :rtype: None
        N)rr6rArurQrZis_snapshot_lvr`rU�format_immutablerrtr�remove)r8rNZaction_create_devZis_snapshotZaction_create_fmt�er:r:r;�
create_deviceaszBlivet.create_devicecCsR|jrtd��|jjr8|jjr8|jr8|jjjt	|��t
|�}|jjj|�dS)z� Schedule destruction of a device.

            :param device: the device to schedule destruction of
            :type device: :class:`~.devices.StorageDevice`
            :rtype: None
        zcannot modify protected deviceN)�	protectedrtr`r�rUr�r6rArurr)r8rN�actionr:r:r;r}wszBlivet.destroy_devicecCsz|jrtd��t|�}t||�}|jjj|�y|jjj|�Wn4tk
rt}z|jjj|�|�WYdd}~XnXdS)a Schedule formatting of a device.

            :param device: the device to create the formatting on
            :type device: :class:`~.devices.StorageDevice`
            :param fmt: the format to create on the device
            :type format: :class:`~.formats.DeviceFormat`
            :rtype: None

            A format destroy action will be scheduled first, so it is not
            necessary to create and schedule an
            :class:`~.deviceaction.ActionDestroyFormat` prior to calling this
            method.
        zcannot modify protected deviceN)	r�rtrrr6rArur3r�)r8rNroZ
destroy_acZ	create_acr�r:r:r;�
format_device�s
zBlivet.format_devicecCsB|jjj|d�}xt|�D]}|jjj|�qWtj|j�|_dS)z� Cancel all scheduled actions and reset formatting.

            :param device: the device to reset
            :type device: :class:`~.devices.StorageDevice`
            :rtype: None
        )rNN)	r6rA�find�reversedr��copy�deepcopyZoriginal_formatr`)r8rNrAr�r:r:r;�reset_device�szBlivet.reset_devicecCs�|jrtd��g}|jr(|jt||��|jjr�|jjdkr�|jr�|jt||t	��|jd}|jrz|jt||t	��|jjr�|jt||t	��n|jt||��|s�td��||j
kr�|j�x|D]}|jj
j|�q�WdS)a� Schedule a resize of a device and its formatting, if any.

            :param device: the device to resize
            :type device: :class:`~.devices.StorageDevice`
            :param new_size: the new target size for the device
            :type new_size: :class:`~.size.Size`
            :rtype: None

            If the device has formatting that is recognized as being resizable
            an action will be scheduled to resize it as well.
        zcannot modify protected deviceZluksrzdevice cannot be resizedN)r�rtZ	resizablerKrr`rUrprrr��reverser6rAru)r8rNZnew_sizerAZluks_devr�r:r:r;�
resize_device�s(


zBlivet.resize_devicecCs�|tjtjfkrtjj}n@|tjkr.tjj}n,|tjkrBtj	j}n|tj
krVtjj}nd}d}|j�}d|krz|j
dd�}tjd|d|�}tjdd|�}|dks�|d	kr�dSt|�|kr�|d
|�}|S)aE Convert a device name to something safe and return that.

            LVM limits lv names to 128 characters. I don't know the limits for
            the other various device types, so I'm going to pick a number so
            that we don't have to have an entire library to determine
            device name limits.
        z0-9a-zA-Z._-�`�/�_z[^%s]r�z^[-_]*�.z..N)r"r�ZDEVICE_TYPE_LVM_THINPr$ZlvmZsafe_name_charactersr�Zmdraidr�r�r�Zstratis�strip�replace�re�subrs)r8r>r�ZallowedZmax_lenZtmpr:r:r;r��s(	






zBlivet.safe_device_nameTcCs�|tjkrd}nd}|rJ|r6d|j||f|jkr6|S|rJ||jkrJ|SxXtd�D]L}|r�d|j|||f|jkr�d||fSqTd||f|jkrTd||fSqTWtd��dS)	zB Turn given name into a unique one by adding numeric suffix to it r��-z%s%s%s�dz
%s%s%s%02dz%s%02dz#unable to find suitable device nameN)r"r�r>r��range�RuntimeError)r8r>r�Zname_setr��parent_separator�suffixr:r:r;�unique_device_name	s
zBlivet.unique_device_namecCs|pdS)Nr�r:)r8r�r:r:r;�_get_container_name_template!sz#Blivet._get_container_name_templater�cCsb|s|j|j|�}|j|d�}||jkr^y|j||d�}Wn"tk
r\tjd|��YnX|S)z� Return a reasonable, unused device name.

            :keyword prefix: a prefix for the container name
            :returns: the suggested name
            :rtype: str
        )r�)r�z3failed to create device name based on template '%s')r�r=r�r�r�r�r4�error)r8r�r�r>r:r:r;r�$s
zBlivet.suggest_container_namec
Cs�d}|r,|dkrd}q4|dd�jdd�}n|r4d}|rD|rDd|}|j|||�}|tjkrdd}nd}|r|d	|j||fn|}	|	|jks�|r�y|j||t|�|�}Wn*tk
r�t	j
d
|j|||��YnX|S)a� Return a suitable, unused name for a new device.

            :keyword parent: the parent device
            :type parent: :class:`~.devices.StorageDevice`
            :keyword swap: will this be a swap device
            :type swap: bool
            :keyword mountpoint: the device's mountpoint
            :type mountpoint: str
            :keyword prefix: device name prefix
            :type prefix: str
            :returns: the suggested name
            :rtype: str
        r�r��rootrNr�rir�z%s%s%szZfailed to create device name based on parent '%s', prefix '%s', mountpoint '%s', swap '%s')r�r�r"r�r>r�r��boolr�r4r�)
r8r�rir�r�r�Zbodyr>r�r�r:r:r;r�8s,
zBlivet.suggest_device_namecCs|jj|j�|jj�dS)N)r6Zset_disk_imagesr+�setup_disk_images)r8r:r:r;r�hszBlivet.setup_disk_imagescCsfdtj�|f}tjtj|j���:}ydd�|jD�||<Wntk
rVt�YnXWdQRXdS)z4 Dump the current device list to the storage shelf. z
devices.%d.%scSsg|]
}|j�qSr:)�dict)rRrOr:r:r;rSqsz%Blivet.dump_state.<locals>.<listcomp>N)	�time�
contextlib�closing�shelve�openr2r@�AttributeErrorr)r8r�rHZshelfr:r:r;�
dump_statelszBlivet.dump_statecCs*t�}x|jD]}|j|j�qWt|�S)N)�setr@r��packages�list)r8ZpkgsrNr:r:r;r�uszBlivet.packagescCsbt|�}|jdkrtd|��|js>|js>|js>|jrXtjd||�td|��||_	dS)z` Check the fstype to see if it is valid

            Raise ValueError on invalid input.
        Nz-unrecognized value %s for new default fs typezinvalid default fstype (%s): %rz.new value %s is not valid as a default fs type)
rrUrtZ	mountableZformattableZ	supportedZlinux_nativer4r5�_default_fstype)r8�newtyperor:r:r;�_check_valid_fstype�s
zBlivet._check_valid_fstypecCs|jS)N)r�)r8r:r:r;�default_fstype�szBlivet.default_fstypecCs tjd|�|j|�||_dS)zc Set the default fstype for this instance.

            Raise ValueError on invalid input.
        z(trying to set new default fstype to '%s'N)r4r5r�r�)r8r�r:r:r;r.�s
zBlivet.set_default_fstypecCs|jjS)N)r6�mountpoints)r8r:r:r;r��szBlivet.mountpointsc	Csbt|t�s|j}t|t�s |j}||jkr`||jkr`|j|}|j|}||krTdS||kr`dS||jkrnd	S||jkr|dS|jd�r�d}n.|jd�r�d}n|jd�s�|jd�r�d
}nd}|jd�r�d}n0|jd�r�d}n |jd�s�|jd��r�d}nd}||k�rdS||k�rdSt|�}t|�}||k�r4d
S||k�rBdS||k�rPdS||k�r^dSdS)NrZhdrZsdZvdZxvd����r�r�r�r�r�r�)rQ�strr>r,�
startswithrs)	r8�first�secondZoneZtwoZtype1Ztype2Zlen1Zlen2r:r:r;�
compare_disks�sX















zBlivet.compare_diskscCstj|j�S)N)�	functools�
cmp_to_keyr�)r8r:r:r;rL�szBlivet.compare_disks_keycCs@|j}|sn0|j�dkr"|j�}n|dkr<tj�r8d}nd}|S)z9 Return the default filesystem type based on mountpoint. ri�biosboot�prepbootz	/boot/efiZmacefiZefi)rir�r�)r��lowerr!Z	is_mactel)r8r��fstyper:r:r;�
get_fstype�s
zBlivet.get_fstypecKs�t||f|�|jd�sB|j|jd�d�|d<|ddkrBd|d<|ddkr^|tjkr^tj}tj|fd|i|��}|js�td��g|_	|j
�|jS)a� Schedule creation of a device based on a top-down specification.

            :param device_type: device type constant
            :type device_type: int (:const:`~.devicefactory.DEVICE_TYPE_*`)
            :returns: the newly configured device
            :rtype: :class:`~.devices.StorageDevice`

            See :class:`~.devicefactory.DeviceFactory` for possible kwargs.

        r�r�)r�riNr�z!no disks specified for new device)rr�r�r"r�ZDEVICE_TYPE_PARTITIONZget_device_factoryrMrr-Z	configurerN)r8r�r��factoryr:r:r;�factory_device�s

zBlivet.factory_devicecs4tjd�tj|��dd��jjD�}xV�j|D]H}|js>q2�fdd�|jD�}dd�|D�|_|j	j
jj|j
�}||_q2Wx��jD]�}�fdd�|jD�|_dd�|jD�|_t�}xP|jj�D]B\}}|dkr�qĈjj|jd	d
�}	|	dkr�|j|�q�|	|j|<q�Wx|D]}
|j|
=�qWq�Wtjd��S)Nzstarting Blivet copycSsg|]}t|t�r|�qSr:)rQr
)rRrOr:r:r;rSszBlivet.copy.<locals>.<listcomp>c3s|]}�jj|j�VqdS)N)r6�get_device_by_id�id)rRrw)�newr:r;rZ szBlivet.copy.<locals>.<genexpr>cSsg|]}|dk	r|�qS)Nr:)rRrwr:r:r;rS!scsg|]}�jj|jdd��qS)T)�hidden)r6r�r�)rRrO)r�r:r;rS'scSsg|]}|r|�qSr:r:)rR�sr:r:r;rS(sT)r�zfinished Blivet copy)r4r5r�r�r6Z_hiddenrTZ_parted_partition�	req_disksrwr`Zparted_diskZgetPartitionByPathrvrqr7rjr�Zmounts�itemsr�r�ru)r8Zhidden_partitionsr�r�r|r�Zremovedr�Zold_devZnew_devZmntr:)r�r;r�s2




zBlivet.copy)N)F)NN)N)NTN)N)r�N)NNNr�N)N)D�__name__�
__module__�__qualname__�__doc__r<�propertyr=�setterrBrCrFr@rMrGrTrVr\r^r_rarcrdrfrgrhrjrkrmrnrzr~r�r�r�r�r�r�r�r�r�r�r�r�r�r�r}r�r�r�r�r�r�r�r�r�r�r�r�r�r.r�r�rLr�r"r�r�r�r:r:r:r;r(:s�	




(
.
( hA*.
(



.	
:
$r()@r�r1r�r�r�r�r�ZsixZstorage_logrrr@rrrrr	r
rrr
rZdeviceactionrrrrrrZdevicelibs.eddrZdevicelibs.btrfsrZdevicelibs.cryptor�errorsrrr�rr6rZformatsrrr�utilrr r�r!r"r#r$Zthreadsr%Zstatic_datar&ZloggingZ	getLoggerr4Z
add_metaclass�objectr(r:r:r:r;�<module>sD