Mini Shell

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

3

{)c ��
@srddlZddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddl
mZddlmZddlmZddlmZddlmZddlmZdd	lmZddlZejd
d�ddlmZddlZddl Z e j!d
�Z"e j!d�Z#e j!d�Z$e j!d�Z%ddl&m'Z'e'�Z(yddl)Z)Wne*k
�rLdZ+YnXdZ+dZ,dZ-dZ.dZ/Gdd�de0�Z1d�dd�Z2dd�Z3dd �Z4d!d"�Z5d#d$�Z6d%d&�Z7d�d'd(�Z8d)d*�Z9d+d,�Z:d-d.�Z;d/d0�Z<d1d2�Z=d3d4�Z>d5d6�Z?d�d7d8�Z@d�d9d:�ZAd�d<d=�ZBd>d?�ZCd�d@dA�ZDd�dBdC�ZEd�dDdE�ZFdFdG�ZGdHdI�ZHdJdK�ZIdLdM�ZJdNdO�ZKdPdQ�ZLGdRdS�dSeM�ZNdTdU�ZOdVdW�ZPdXdY�ZQdZd[�ZRd\d]�ZSd�d_d`�ZTd�dadb�ZUdcdd�ZVdedf�ZWedgdh��ZXd�didj�ZYdkdl�ZZdmdn�Z[d�dpdq�Z\d�drds�Z]dtZ^dudv�Z_dwZ`dxZad�dydz�Zbd{d|�Zcd�d~d�Zdd�d�d��ZeGd�d��d�e�Zfejgejh�Gd�d��d�eM��Zid�d��Zjd�d��Zkd�d��ZldS)��N)�Decimal)�contextmanager)�wraps)�
namedtuple)�Enum�)�DependencyError)�	safe_dbus�BlockDevz2.0)r
�blivetZprogramZtestdatazblivet.console)�LockFTzorg.freedesktop.systemd1z/org/freedesktop/systemd1z org.freedesktop.systemd1.ManagerZVirtualizationc@s�eZdZdZdZdZdd�Zedd��Zedd��Z	ed	d
��Z
edd��Zed
d��Zd%dd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#d$�ZdS)&�Patha( Path(path, root=None) provides a filesystem path object, which
        automatically normalizes slashes, assumes appends are what you
        always hoped os.path.join() was (but with out the weird slash
        games), and can easily handle paths with a root directory other
        than /
    NcOsF|jdd�}tj||f|�|�}||_d|_|dk	rB|jt|��|S)N�root)�pop�str�__new__�_path�_root�newroot)�cls�path�args�kwdsr�obj�r�/usr/lib/python3.6/util.pyrAszPath.__new__cCs,|jrtt|j�t|j��St|j�SdS)z{ Path.ondisk evaluates as the real filesystem path of the path,
            including the path's root in the data.
        N)r�normalize_path_slashesr
r)�selfrrr�ondiskJszPath.ondiskcCs|jS)N)r)rrrrrTsz	Path.pathcCsttjjt|j��|jd�S)N)r)r
�osr�normpathrr)rrrrr Xsz
Path.normpathcCstjj|j�}t||jd�S)N)r)rr�realpathrr
r)rZrprrrr!\sz
Path.realpathcCs|jS)N)r)rrrrrasz	Path.rootcCsH|dkrd|_n4t|�|_|j|j�rD|jt|j�d�}t|�|_|S)z( Change the root directory of this Path N)rr�
startswithr�len)rrrrrrres

zPath.newrootcCs
t|j�S)N)rr)rrrr�__str__pszPath.__str__cCstt|j��S)N)�reprrr)rrrr�__repr__ssz
Path.__repr__cCst|�}|j|�S)N)r�__getitem__)r�idx�retrrrr'vszPath.__getitem__cCs�t|t�rd|jdk	rR|jdkrR|jdkr2|j|_n |j|jkrRtd|j|jf��d|j|jf}nd|j|f}t|�}t||jd�S)N�/z roots <%s> and <%s> don't match.z%s/%s)r)�
isinstancer
rr�
ValueErrorrr)r�otherrrrr�__add__zs


