o
    b.                     @   sN   d dl Z ddlmZ dd Zdd ZG dd	 d	eZd
d ZG dd dZdS )    N   )xmlutilc              
   C   s  |  d\}}tt|d}|sdS t||dsdS d}|r,tt|d}|du r)dS |f}|du r2dS t||sDtd|t|t|f |}	|rL|	|7 }	z
t|||  W dS  tjy }
 zt	|
rkW Y d}
~
dS t
|rvW Y d}
~
dS W Y d}
~
dS d}
~
w ty   Y dS w )z
    Make sure function and option flag is present in the libvirt module.
    If run_args specified, try actually running the function against
    the passed 'data' object
    .NFz2Passed obj %s with args must be of type %s, was %sT)splitgetattrlibvirt
isinstance
ValueErrorstrtypelibvirtErrorSupportCacheis_error_nosupportbool	Exception)functionflagrun_argsdataobject_namefunction_nameclassobj
flag_tuple
found_flaguse_argse r   +/usr/share/virt-manager/virtinst/support.py_check_function   sJ   
	

r   c                 C   sr   | d u rd S | dkrdS |  ddkrtd|  t| dd d t| dd d  t| dd  S )Nr   r      z(version string '%s' needs two '.' in it.i@B r   i  )countr   DevErrorintr   )verstrr   r   r   _version_str_to_int=   s   r$   c                   @   s(   e Zd ZdZ		dddZdddZdS )	_SupportChecka5  
    @version: Minimum libvirt version required for this feature. Not used
        if 'args' provided.

    @function: Function name to check exists. Expected to be of the
        format $obj.$func. Like virDomain.isActive

    @run_args: Argument tuple to actually test 'function' with, and check
        for an 'unsupported' error from libvirt.

    @flag: A flag to check exists. This will be appended to the argument
        :list if run_args are provided, otherwise we will only check against
        that the flag is present in the python bindings.

    @hv_version: A dictionary with hypervisor names for keys, and
        hypervisor versions as values. This is for saying 'this feature
        is only supported with qemu version 1.5.0' or similar. If the
        version is 0, then perform no version check.

    @hv_libvirt_version: Similar to hv_version, but this will check
        the version of libvirt for a specific hv key. Use this to say
        'this feature is supported with qemu and libvirt version 1.0.0,
         and xen with libvirt version 1.1.0'
    Nc           
      C   s   || _ || _|| _|| _|pi | _|pi | _| j r$t|ddks$J | jgt| j	  }|D ]}t
|}	|d urJ|	dkrJ|	dk rJtd| q1d S )Nr   r   r   i[  zrCannot enforce support checks for libvirt versions less than 0.7.3, since required APIs were not available. ver=%s)r   r   r   version
hv_versionhv_libvirt_versionlenr   listvaluesr$   r   r!   )
selfr   r   r   r&   r'   r(   versionsvstrvr   r   r   __init__d   s&   