zPath.__add__cCs(t|t�r|j|jkS|jt|�kSdS)N)r+r
rr)rr-rrr�__eq__�s
zPath.__eq__cCs(t|t�r|j|jkS|jt|�kSdS)N)r+r
rr)rr-rrr�__lt__�s
zPath.__lt__cCs(t|t�r|j|jkS|jt|�kSdS)N)r+r
rr)rr-rrr�__gt__�s
zPath.__gt__cCs|jjt|��S)N)rr"r)rr-rrrr"�szPath.startswithccsftjd|j�d|jkr0tjd|j�tjd�x0tj|j�D] }tjd|�t||jd�Vq>WdS)z� Similar to glob.glob(), except it takes the Path's root into
            account when globbing and returns path objects with the same
            root, so you don't have to think about that part.
        zglob: %s�Nonez4^^ Somehow "None" got logged and that's never right.zglob match: %s)rN)�testdata_log�debugr�log�error�globr
r)r�grrrr7�s

z	Path.globcCs
|jj�S)N)r�__hash__)rrrrr9�sz
Path.__hash__)N)�__name__�
__module__�__qualname__�__doc__rrr�propertyrrr r!rrr$r&r'r.r/r0r1r"r7r9rrrrr
6s(	

r
r*cs~|dkrg}�fdd�}t��Ptjddj|��tjj�}|jd�d��x|D]}|j|d�qRW|rrt	j
}	nt	j}	y�t	j||t	j|	d|�|d�}
|
j
�\}}|r�tjr�|jd	�}|r�|s�tjd
�x|j�D]}
tjd|
�q�W|o�|�rtjd�x|j�D]}
tjd|
��qWWn:tk
�rZ}ztjd
|d|j��WYdd}~XnXtjd|
j�WdQRX|
j|fS)Ncs�r�dkrtj��dS)Nr*)r�chrootr)rrrr?�sz_run_program.<locals>.chrootz
Running... %s� �C)�LC_ALLZINSTALL_PATHT)�stdin�stdout�stderrZ	close_fdsZ
preexec_fn�cwd�envzutf-8zstdout:z%szstderr:zError running %s: %srzReturn code: %d)�program_log_lock�program_log�info�joinr�environ�copy�updater�
subprocessZSTDOUT�PIPE�PopenZcommunicate�sixZPY3�decode�
splitlines�OSErrorr6�strerrorr4�
returncode)�argvrrCZ	env_pruneZstderr_to_stdout�
binary_outputr?rG�varZ
stderr_dir�proc�out�err�line�er)rr�_run_program�sJ





r`cOst||�dS)Nr)r`)r�kwargsrrr�run_program�srbcOst||�dS)Nr)r`)rrarrr�capture_output�srccOsd|d<t||�dS)NTrYr)r`)rrarrr�capture_output_binary�srdcOs
t||�S)N)r`)rrarrr�run_program_and_capture_output�srecOsd|d<t||�S)NTrY)r`)rrarrr�%run_program_and_capture_output_binary�srfcCsF|dkrd}tjj|�}tjj|�s,t|�dd|d|||g}t|�S)NZdefaults�mountz-tz-o)rrr �isdir�makedirsrb)�device�
mountpointZfstype�optionsrXrrrrg�srgcCstd|g�S)N�umount)rb)rkrrrrmsrmcCs2ddlm}|j|�}|r.tjd|dj|��|S)z� Given a device node path, return a list of all active mountpoints.

        :param str dev: Device path
        :returns: A list of mountpoints or []
        :rtype: list
    r)�mounts_cachez%s is mounted on %sz, )�mountsrnZget_mountpointsr5r4rK)ZdevrnZmount_pathsrrr�get_mount_paths	s

rpcCs�tjj|�}td�j�}d}xH|D]@}y|jdd�\}}}Wntk
rRw"YnX||kr"|}Pq"W|r�tjd|�r�tjj	|�}t
jj|�}t
jd||�|r�t
jd||�|S)z@ Given a mountpoint, return the device node path mounted there. z/proc/mountsN�z
/dev/loop\d+$z(found backing file %s for loop device %sz%s is mounted on %s)rrr!�open�	readlines�splitr,�re�match�basename�blockdevZloopZget_backing_filer5r4)rkroZmount_deviceZmntrjrZ_restZ	loop_namerrr�get_mount_devices&
rycCsdddlm}td��.}tjdd�|D��}|d|j�d�}WdQRX|d�}||d|}|S)	zL Return the amount of system RAM.

        :rtype: :class:`~.size.Size`
    r)�Sizez
/proc/meminfocss|]}|jd�r|VqdS)z	MemTotal:N)r")�.0�lrrr�	<genexpr><sztotal_memory.<locals>.<genexpr>z%s KiBNZ128MiB)�sizerzrrrR�nextrt)rz�linesr^ZmemZbsrrr�total_memory3s
r�cCs�ddlm}td��}dd�dd�|D�D�}WdQRXd	|j�kr\|d
|d	j�d�S|d
|dj�d�}|d
|d
j�d�}|d
|dj�d�}|||SdS)zg Return the amount of system RAM that is currenly available.

        :rtype: :class:`~.size.Size`
    r)rzz
/proc/meminfocSsi|]\}}|j�|j��qSr)�strip)r{�k�vrrr�
<dictcomp>Psz$available_memory.<locals>.<dictcomp>css|]}|jdd�VqdS)�:rN)rt)r{r|rrrr}Psz#available_memory.<locals>.<genexpr>NZMemAvailablez%s KiBrZMemFreeZCachedZBuffers)r~rzrr�keysrt)rzr�ZmemsZfree�cachedZbuffersrrr�available_memoryGs
"r�cCsxd|kr|jdd�}qW|S)zn Normalize the slashes in a filesystem path.
        Does not actually examine the filesystme in any way.
    z//r*)�replace)rrrrrbs
rcGs4t|�dkr&t|dd�r&t|d�Stdj|��S)zx Joins filesystem paths without any consiration of slashes or
        whatnot and then normalizes repeated slashes.
    rr�__iter__r*)r#�hasattr�
join_pathsrrK)�pathsrrrr�ksr�cCs�|stjd�dSt|t�s*t||d�}n|dk	r<|j|�||}tjj|j�}tjj	|�r~tjj
|�r~tjd|�dSt|dddd�}|j
�}|j�djd	d
�|D��}tjd||�|j�S)Nz&get_sysfs_attr() called with attr=None)rrz%s is not a valid attribute�rzutf-8r�)�encoding�errors�cSsg|]}dt|�f�qS)z%02x)�ord)r{�xrrr�
<listcomp>�sz"get_sysfs_attr.<locals>.<listcomp>zsysfs attr %s: %s)r5r4r+r
rrrr!r�isfile�islink�warningrr�read�closerKr3r�)r�attrrZ	attributeZfullattr�f�dataZsdatarrr�get_sysfs_attrts$


r�cCs�|stjd�t|t�r"||}nt||d�|}ttjj|�|jd�}tjj|j�}tjj	|�srtj
d|�dStj|�}tjd||�|S)Nz&sysfs_readlink() called with link=None)rz%s is not a valid symlinkznew sysfs link: "%s" -> "%s")
r5r4r+r
rrr rrr�r��readlinkr3)r�linkrZlinkpathZfullpath�outputrrr�sysfs_readlink�s



r��blockcCsdtjj|�}|jd�r*|dd�jdd�}d|}tjj||�}tjj|�rP|Std||f��dS)a Return sysfs path for a given device.

        For a device node (e.g. /dev/vda2) get the respective sysfs path
        (e.g. /sys/class/block/vda2). This also has to work for device nodes
        that are in a subdirectory of /dev like '/dev/cciss/c0d0p1'.
     z/dev/�Nr*�!z