z_SupportCheck.__init__c                 C   s   dt |v r
| }| jrt| j| j| j|}|dur|S | }| }| }t	| j
}|r6||kr6dS | jrQ|| jvrFd| jvrEdS n|t	| j| k rQdS | jrm|| jvrbd| jvr`dS dS |t	| j| k rmdS dS )a  
        Attempt to determine if a specific libvirt feature is support given
        the passed connection.

        :param virtconn: VirtinstConnection to check feature on
        :param feature: Feature type to check support for
        :type feature: One of the SUPPORT_* flags
        :param data: Option libvirt object to use in feature checking
        :type data: Could be virDomain, virNetwork, virStoragePool, hv name, etc

        :returns: True if feature is supported, False otherwise
        VirtinstConnectionNFallT)reprget_conn_for_api_argr   r   r   r   get_uri_driverdaemon_versionconn_versionr$   r&   r'   r(   )r,   virtconnr   rethv_typeactual_libvirt_versionactual_hv_versionr/   r   r   r   __call__z   sB   




z_SupportCheck.__call__)NNNNNNN)__name__
__module____qualname____doc__r0   r=   r   r   r   r   r%   K   s    
r%   c                     s    t | i | d fdd	}|S )z
    Create a _SupportCheck from the passed args, then turn it into a
    SupportCache method which captures and caches the returned support
    value in self._cache
    Nc                    s0    | j vr | j|p| j}|| j  < | j   S r>   _cache	_virtconn)r,   r   support_retsupport_objr   r   cache_wrapper   s   


z_make.<locals>.cache_wrapperr>   )r%   )argskwargsrI   r   rG   r   _make   s   rL   c                   @   s*  e Zd ZdZedd Zedd Zdd Zedd	d
Z	edd	d
Z
eddd
Zedd	d
Zeddd
ZeddddZeddddZeddidZeddddZedddddZedddddZedddddZeddd
Zed d!dddZed"d#dd$dd%Zed&d'Zed(d'Zed)d'Zed*d'Zed+dd,idZedd,idZeddddZed-ddidZed.d/ddZ edd0d1ddd1d2Z!ed3d	d4d5Z"ed3d	d6d5Z#ed7dd
Z$ed8d	d
Z%ed9d	d
Z&ed:d	d
Z'ed;d	d
Z(ed<d=ddid%Z)ed>d?d@Z*edAd	d
Z+dBdC Z,dDS )Er   zk
    Class containing all support checks and access APIs, and support for
    caching returned results
    c                 C   s   t | tjsdS |  tjkS )zv
        Small helper to check if the passed exception is a libvirt error
        with code VIR_ERR_NO_DOMAIN
        F)r   r   r   get_error_codeVIR_ERR_NO_DOMAINerrr   r   r   is_libvirt_error_no_domain   s   z'SupportCache.is_libvirt_error_no_domainc                 C   s4   t | tjsdS |  tjks|  tjkrdS dS )z
        Check if passed exception indicates that the called libvirt command isn't
        supported

        :param err: Exception raised from command call
        :returns: True if command isn't supported, False if we can't determine
        FT)r   r   r   rM   VIR_ERR_RPCVIR_ERR_NO_SUPPORTrO   r   r   r   r      s   	zSupportCache.is_error_nosupportc                 C   s   i | _ || _d S r>   rC   )r,   r8   r   r   r   r0      s   
zSupportCache.__init__zvirConnect.listAllDomainsr   )r   r   zvirConnect.listAllStoragePoolszvirConnect.listDevices)Nr   zvirConnect.listNetworkszvirConnect.newStream)r   z4.0.0r   )xenr2   )r'   z1.2.0)qemutestrU   z1.0.6)r(   z1.1.0)r&   r'   z1.2.2z1.5.3z virConnect.getDomainCapabilities)NNNNz1.2.16z2.2.0zvirDomain.setMemoryStatsPeriodz1.1.1z5.6.0)r   r&   r'   z2.0.0r&   z1.3.4z1.3.5z3.0.0z3.3.0z2.9.0z5.3.0z2.11.00z4.2.0)rU   rT   )r'   r(   zvirDomain.XMLDescVIR_DOMAIN_XML_INACTIVE)r   r   r   VIR_DOMAIN_XML_SECUREzvirDomain.hasManagedSaveImagezvirDomain.jobInfozvirDomain.listAllSnapshotszvirDomain.memoryStatszvirDomain.statezvirDomain.openGraphicsFDz1.2.8(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATAz1.0.1)r   r&   zvirNodeDevice.isActivec                 C   s   t |d}|| jdS )z~
        Check libvirt version. Useful for the test suite so we don't need
        to keep adding new support checks.
        rW   N)r%   rE   )r,   r&   sobjr   r   r   _check_version9  s   
zSupportCache._check_versionN)-r?   r@   rA   rB   staticmethodrQ   r   r0   rL   conn_domainconn_storageconn_nodedevconn_networkconn_streamconn_working_xen_eventsconn_default_qcow2conn_autosocketconn_pm_disableconn_qcow2_lazy_refcountsconn_hyperv_vapicconn_hyperv_clockconn_domain_capabilitiesconn_vmportconn_mem_stats_periodconn_graphics_listen_noneconn_rng_urandomconn_usb3_portsconn_machvirt_pci_defaultconn_qemu_xhciconn_vnc_none_authconn_device_boot_orderconn_riscv_virt_pci_defaultqemu_q35_defaultconn_disk_driver_name_qemudomain_xml_inactivedomain_xml_securedomain_managed_savedomain_job_infodomain_list_snapshotsdomain_memory_statsdomain_statedomain_open_graphicspool_metadata_preallocnodedev_isactiver]   r   r   r   r   r      s    
	









r   )	r    r   r   r$   objectr%   rL   r   r   r   r   r   <module>   s   /c