/sys/class/%szNget_sysfs_path_by_name: Could not find sysfs path for '%s' (it is not at '%s'))rrrwr"r�rK�exists�RuntimeError)Zdev_node�
class_nameZdev_nameZsysfs_class_dir�dev_pathrrr�get_sysfs_path_by_name�s
r�cCsR|d}tjj|�s td|��tjjtjj|��}tjjtjj|�d|�}|S)z9 Return sysfs path of cow device for a given device.
    z-cowz4get_cow_sysfs_path: Could not find cow device for %sr)rrr�r�rwr!rKrt)r�Z
dev_sysfsPathZcow_pathZdm_nameZ
cow_sysfsPathrrr�get_cow_sysfs_path�sr�cCsbtstd��d}ytjtjj|�|�d}Wn0tk
r\}ztj	d||�WYdd}~XnX|S)z8 Return the default SELinux context for the given path. z%SELinux python bindings not availableNrz0failed to get default SELinux context for %s: %s)
�HAVE_SELINUXr��selinuxZmatchpathconrrr rUr5rJ)r�mode�contextr_rrr�match_path_context�s r�cCs�tstd��|dkrd}tjjd||f�}|dksDtj|tj�rHdSytj||�dk}Wn4t	k
r�}zt
jd||�d}WYdd}~XnX|S)a& Set the SELinux file context of a file.

        Arguments:

            path        filename string
            context     context string

        Keyword Arguments:

            root        an optional chroot string

        Return Value:

            True if successful, False if not.
    z%SELinux python bindings not availableNr*z%s/%sFrz(failed to set SELinux context for %s: %s)r�r�rrr �access�F_OKr�ZlsetfileconrUr5rJ)rr�r�	full_pathZrcr_rrr�set_file_context�sr�cCs0tstd��t||�}|r,t|||d�r,|SdS)aX Restore the SELinux context of a file to its default value.

        Arguments:

            path        filename string

        Keyword Arguments:

            root        an optional chroot string
            mode        an optional mode to use

        Return Value:

            If successful, returns the file's new/default context.
    z%SELinux python bindings not available)rN)r�r�r�r�)rrr�r�rrr�reset_file_context�s
r�cCstjj|�stj|d�dS)Ni�)rrrhri)rrrrrisric	Cs*td��}|j�}WdQRXdd�|D�S)z. Returns list of names of all loaded modules. z
/proc/modulesNcSsg|]}|j�d�qS)r)rt)r{r|rrrr�szlsmod.<locals>.<listcomp>)rrrs)r�r�rrr�lsmods
r�cCs@x:|jd�D],}d|krq|jd�\}}||kr|j�SqWdS)zE Return the value of a named option in the specified options string. �,�=N)rtr�)Zopt_namerl�opt�name�valrrr�get_option_valuesr�cCs>ddlm}|dkrd}n t|tjt|tf�s:td|��|S)z� Verify that a value is given as a numeric data type.

        Return the number if the type is sensible or raise ValueError
        if not.
    r)rzNrz*value (%s) must be either a number or None)r~rzr+rRZ
integer_types�floatrr,)Znumrzrrr�numeric_type*sr�cCs8|dd�}t|�dkr0t|dd��d|S|SdS)z� Insert colon between every second character.

        E.g. creates 'al:go:ri:th:ms' from 'algoritms'. Useful for formatting
        MAC addresses and wwids for output.
    rqNr����r�)r#�
insert_colons)Za_string�suffixrrrr�;sr�c	CsNtj�}t|d��.}|jd�}x|r:|j|�|jd�}q WWdQRX|j�S)N�rbi)�hashlib�sha256rrr�rNZ	hexdigest)�filenamer�r�r�rrr�sha256_fileHs

r�cs0eZdZdZejeej��Z	�fdd�Z
�ZS)�ObjectIDa*This class is meant to be extended by other classes which require
       an ID which is preserved when an object copy is made.
       The value returned by the builtin function id() is not adequate:
       that value represents object identity so it is not in general
       preserved when the object is copied.

       The name of the identifier property is id, its type is int.

       The id is set during creation of the class instance to a new value
       which is unique for the object type. Subclasses can use self.id during
       __init__.
    cstt|�j|�}|j�|_|S)N)�superr�r�
_newid_gen�id)rrrar)�	__class__rrres
zObjectID.__new__)r:r;r<r=�	functools�partialr�	itertools�countr�r�
__classcell__rr)r�rr�Us
r�cCsttj|jdd���S)a Converts uuids to canonical form.

        :param str a_uuid: the UUID

        :returns: a canonicalized UUID
        :rtype: str

        mdadm's UUIDs are actual 128 bit uuids, but it formats them strangely.
        This converts the uuids to canonical form.
        Example:
            mdadm UUID: '3386ff85:f5012621:4a435f06:1eb47236'
        canonical UUID: '3386ff85-f501-2621-4a43-5f061eb47236'

        If the UUID is already in canonical form, the conversion
        is equivalent to the identity.
    r�r�)r�uuidZUUIDr�)Za_uuidrrr�canonicalize_UUIDlsr�cCs"tjrt|t�r|jd�}t|�S)a� Convert strings to a format compatible with Python 2's str.

        :param str inputstr: the string to convert

        :returns: a string with the correct type
        :rtype: str

        This method is for use in __str__ calls to ensure that they always
        return a str. In Python 3, this method simply inputstr as a string. In
        Python 2, it converts unicode into str. The returned str in python 2 is
        encoded using utf-8.
    zutf-8)rR�PY2r+�unicode�encoder)�inputstrrrr�	stringize�s


r�cCstjrt|�St|�SdS)a� Convert strings to a format compatible with Python 2's unicode.

        :param str inputstr: the string to convert

        :returns: a string with the correct type
        :rtype: unicode

        This method is for use in __unicode__ calls to ensure that they always
        return a unicode. This method does not handle non-ASCII characters
        in str parameters, but non-ASCII characters in unicode parameters will
        be correctly passed through.
    N)rRr�r�r)r�rrr�
unicodeize�s
r�cCs@|dkr|dkrdS|dkr dS|dkr,dS||k||kSdS)a Compare two objects.

        :param first: first object to compare
        :param second: second object to compare
        :returns: 0 if first == second, 1 if first > second, -1 if first < second
        :rtype: int

        This method replaces Python 2 cmp() built-in-function.
    Nrr���r)�first�secondrrr�compare�sr�cCs8t�}g}x(|D] }||kr&|j|�|j|�qW|S)zMDeduplicates the given list by removing duplicates while preserving the order)�set�append�add)Zalist�seenr)�itemrrr�
dedup_list�s

r��/tmpcCs�tjtj�tjtj�dd�}|||tj�}tj|�tj|�tjd�}|j|�|rdt|d�tjdt	j
�d|f}|||tj�}tjtj�tj|�dS)a	 Configure the blivet logger to write out a log file.

        :keyword str log_dir: path to directory where log files are
        :keyword str log_prefix: prefix for log file names
        :keyword list console_logs: list of log names to output on the console
    cSsDd||f}tjj|�}tj|�}|j|�tjd�}|j|�|S)Nz	%s/%s.logz>%(asctime)s %(levelname)s %(name)s/%(threadName)s: %(message)s)rrr!�loggingZFileHandler�setLevel�	Formatter�setFormatter)r�prefix�levelZlog_file�handler�	formatterrrr�make_handler�s



z$set_up_logging.<locals>.make_handlerzpy.warnings)�	log_namesz
sys.argv = %sz%s-testdataN)r5r�r��DEBUGrI�
addHandler�	getLogger�set_up_console_logrJ�sysrXr3)Zlog_dirZ
log_prefixZconsole_logsr�r�Zwarning_logr�rrr�set_up_logging�s	





r�cCsh|pg}tj�}tjtj�|jtj�tjd�}|j|�tj|�x|D]}tj|�j|�qLWdS)Nz%(threadName)s: %(message)s)	r�Z
StreamHandler�console_logr�r�r�r�r�r�)r�r�r�r�rrrr��s



r�cCs.tjdd|d�\}}tj|�t||�|S)z� Create a temporary sparse file.

        :param str name: suffix for filename
        :param :class:`~.size.Size` size: the file size
        :returns: the path to the newly created file
    zblivet.z-%s)r�r�)�tempfileZmkstemprr��create_sparse_file)r�r~�fdrrrr�create_sparse_tempfile
s

r�cCs4tj|tjtjBtjB�}tj||�tj|�dS)z� Create a sparse file.

        :param str path: the full path to the file
        :param :class:`~.size.Size` size: the size of the file
        :returns: None
    N)rrr�O_WRONLY�O_CREAT�O_TRUNC�	ftruncater�)rr~r�rrrr�sr�ccs&t||�}z
|VWdtj|�XdS)z� Context manager that creates a sparse tempfile and then unlinks it.

        :param str name: suffix for filename
        :param :class:`~.size.Size` size: the file size

        Yields the path to the newly created file on __enter__.
    N)r�r�unlink)r�r~rrrr�
sparsetmpfile#s	

r�cCs�|pg}|pg}|pg}|jj|j�}||t|�<x~|jj�D]p\}}||ksV|dkrdt|||�q>||kr�t||tj|��q>||kr�t|||j��q>t||tj||��q>W|S)a; A configurable copy function. Any attributes not specified in omit,
        shallow, or duplicate are copied using copy.deepcopy().

        :param object obj: a python object to be copied.
        :param dict memo: a dictionary of already copied items
        :param omit: a list of names of attributes not to copy
        :type omit: iterable of str
        :param shallow: a list of names of attributes to shallow copy
        :type shallow: iterable of str
        :param duplicate: a list of names of attributes to duplicate
        :type duplicate: iterable of str

        Note that all atrributes in duplicate must implement a duplicate()
        method that does what is expected of it. Attributes with type
        pyparted.Disk are known to do so.

        A shallow copy is implemented by calling copy.copy().
    N)	r�rr��__dict__�items�setattrrM�	duplicate�deepcopy)r�memoZomitZshallowr�newr��valuerrr�
variable_copy3src	Cs"tdd��}t|j��SQRXdS)Nz%/proc/sys/kernel/random/entropy_availr�)rr�int�readline)Zfobjrrr�get_current_entropyYsr
cCsxyt|�}Wnttfk
r$dSX||kr2dS|}|dkrBdS|d}}x&|dkrr|dkrbdSt|d�\}}qNWdS)z� Checks whether value is a power of 2 greater than 1.

        :param any value: a value
        :returns: True if the value is a power of 2
        :rtype: bool
    FrqrT)rr,�	TypeError�divmod)rZ	int_value�qr�rrr�power_of_two^s

r�cCsN|s|j�r|Sd|}g}x"|j�D]}|jd||f�q*Wdj|�S)a/ Indent text by a specified number of spaces.

        :param str text: the text to indent
        :keyword int spaces: the number of spaces to indent text

        It would be nice if we could use textwrap.indent for this but, since it
        does not exist in python2, I prefer to just use this.
    r@z%s%s�
)r�rTr�rK)�text�spacesZindentationZindentedr^rrr�indent{s	rc
Cs�|j}|dkrd}n|dd�}|r0||kr0dSd}xn|j�dd�D]Z}|j�sTqFd}|dd�}x&|r�|jd�r�|d7}|dd�}qfW|dks�||krF|}qFW|dkr�d}d}	tjd|�s�d}	|p�d}|	|d|7}	|dt|	|�|_dS)	a{ Add extra doc text to a function's docstring.

        :param :class:`function` func: the function
        :param str field: (sphinx) field to add to the doc text
        :param str desc: description to add in the given :param:`field`
        :param bool field_unique: whether the given :param:`field` should only
                                  appear in the doc text once (a new one won't
                                  be added if there already is an existing one)

        If your doctext is indented with something other than spaces the added
        doctext's indentation will probably not match. That'd be your fault.
    Nr@rrr�z\n\s*$rr�)r=rTr�r"ru�searchr)
�func�field�desc�field_uniqueZ	base_textZ
indent_spacesr|rZ_lrrrr�_add_extra_doc_text�s2rz$will be removed in a future version.cCsd|jtfS)Nz%s %s)r:�_DEPRECATION_MESSAGE)rrrr�_default_deprecation_msg�srz.. deprecated::z%(version)s
    %(message)s
cCs"t||d�}t|t|dd�dS)N)�version�messageT)r)�_DEPRECATION_INFOr�_SPHINX_DEPRECATE)rrrrrrr�_add_deprecation_doc_text�sr cs��fdd�}|S)a9 Decorator to deprecate a function or method via warning and docstring.

        :param str version: version in which the deprecation is effective
        :param str message: message suggesting a preferred alternative

        .. note::
            At the point this decorator gets applied to a method in a class the
            method is just a function. It becomes a method later.

        The docstring manipulation is performed only once for each decorated
        function/method, but the warning is issued every time the decorated
        function is called.
    cs(t����fdd��}t|��d�|S)Ncs2t��}�r|d�7}tj|tdd��||�S)z9 Issue a deprecation warning for, then call, a function. z %srq)�
stacklevel)r�warnings�warn�DeprecationWarning)rraZwarn_msg)rrrr�the_func�s
z4deprecated.<locals>.deprecate_func.<locals>.the_func)rr)rr )rr%)rr)rr�deprecate_func�s
z"deprecated.<locals>.deprecate_funcr)rrr&r)rrr�
deprecated�sr'r�cs`t��x0�D](}t|t�r*�j|d�q�j|�qWt|���G����fdd�d��}|S)aiCreate a namedtuple class

    The difference between a namedtuple class and this class is that default
    values may be specified for fields and fields with missing values on
    initialization being initialized to None.

    :param str name: name of the new class
    :param fields: field descriptions - an iterable of either "name" or ("name", default_value)
    :type fields: list of str or (str, object) objects
    :param str doc: the docstring for the new class (should at least describe the meanings and
                    types of fields)
    :returns: a new default namedtuple class
    :rtype: type

    rcs$eZdZ�r�Z���fdd�ZdS)z0default_namedtuple.<locals>.TheDefaultNamedTuplecs�t|�}t|j��jd�}xftt|�t���D]P}�||krR|j|�|�q.t�|t�rt|j�|d�q.|jd�q.W�j	|f|��S)N)�keyr)
�list�sortedr��index�ranger#r�r+�tupler)rrraZ	args_listZ
sorted_kwargs�i)�field_names�fields�ntrrrsz8default_namedtuple.<locals>.TheDefaultNamedTuple.__new__N)r:r;r<r=rr)�docr/r0r1rr�TheDefaultNamedTuplesr3)r)r+r-r�r)r�r0r2rr3r)r2r/r0r1r�default_namedtuple�s


r4cs��fdd�}|S)a
    Function returning a decorator that can be used to guard methods and
    properties with evaluation of the given property.

    :param str prop_name: property to evaluate
    :param val: guard value of the :param:`prop_name`
    :type val: :class:`Object` (anything)
    cst�����fdd��}|S)Ncs6t|���kr�|f|�|�Std�j��f��dS)Nz-%s can only be accessed if %s evaluates to %s)�getattrr,r:)rrra)�fn�	prop_namer�rrr1sz.requires_property.<locals>.guard.<locals>.func)r)r6r)r7r�)r6r�guard0sz requires_property.<locals>.guardr)r7r�r8r)r7r�r�requires_property's	r9c@seZdZdZdZdS)�EvalModerrqN)r:r;r<�onetime�alwaysrrrrr:;sr:c@sLeZdZejdd�Zefdd�Zd
dd�Zej	dd	��Z
dejfd
d�Z
dS)�DependencyGuardz4Error message to report when a dependency is missing)r2cCs||_d|_dS)N)�_exn_cls�_avail)rZexn_clsrrr�__init__FszDependencyGuard.__init__FcCs |jdks|r|j�|_|jS)N)r?�_check_avail)rr;rrr�check_availJs
zDependencyGuard.check_availcCs
t��dS)N)�NotImplementedError)rrrrrAOszDependencyGuard._check_availcs���fdd�}|S)Ncst������fdd��}|S)NcsL�tjk}�j|d�r �||�S�r2�j�j��ntjd�j�j�dSdS)N)r;z Failed to call the %s method: %s)r:r;rBr>�	error_msgr5r�r:)rraZjust_onetime)�critical�	eval_moder6rrr�	decoratedUs

z>DependencyGuard.__call__.<locals>.decorator.<locals>.decorated)r)r6rG)rErFr)r6r�	decoratorTs
z+DependencyGuard.__call__.<locals>.decoratorr)rrErFrHr)rErFrr�__call__SszDependencyGuard.__call__N)F)r:r;r<�abc�abstractpropertyrDrr@rB�abstractmethodrAr:r<rIrrrrr=As

r=cCsBytjtttt�}Wntjtjfk
r0dSX|ddkSdS)z5 Return True if we are running in a virtual machine. Fr�qemu�kvm�xenN)rMrNrO)r	Zget_property_sync�SYSTEMD_SERVICE�SYSTEMD_MANAGER_PATH�SYSTEMD_MANAGER_IFACE�VIRT_PROP_NAMEZ
DBusCallErrorZDBusPropertyError)Zvmrrr�detect_virtcsrTcCs>|jdkr0|jr0|jr0t|jdd�}|jj|gS|jdgSdS)z� Sorting key for devices which makes sure partitions are sorted in natural
        way, e.g. 'sda1, sda2, ..., sda10' and not like 'sda1, sda10, sda2, ...'
    �	partitionZnumberrrNr�)�typeZparted_partitionZdiskr5r�)rjZpart_numrrr�natural_sort_keynsrWcCsvd}tjjd|d|�}y$t|��}|j�j�}WdQRXWn6tk
rp}ztjd||t	|��WYdd}~XnX|S)z� Return the value of a given kernel module parameter

    :param str module: a kernel module
    :param str parameter: a module parameter
    :returns: the value of the given kernel module parameter or None
    :rtype: str
    Nz/sys/moduleZ
parameterszLCouldn't get the value of the parameter '%s' from the kernel module '%s': %s)
rrrKrrr�r��IOErrorr5r�r)�moduleZ	parameterrZparameter_pathr�r_rrr�get_kernel_module_parameterys	
 rZ)r*NNFF)N)N)N)r�)r)N)Nr)r�rN)N)NNN)r)NNF)NN)r�)T)mrMr�r7r�rrOrur�r�r�r�r"rJZdecimalr�
contextlibrr�collectionsr�enumrr�rr�r	ZgiZrequire_versionZ
gi.repositoryr
rxrRr�r�r5rIr3r�Z	threadingrrHr��ImportErrorr�rPrQrRrSrr
r`rbrcrdrerfrgrmrpryr�r�rr�r�r�r�r�r�r�r�rir�r�r�r�r��objectr�r�r�r�r�r�r�r�r�r�r�rr
rrrrrrrr r'r4r9r:Z
add_metaclass�ABCMetar=rTrWrZrrrr�<module>s�




y
4
		




"



&


&

8
"
,
!