o
    pb;                    @   s  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	ddl
mZ ddlmZ ddlmZ ddlmZmZmZmZmZmZmZ ddlmZ ddlmZmZ dd	lmZ dd
lm Z  ddl!m"Z"m#Z# ddl$m%Z% ddl&m'Z' e(dZ)G dd de*Z+da,dd Z-dd Z.g Z/G dd de j0Z1dddZ2dd Z3d ddZ4d!dd Z5d!d" Z6d d#d$Z7d"d%d&Z8d'd( Z9d)d* Z:d+d, Z;d-d. Z<d/d0 Z=d1d2 Z>d d3d4Z?d5d6 Z@dd7d8ZAd9d: ZBd;d< ZCd=d> ZDd?d@ ZEddAdBZFdCdD ZGdEdF ZHdGdH ZIdIdJ ZJdKdL ZKdMdN ZLd!dOdPZM				d#dQdRZNdSdT ZOddUdVZPd$dWdXZQdYdZ ZRd[d\ ZSdd]d^ZTd_d` ZUdadb ZVddcddZWdedf ZXdgdh ZYdidj ZZdkdl Z[G dmdn dnZ\e\ Z]G dodp dpe*Z^G dqdr dre*Z_dsdt Z`dudv ZaG dwdx dxebZcG dydz dzecd{ZdG d|d} d}edZed~d Zfdd ZgG dd dedZhdd Zidd ZjG dd dedZkdd ZlG dd dedZmG dd dZndd ZoG dd dedZpdd ZqG dd dedZrdd ZsG dd de*ZtG dd dedZudd Zvdd ZwG dd de*Zxdd ZyG dd dedZzG dd dedZ{G dd dedZ|G dd dedZ}G dd dedZ~G dd dedZG dd dedZG dd dedZG dd dedZG dd dedZG dd dedZG dd dedZG dd dedZG dd dedZG ddÄ dedZG ddń dedZG ddǄ dedZG ddɄ dedZG dd˄ dedZG dd̈́ dedZG ddτ dedZ	d%ddфZd&ddԄZd&ddքZdd؄ Zddڄ Zdd܄ ZG ddބ dedZG dd dedZG dd dedZG dd dedZG dd dedZG dd dedZG dd dedZG dd dedZG dd dedZG dd dedZG dd dedZG dd dedZG dd dedZG dd dedZG dd dedZG dd dedZG dd dedZG dd  d eZG dd deZG dd deZG dd deZG dd dedZG d	d
 d
edZG dd dedZG dd dedZdd Zdd Zdd ZG dd dedZG dd dedZdddZdd Zdd ZdS ('      N   )xmlutil)BuildConfig)VirtinstConnection)DeviceDeviceController
DeviceDiskDeviceGraphicsDeviceHostdevDeviceInterfaceDevicePanic)Guest)logreset_logging)
NodeDevice)OSDB)StoragePoolStorageVolume)UnattendedData)CloudInitDatavirt-viewerc                   @   s$   e Zd Zdd Zdd Zdd ZdS )_GlobalStatec                 C   s   d| _ d | _i | _d S NF)quiet
all_checks_validation_checksself r   '/usr/share/virt-manager/virtinst/cli.py__init__+   s   
z_GlobalState.__init__c                 C   s   || j |< d S N)r   )r   	checknamevalr   r   r   set_validation_check1      z!_GlobalState.set_validation_checkc                 C   s   | j d ur| j S | j|dS NT)r   r   get)r   r"   r   r   r   get_validation_check4   s   
z!_GlobalState.get_validation_checkN)__name__
__module____qualname__r    r$   r(   r   r   r   r   r   *   s    r   c                   C   s   t S r!   )_globalstater   r   r   r   get_global_state?   s   r-   c                   C   s
   t  ad S r!   )r   r,   r   r   r   r   _reset_global_stateC   s   
r.   c                   @   s   e Zd ZdZdZdd ZdS )VirtHelpFormattera  
    Subclass the default help formatter to allow printing newline characters
    in --help output. The way we do this is a huge hack :(

    Inspiration: http://groups.google.com/group/comp.lang.python/browse_thread/thread/6df6e6b541a15bc2/09f28e26af0699b1
    Nc                    sj    fdd}t dkrt  dkr| S z d }d|v r%| W S | W S  ty4   |  Y S w )Nc                      s   t jjg R i S r!   )argparseRawDescriptionHelpFormatter_split_linesr   argskwargsr   r   r   return_defaultZ   s   z6VirtHelpFormatter._split_lines.<locals>.return_defaultr      
)len
splitlines	Exception)r   r4   r5   r6   textr   r3   r   r2   Y   s   

zVirtHelpFormatter._split_lines)r)   r*   r+   __doc__oldwrapr2   r   r   r   r   r/   O   s    r/   Fc                 C   sD   t d}|rt dd | }tj| |t|d}|jddtjd |S )Nz1See man page for examples and full option syntax.z?Use '--option=?' or '--option help' to see available suboptionsr8   )usagedescriptionformatter_classepilogz	--versionversion)actionrC   )_r0   ArgumentParserr/   add_argumentr   rC   )r?   r@   introspection_epilogrB   parserr   r   r   setupParserj   s    rJ   c                  C   s"   t   dd l} | j| jdd d S )Nr   z%(message)s)levelformat)r   loggingbasicConfigDEBUG)rM   r   r   r   earlyLoggingz   s   rP   Tc              
      s  t   |t _t }tj|| d }t	 rd }d }zJ|rPt
|tjsPtj|r2td| zt|d W n tyO } z	td||f d d }~ww |retj|ret
|tjsetd| W n ty } ztd| d }W Y d }~nd }~ww d}d|  d	 }d
}	dd l}
dd l}
t  t|
j |r|
j|ddd}||
|| t| |
tj} r||
j ||
|| n|s|st jr|
j }n|
j!}|| ||
|	 nd }|rt|  fdd}|t_"t#ddtj$ d S )Nz.logzNo write access to directory %si  z!Could not create directory %s: %szNo write access to logfile %szError setting up logfile: %sz%a, %d %b %Y %H:%M:%Sz[%(asctime)s z? %(process)d] %(levelname)s (%(module)s:%(lineno)d) %(message)sz%(levelname)-8s %(message)sr   aei      c              
      s6   t ddt| ||  st| || d S d S )NzUncaught exception:
%s )r   debugjoin	tracebackformat_exceptionsys__excepthook__)typr#   tbdebug_stdoutr   r   exception_log   s   z#setupLogging.<locals>.exception_logzLaunched with command line: %s )%r.   r-   r   r   get_app_cache_dirospathrU   r   in_testsuiteaccessW_OKexistsRuntimeErrormakedirsIOErrorr;   r   warningrM   logging.handlersr   setLevelrO   handlersRotatingFileHandlersetFormatter	Formatter
addHandlerStreamHandlerrX   stderrERRORWARN
excepthookrT   argv)appnamer]   do_quietcli_appvi_dirlogfilee
dateFormat
fileFormatstreamErrorFormatrM   fileHandlerstreamHandlerrK   r^   r   r\   r   setupLogging   s   





r   c                 C   s>   |r|S t d| p
d t| }|td  t d|j |S )NzRequesting libvirt URI %sdefaultzReceived libvirt URI %s)r   rT   r   open_openauth_cburi)r   connr   r   r   getConnection   s   r   c                 C   s~   | D ]:}|\}}}}}|t jt jfv }|std|  dS td| |d7 }|r4dd l}	|	|}
nt|}
|
|d< qdS )NzNo prompt for auth credtype=%szopenauth_cb prompt=%sz: r   )libvirtVIR_CRED_PASSPHRASEVIR_CRED_NOECHOPROMPTr   errorrT   getpassinput)creds_cbdatacredcredtypeprompt
_challenge
_defresult_resultnoechor   resr   r   r   r      s    
r   c                 C   sN   t dt  t |  t d durt jddd |r%t  dS dS )z6
    Convenience function when failing in cli app
    rS   r   NTexc_info)	r   rT   rU   rV   format_stackr   rX   r   
_fail_exit)msgdo_exitr   r   r   fail   s   

r   c                 C   s.   |rt |  |st jr|st|  d S d S r!   )r   rT   r-   r   print)r   do_forcedo_logr   r   r   print_stdout  s
   
r   c                 C   s   t |  t| tjd d S )N)file)r   rT   r   rX   rs   )r   r   r   r   print_stderr  s   
r   c                   C   s   t d d S Nr   )rX   exitr   r   r   r   r     r%   r   c                 C   s   d| j j| jf S )Nzvirsh --connect %s start %s)r   r   name)guestr   r   r   virsh_start_cmd  s   r   c                 C   s&   t | }ttd|  td d S )NzDomain installation does not appear to have been successful.
If it was, you can restart your domain by running:
  %s
otherwise, please restart your installation.r   )r   r   rE   rX   r   )r   virshcmdr   r   r   install_fail  s   r   c                 C   s   | r	t d d S d S )Nz%--prompt mode is no longer supported.)r   rj   )r   r   r   r   
set_prompt&  s   r   c                 C   s<   t | |}|jsd S td||j|jd }t| d S )Nz%(path)s may not be accessible by the hypervisor. You will need to grant the '%(user)s' user search permissions for the following directories: %(dirs)s)rb   userdirs)r   check_path_searchfixlistrE   r   r   rj   )r   rb   
searchdatar   r   r   r   r   ,  s   r   c                 C   sH   t  |}|rt| td|   td||  |r"t|  dS dS )zE
    Handle printing a message with an associated --check option
    z4 (Use --check %s=off or --check all=off to override)z(Skipping --check %s error condition '%s'N)r-   r(   r   rE   r   rT   rj   )r   r"   warn_on_skipdo_checkr   r   r   _optional_fail8  s   
r   c              
   C   sH   z	t | | W dS  ty# } ztt|d W Y d}~dS d}~ww )z
    There's legitimate use cases for creating/cloning VMs with duplicate
    MACs, so we do the collision check here but allow it to be skipped
    with --check
    N
mac_in_use)r   check_mac_in_user;   r   str)r   macaddrr}   r   r   r   validate_macG  s   r   c                    sT       fdd} fdd} fdd}|  |  |  t j d S )Nc                      s0   sdS t  jsdS ttd d dS )zR
        Prompt if disk file already exists and preserve mode is not used
        Nz*This will overwrite the existing path '%s'path_exists)r   path_definitely_existsr   r   rE   r   devrb   warn_overwriter   r   check_path_existsW  s   
z(validate_disk.<locals>.check_path_existsc                     s0      } | sdS td| d }t|d dS )z9
        Check if disk is inuse by another guest
        Nz:Disk %(path)s is already in use by other guests %(names)s.)rb   namespath_in_use)is_conflict_diskrE   r   )r   r   )r   rb   r   r   check_inuse_conflictc  s   z+validate_disk.<locals>.check_inuse_conflictc                     s.      \} }| s|rt|ddd dS dS dS )zC
        Check if specified size exceeds available storage
        	disk_sizeF)r   N)is_size_conflictr   )isfatalerrmsg)r   r   r   check_size_conflicto  s   z*validate_disk.<locals>.check_size_conflict)get_source_pathr   r   )r   r   r   r   r   r   r   r   validate_diskT  s   	r   c              
   C   s   t dd| ddd |D }t| d|i  t r"dg}t }|r*|S z5z
t|d | W n t	yO } zt
d||f  W Y d }~nd }~ww W td	 d S W td	 d S td	 w )
NzRunning: %sr_   c                 S   s   g | ]}t |qS r   )shlexquote).0ar   r   r   
<listcomp>  s    z _run_console.<locals>.<listcomp>commandz	/bin/testr   zError launching %s: %sr   )r   rT   rU   r   r   rc   ra   forkexecvpr;   r   _exit)messager4   argstrchildr}   r   r   r   _run_console~  s$   r   c                 C   s@   dd| j jd| jg}td}|  s|  r|d t||S )Nr   	--connectz--waitz.Running graphical console command: %(command)sz--attach)r   r   r   rE   has_glhas_listen_noneappendr   r   r4   r   r   r   r   _gfx_console  s   

r   c                 C   s&   dd| j jd| jg}td}t||S )Nvirshr   consolez)Running text console command: %(command)s)r   r   r   rE   r   r   r   r   r   _txt_console  s   
r   c                  C   s&   dd l } t jpt }| jj|dS )Nr   )r   )virtinst.progressr-   r   r   rc   progress
make_meter)virtinstr   r   r   r   	get_meter  s   r   c                 C   s   t j}|r
|t jO }| |S r!   )r   VIR_DOMAIN_XML_SECUREVIR_DOMAIN_XML_INACTIVEXMLDesc)domaininactiveflagsr   r   r   get_xmldesc  s   

r   c           
   
   C   s(  zt | d}W n ty   d}Y nw d}tt||}z/d }z| |}W n# tyK   tjddd |r@| 	t |}n	|rH| 
|}n Y nw W n  tjym } zttd|t|d  W Y d }~nd }~ww | d }d }t| t|d	}	|tjkr|	}t| t|dd
d	}	||	|fS )NTFz7[a-fA-F0-9]{8}[-]([a-fA-F0-9]{4}[-]){3}[a-fA-F0-9]{12}$zError looking up domain by namer   z-Could not find domain '%(domain)s': %(error)s)r   r   r   parsexml)r   )int
ValueErrorboolrematchlookupByNamer;   r   rT   
lookupByIDlookupByUUIDStringr   libvirtErrorr   rE   r   infor   r   VIR_DOMAIN_SHUTOFF)
r   domstrisintuuidreisuuidr   r}   stateactive_xmlobjinactive_xmlobjr   r   r   get_domain_and_guest  sL   	


r  c                 C   s   t d| |d }t| d S )Nz7Cannot use %(option1)s and %(option2)s at the same time)option1option2)rE   r   )r  r  r   r   r   r   fail_conflicting  s
   r  c                   C   s   t tttttttg S r!   )VIRT_PARSERSParserCheckParserLocationParserUnattendedParserInstallParserCloudInit	ParserXMLParserOSVariantr   r   r   r   _get_completer_parsers  s   r  c                 K   s   g }t  D ]}|d j|jkr$t|jdd dD ]}|| d  qq| d}|D ] }|d}|dkrL|d |d  |v rL|	|d |d   q,|S )	NrD   c                 S   s   |   S r!   )nonregex_cliname)pr   r   r   <lambda>  s    z'_virtparser_completer.<locals>.<lambda>key=,r   r   )
r  destcli_arg_namesorted	_virtargsr   r  splitfindremove)prefixr5   sub_optionsparserclassvirtargentered_optionsoptionposr   r   r   _virtparser_completer  s   



r&  c                 C   s&   |dkrdS | ddd }| |S )aW  
    :param suboption: The virtarg.cliname we are checking for a match
    :param current_input: The user typed string we are checking against.
        So if the user types '--disk path=foo,dev<TAB>',
        current_input=='path=foo,dev'

    For debugging here, 'export _ARC_DEBUG=1'. Now exceptions/printing
    will be shown on stderr
    rS   Tr  r   r   )rsplit
startswith)	suboptioncurrent_inputcurrent_optionr   r   r   _completer_validator  s   
r,  c              	   C   s"  dt jvrd S dd l}dd l}dd t D }| jD ]}|jD ]}||v r*t|_ nqqdt	i}t
 rCdd l}| |d< tj|d< t j}t
 rPdd	 }	|	}|jjt d
|. z|j| fi | W n ty~   t
 r}|d  d}
t|
  w W d    d S 1 sw   Y  d S )N_ARGCOMPLETEr   c                 S   s   g | ]}|  qS r   )cli_flag_name)r   pclassr   r   r   r     s    z autocomplete.<locals>.<listcomp>	validatoroutput_streamexit_methodc                  _   s   t jS r!   )rX   rs   r4   r5   r   r   r   fake_fdopen_cb2     z$autocomplete.<locals>.fake_fdopen_cbfdopenzutf-8)ra   environargcompleteunittest.mockr  _actionsoption_stringsr&  	completerr,  r   rc   ioBytesIOrX   r   r6  mockpatchobjectautocomplete
SystemExitgetvaluedecoder   )rI   r8  unittestparsernamesrD   optr5   r=  fake_fdopenr4  outputr   r   r   rB    sD   



"rB  c                 C   s:   |dkr| j dddtdd d S | j ddtdd d S )Nzvirt-xmlz-cr   URIz&Connect to hypervisor with libvirt URI)metavarhelprG   rE   )rI   invokerr   r   r   add_connect_optionD  s   


rP  c           	      C   sF  |r| j dddtjd | j dddtjd |r.| j ddtdd	 | j d
dddtdd |r:| j ddtdd |rF| j ddtdd |rrddtdd}|r[d|d< d|d< nd|d< | j d.i | |rr| j ddtjd  |r| j d!dd"td#d$ |r| j d%d&td'd | j d(d)dtd*d | j d+d,dtd-d d S )/Nz--prompt
store_trueFrD   r   rM  z--forcez--autoconsoler   zlConfigure guest console auto connect. Example:
--autoconsole text
--autoconsole graphical
--autoconsole none)r   rM  z--noautoconsoleautoconsolestore_constnonez7Don't automatically try to connect to the guest console)r  rD   constrM  z
--norebootz*Don't boot guest after completing install.rD   rM  z	--replacezCDon't check name collision, overwrite any guest with the same name.xmlonlyz<Print the generated domain XML rather than create the guest.)r  r   rM  ?nargsallrV  rD   --print-xmlz--print-stepxmlstep)r  rM  z	--dry-rundryzKRun through install process, but do not create devices or define the guest.rD   r  rM  z--checkr   zUEnable or disable validation checks. Example:
--check path_in_use=off
--check all=offz-qz--quietzSuppress non-error outputz-dz--debugzPrint debugging information)r\  )rG   r0   SUPPRESSrE   )	grpr   replaceprintxml	printstepnorebootdryrunnoautoconsoleprint_kwargsr   r   r   add_misc_optionsM  sf   




ri  c                 C       t   | jddtdd d S )Nz
--metadatar   zConfigure guest metadata. Ex:
--metadata name=foo,title="My pretty title",uuid=...
--metadata description="My nice long description"rW  )ParserMetadataregisterrG   rE   ra  r   r   r   add_metadata_option     
rn  c                 C   s>   t   | jddtdd |r| jddtdtjd d S d S )	Nz--memoryr   zeConfigure guest memory allocation. Ex:
--memory 1024 (in MiB)
--memory memory=1024,currentMemory=512
rW  z-rz--ram	oldmemory)typer  rM  )ParserMemoryrl  rG   rE   r   r0   r`  )ra  
backcompatr   r   r   add_memory_option  s   
rt  c                 C   sv   t   t  | jddtdd d}|rd}| jddtd| d |r9| jd	d
tjd | jdtjd d S d S )Nz--vcpusr   zNumber of vCPUs to configure for your guest. Ex:
--vcpus 5
--vcpus 5,maxvcpus=10,cpuset=1-4,6,8
--vcpus sockets=2,cores=4,threads=2rW  z
--cpu hostz--cpu host-model,clearxml=yesz--cpuzICPU model and features. Ex:
--cpu coreduo,+x2apic
--cpu host-passthrough
z--check-cpurQ  z--cpusetrM  )	ParserCPUrl  
ParserVCPUrG   rE   r0   r`  )ra  rs  editexampleextramsgr   r   r   vcpu_cli_options  s&   rz  c                 C   rj  )Nz
--graphicsr   zoConfigure guest display settings. Ex:
--graphics spice
--graphics vnc,port=5901,listen=0.0.0.0
--graphics none
rW  )ParserGraphicsrl  rG   rE   devgr   r   r   add_gfx_option  ro  r~  c                 C   s"   t   | jdddtdd d S )Nz-wz	--networkr   zConfigure a guest network interface. Ex:
--network bridge=mybr0
--network network=my_libvirt_virtual_net
--network network=mynet,model=virtio,mac=00:11...
--network none
--network helprW  )ParserNetworkrl  rG   rE   r|  r   r   r   add_net_option  s   

r  c                 C   s  t   | jddtdd t  | jddtdd t  | jddtdd t  | jd	dtd
d t  | jddtdd t  | jddtdd t	  | jddtdd | jdddt
jd t  | jddtdd t  dtdd}|rd|d< | jd6i | |r| jdddt
jd t  | jddtdd t  | jddtdd t  | jd dtd!d t  | jd"dtd#d t  | jd$dtd%d t  | jd&dtd'd t  | jd(dtd)d t  | jd*dtd+d t  | jd,dtd-d t  | jd.dtd/d t  | jd0dtd1d t  | jd2dtd3d t  | jd4dtd5d d S )7Nz--controllerr   zxConfigure a guest controller device. Ex:
--controller type=usb,model=qemu-xhci
--controller type=scsi,model=virtio-scsi
rW  z--inputzKConfigure a guest input device. Ex:
--input tablet
--input keyboard,bus=usbz--serialzConfigure a guest serial devicez
--parallelz!Configure a guest parallel devicez	--channelz'Configure a guest communication channelz	--consolez>Configure a text console connection between the guest and hostz	--hostdevzGConfigure physical USB/PCI/etc host devices to be shared with the guestz--host-devicehostdevr_  z--filesystemz{Pass host directory to the guest. Ex: 
--filesystem /my/source/dir,/dir/in/guest
--filesystem template_name,/,type=templatez&Configure guest sound device emulationrY  rZ  --soundz	--soundhwsoundz--audioz.Configure host audio backend for sound devicesz
--watchdogz!Configure a guest watchdog devicez--videozConfigure guest video hardware.z--smartcardzDConfigure a guest smartcard device. Ex:
--smartcard mode=passthroughz
--redirdevzYConfigure a guest redirection device. Ex:
--redirdev usb,type=tcp,server=192.168.1.1:4000z--memballoonzBConfigure a guest memballoon device. Ex:
--memballoon model=virtioz--tpmz0Configure a guest TPM device. Ex:
--tpm /dev/tpmz--rngz4Configure a guest RNG device. Ex:
--rng /dev/urandomz--panicz3Configure a guest panic device. Ex:
--panic defaultz--shmemz?Configure a guest shared memory device. Ex:
--shmem name=shmem0z--memdevzCConfigure a guest memory device. Ex:
--memdev dimm,target.size=1024z--vsockzMConfigure guest vsock sockets. Ex:
--vsock cid.auto=yes
--vsock cid.address=7z--iommuzDConfigure an IOMMU device. Ex:
--iommu model=intel,driver.aw_bits=48)r  )ParserControllerrl  rG   rE   ParserInputParserSerialParserParallelParserChannelParserConsoleParserHostdevr0   r`  ParserFilesystemParserSoundParserAudioParserWatchdogParserVideoParserSmartcardParserRedirParserMemballoon	ParserTPM	ParserRNGParserPanicParserShMemParserMemdevParserVsockParserIommu)r}  sound_back_compatsound_kwargsr   r   r   add_device_options  s   


r  c                 C   s  t   | jddtdd t  | jdddtdd t  | jddtd	d t  | jd
dtdd t  | jddtdd t  | jddtdd t	  | jddtdd t
  | jddtdd t  | jddtdd t  | jddtdd t  | jddtdd t  | jddtdd t  | jddtdd t  | jddtdd t  | jd dtd!d t  | jd"d#dtd$d d S )%Nz--iothreadsr   z7Set domain <iothreads> and <iothreadids> configuration.rW  z
--seclabelz
--securityz"Set domain seclabel configuration.z	--keywrapzFSet guest to perform the S390 cryptographic key management operations.z	--cputunez+Tune CPU parameters for the domain process.z
--numatunez(Tune NUMA policy for the domain process.z	--memtunez*Tune memory policy for the domain process.z--blkiotunez)Tune blkio policy for the domain process.z--memorybackingzRSet memory backing policy for the domain process. Ex:
--memorybacking hugepages=onz
--featureszQSet domain <features> XML. Ex:
--features acpi=off
--features apic=on,apic.eoi=onz--clockzKSet domain <clock> XML. Ex:
--clock offset=localtime,rtc_tickpolicy=catchupz--pmz&Configure VM power management featuresz--eventsz(Configure VM lifecycle management policyz
--resourcez,Configure VM resource partitioning (cgroups)z	--sysinfoznConfigure SMBIOS System Information. Ex:
--sysinfo host
--sysinfo bios.vendor=MyVendor,bios.version=1.2.3,...
z--qemu-commandlinez}Pass arguments directly to the QEMU emulator. Ex:
--qemu-commandline='-display gtk,gl=on'
--qemu-commandline env=DISPLAY=:0.1z--launchSecurityz--launchsecurityzSConfigure VM launch security (e.g. SEV memory encryption). Ex:
--launchSecurity sev)ParserIOThreadsrl  rG   rE   ParserSeclabelParserKeyWrapParserCputuneParserNumatuneParserMemtuneParserBlkiotuneParserMemoryBackingParserFeaturesParserClockParserPMParserEventsParserResourceParserSysinfoParserQemuCLIParserLaunchSecurity)gengr   r   r   add_guest_xml_options6  s   


r  c                 C   s<   t   | jddtdd t  | jddtdd d S )Nz--bootr   zbConfigure guest boot settings. Ex:
--boot hd,cdrom,menu=on
--boot init=/sbin/init (for containers)rW  z--idmapz]Enable user namespace for LXC container. Ex:
--idmap uid.start=0,uid.target=1000,uid.count=10)
ParserBootrl  rG   rE   ParserIdmap)insgr   r   r   add_boot_options  s   
r  c                 C   s4   t   d}|r|d7 }| jddtd| d d S )NrS   z
--disk cache=  (unset cache)z--diskr   zSpecify storage with various options. Ex.
--disk size=10 (new 10GiB image in default location)
--disk /my/existing/disk,cache=none
--disk device=cdrom,bus=scsi
--disk=?rW  )
ParserDiskrl  rG   rE   )stogrx  editmsgr   r   r   add_disk_option  s   
r  c                 C   sL   |  td}|rtd}ntd}|d7 }|td7 }|jdd|d |S )	Nz
OS optionsz$The OS being installed in the guest.zThe OS installed in the guest.r8   zThis is used for deciding optimal defaults like VirtIO.
Example values: fedora29, rhel7.0, win10, ...
Use '--osinfo list' to see a full list.z--os-variantz--osinforu  )add_argument_grouprE   rG   )rI   virtinstallosgr   r   r   r   add_os_variant_option  s   
r  c                 C   s   | j ddg tdd d S )Nz--xmlr   zPerform raw XML XPath options on the final XML. Example:
--xml ./cpu/@mode=host-passthrough
--xml ./devices/disk[2]/serial=new-serial
--xml xpath.delete=./clockrR  rN  rm  r   r   r   add_xml_option  s   

r  c                 C   s8   g d}g d}| pd  } | |v rdS | |v rdS d S )N)yyes1trueton)nno0falsefoffrS   TF)lower)stvaluesfvaluesr   r   r   _raw_on_off_convert  s   r  c                 C   s8   |d u rd S t |}|d ur|S ttdd| i  d S )Nz%(key)s must be 'yes' or 'no'r  )r  r   rE   )r  r#   r   r   r   _on_off_convert  s   r  c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )_SuboptCheckerClasszN
    Used by the test suite to ensure we actually test all cli suboptions
    c                 C   s   t  | _t  | _d S r!   )set_all_seenr   r   r   r   r         z_SuboptCheckerClass.__init__c                 C      | j | d S r!   )r  addr   r   r   r   r   add_all     z_SuboptCheckerClass.add_allc                 C   r  r!   )r  r  r  r   r   r   add_seen  r  z_SuboptCheckerClass.add_seenc                 C   s   | j | j S r!   )r  r  r   r   r   r   
get_unseen     z_SuboptCheckerClass.get_unseenN)r)   r*   r+   r=   r    r  r  r  r   r   r   r   r    s    r  c                   @   s@   e Zd ZdZ			dddZdd Zd	d
 Zdd Zdd ZdS )_VirtCLIArgumentStatica8  
    Helper class to hold all of the static data we need for knowing
    how to parse a cli subargument, like --disk path=, or --network mac=.

    @cliname: The command line option name, 'path' for path=FOO
    @propname: The virtinst API attribute name the cliargument maps to.
    @cb: Rather than set a virtinst object property directly, use
        this callback instead. It should have the signature:
        cb(parser, inst, val, virtarg)

    @ignore_default: If the value passed on the cli is 'default', don't
        do anything.
    @can_comma: If True, this option is expected to have embedded commas.
        After the parser sees this option, it will iterate over the
        option string until it finds another known argument name:
        everything prior to that argument name is considered part of
        the value of this option, '=' included. Should be used sparingly.
    @is_onoff: The value expected on the cli is on/off or yes/no, convert
        it to true/false.
    @lookup_cb: If specified, use this function for performing match
        lookups.
    @find_inst_cb: If specified, this can be used to return a different
        'inst' to check and set attributes against. For example,
        DeviceDisk has multiple seclabel children, this provides a hook
        to lookup the specified child object.
    NFr   c
           
      C   s   || _ || _|| _|| _|| _|| _|| _|	| _|| _g | _	| js)| js)t
d| js9| jdkr9t
d| j  | jdkrAd | _t| | j  d S )Nz!propname or cb must be specified.r   a  cliname=%s propname is None but lookup_cb is not specified. Even if a 'cb' is passed, 'propname' is still used for device lookup for virt-xml --edit.

If cb is just a converter function for a single propname, then set both propname and cb. If this cliname is truly not backed by a single propname, set lookup_cb=None or better yet implement a lookup_cb. This message is here to ensure propname isn't omitted without understanding the distinction.)clinamepropnamecb	can_commaignore_defaultis_onoff	lookup_cbfind_inst_cb_parent_cliname_aliasesr   DevError_SuboptCheckerr  _testsuite_argcheck_name)
r   r  r  parent_clinamer  r  r  r  r  r  r   r   r   r      s*   

z_VirtCLIArgumentStatic.__init__c                 C   s   | j sd| S d| j |f S )Nzsharedoption %sz--%s %s)r  )r   r  r   r   r   r  !  s   z/_VirtCLIArgumentStatic._testsuite_argcheck_namec                 C   s&   || _ | j D ]
}t| | qd S r!   )r  r  r  r  )r   aliasesaliasr   r   r   set_aliases&  s   
z"_VirtCLIArgumentStatic.set_aliasesc                 C   s   | j ddS )Nz[0-9]*rS   )r  rb  r   r   r   r   r  +  r%   z'_VirtCLIArgumentStatic.nonregex_clinamec                 C   sb   | j gt| j D ]$}d|v rtd|dd |}n||k}|r.t| 	|  dS q
dS )z
        Return True if the passed user string matches this
        VirtCLIArgument. So for an option like --foo bar=X, this
        checks if we are the parser for 'bar'
        [z^%s$.z\.TF)
r  r   listifyr  r   r   rb  r  r  r  )r   userstrr  retr   r   r   
match_name.  s   z!_VirtCLIArgumentStatic.match_name)NNFFr   N)	r)   r*   r+   r=   r    r  r  r  r  r   r   r   r   r    s    
"r  c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	_VirtCLIArgumentz
    A class that combines the static parsing data _VirtCLIArgumentStatic
    with actual values passed on the command line.
    c                 C   sV   |du r
t d| |dkrd}|jrt||}|| _|| _|| _|j| _|j| _dS )zk
        Instantiate a VirtCLIArgument with the actual key=val pair
        from the command line.
        NzOption '%s' had no value set.rS   )rg   r  r  r#   r  _virtargr  r  )r   r"  r  r#   r   r   r   r    E  s   
z_VirtCLIArgument.__init__c                 C   s   | j dkr| jjrdS | jjr| jj||| j | dd}z| jr&t|| j W n ty;   d|| jf }t|dw | jj	rL| j	||| j |  dS t
|| j| j  dS )z
        Process the cli param against the pass inst.

        So if we are VirtCLIArgument for --disk device=, and the user
        specified --disk device=foo, we were instantiated with
        key=device val=foo, so set inst.device = foo
        r   NTcan_editzobj=%s does not have member=%s)r#   r  r  r  r  r   get_prop_pathAttributeErrorr  r  set_prop_path)r   rI   instr   r   r   r   parse_param^  s$   z_VirtCLIArgument.parse_paramc                 C   s   | j s| jjsttdt|dd| jd | jjr+| jj||| j| dd}|s+dS | jjr9| j||| j| S t	
|| j }|j|j| d}t	|| j | j t	
|| j }||kS )a1  
        See if the passed value matches our Argument, like via virt-xml

        So if this Argument is for --disk device=, and the user
        specified virt-xml --edit device=floppy --disk ..., we were
        instantiated with key=device val=floppy, so return
        'inst.device == floppy'
        zRDon't know how to match device type '%(device_type)s' property '%(property_name)s'DEVICE_TYPErS   )device_typeproperty_nameFr  r   )r  r  r  rg   rE   getattrr  r  r#   r   r  	__class__r   get_xmlr  )r   rI   r  xmlvalsetterclivalr   r   r   lookup_paramz  s0   	
z_VirtCLIArgument.lookup_paramN)r)   r*   r+   r=   r    r  r  r   r   r   r   r  ?  s
    r  c                 C   sj   t j | pddd}d|_d|_d|_g }t|D ]}d|v r'|dd\}}n|}d}|||f q|S )z
    Parse the command string into an ordered list of tuples. So
    a string like --disk path=foo,size=5,path=bar will end up like

    [("path", "foo"), ("size", "5"), ("path", "bar")]
    rS   T)posixr  r  r   N)r   
commenters
whitespacewhitespace_splitlistr  r   )optstrargsplitterr  rH  r  r#   r   r   r   parse_optstr_tuples  s   r  c           
         s   t  }t| fdd  fdd}tD ]\}\}}|dus%|s' n
|d|f|< qr\d\}} |}|sE|||< q1|jrV|||g}	|	d }|	d }|||< s3|S )z
    Parse the passed argument string into an OrderedDict WRT
    the passed list of VirtCLIArguments and their special handling.

    So for --disk path=foo,size=5, optstr is 'path=foo,size=5', and
    we return {"path": "foo", "size": "5"}
    c                    s     D ]}| | r|  S qd S r!   )r  )r  r"  )virtargsr   r   _lookup_virtarg  s
   
z._parse_optstr_to_dict.<locals>._lookup_virtargc                    s\   r,d \}} |r	 | S  d | d  d| 7  < |r*| d  d| 7  < s| S )Nr   r   r  r  )pop)commaoptr  r#   )r  	opttuplesr   r   _consume_comma_arg  s   	
z1_parse_optstr_to_dict.<locals>._consume_comma_argNr   r   )collectionsOrderedDictr  	enumerater  r  )
r  r  remove_firstoptdictr  idxr  r#   r"  r  r   )r  r  r  r   _parse_optstr_to_dict  s*   r  c                       s    e Zd ZdZ fddZ  ZS )
_InitClassa  Metaclass for providing the _virtcli_class_init function.

    This allows the customisation of class creation. Similar to
    '__init_subclass__' (see https://www.python.org/dev/peps/pep-0487/),
    but without giving us an explicit dep on python 3.6

    c           	         s   t |dkrt j| g|R  S |}|\}}}|d}t|tjr&tdt | |||}|  |j	r@t
d||j	f |S )N   _virtcli_class_initz*_virtcli_class_init must be a @classmethodzclass=%s leftover aliases=%s)r9   super__new__r'   
isinstancetypesFunctionTyperg   r  r  r   r  )	clsr4   r5   dummyr   basesnsinitr   r   r   r   r    s    

z_InitClass.__new__)r)   r*   r+   r=   r  __classcell__r   r   r(  r   r    s    r  c                   @   s   e Zd ZdZdZdZdZdZg Zi Z	dZ
edd Zedd Zedd	 Zed
d Zedd Zedd Zedd Zedd Zd&ddZdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% ZdS )'VirtCLIParsera  
    Parse a compound arg string like --option foo=bar,baz=12. This is
    the desired interface to VirtCLIArgument and VirtCLIOptionString.

    A command line argument like --disk just extends this interface
    and calls add_arg a bunch to register subarguments like path=,
    size=, etc. See existing impls examples of how to do all sorts of
    crazy stuff.

    Class parameters:
    @guest_propname: The property name in the Guest class that tracks
        the object type that backs this parser. For example, the --sound
        option maps to DeviceSound, which on the guest class is at
        guest.devices.sound, so guest_propname = "devices.sound"
    @remove_first: List of parameters to peel off the front of the
        option string, and store in the optdict. So:
        remove_first=["char_type"] for --serial pty,foo=bar
        maps to {"char_type", "pty", "foo": "bar"}
    @stub_none: If the parsed option string is just 'none', make it a no-op.
        This helps us be backwards compatible: for example, --rng none is
        a no-op, but one day we decide to add an rng device by default to
        certain VMs, and --rng none is extended to handle that. --rng none
        can be added to users command lines and it will give the expected
        results regardless of the virt-install version.
    @cli_arg_name: The command line argument this maps to, so
        "hostdev" for --hostdev
    NTc                 O   s   | j sg | _ | jrtddd| jddd}| j | | j}|ddr%d}t|||g|R i |}|j| jv rE|	t
| j|j | j | dS )a  
        Add a VirtCLIArgument for this class.

        :param skip_testsuite_tracking: Special argument handled here. If True,
            if means the argument is shared among multiple cli commands.
            Don't insist that each instance has full testsuite coverage.
        clearxmlNTr  r  r  skip_testsuite_trackingF)r  supports_clearxmlr  _clearxml_cbr   r  r  r  r  r  r   r  )r#  r  r  r4   r5   clearxmlvirtargr  r"  r   r   r   add_arg-  s(   	
zVirtCLIParser.add_argc                 C   s   d| j dd S )Nz--rE   -)r  rb  r#  r   r   r   r.  I     zVirtCLIParser.cli_flag_namec                 C   sF   dd }t d|    t| j|dD ]	}t d|j  qt d dS )zK
        Print out all _param names, triggered via ex. --disk help
        c                 S   s<   d}| j dkr	d}| j drd}| j drd}|| j  S )NrS   r+  r  zaddress.r  xpath2)r  r(  )r"  r  r   r   r   _sortkeyR  s   

z3VirtCLIParser.print_introspection.<locals>._sortkeyz%s options:r  z  %srS   N)r   r.  r  r  r  )r#  r7  argr   r   r   print_introspectionM  s
   
z!VirtCLIParser.print_introspectionc                 C   s   | j sdS t|| j S )z
        For the passed obj, return the equivalent of
        getattr(obj, cls.guest_propname), but handle '.' in the guest_propname
        N)guest_propnamer   r  )r#  objr   r   r   lookup_propa  s   zVirtCLIParser.lookup_propc                 C   s   |  |}t|tS r!   )r<  r   r
  )r#  r;  r  r   r   r   prop_is_listk  s   

zVirtCLIParser.prop_is_listc                 C   s   | t vrt |  d S d S r!   )r  r   r3  r   r   r   rl  p  s   zVirtCLIParser.registerc                 C      dS )z-This method also terminates the super() chainNr   r3  r   r   r   r  v      z!VirtCLIParser._virtcli_class_initc                 C   s   | r| j rt|  d S d S d S r!   )r:  _add_xpath_args)subclassr   r   r   _virtcli_class_init_commonz  s   
z(VirtCLIParser._virtcli_class_init_commonc                 C   s8   || _ || _|| _t| j | jt| jd d  | _d S r!   )	r  r   editingr  r  r   r  r  r  )r   r  r   rC  r   r   r   r      s   
zVirtCLIParser.__init__c                 C   s8   | j std|   |durdS |jd| jv d dS )zF
        Callback that handles virt-xml clearxml=yes|no magic
        z!Don't know how to clearxml for %sTNr  )
leave_stub)r:  rg   r.  clearr  r   r  r#   r"  r   r   r   r/    s   zVirtCLIParser._clearxml_cbc                    s    fdd}|S )a  
        Create a callback used for find_inst_cb command line lookup.

        :param cliarg: The cliarg string that is followed by an index.
            Example, for --disk seclabel[0-9]* mapping, this is 'seclabel'
        :param list_propname: The property name on the virtinst object that
            this parameter maps too. For the seclabel example, we want
            disk.seclabels, so this value is 'seclabels'
        c                    s   |}d}t d  |j}|rt| d }|r9tt| |d k r9t|   tt| |d k s%z	t| | W S  t	yO   |sNY d S  w )Nr   z%s(\d+)r   )
r   searchr  r   groupsr9   r   r  add_new
IndexError)r  r#   r"  r  ignorenumregcliarglist_propnamer   r   r    s    z,VirtCLIParser._make_find_inst_cb.<locals>.cbr   )r   rO  rP  r  r   rN  r   _make_find_inst_cb  s   
z VirtCLIParser._make_find_inst_cbc                 C   sL   g }| j D ]}t| D ]}||r"t||||}|| qq|S )zy
        Convert the passed optdict to a list of instantiated
        VirtCLIArguments to actually interact with
        )r  r
  keysr  r  r  r   )r   r  r  virtargstaticr  arginstr   r   r   _optdict_to_param_list  s   



z$VirtCLIParser._optdict_to_param_listc                 C   s.   |rt td|  t| d  dS dS )z
        Used to check if there were any unprocessed entries in the
        optdict after we should have emptied it. Like if the user
        passed an invalid argument such as --disk idontexist=foo
        z*Unknown %(optionflag)s options: %(string)s)
optionflagstringN)r   rE   r.  r
  rR  )r   r  r   r   r   _check_leftover_opts  s   

z"VirtCLIParser._check_leftover_optsc                 C   s4   | j  }| |D ]}|| | q
| | |S )zr
        Subclasses can hook into this to do any pre/post processing
        of the inst, or self.optdict
        )r  copyrU  r  rX  )r   r  r  paramr   r   r   _parse  s
   

zVirtCLIParser._parsec              
   C   s0  | j sdS | jr| j dkrdS d}| jr(|s(| | j}| | j}|r(| }g }z?| |du r4| jp5|}t	|D ]#}| j
sJt|drJ|  |sMq<t|trY| j| q<| j| q<|t	|7 }W |S  ty } z"tjd|| j dd ttd|  | j t|d	  W Y d}~|S d}~ww )
a  
        Main entry point. Iterate over self._virtargs, and serialize
        self.optdict into 'inst'.

        For virt-xml, 'inst' is the virtinst object we are editing,
        ex. a DeviceDisk from a parsed Guest object.
        For virt-install, 'inst' is None, and we will create a new
        inst for self.guest_propname, or edit a singleton object in place
        like Guest.features/DomainFeatures
        NrU  Fvalidate#Exception parsing inst=%s optstr=%sTr   -Error: %(cli_flag_name)s %(options)s: %(err)sr.  optionserr)r  	stub_noner:  r<  r   r=  newr[  r   r  rC  hasattrr\  r   r   
add_device	add_childr;   r   rT   r   rE   r.  r   )r   r  
new_objectr  objsr;  r}   r   r   r   parse  sF   


zVirtCLIParser.parsec           	   
   C   s   g }t | | j}z1|D ]+}| j }d}| |D ]}|| |}|du r,d} nq|r4|| | 	| qW |S  t
yj } z"tjd|| jdd ttd|  | jt|d  W Y d}~|S d}~ww )z
        Given a passed option string, search the guests' child list
        for all objects which match the passed options.

        Used only by virt-xml --edit lookups
        TFr]  r   r^  r_  N)r   r  r<  r   r  rY  rU  r  r   rX  r;   r   rT   r  r   rE   r.  r   )	r   r  objlistr  r  validrZ  paramretr}   r   r   r   lookup_child_from_option_string  s:   


z-VirtCLIParser.lookup_child_from_option_stringc                 C   r>  )zDo nothing callbackNr   rF  r   r   r   noset_cb*  r?  zVirtCLIParser.noset_cb)NN)r)   r*   r+   r=   r:  r  rb  r  r  r  r.  classmethodr1  r.  r9  r<  r=  rl  r  staticmethodrB  r    r/  rQ  rU  rX  r[  ri  rm  rn  r   r   r   r   r*  	  sD    



	




.r*  )	metaclassc                       s4   e Zd ZdZdZdZedd Z fddZ  Z	S )r  zl
    Parser to set values on XMLManualAction instances, which are tracked
    in XMLBuilder.xml_actions
    xmlFc                 C   sN   t |  | jdddd | jdddd | jdddd | jd	d
dd d S )Nzxpath.deletexpath_deleteTr  	xpath.set	xpath_setzxpath.createxpath_createzxpath.valuexpath_valuer*  rB  r1  r3  r   r   r   r  :  s
   
zParserXML._virtcli_class_initc                    s2   | j ds| j  | j | jd< t | d S )Nzxpath.ru  )r  r(  r  rE  r  r[  r   r  r(  r   r   r[  B  s   
zParserXML._parse)
r)   r*   r+   r=   r  r.  ro  r  r[  r)  r   r   r(  r   r  2  s    
r  c                 C   s4   |j D ]}| j }t|| | j| qdS )zg
    Parse --xml option string into XMLManualAction instances and append
    to guest.xml_actions.
    N)rr  xml_actionsrc  r  ri  r   )r   r`  r  r  r   r   r   parse_xmlcliJ  s
   

r|  c                    s`   dd } fdd}|dddd|d	 |d
ddd|d	 |dddd|d	 |dddd|d	 dS )z;
    Add xpath.* subarguments to XML based CLI options
    c                 _   "   d}d}|  ||}||i |S )Nr5  r{  rQ  r   r4   r5   rO  rP  r  r   r   r   find_xpath_cbY  s   z&_add_xpath_args.<locals>.find_xpath_cbc                        d|d<  j | i | d S NTr-  r1  r3  r3  r   r   _add_arg`     z!_add_xpath_args.<locals>._add_argzxpath[0-9]*.deleters  TN)r  r  r  zxpath[0-9]*.setrv  zxpath[0-9]*.createrw  zxpath[0-9]*.valuerx  r   )r#  r  r  r   r3  r   r@  U  s   
r@  c                   @       e Zd ZdZdZedd ZdS )r  
unattendedFc                 C   sV   t |  | dd | dd | dd | dd | dd	 | d
d d S )Nprofilezadmin-password-fileadmin_password_filez
user-login
user_loginzuser-password-fileuser_password_filezproduct-keyproduct_keyz	reg-login	reg_loginry  r3  r   r   r   r  v     
z$ParserUnattended._virtcli_class_initN)r)   r*   r+   r  r.  ro  r  r   r   r   r   r  r  
    r  c                 C   s,   t  }| dkr	|S t| }||r|S d S r   )r   r  ri  r  r  rI   r   r   r   parse_unattended  s   
r  c                 C   s   | j r| js	d| _| ` d S d S )Nzall=off)forcecheck)r`  r   r   r   convert_old_force  s
   r  c                   @   s(   e Zd ZdZdZedd Zdd ZdS )r	  r  Fc                 C   sv   t |  | jdd d| jd d | jdd d| jd d | jdd d| jd d | jdd d| jd d | jdddd	 d S )
Nr   T)r  r  r  r   r   r   r[  r   r  )r*  rB  r1  set_cbr3  r   r   r   r    s   




zParserCheck._virtcli_class_initc                 C   s   | |j| d S r!   )r$   r  rF  r   r   r   r    r4  zParserCheck.set_cbN)r)   r*   r+   r  r.  ro  r  r  r   r   r   r   r	    s    
r	  c                 C   s(   t | D ]}t|}|t  qd S r!   )r   r  r	  ri  r-   )checksr  rI   r   r   r   parse_check  s   r  c                   @   $   e Zd ZdZdZdZedd ZdS )r  installra   Fc                 C   sz   t |  | jdddd | jdddd | jdddd | jdddd | jdddd | d	d	 | jd
d
dd d S )NbootdevTrt  kernelinitrdkernel_argskernel_args_overwriter  ra   
no_installry  r3  r   r   r   r    s   
z!ParserInstall._virtcli_class_initNr)   r*   r+   r  r  r.  ro  r  r   r   r   r   r        r  c                   @      e Zd Zdd ZdS )InstallDatac                 C   s4   d | _ d | _d | _d | _d | _d | _d| _d | _d S r   )r  r  r  r  r  ra   is_setr  r   r   r   r   r      s   
zInstallData.__init__Nr)   r*   r+   r    r   r   r   r   r        r  c                 C   s*   t  }t| |_t| pd }|| |S r!   )r  r   r  r  ri  )r  installdatarI   r   r   r   parse_install  s
   

r  c                   @   s(   e Zd ZdZdZddiZedd ZdS )r  
cloud_initFroot-ssh-keyzssh-keyc                 C   sv   t |  | jdddd | dd | jdddd | dd	 | d
d | dd | dd | dd d S )Nzroot-password-generateroot_password_generateTr  zroot-password-fileroot_password_filedisabler  root_ssh_keyzclouduser-ssh-keyclouduser_ssh_keyz	user-data	user_dataz	meta-data	meta_dataznetwork-confignetwork_configry  r3  r   r   r   r    s   
z#ParserCloudInit._virtcli_class_initN)r)   r*   r+   r  r.  r  ro  r  r   r   r   r   r    s    r  c                 C   sB   t  }| dkrtd d|_d|_|S t| }||r|S d S )Nr   zADefaulting to --cloud-init root-password-generate=yes,disable=yesT)r   r   rj   r  r  r  ri  r  r   r   r   parse_cloud_init  s   

r  c                   @   $   e Zd ZdZdZdZedd ZdS )r
  locationFc                 C   s>   t |  | jdddd | jdddd | jdddd d S )Nr  Trt  r  r  ry  r3  r   r   r   r    s   
z"ParserLocation._virtcli_class_initNr  r   r   r   r   r
    r  r
  c                 C   s:   G dd d}| }t | pd }|| |j|j|jfS )Nc                   @   r  )z$parse_location.<locals>.LocationDatac                 S   s   d | _ d | _d | _d S r!   )r  r  r  r   r   r   r   r      s   
z-parse_location.<locals>.LocationData.__init__Nr  r   r   r   r   LocationData  r  r  )r
  ri  r  r  r  )r  r  	parsedatarI   r   r   r   parse_location  s
   
r  c                   @   sD   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dS )OSVariantDatac                 C   s   d | _ d | _d| _d| _d S r   )_name_id_detect_requirer   r   r   r   r    '  s   
zOSVariantData.__init__c                 C   sN   |d u s|dkrd| _ d| _d S |dkrd| _d S d|v r"|| _d S || _d S )NautoTrU  genericz://)r  r  r  r  )r   rawstrr   r   r   set_compat_str-  s   


zOSVariantData.set_compat_strc                 C   sF   d }| j rtj| j dd}n| jrtj| jdd}|r!|j| _d S d S NT)raise_error)r  r   lookup_os_by_full_idr  	lookup_osr   )r   osobjr   r   r   r\  ;  s   zOSVariantData.validatec                 C      | j S r!   )r  r   r   r   r   	is_detectD  r5  zOSVariantData.is_detectc                 C   s   |    o	t| jS r!   )is_require_defaultr   r  r   r   r   r   is_require_onF  s   zOSVariantData.is_require_onc                 C   
   | j dkS Nr  )r  r   r   r   r   r  H     
z OSVariantData.is_require_defaultc                 C   r  r!   )r  r   r   r   r   get_nameJ  r5  zOSVariantData.get_nameN)
r)   r*   r+   r    r  r\  r  r  r  r  r   r   r   r   r  &  s    	r  c                       s0   e Zd ZdZdZedd Z fddZ  ZS )r  
os_variantFc                 C   sR   t |  | dd | dd | dd | jdddd	 | jd
ddd	 d S )Nr   r  zshort-ididr  detectr  Tr  requirer  ry  r3  r   r   r   r  R  s   
z#ParserOSVariant._virtcli_class_initc                    s*   dt | jvr|| j d S t |S )Nr  )r   r  r  r  ri  rz  r(  r   r   ri  [  s   zParserOSVariant.parse)	r)   r*   r+   r  r.  ro  r  ri  r)  r   r   r(  r   r  N  s    
r  c                 C   s$   t  }t| }|| |  |S r!   )r  r  ri  r\  )r  datarI   r   r   r   parse_os_variantb  s
   
r  c                 C   s   |  rtd dS | jj}|sdS |d j}|dtjtjfvr)t	d| dS t
s8t s8ttd dS tjdd	sLt sLttd
 dS dS )zo
    Determine the default console for the passed guest config

    :returns: 'text', 'graphical', or None
    z8--cloud-init specified, defaulting to --autoconsole textr<   r   r   z*No viewer to launch for graphics type '%s'NzlUnable to connect to graphical console: virt-viewer not installed. Please install the 'virt-viewer' package.DISPLAYrS   zCGraphics requested but DISPLAY is not set. Not running virt-viewer.	graphical)has_cloudinitr   r   devicesgraphicsrq  r	   TYPE_VNC
TYPE_SPICErT   HAS_VIRTVIEWERr   rc   rj   rE   ra   r7  r'   )r   	installergdevsgtyper   r   r   #_determine_default_autoconsole_typen  s,   

r  c                   @   s<   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd ZdS )_AutoconsoleDatac                 C   sP   || _ | j dvrttd| j   | j dk| _| jr&t||}|p"d| _ d S d S )N)rU  r   r<   r  zUnknown autoconsole type '%s'r   rU  )_autoconsoler   rE   _is_defaultr  )r   rS  r   r  r   r   r   r   r      s   

z_AutoconsoleData.__init__c                 C   r  )Nr<   r  r   r   r   r   is_text  r  z_AutoconsoleData.is_textc                 C   r  )Nr  r  r   r   r   r   is_graphical  r  z_AutoconsoleData.is_graphicalc                 C   r  r!   )r  r   r   r   r   
is_default  r5  z_AutoconsoleData.is_defaultc                 C   s   t |  S r!   )r   get_console_cbr   r   r   r   has_console_cb  r  z_AutoconsoleData.has_console_cbc                 C   s   |   rtS |  rtS d S r!   )r  r   r  r   r   r   r   r   r    s
   z_AutoconsoleData.get_console_cbN)	r)   r*   r+   r    r  r  r  r  r  r   r   r   r   r    s    
r  c                 C   s   t | j||S r!   )r  rS  )r`  r   r  r   r   r   parse_autoconsole  r%   r  c                   @   s,   e Zd ZdZedd Zdd Zdd ZdS )	rk  metadatac                 C   s   t |  | jdddd | jdddd | dd | dd | jdddd | jd	d	dd | jd
d d | jd | jdd d | jd d S )Nr   Trt  titleuuidgenidgenid_enabler  r@   os_namer  r  
os_full_id)r*  rB  r1  set_os_name_cbset_os_full_id_cbr3  r   r   r   r    s   



z"ParserMetadata._virtcli_class_initc                 C      | | d S r!   )set_os_namerF  r   r   r   r    r%   zParserMetadata.set_os_name_cbc                 C   s   t j|dd}||j d S r  )r   r  r  r   )r   r  r#   r"  r  r   r   r   r    s   z ParserMetadata.set_os_full_id_cbN)r)   r*   r+   r  ro  r  r  r  r   r   r   r   rk    s    
rk  c                   @   s   e Zd ZdZedd ZdS )r  eventsc                 C   >   t |  | dd | dd | dd | dd d S )Non_poweroff	on_rebooton_crashon_lockfailurery  r3  r   r   r   r    
   
z ParserEvents._virtcli_class_initN)r)   r*   r+   r  ro  r  r   r   r   r   r    s    r  c                   @   r  )r  resource	partitionc                 C   s*   t |  | dd | jdddd d S )Nr   zfibrechannel.appidfibrechannel_appidTrt  ry  r3  r   r   r   r    s   
z"ParserResource._virtcli_class_initNr)   r*   r+   r  r:  r  ro  r  r   r   r   r   r    r  r  c                   @   s6   e Zd ZdZdZdZdddZdd Zedd Z	d	S )
r  numatunenodesetmode)memory.modememory.nodesetc                 O   "   d}d}|  ||}||i |S )Nmemnoder~  r  r   r   r   memnode_find_inst_cb     z#ParserNumatune.memnode_find_inst_cbc                 C   sp   t |  | jdddd | dd | dd | jd	d
d| jd | jdd| jd | jddd| jd d S )Nr  memory_nodesetTrt  r  memory_modezmemory.placementmemory_placementzmemnode[0-9]*.cellidcellidr  r  zmemnode[0-9]*.moder  r  zmemnode[0-9]*.nodesetr  )r*  rB  r1  r
  r3  r   r   r   r    s   



z"ParserNumatune._virtcli_class_initN)
r)   r*   r+   r  r:  r  r  r
  ro  r  r   r   r   r   r    s    r  c                       sJ   e Zd ZdZdZdddZdd Z fddZd	d
 Ze	dd Z
  ZS )rr  memoryhotplugmemoryslotshotplugmemorymax)maxMemory.slots	maxMemoryc                 C   s   d| j v }d| j v }d| j v }|r!|r| j dd| j d< dS dS |r9|r.| j d| j d< | j d| j d< dS |rF| j d| j d< dS dS )a  
        Historically the cli had:
            memory -> ./currentMemory
            maxmemory -> ./memory
        Then later libvirt gained ./maxMemory. So things are quite a mess.

        Try to convert the back compat cases. Basically if new style option
        currentMemory is specified, interpret currentMemory and memory as
        the XML values. Otherwise treat memory and maxmemory as the old
        swapped names.
        currentMemory	maxmemoryr  Nr  r  )r   havecurhavemaxhavememr   r   r   _convert_old_memory_options  s   


z(ParserMemory._convert_old_memory_optionsc                       |    t |S r!   )r  r  r[  rz  r(  r   r   r[  6  r  zParserMemory._parsec                 C      t ||jt|d  d S Ni   r   r  r  r   rF  r   r   r   set_memory_cb?     zParserMemory.set_memory_cbc                 C   sj   | j dd| jd | j dd| jd | j dd| jd |  dd | j dd d | jd | j d	d
dd d S )Nr  r  r  r  r  maxMemorySlotsr  r  	hugepageszmemoryBacking.hugepagesTr  )r1  r"  rn  r3  r   r   r   r  B  s   z ParserMemory._virtcli_class_init)r)   r*   r+   r  r  r  r  r[  r"  ro  r  r)  r   r   r(  r   rr    s    	rr  c                   @   r  )r  memtune
soft_limitc                 C   r  )N
hard_limitr(  swap_hard_limitmin_guaranteery  r3  r   r   r   r  Y  r  z!ParserMemtune._virtcli_class_initNr  r   r   r   r   r  T  r  r  c                   @   s>   e Zd ZdZdZdZddddddd	Zd
d Zedd Z	dS )r  	blkiotuneweightdevice_pathdevice_weightread_bytes_secwrite_bytes_secread_iops_secwrite_iops_sec)device[0-9]*.pathdevice[0-9]*.weightdevice[0-9]*.read_bytes_secdevice[0-9]*.write_bytes_secdevice[0-9]*.read_iops_secdevice[0-9]*.write_iops_secc                 O   r}  )Ndevicer  r~  r  r   r   r   device_find_inst_cbs  r  z#ParserBlkiotune.device_find_inst_cbc                 C   s   t |  | dd | jdd| jd | jdd| jd | jdd| jd | jdd	| jd | jd
d| jd | jdd| jd d S )Nr-  r4  rb   r  r5  r6  r0  r7  r1  r8  r2  r9  r3  )r*  rB  r1  r;  r3  r   r   r   r  y  s(   

z#ParserBlkiotune._virtcli_class_initN)
r)   r*   r+   r  r:  r  r  r;  ro  r  r   r   r   r   r  f  s    	r  c                   @   s8   e Zd ZdZdZddddddZd	d
 Zedd ZdS )r  memorybackingmemoryBackingsizeunitr  access_modesource_type)hugepages.page[0-9]*.sizehugepages.page[0-9]*.unithugepages.page[0-9]*.nodesetaccess.modesource.typec                 O   r}  )Npagepagesr~  r  r   r   r   page_find_inst_cb  r  z%ParserMemoryBacking.page_find_inst_cbc                 C   s   t |  | jdddd | jdd| jd | jdd| jd | jd	d
d| jd | jdddd | jdddd | dd | dd | jdddd | dd d S )Nr&  Tr  rB  r>  r  rC  r?  rD  r  r  nosharepageslockedrE  r@  rF  rA  discardzallocation.modeallocation_mode)r*  rB  r1  rI  r3  r   r   r   r    s"   

z'ParserMemoryBacking._virtcli_class_initN)	r)   r*   r+   r  r:  r  rI  ro  r  r   r   r   r   r    s    r  c                       s   e Zd ZdZdZdZdZdddddd	Zd
d Z fddZ	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zedd Z  ZS )rv  cpumodelFz%cell[0-9]*.distances.sibling[0-9]*.idz(cell[0-9]*.distances.sibling[0-9]*.valuezcell[0-9]*.idzcell[0-9]*.cpuszcell[0-9]*.memory)*numa.cell[0-9]*.distances.sibling[0-9]*.id-numa.cell[0-9]*.distances.sibling[0-9]*.valuenuma.cell[0-9]*.idnuma.cell[0-9]*.cpusnuma.cell[0-9]*.memoryc                 C   s   t t}t| jD ]\}}|dv r|| | q
t| j D ]/\}}d }|s/t|dkr0q!|	dr8d}n|	dr?d}|rP| j|= || |dd   q!| j
| d S )N)r  r  optionalr  forbidr   +r  r2  r  )r  defaultdictr
  r  r  r   r  itemsr9   r(  update)r   	convertedr  valuepolicyr   r   r   _convert_old_feature_options  s$   


z&ParserCPU._convert_old_feature_optionsc                    r  r!   )r^  r  r[  rz  r(  r   r   r[    r  zParserCPU._parsec                 O   r}  )Ncellcellsr~  r  r   r   r   cell_find_inst_cb  r  zParserCPU.cell_find_inst_cbc                 O   F   | j |g|R i |}|}d}d}| ||}||g|R i |S )Nsiblingsiblingsra  rQ  r   r  r4   r5   r_  rO  rP  r  r   r   r   cell_sibling_find_inst_cb     z#ParserCPU.cell_sibling_find_inst_cbc                 O   rb  Ncachecachesre  rf  r   r   r   cell_cache_find_inst_cb  rh  z!ParserCPU.cell_cache_find_inst_cbc                 O   r}  )Nlatency	latenciesr~  r  r   r   r   latency_find_inst_cb	  r  zParserCPU.latency_find_inst_cbc                 O   r}  )N	bandwidth
bandwidthsr~  r  r   r   r   bandwidth_find_inst_cb	  r  z ParserCPU.bandwidth_find_inst_cbc                 C   sJ   |dkr|j }|dkr|j}||jv r|| j| d S || j| d S )NhostrU  )SPECIAL_MODE_HOST_MODELSPECIAL_MODE_CLEARSPECIAL_MODESset_special_moder   	set_modelrF  r   r   r   set_model_cb	  s   
zParserCPU.set_model_cbc                 C   sT   |j }t|D ]}d }|jD ]}|j|kr|} nq|r!||_q||| qd S r!   )r  r   r  featuresr   r]  add_feature)r   r  r#   r"  r]  feature_name
featureobjr  r   r   r   set_feature_cb$	  s   

zParserCPU.set_feature_cbc                 C   s  t |  | jdddd | jdd| jd | dd | dd	 | d
d
 | dd | dd | dd | jdddd | dd | dd | dd | dd | dd | dd | jdd d | jd | jdd d | jd | jdd d | jd | jdd d | jd | jdd d | jd | jdd| jd | jddd| jd  | jd!d"| jd | jd#d$| jd | jd%d&| jd | jd'd(| jdd) | jd*d| jd | jd+d,| jd | jd-d.| jd | jd/d0| jd | jd1d2| jd | jd3d4| jd | jd5d6| jd | jd7d8| jd | jd9d:| jd | jd;d<| jd | jd=d>| jd | jd?d@| jd | jdAdB| jd | jdCd,| jd | jdDd$| jd | jdEd<| j	d | jdFd>| j	d | jdGdB| j	d | jdHd@| j	d | jdId,| j	d | jdJd$| j	d d S )KNsecureTr  rO  r$  zmodel.fallbackmodel_fallbackzmodel.vendor_idmodel_vendor_idvendorr  r   r  
migratableztopology.socketsztopology.diesztopology.coresztopology.threadszcache.levelz
cache.moder  r  r  rU  r  rV  rR  r  r  rS  cpusr  rT  r  znuma.cell[0-9]*.unitr?  znuma.cell[0-9]*.memAccess	memAccessznuma.cell[0-9]*.discardrL  r  r  rP  rQ  r\  z!numa.cell[0-9]*.cache[0-9]*.levelrK   z)numa.cell[0-9]*.cache[0-9]*.associativityassociativityz"numa.cell[0-9]*.cache[0-9]*.policyr]  z&numa.cell[0-9]*.cache[0-9]*.size.value
size_valuez%numa.cell[0-9]*.cache[0-9]*.size.unit	size_unitz&numa.cell[0-9]*.cache[0-9]*.line.value
line_valuez%numa.cell[0-9]*.cache[0-9]*.line.unit	line_unitz*numa.interconnects.latency[0-9]*.initiator	initiatorz'numa.interconnects.latency[0-9]*.targettargetz&numa.interconnects.latency[0-9]*.cacherj  z%numa.interconnects.latency[0-9]*.typerq  z&numa.interconnects.latency[0-9]*.valuez%numa.interconnects.latency[0-9]*.unitz,numa.interconnects.bandwidth[0-9]*.initiatorz)numa.interconnects.bandwidth[0-9]*.targetz'numa.interconnects.bandwidth[0-9]*.typez(numa.interconnects.bandwidth[0-9]*.cachez(numa.interconnects.bandwidth[0-9]*.valuez'numa.interconnects.bandwidth[0-9]*.unit)
r*  rB  r1  ry  r~  ra  rg  rl  ro  rr  r3  r   r   r   r  3	  s   


zParserCPU._virtcli_class_init)r)   r*   r+   r  r:  r  rb  r  r^  r[  ra  rg  rl  ro  rr  ry  r~  ro  r  r)  r   r   r(  r   rv    s,    			rv  c                   @   sp   e Zd ZdZdZdZdZdd Zdd Zdd	 Z	d
d Z
dd Zdd Zdd Zdd Zdd Zedd ZdS )r  cputunerO  Fc                 O   r}  )Nvcpupinvcpupinsr~  r  r   r   r   vcpupin_find_inst_cb	  r  z"ParserCputune.vcpupin_find_inst_cbc                 O   r}  )Niothreadpiniothreadpinsr~  r  r   r   r   iothreadpin_find_inst_cb	  r  z&ParserCputune.iothreadpin_find_inst_cbc                 O   r}  )N	vcpusched
vcpuschedsr~  r  r   r   r   vcpusched_find_inst_cb	  r  z$ParserCputune.vcpusched_find_inst_cbc                 O   r}  )Niothreadschediothreadschedsr~  r  r   r   r   iothreadsched_find_inst_cb	  r  z(ParserCputune.iothreadsched_find_inst_cbc                 O   r}  )N	cachetune
cachetunesr~  r  r   r   r   cachetune_find_inst_cb	  r  z$ParserCputune.cachetune_find_inst_cbc                 O   rb  ri  r  rQ  r   r  r4   r5   r  rO  rP  r  r   r   r   cache_find_inst_cb	  rh  z ParserCputune.cache_find_inst_cbc                 O   rb  )Nmonitormonitorsr  r  r   r   r   monitor_find_inst_cb	  rh  z"ParserCputune.monitor_find_inst_cbc                 O   r}  )N
memorytunememorytunesr~  r  r   r   r   memorytune_find_inst_cb	  r  z%ParserCputune.memorytune_find_inst_cbc                 O   rb  )Nnodenodes)r  rQ  )r   r  r4   r5   r  rO  rP  r  r   r   r   node_find_inst_cb	  rh  zParserCputune.node_find_inst_cbc                 C   s*  t |  | dd | dd | dd | dd | dd | dd | dd | dd | d	d	 | jd
d| jd | jddd| jd | jdddd | jdd| jd | jddd| jd | dd | dd | jddd| jd | jdd| jd | jdd | jd | jd!d"d| jd | jd#d| jd | jd$d | jd | jd%d| jdd& | jd'd(| jd | jd)d*| jd | jd+d,| jd | jd-d.| jd | jd/d0| jd | jd1d*| j	d | jd2d| j	dd& | jd3d| j
dd& | jd4d(| jd | jd5d6| jd d S )7Nsharesperiodquotaglobal_periodglobal_quotaemulator_periodemulator_quotaiothread_periodiothread_quotazvcpupin[0-9]*.vcpuvcpur  zvcpupin[0-9]*.cpusetcpusetTr  zemulatorpin.cpusetemulatorpin_cpusetrt  ziothreadpin[0-9]*.iothreadiothreadziothreadpin[0-9]*.cpusetzemulatorsched.scheduleremulatorsched_schedulerzemulatorsched.priorityemulatorsched_priorityzvcpusched[0-9]*.vcpusvcpuszvcpusched[0-9]*.scheduler	schedulerzvcpusched[0-9]*.prioritypriorityziothreadsched[0-9]*.iothreads	iothreadsziothreadsched[0-9]*.schedulerziothreadsched[0-9]*.priorityzcachetune[0-9]*.vcpus)r  r  zcachetune[0-9]*.cache[0-9]*.idr  z!cachetune[0-9]*.cache[0-9]*.levelrK   z cachetune[0-9]*.cache[0-9]*.typerq  z cachetune[0-9]*.cache[0-9]*.sizer>  z cachetune[0-9]*.cache[0-9]*.unitr?  z#cachetune[0-9]*.monitor[0-9]*.levelz#cachetune[0-9]*.monitor[0-9]*.vcpuszmemorytune[0-9]*.vcpuszmemorytune[0-9]*.node[0-9]*.idz%memorytune[0-9]*.node[0-9]*.bandwidthrp  )r*  rB  r1  r  r  r  r  r  r  r  r  r  r3  r   r   r   r  	  s   





z!ParserCputune._virtcli_class_initN)r)   r*   r+   r  r:  r  rb  r  r  r  r  r  r  r  r  r  ro  r  r   r   r   r   r  	  s     			r  c                   @   s,   e Zd ZdZdZdZdd Zedd ZdS )r  r  c                 O   r}  )Nr  iothreadidsr~  r  r   r   r   iothreads_find_inst_cb#
  r  z&ParserIOThreads.iothreads_find_inst_cbc                 C   s,   t |  | dd | jdd| jd d S )Nr  ziothreadids.iothread[0-9]*.idr  r  )r*  rB  r1  r  r3  r   r   r   r  )
  s
   

z#ParserIOThreads._virtcli_class_initN)	r)   r*   r+   r  r:  r  r  ro  r  r   r   r   r   r  
      r  c                       sX   e Zd ZdZdZddiZdd Zdd Z fd	d
Zdd Z	dd Z
edd Z  ZS )rw  r  r  vcpu.placement	placementc                 C   st   d| j v }d| j v }d| j v }|r |r| j d| j d< d S d S |r8|r-| j d| j d< | j d| j d< d S d S )Nmaxvcpusvcpu.currentr  r  )r   r  r  havevcpr   r   r   _convert_old_vcpu_opts=
  s   


z!ParserVCPU._convert_old_vcpu_optsc                 C   @   d| j v r| j d| j d< d| j v r| j d| j d< d S d S )Nr  vcpu.cpusetr  r  r  r   r   r   r   _add_advertised_aliasesJ
  
   

z"ParserVCPU._add_advertised_aliasesc                    s   |    |   t |S r!   )r  r  r  r[  rz  r(  r   r   r[  S
  s   zParserVCPU._parsec                 O   r}  )Nr  zvcpulist.vcpur~  r  r   r   r   vcpu_find_inst_cb]
  r  zParserVCPU.vcpu_find_inst_cbc                 C   s   |dkr	||_ d S d|_d S r  )vcpu_cpusetvcpu_placementrF  r   r   r   set_cpuset_cbc
  s   
zParserVCPU.set_cpuset_cbc                 C   s   t |  | jdd| jd | jddd| jd | jdd| jd | dd	 | d
d | dd | dd | dd | dd | jddd| jd | dd | jdd| jd | jdd| jdd | jdd| jdd | jdd| jd d S ) Nr  r  r$  r  r  T)r  r  socketszcpu.topology.socketsdieszcpu.topology.diescoreszcpu.topology.coresthreadszcpu.topology.threadsr  r  vcpu_currentr  r  r  zvcpus.vcpu[0-9]*.idr  r  zvcpus.vcpu[0-9]*.enabledenabledr  zvcpus.vcpu[0-9]*.hotpluggablehotpluggablezvcpus.vcpu[0-9]*.orderorder)r*  rB  r1  rn  r  r  r3  r   r   r   r  n
  s4   

zParserVCPU._virtcli_class_init)r)   r*   r+   r  r  r  r  r  r[  r  r  ro  r  r)  r   r   r(  r   rw  6
  s    	
rw  c                
       s   e Zd ZdZdZdddddgdd	d
ddd	Zdd Z fddZdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zed(d) Z  ZS )*r  bootra   rebootTimeout	useserialmenu
extra_argsr  	loader_roloader_typeloader_securenvram_templatesmbios_mode)	bios.rebootTimeoutbios.useserialbootmenu.enablecmdlineloader.readonlyloader.typeloader.securenvram.templatesmbios.modec                 C   sP   g }t | j D ]}||jvrq	| j|= ||vr|| q	|r&||_d S d S r!   )r
  r  rR  BOOT_DEVICESr   	bootorder)r   r  
boot_orderr  r   r   r   _convert_boot_order
  s   


zParserBoot._convert_boot_orderc                    s*   |  | d| jv rd| jd< t |S )NuefiT)r  r  r  r[  rz  r(  r   r   r[  
  s   


zParserBoot._parsec                 C   s   |du r| j   d S d S r&   )r   refresh_machine_typerF  r   r   r   refresh_machine_type_cb
  s   z"ParserBoot.refresh_machine_type_cbc                 C   s    | j s	d| j_d S | j  d S r&   )rC  r   uefi_requestedenable_uefirF  r   r   r   set_uefi_cb
  s   zParserBoot.set_uefi_cbc                 C   r  r!   )set_initargs_stringrF  r   r   r   set_initargs_cb
  r%   zParserBoot.set_initargs_cbc                 C      || j _d S r!   )r   
bootloaderrF  r   r   r   set_bootloader_cb
  r  zParserBoot.set_bootloader_cbc                 C   r  r!   )r   bootloader_argsrF  r   r   r   set_bootloader_args_cb
  r  z!ParserBoot.set_bootloader_args_cbc                 C   r  r!   )r   rq  rF  r   r   r   set_domain_type_cb
  r  zParserBoot.set_domain_type_cbc                 C   r  r!   )r   emulatorrF  r   r   r   set_emulator_cb
  r  zParserBoot.set_emulator_cbc                 O   r}  )Nr  bootdevsr~  r  r   r   r   boot_find_inst_cb
  r  zParserBoot.boot_find_inst_cbc                 O   r}  )Ninitarginitargsr~  r  r   r   r   initarg_find_inst_cb
  r  zParserBoot.initarg_find_inst_cbc                 O   r}  )Ninitenvinitenvsr~  r  r   r   r   initenv_find_inst_cb
  r  zParserBoot.initenv_find_inst_cbc                 O   r}  )Nfeaturefirmware_featuresr~  r  r   r   r   feature_find_inst_cb
  r  zParserBoot.feature_find_inst_cbc                 C   s  t |  | jdd d | jd | jdd d | jd | jdd d | jd | jdd d | jd | jdd | jd dd | d	d	 | d
d
 | dd | jdd d | jd | jdd d | jd | jdd d | jd | jdd d | jd | jdd d | j	d | dd | jdddd | dd | jdddd | dd | jdd| j
dd | jdd| j
d | d d  | d!d" | jd#d$| jd | jd%d&dd | d'd( | jd)d*dd | d+d, | d-d. | d/d/ | d0d0 | jd1d2dd3 | d4d4 | d5d6 | d7d8 | d9d9 | jd:d:| jd; | jd<d=| jd | jd>d?| jd | jd@d| jd | dAdA | dBdB | dCdC d S )DNhdr  cdromfdnetworkzrefresh-machine-typeTr,  os_typearchmachiner  r  domain_typer  r  loaderr  r  r  r  r  r  r  firmwarezfirmware.feature[0-9]*.enabledr  r  zfirmware.feature[0-9]*.namer   r  nvramr  r  zboot[0-9]*.devr   r  bootmenu_enablezbootmenu.timeoutbootmenu_timeoutr  bios_useserialr  bios_rebootTimeoutr  r  r  r  r  r  rt  dtbz
acpi.tableacpi_tbzacpi.table.typeacpi_tb_typer'  r   r$  zinitarg[0-9]*r#   zinitenv[0-9]*r\  zinitenv[0-9]*.nameinitdirinituser	initgroup)r*  rB  r1  rn  r  r  r  r  r  r  r  r  r  r  r  r3  r   r   r   r  
  s   





zParserBoot._virtcli_class_init)r)   r*   r+   r  r:  r  r  r[  r  r  r  r  r  r  r  r  r  r  r  ro  r  r)  r   r   r(  r   r  
  s8    	r  c                   @   s2   e Zd ZdZdZdddddddZed	d
 ZdS )r  idmap	uid_start
uid_target	uid_count	gid_start
gid_target	gid_count)	uid.start
uid.target	uid.count	gid.start
gid.target	gid.countc                 C   sV   t |  | dd | dd | dd | dd | d	d
 | dd d S )Nr$  r  r%  r  r&  r   r'  r!  r(  r"  r)  r#  ry  r3  r   r   r   r  L  r  zParserIdmap._virtcli_class_initNr)   r*   r+   r  r:  r  ro  r  r   r   r   r   r  @  s    	r  c                   @   r  )r  seclabel	seclabelsc                 C   sV   t |  | dd | dd | jdddd | jdddd | jdddd d S )	Nrq  rO  relabelTr  labelrt  	baselabelry  r3  r   r   r   r  _  s   
z"ParserSeclabel._virtcli_class_initNr)   r*   r+   r  r:  ro  r  r   r   r   r   r  [  r  r  c                   @   s(   e Zd ZdZdZdd Zedd ZdS )r  keywrapc                 O   r  )Ncipherr~  r  r   r   r   cipher_find_inst_cbq  r  z!ParserKeyWrap.cipher_find_inst_cbc                 C   s6   t |  | jddd| jd | jddd| jd d S )Nzcipher[0-9]*.namer   Tr  zcipher[0-9]*.stater  )r*  rB  r1  r3  r3  r   r   r   r  w  s   



z!ParserKeyWrap._virtcli_class_initN)r)   r*   r+   r  r:  r3  ro  r  r   r   r   r   r  m  s    r  c                   @   s@   e Zd ZdZdZdddddddd	d
dddddZedd ZdS )r  rz  eoipmuvmport
kvm_hiddengic_versionsmm
vmcoreinfohyperv_resethyperv_vapichyperv_relaxedhyperv_spinlockshyperv_spinlocks_retrieshyperv_synic)apic.eoi	pmu.statevmport.statekvm.hidden.stategic.version	smm.statevmcoreinfo.statehyperv.reset.statehyperv.vapic.statehyperv.relaxed.statehyperv.spinlocks.statehyperv.spinlocks.retrieshyperv.synic.statec                 C   sr  t |  | jdddd | jdddd | jdddd | jdddd | jdddd | jdddd | jd	d
dd | jdddd | jdddd | jdddd | jdddd | jdddd | dd | jdddd | jdddd | jdddd | jdddd | jdd dd | jd!d"dd | d#d$ | jd%d&dd | jd'd(dd | d)d* d S )+NacpiTr  apicpaeprivnethapviridianrA  r4  rB  r5  rH  r;  rI  r<  rJ  r=  rK  r>  rL  r?  rM  r@  rC  r6  rD  r7  zkvm.hint-dedicated.statekvm_hint_dedicatedzkvm.poll-control.statekvm_poll_controlzpvspinlock.state
pvspinlockrE  r8  rF  r9  rG  r:  zioapic.driverioapic_driverry  r3  r   r   r   r    s0   
z"ParserFeatures._virtcli_class_initNr*  r   r   r   r   r    s&    r  c                       sH   e Zd ZdZdZdd Z fddZdd Zdd	 Ze	d
d Z
  ZS )r  clockc                 C   sv   d| j v r| j d d| j v r| j d d| j v r!| j d d| j v r,| j d d| j v r9| j d d S d S )Nplatform_tickpolicyhpet_tickpolicytsc_tickpolicykvmclock_tickpolicyhypervclock_tickpolicyr  r   r   r   r   _remove_old_options  s   




zParserClock._remove_old_optionsc                    r  r!   )r^  r  r[  rz  r(  r   r   r[    r  zParserClock._parsec                 C   sX   |j d\}}d }|jD ]}|j|kr|} nq|s#|j }||_t||| d S )NrE   )r  r  timersr   rI  r   r  )r   r  r#   r"  tnamer  timerobjr  r   r   r   	set_timer  s   


zParserClock.set_timerc                 O   r}  )Ntimerr_  r~  r  r   r   r   timer_find_inst_cb  r  zParserClock.timer_find_inst_cbc                 C   s  t |  | jdd d | jd | jdd d | jd | jdd d d| jd | jdd d d| jd | jdd d d| jd | jd	d d d| jd | jd
d d d| jd | jdd d d| jd | jdd d d| jd | dd | jdd| jd | jddd| jd | jdd| jd | jdd| jd | jdd| jd | jdd| jd | jdd| jd | jdd| jd | jd d!| jd d S )"Npit_tickpolicyr  rtc_tickpolicyplatform_presentT)r  r  r  pit_presentrtc_presenthpet_presenttsc_presentkvmclock_presenthypervclock_presentoffsetztimer[0-9]*.namer   r  ztimer[0-9]*.presentpresentr  r  ztimer[0-9]*.tickpolicy
tickpolicyztimer[0-9]*.tracktrackztimer[0-9]*.moder  ztimer[0-9]*.frequency	frequencyztimer[0-9]*.catchup.threshold	thresholdztimer[0-9]*.catchup.slewslewztimer[0-9]*.catchup.limitlimit)r*  rB  r1  rb  rd  r3  r   r   r   r    sp   




zParserClock._virtcli_class_init)r)   r*   r+   r  r:  r^  r[  rb  rd  ro  r  r)  r   r   r(  r   r    s    	r  c                   @   s*   e Zd ZdZdZdddZedd ZdS )r  pmsuspend_to_memsuspend_to_disk)suspend_to_mem.enabledsuspend_to_disk.enabledc                 C   s.   t |  | jdddd | jdddd d S )Nrz  rx  Tr  r{  ry  ry  r3  r   r   r   r  )  s   
zParserPM._virtcli_class_initNr*  r   r   r   r   r  !  s    r  c                       s   e Zd ZdZdZdZi ddddddd	d
dddddddddddddddddddddd d!d"d#d$Z fd%d&Zd'd( Zd)d* Z	d+d, Z
d-d. Zed/d0 Z  ZS )1r  sysinforq  bios.vendorbios_vendorbios.versionbios_version	bios.date	bios_datebios.releasebios_releasesystem.manufacturersystem_manufacturersystem.productsystem_productsystem.versionsystem_versionsystem.serialsystem_serialsystem.uuidsystem_uuid
system.sku
system_skusystem.familysystem_familybaseBoard.manufacturerbaseBoard_manufacturerbaseBoard.productbaseBoard_productbaseBoard.versionbaseBoard_versionbaseBoard.serialbaseBoard_serialbaseBoard.assetbaseBoard_assetbaseBoard.locationbaseBoard_locationc                    sT   | j rd| jvrd| jd< |s$| jd }| jjD ]}|j|kr#|} nqt |S )Nrq  smbios)r  r  r   r|  rq  r  ri  )r   r  rZ   r|  r(  r   r   ri  N  s   


zParserSysinfo.parsec                 C   s:   |dks|dkr|| j j_d S |dkrd| j j_||_d S )Nrs  emulater  r|  )r   ra   r  rq  rF  r   r   r   set_type_cbf  s   


zParserSysinfo.set_type_cbc                 C   s   ||_ || j_d S r!   )r  r   r  rF  r   r   r   set_uuid_cbo  s   zParserSysinfo.set_uuid_cbc                 O   r}  )Nentry
oemStringsr~  r  r   r   r   oem_find_inst_cbw     zParserSysinfo.oem_find_inst_cbc                 O   r}  )Nr  entriesr~  r  r   r   r   entry_find_inst_cb~  r  z ParserSysinfo.entry_find_inst_cbc                 C   s  t |  | jdd| jdd | dd | dd | dd	 | d
d | dd | dd | dd | dd | jdd| jd | dd | dd | dd | dd | dd  | d!d" | d#d$ | d%d& | d'd( | d)d* | d+d, | d-d. | d/d0 | jd1d2d| jd3 | jd4d2d| jd3 | jd5d6d| jd3 | jd7d8d| jd3 d S )9Nrq  T)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  r  r  r  r  r  r  zchassis.manufacturerchassis_manufacturerzchassis.versionchassis_versionzchassis.serialchassis_serialzchassis.assetchassis_assetzchassis.skuchassis_skuzoemStrings.entry[0-9]*r\  r  zentry[0-9]*zentry[0-9]*.namer   zentry[0-9]*.filer   )r*  rB  r1  r  r  r  r  r3  r   r   r   r    sH   





z!ParserSysinfo._virtcli_class_init)r)   r*   r+   r  r:  r  r  ri  r  r  r  r  ro  r  r)  r   r   r(  r   r  4  s\    	
	r  c                       s@   e Zd ZdZdZdd Zdd Z fddZed	d
 Z	  Z
S )r  qemu_commandline
xmlns_qemuc                 C   s$   t |D ]
}|j }||_qd S r!   )r   r  r4   rI  r\  )r   r  r#   r"  rH  r;  r   r   r   args_cb  s   
zParserQemuCLI.args_cbc                 C   s*   | dd\}}|j }||_||_d S )Nr  r   )r  envsrI  r   r\  )r   r  r#   r"  r   envvalr;  r   r   r   env_cb  s   

zParserQemuCLI.env_cbc                    s   | j   | jdr| jddd | j d< n,| jdr+| jddd | j d< n| jdr>| jddd | j d< n| j| j d< t |S )	Nzenv=r  r   envzargs=r4   z	clearxml=r+  )r  rE  r  r(  r  r  r[  rz  r(  r   r   r[    s   
zParserQemuCLI._parsec                 C   s:   t |  | jdd d | jdd | jdd d | jdd d S )Nr4   T)r  r  r  r  )r*  rB  r1  r  r  r3  r   r   r   r    s   



z!ParserQemuCLI._virtcli_class_init)r)   r*   r+   r  r:  r  r  r[  ro  r  r)  r   r   r(  r   r    s    r  c                    sN   fdd}|dd |dd |dd |dd |dddd	 |d
d
 |dd |dd |dd |dd |dd |dd |dd |dd |dd |dd |dd |dd |dd |dd dd }|r~d j d< |dd|d |r|d d  |r|d!d"dd	 |d#d$dd	 |d%d&dd	 |d'd(dd	 d)S d)S )*z6
    Add common Device parameters, like address.*
    c                     r  r  r  r3  r3  r   r   r    r  z)_add_common_device_args.<locals>._add_argzaddress.typezaddress.domainzaddress.buszaddress.slotzaddress.multifunctionTr  zaddress.functionzaddress.controllerzaddress.unitzaddress.portzaddress.targetzaddress.regzaddress.cssidzaddress.ssidzaddress.devnoaddress.iobasezaddress.irqzaddress.basezaddress.zpci.uidzaddress.zpci_uidzaddress.zpci.fidzaddress.zpci_fidz
alias.namec                 S   s   t |}| j|| d S r!   )r   r   reorder_boot_orderrF  r   r   r   set_boot_order_cb   s   z2_add_common_device_args.<locals>.set_boot_order_cbr  z
boot.orderr$  zboot.loadparmz
driver.atszvirtio_driver.atszdriver.iommuzvirtio_driver.iommuzdriver.packedzvirtio_driver.packedzdriver.page_per_vqzvirtio_driver.page_per_vqN)r  )r#  r  boot_loadparmvirtio_optionsr  r  r   r3  r   _add_common_device_args  sJ   





















r  rS   c                    sV   fdd} fdd}||d d|d ||d d	d
|d ||d dd
|d d S )Nc                    s   d}|  | }||i |S )Nr+  r~  )cr4   r5   rO  r  )rP  r   r   seclabel_find_inst_cb  s   z8_add_device_seclabel_args.<locals>.seclabel_find_inst_cbc                     r  r  r  r3  r3  r   r   r    r  z+_add_device_seclabel_args.<locals>._add_argsource.seclabel[0-9]*.modelrO  r  source.seclabel[0-9]*.relabelr-  Trp  source.seclabel[0-9]*.labelr.  r  r   )r#  rP  r  r  r  r   )r#  rP  r   _add_device_seclabel_args  s   



r  c                    s   dd }dd }dd } fdd}|d	d	 |d
d
|d |dd |dd|d |dd |dd|d |dd |dd |dd |dd t  dd |dd |dd |dddd dS )zm
    Add arguments that represent the CharSource object, which is shared
    among multiple device types
    c                 S      |j | d S r!   sourceset_friendly_hostr  r  r#   r"  r   r   r   set_sourcehost_cb,  r  z0_add_char_source_args.<locals>.set_sourcehost_cbc                 S   r  r!   )r  set_friendly_bindr  r   r   r   set_bind_cb/  r  z*_add_char_source_args.<locals>.set_bind_cbc                 S   r  r!   )r  set_friendly_connectr  r   r   r   set_connect_cb2  r  z-_add_char_source_args.<locals>.set_connect_cbc                    s*   d|d<  j |  |g|R i | d S r  r  )r  r  r4   r5   r#  r  r   r   r  5  s   "z'_add_char_source_args.<locals>._add_argsource.pathsource.hostr$  zsource.servicesource.bind_hostzsource.bind_servicezsource.connect_hostzsource.connect_servicesource.modezsource.masterzsource.slavezsource.seclabelsr  protocol.typesource.protocolzlog.filezsource.log_filez
log.appendzsource.log_appendTr  N)r  )r#  r  r  r  r  r  r   r  r   _add_char_source_args'  s$   








r  c                 C   s   | j  rdS dS )Nqcow2raw)supportconn_default_qcow2)r   r   r   r   _default_image_file_formatM  s   
r  c                 C   s&   t | }||_|jt jkrd S t| S r!   )r   pool	file_type	TYPE_FILEr  )r   poolobjtmpvolr   r   r   _get_default_image_formatS  s
   r  c                 C   s&   t |}t j| j|| jpd|| dS )Ndisk)suffixcollideguest)r   get_file_extension_for_formatfind_free_namer   r   )r   r  fmtextr   r   r   _generate_new_volume_name\  s
   
r  c                       s,  e Zd ZdZdZdZdZi ddddd	d
dddddddddddddddddddddd d!d"d#d$d%d&i d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHZdIdJ Z fdKdLZ	dMdN Z
dOdP ZdQdR ZedSdT Z  ZS )Ur  r  zdevices.diskrb   Fblockio.logical_block_sizelogical_block_sizeblockio.physical_block_sizephysical_block_sizeiotune.read_bytes_secr0  iotune.write_bytes_secr1  iotune.total_bytes_sectotal_bytes_seciotune.read_iops_secr2  iotune.write_iops_secr3  iotune.total_iops_sectotal_iops_secsource.poolsource_poolsource.volumesource_volumesource.namesource_namer  source_protocolsource.host[0-9]*.namesource_host_namesource.host[0-9]*.portsource_host_portsource.host[0-9]*.socketsource_host_socketsource.host[0-9]*.transportsource_host_transportsource.startupPolicystartup_policyr  zseclabel[0-9]*.modelr  zseclabel[0-9]*.relabelr  zseclabel[0-9]*.labelsource.reservations.managedzreservations.managedsource.reservations.source.typezreservations.source.typesource.reservations.source.pathzreservations.source.pathsource.reservations.source.modezreservations.source.modesnapshotsnapshot_policy
target.devr  target.removable	removabletarget.rotation_raterotation_ratedriver.discardrL  driver.detect_zeroesdetect_zeroesdriver.error_policyerror_policy	driver.ior=  driver.namedriver_namedriver.typedriver_typec                 C   r  )Nbus
target.busrj  driver.cacher  r   r   r   r   r    r  z"ParserDisk._add_advertised_aliasesc              
      s        jdkrd S dd } fdd} jdd } jdd } jdd } jd	d }| jd
d } jdd }	td jdd}
| jdd   jdd }|rx|ddkrjttd|d\}}t	
d|| |r}||_t | |r|s|s| r|j|jkrd}d }d }|r|dkrt jj}|r|j} jj|}t| |r||}||| d }|s| r|	s|s|
s|r|s| }tj| }|r|	st jj|}	|d u rt  j||	}t!j" jj||||
|	||d}|#| |S )NrU  c              
   S   sR   | d u rd S zt | W S  ty( } zttdt|  W Y d }~d S d }~ww )NzImproper value for 'size': %s)floatr;   r   rE   r   )r#   r}   r   r   r   
parse_size  s   
"z%ParserDisk._parse.<locals>.parse_sizec                    s^   | d u rd S | dkrd j d< d S | dkrd j d< d S | dkr"d S ttdd| d	  d S )
Nror  readonlysh	shareablerwz+Unknown '%(optionname)s' value '%(string)s'perms)
optionnamerW  )r  r   rE   )r#   r   r   r   convert_perms  s   
z(ParserDisk._parse.<locals>.convert_permsbacking_storebacking_formatr  volr>  rL   sparser  r#  rq  /r   z8Storage volume must be specified as vol=poolname/volnamez'Parsed --disk volume as: pool=%s vol=%sr   )r  r&  r'  )$r  r  r  r  r  countr   rE   r  r   rT   rq  r  r[  is_emptyr  r   build_default_poolr   r   r   storagePoolLookupByNameensure_pool_is_runningstorageVolLookupByNameset_vol_objectwants_storage_creationget_parent_poolra   rb   basenamer   r  r  r   build_vol_installset_vol_install)r   r  r  r%  r&  r'  poolnamevolnamer>  r  r)  disktype
newvolnamer  poolxml
vol_objectvol_installr(  r   r   r[    s   



zParserDisk._parsec                 C   r  r!   )set_source_pathrF  r   r   r   set_path_cb  r%   zParserDisk.set_path_cbc                 C   s   |  |kS r!   )r   rF  r   r   r   path_lookup_cb  r  zParserDisk.path_lookup_cbc                 O   r}  )Nhostszsource.hostsr~  r  r   r   r   host_find_inst_cb  r  zParserDisk.host_find_inst_cbc                 C   s  t |  t| dddd | jdd d | jd | jdd d | jd | jdd d | jd | jdd d | jd | jdd d | jd | jd	d d | jd | jd
d d | jd | jdd d | jd | jdd| jd | jdd| jd | dd | dd | dd | dd | dd | dd | dd | dd | dd | dd | jdddd | dd | dd | dd | d d  | jd!d"| jd# | jd$d%| jd# | jd&d'| jd# | jd(d)| jd# t| d* | jd+d | j| jd, | d-d- | d.d/ | d0d0 | d1d1 | d2d2 | d3d3 | jd4d5dd | jd6d6dd | jd7d7dd | jd8d9dd | d:d | jd;d<dd | d=d> | d?d@ | dAd | dBdC | dDdE | dFdG | dHdI | jdJdKdd | dLdM | dNdO | dPdQ | dRdS | dTdU | dVdW | dXdY | dZd[ | d\d] | d^d_ | d`da | dbdc | ddde | dfdg | dhdi | djdk | dldm | dndo | dpdq | drds d S )tNTr  r  r  r&  r  r'  r  r(  r>  rL   r)  rq  r  r$  rj  driver_cache
source.dirsource.file
source.devr  r  r  r  r  r  rF  zsource.namespacezsource.managedr  zsource.address.domainzsource.address.buszsource.address.slotzsource.address.functionr  r   r  r  portr  socketr   	transportr,  rb   r  r  r:  r  r	  sgiorawioserialwwnr  	read_onlyr!  	transientztransient.shareBackingtransient_shareBackingr  r  r  r
  r  r  r  r  r  driver_discardr  driver_detect_zeroesr  r  r  r  zdriver.copy_on_readdriver_copy_on_readr  	driver_iodriver.iothreaddriver_iothreaddriver.queuesdriver_queuesr  r  r  
iotune_rbsr  
iotune_wbsr  
iotune_tbsr  
iotune_risr  
iotune_wisr  
iotune_tisr  r  r  r  zgeometry.cylsgeometry_cylszgeometry.headsgeometry_headszgeometry.secsgeometry_secszgeometry.transgeometry_transr  reservations_managedr  reservations_source_typer  reservations_source_pathr  reservations_source_mode)	r*  rB  r  r1  rn  rB  r  r?  r@  r3  r   r   r   r    s   

zParserDisk._virtcli_class_init)r)   r*   r+   r  r:  r  rb  r  r  r[  r?  r@  rB  ro  r  r)  r   r   r(  r   r  c  s    	 "#$%&'*	br  c                       s   e Zd ZdZdZdZdZi ddddd	d
dddddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*Zd+d, Z fd-d.Z	d/d0 Z
d1d2 Zd3d4 Zed5d6 Z  ZS )7r  r  zdevices.interfacerq  Fr  r  rY  rZ  filterref.filter	filterref
link.state
link_statemac.addressmac
model.typerO  rom.filerom_filerom.barrom_barr
  r  source.portgroup	portgrouprF  rA  r  source_pathr  source_modevirtualport.typevirtualport_type virtualport.parameters.manageridvirtualport_manageridvirtualport.parameters.typeidvirtualport_typeid$virtualport.parameters.typeidversionvirtualport_typeidversionvirtualport_instanceidvirtualport_profileidvirtualport_interfaceid)!virtualport.parameters.instanceid virtualport.parameters.profileid"virtualport.parameters.interfaceidc                 C   s   d| j v r| j d| j d< d| j v r| j d| j d< d| j vrOd| j v r7tj| j d< | j d| j d< d S d| j v rMtj| j d< | j d| j d< d S d S | j dd  | j dd  d S )	NrO  ro  rn  rm  rq  r  r  bridge)r  r  r   TYPE_VIRTUALTYPE_BRIDGEr   r   r   r   r    s   




z%ParserNetwork._add_advertised_aliasesc                    s"   |    | jdkrd S t |S )NrU  )r  r  r  r[  rz  r(  r   r   r[    s   
zParserNetwork._parsec                 C   s   |dkrd S ||_ |S )NRANDOM)r   rF  r   r   r   
set_mac_cb  s   zParserNetwork.set_mac_cbc                 C   s   |dkr
|   d S ||_d S Nr   )set_default_sourcerq  rF  r   r   r   r    s   
zParserNetwork.set_type_cbc                 C   sB   |}|dv r||_ d S t|}|du rd}n|du rd}||_ d S )N)updownTr  Fr  )rl  r  )r   r  r#   r"  rK  r  r   r   r   set_link_state  s   
zParserNetwork.set_link_statec                 C   s  t |  t| dddd | jdd| jd | jdd| jd | jdd| jd | jd	d| jd | jd
d
| jd | jdddd | dd | dd | dd | dd | dd | dd | dd | jdd| jd | dd | jdd| jd | dd | dd  | d!d" | jd#d$dd | d%d& | d'd' | d(d) | d*d+ | d,d- | d.d/ | d0d1 | d2d3 d S )4NTrC  rO  r$  rn  r   r  r  r  rq  trustGuestRxFiltersr  r  rw  rF  rA  r  rv  rt  ru  r
  
target_devro  rm  ri  rj  rk  rl  r  r  rY  rZ  rp  rq  rr  rs  zmtu.sizemtu_sizerx  rz  zvirtualport.manageridr|  zvirtualport.typeidr~  zvirtualport.typeidversionr  zvirtualport.instanceidr  zvirtualport.profileidr  zvirtualport.interfaceid)r*  rB  r  r1  rn  r  r  r  r3  r   r   r   r    s\   
z!ParserNetwork._virtcli_class_init)r)   r*   r+   r  r:  r  rb  r  r  r[  r  r  r  ro  r  r)  r   r   r(  r   r  t  sf    	r  c                       sj   e Zd ZdZdZdZdZddddd	d
ddddd
Z fddZdd Z	dd Z
dd Zedd Z  ZS )r{  r  zdevices.graphicsrq  FtlsportpasswdpasswdValidToimage_compressionstreaming_modeclipboard_copypastefiletransfer_enable
mouse_modegl
rendernode)
tlsPortpasswordpasswordValidToimage.compressionstreaming.modeclipboard.copypastefiletransfer.enable
mouse.mode	gl.enablegl.rendernodec                    "   | j dkrd| j_d S t |S NrU  T)r  r   skip_default_graphicsr  r[  rz  r(  r   r   r[    s   
zParserGraphics._parsec                 C   s@   |sd }n|  dkrtd d }n|  dkrd }||_d S )Nlocalz2keymap=local is no longer implemented. Using None.rU  )r  r   rT   keymaprF  r   r   r   set_keymap_cb"  s   

zParserGraphics.set_keymap_cbc                 C   s   |dkrd S ||_ d S r  )rq  rF  r   r   r   r  ,  s   
zParserGraphics.set_type_cbc                 O   r  )Nlistensr~  r  r   r   r   listens_find_inst_cb1  r  z#ParserGraphics.listens_find_inst_cbc                 C   sN  t |  t|  | jdd| jd | dd | dd | dd | dd | jdd| jd | dd	 | d
d | dd | dd | jdd| jd | jdd| jd | jdd| jd | jdd| jd | dd | dd | jdddd | dd | jd d!dd | d"d# | jd$d%dd | d&d' d S )(Nrq  r$  rH  r  	websocketlistenr  r  r  r  r  	connecteddefaultModezlistens[0-9]*.typer  zlistens[0-9]*.addressaddresszlistens[0-9]*.networkr  zlistens[0-9]*.socketrI  r  r  r  r  r  r  Tr  r  r  r  r  zzlib.compressionzlib_compressionr  r  r  r  )r*  rB  r  r1  r  r  r  r3  r   r   r   r  7  sH   
z"ParserGraphics._virtcli_class_init)r)   r*   r+   r  r:  r  rb  r  r[  r  r  r  ro  r  r)  r   r   r(  r   r{    s,    
r{  c                       sF   e Zd ZdZdZdZdddZ fddZd	d
 Ze	dd Z
  ZS )r  
controllerzdevices.controllerrq  masterrZ  )master.startportrY  c                    s^   | j dkrt|jS | j dkrt|j| jS d| jv r)t| jd| j_	d S t
 |S )Nusb2usb3num_pcie_root_ports)r  r   get_usb2_controllersr   get_usb3_controllerr   r  r   r  r  r  r[  rz  r(  r   r   r[  j  s   



zParserController._parsec                 C   s   |}| ddv r=d|v r=|jj|j_|dd\}|j_|dd\}|j_d|j_d|v r;|dd\|j_|j_	d S t
td| )N:r   r7   r  r   r  z#Expected PCI format string for '%s')r+  r  ADDRESS_TYPE_PCIrq  r  functionr'  slotr   r  r   rE   )r   r  r#   r"  addrstrr   r   r   set_address_cb|  s   
zParserController.set_address_cbc                 C   s   t |  t| dd | dd | dd | dd | dd | dd | dd	 | d
d | dd | dd | dd | dd | dd | dd | dd | dd | jdd d | jd | jdd d | jd d S )NTr  rq  rO  indexmaxGrantFramesvectorsr  master_startportrW  rX  rY  rZ  ztarget.chassisNrtarget_chassisNrztarget.chassistarget_chassistarget.porttarget_portztarget.hotplugtarget_hotplugztarget.busNrtarget_busNrztarget.indextarget_indextarget.nodetarget_noder  r  r  )r*  rB  r  r1  r  rn  r3  r   r   r   r    s&   
z$ParserController._virtcli_class_init)r)   r*   r+   r  r:  r  r  r[  r  ro  r  r)  r   r   r(  r   r  a  s    r  c                   @   r  )r  r   zdevices.inputrq  c                 C   s   t |  t| dd | jdddd | jdddd | dd | dd | d	d
 | jdddd | dd | dd d S )NTr  rq  r  r  rO  zsource.evdevsource_evdevrG  
source_devzsource.repeatsource_repeatr  zsource.grabsource_grabzsource.grabTogglesource_grabToggler*  rB  r  r1  r3  r   r   r   r    s   
zParserInput._virtcli_class_initNr  r   r   r   r   r    r  r  c                   @   r  )r  iommuzdevices.iommurO  c                 C   sf   t |  | dd | dd | jdddd | jdd	dd | jd
ddd | jdddd d S )NrO  zdriver.aw_bitsaw_bitszdriver.intremapintremapTr  zdriver.caching_modecaching_modez
driver.eimeimzdriver.iotlbiotlbry  r3  r   r   r   r    s   
zParserIommu._virtcli_class_initNr  r   r   r   r   r    r  r  c                   @   s,   e Zd ZdZdZdZdd Zedd ZdS )	r  	smartcardzdevices.smartcardr  c                 O   r}  )Ncertificatecertificatesr~  r  r   r   r   certificate_find_inst_cb  r  z(ParserSmartcard.certificate_find_inst_cbc                 C   sb   t |  t|  | jdddd | jdddd t|  | jdddd | jddd| jd	 d S )
Nr  Tr  rq  databasert  zcertificate[0-9]*r\  r  )r*  rB  r  r1  r  r  r3  r   r   r   r    s   


z#ParserSmartcard._virtcli_class_initN)	r)   r*   r+   r  r:  r  r  ro  r  r   r   r   r   r    r  r  c                       s@   e Zd ZdZdZdZdZdd Z fddZe	d	d
 Z
  ZS )r  redirdevzdevices.redirdevr  Fc                 C   r  r!   r  rF  r   r   r   set_server_cb  r  zParserRedir.set_server_cbc                    r  r  )r  r   skip_default_usbredirr  r[  rz  r(  r   r   r[       
zParserRedir._parsec                 C   sV   t |  t| dd | jdddd | jdddd | jdd d | jd t|  d S )NTr  r  r  rq  serverr  )r*  rB  r  r1  r  r  r3  r   r   r   r    s   
zParserRedir._virtcli_class_init)r)   r*   r+   r  r:  r  rb  r  r[  ro  r  r)  r   r   r(  r   r    s    r  c                       sD   e Zd ZdZdZdZdZddddZ fdd	Ze	d
d Z
  ZS )r  tpmzdevices.tpmrq  FrC   rb   )backend.typebackend.versionbackend.device.pathc                    sd   | j dkrd| j_d S | jdddr| jd| jd< | jddkr,| jd t |S )NrU  Trq  rS   r*  rb   r   )	r  r   skip_default_tpmr  r'   r(  r  r  r[  rz  r(  r   r   r[    s   
zParserTPM._parsec                 C   s   t |  t|  | dd | dd | dd | dd | dd	 | jd
ddd | jdddd | jdddd | jdddd | jdddd d S )NrO  r  rq  r  rC   r  r.  zbackend.encryption.secretencryption_secretzbackend.persistent_statepersistent_stateTr  zactive_pcr_banks.sha1zactive_pcr_banks.sha256zactive_pcr_banks.sha384zactive_pcr_banks.sha512r  r3  r   r   r   r  -  s,   

zParserTPM._virtcli_class_init)r)   r*   r+   r  r:  r  rb  r  r[  ro  r  r)  r   r   r(  r   r    s    r  c                	       sV   e Zd ZdZdZdZdZddddd	d
dddZdd Z fddZ	e
dd Z  ZS )r  rngzdevices.rngbackend.modelFbackend_typebackend_modebackend_hostbackend_servicebackend_connect_hostbackend_connect_service
rate_bytesrate_period)r  zbackend.source.modezbackend.source.hostzbackend.source.servicezbackend.source.connect_hostzbackend.source.connect_service
rate.bytesrate.periodc                 C   r  )Nrq  r  r:  backendr  r   r   r   r   r  X  r  z!ParserRNG._add_advertised_aliasesc                    sZ   | j dkrd| j_d S |   | jdddr'| jd| jd< d| jd< t 	|S )NrU  Tr  rS   r*  r  random)
r  r   skip_default_rngr  r  r'   r(  r  r  r[  rz  r(  r   r   r[  a  s   

zParserRNG._parsec                 C   s   t |  t| dd | jdd| jd | jdd| jd | dd | dd | d	d | d
d t| dd | dd | dd d S )NTr  rq  backend_modelr$  r:  rO  r  r  r  r  zbackend.r  r  r  r  r  )r*  rB  r  r1  rn  r  r3  r   r   r   r  s  s   
zParserRNG._virtcli_class_init)r)   r*   r+   r  r:  r  rb  r  r  r[  ro  r  r)  r   r   r(  r   r  H  s$    	r  c                   @   r  )r  watchdogzdevices.watchdogrO  c                 C   s6   t |  t|  | jdddd | jdddd d S )NrO  Tr  rD   r  r3  r   r   r   r    s   
z"ParserWatchdog._virtcli_class_initNr  r   r   r   r   r    r  r  c                   @   s>   e Zd ZdZdZdZdddddd	d
Zdd Zedd Z	dS )r  memdevzdevices.memoryrO  target_sizer  target_label_sizesource_pagesizerv  source_nodemask)target.sizer  target.label_sizesource.pagesizer  source.nodemaskc                 C   r  r   r!  rF  r   r   r   set_target_size  r#  zParserMemdev.set_target_sizec                 C   s   t |  t|  | dd | dd | jdddd | dd | jdd| jd | d	d	 | jd
d
| jd | dd | dd | dd | jdddd | dd | dd | jdddd | jdddd | jdd| jd d S )NrO  rd   rL  Tr  r  r  r$  r  r  ztarget.blockztarget.currentztarget.requestedztarget.readonlyr	  r  r
  rt  zsource.pmemzsource.alignsize)r*  rB  r  r1  r  r3  r   r   r   r    s,   

z ParserMemdev._virtcli_class_initN)
r)   r*   r+   r  r:  r  r  r  ro  r  r   r   r   r   r    s    	r  c                   @   s(   e Zd ZdZdZdZdZedd ZdS )r  
memballoonzdevices.memballoonrO  Fc                 C   sV   t |  t| dd | jdddd | jdddd | dd | jd	d	dd d S )
NTr  rO  r  autodeflater  zstats.periodstats_periodfreePageReportingr  r3  r   r   r   r    s   
z$ParserMemballoon._virtcli_class_initN)	r)   r*   r+   r  r:  r  rb  ro  r  r   r   r   r   r    s    r  c                       s<   e Zd ZdZdZdZddiZ fddZedd	 Z	  Z
S )
r  paniczdevices.panicrO  r  iobasec                    sJ   t | jdkr| jdddr| jd | jd< tj| jd< t |S )Nr   rO  rS   0xr  )r9   r  r'   r(  r   	MODEL_ISAr  r[  rz  r(  r   r   r[    s   zParserPanic._parsec                 C   s&   t |  t|  | jdddd d S )NrO  Tr  r  r3  r   r   r   r    s   
zParserPanic._virtcli_class_init)r)   r*   r+   r  r:  r  r  r[  ro  r  r)  r   r   r(  r   r    s    	r  c                   @   r  )r  shmemzdevices.shmemr   c                 C   sv   t |  t|  | dd | dd | dd | dd | dd | dd	 | d
d | dd d S )Nr   rolero  rq  r>  z	size.unitr  zserver.pathserver_pathzmsi.vectorsmsi_vectorszmsi.ioeventfdmsi_ioeventfdr  r3  r   r   r   r    s   
zParserShMem._virtcli_class_initNr  r   r   r   r   r    r  r  c                   @   s2   e Zd ZdZdZdZdZdddZedd	 Z	d
S )r  vsockzdevices.vsockrO  Fauto_cidcid)cid.autocid.addressc                 C   sF   t |  t| dd | jdddd | jdddd | dd	 d S )
NTr  rO  r  r  r  r  r  r  r  r3  r   r   r   r  !  s
   
zParserVsock._virtcli_class_initN)
r)   r*   r+   r  r:  r  rb  r  ro  r  r   r   r   r   r    s    r  c                       sX   e Zd ZdZdZddddddZd	d
 Z fddZdd Zdd Z	e
dd Z  ZS )_ParserCharrq  F	char_typeprotocoltarget_addresstarget_typer   )rq  r  target.addresstarget.typetarget.namec                 C   s\   d| j v r| j d| j d< d| j v r| j d| j d< d| j v r,| j d| j d< d S d S )Nrb   r  r  r  	bind_hostr  r  r   r   r   r   r  ;  s   


z#_ParserChar._add_advertised_aliasesc                    sT   | j dkr|jdkrd| j_d S | j dkr |jdkr d| j_d S |   t |S )NrU  r   Tchannel)r  r  r   skip_default_consoleskip_default_channelr  r  r[  rz  r(  r   r   r[  F  s   z_ParserChar._parsec                 C   s<   d| j vr| j dd dkr|j| d S |j| d S )Nr  r  bind)r  r'   r  r  r  rF  r   r   r   set_host_cbV  s   
z_ParserChar.set_host_cbc                 C   r  r!   )set_friendly_targetrF  r   r   r   set_target_cb]  r%   z_ParserChar.set_target_cbc                 C   s   | j rd S t|  t|  t|  | dd | jdd| jd | jdd| jd | jdd| jd | jd	d
| jd t|  | jdd| j	d | dd | dd | dd | dd d S )Nrq  rb   r  r$  r  r  r&  r  rs  r  r#  r!  r$  r"  r%  target_namer  r  ztarget.model.nametarget_model_name)
r  r*  rB  r  r@  r1  rn  r+  r  r-  r3  r   r   r   r  `  s    
z_ParserChar._virtcli_class_init)r)   r*   r+   r  rb  r  r  r[  r+  r-  ro  r  r)  r   r   r(  r   r  /  s    	r  c                   @      e Zd ZdZdZdS )r  rN  zdevices.serialNr)   r*   r+   r  r:  r   r   r   r   r  }      r  c                   @   r0  )r  parallelzdevices.parallelNr1  r   r   r   r   r    r2  r  c                   @   r0  )r  r'  zdevices.channelNr1  r   r   r   r   r    r2  r  c                   @   r0  )r  r   zdevices.consoleNr1  r   r   r   r   r    r2  r  c                   @   s0   e Zd ZdZdZddgZddiZedd Zd	S )
r  
filesystemzdevices.filesystemr  r  
accessmoder  c                 C   s  t |  t| dd | dd | dd | dd | dd | jdddd | d	d	 | d
d
 | dd | dd | dd | dd | dd | dd | dd | dd | dd | dd | dd | dd | dd  | d!d" | d#d$ | jd%d&dd | d'd( | jd)d*dd | jd+d,dd | d-d. | d/d0 | d1d2 | d3d4 | d5d6 | d7d8 d S )9NTr  rq  r5  rO  	multidevsr  r  space_hard_limitspace_soft_limitfmodedmoder  r  rF  source_filerE  
source_dirrG  r  r  r  r  r  r  r  zsource.unitssource_unitszsource.usagesource_usagezsource.socketsource_socketz
target.dir
target_dirzbinary.pathbinary_pathzbinary.xattrbinary_xattrzbinary.cache.modebinary_cache_modezbinary.lock.posixbinary_lock_posixzbinary.lock.flockbinary_lock_flockzbinary.sandbox.modebinary_sandbox_modezdriver.formatdriver_formatr  r  zdriver.queuedriver_queuer  r  zdriver.wrpolicydriver_wrpolicyr  r3  r   r   r   r    sD   
z$ParserFilesystem._virtcli_class_initN	r)   r*   r+   r  r:  r  r  ro  r  r   r   r   r   r    s    r  c                   @   s8   e Zd ZdZdZdZdddddd	d
dZedd ZdS )r  videozdevices.videoro  rO  headsramvramvram64vgamemaccel3d)ro  model.heads	model.ram
model.vrammodel.vram64model.vgamemmodel.acceleration.accel3dc                 C   sv   t |  t| dd | jdddd | jdddd | d	d
 | dd | dd | dd | dd d S )NTr  ro  rO  r  rW  rQ  r  rR  rL  rS  rM  rT  rN  rU  rO  rV  rP  r  r3  r   r   r   r    s   
zParserVideo._virtcli_class_initNrJ  r   r   r   r   r    s    
r  c                       s@   e Zd ZdZdZdZdZ fddZdd Ze	d	d
 Z
  ZS )r  r  zdevices.soundrO  Fc                    r  r  )r  r   skip_default_soundr  r[  rz  r(  r   r   r[    r  zParserSound._parsec                 O   r}  )Ncodeccodecsr~  r  r   r   r   codec_find_inst_cb  r  zParserSound.codec_find_inst_cbc                 C   sD   t |  t|  | jdddd | dd | jdd| jd d S )	NrO  Tr  zaudio.idaudio_idzcodec[0-9]*.typerq  r  )r*  rB  r  r1  r[  r3  r   r   r   r    s   

zParserSound._virtcli_class_init)r)   r*   r+   r  r:  r  rb  r[  r[  ro  r  r)  r   r   r(  r   r    s    r  c                   @   r  )r  audiozdevices.audioc                 C   s&   t |  | dd | dd d S )Nrq  r  ry  r3  r   r   r   r    s   
zParserAudio._virtcli_class_initNr0  r   r   r   r   r  
  r  r  c           
      C   s$  t | }|ddv rUd|v rU|dd\}}|dd\}}d}d|v r.|dd\}}n|}d|_dt|d |_d	t|d |_d	t|d |_d	t|d |_	|S d|v ru|d\}}d
|_dt|d |_
dt|d |_|S d|v r|dd\}}	d
|_||_	|	|_|S td| )a   
    Decompose common USB and PCI address string formats into a DeviceHostdev
    instance. The 3 expected formats are:

    - bus.addr (ex. 001.003 for a usb device)
    - vendor:product (ex. 0x1234:0x5678 for a usb device
    - (domain:)bus:slot.func (ex. 00:10.0 for a pci device)
    r  r  r  r   r  pciz0x%.4X   z0x%.2Xusbz*Unknown hostdev address string format '%s')r
   r+  r  r'  rq  r   r   r  r  r  r  productr:  rg   )
r   r  r  funcr  r   r  r  ra  r:  r   r   r   _AddressStringToHostdev  s:   	rc  c                 C   s   zt | |}W n ty   tjddd  w d}d }|  D ]}||r,|}|d7 }q|dkr9ttd| |dk rEttd| |S )Nz!Error parsing node device string.Tr   r   r   z'%s corresponds to multiple node devicesz,Did not find a matching node device for '%s')rc  r;   r   rT   fetch_all_nodedevscompare_to_hostdevr   rE   )r   r  r  r+  nodedevxmlobjr   r   r   _AddressStringToNodedevK  s,   
rh  c                 C   sB   t | |}|r
|S zt| |W S  ty    tjd|dd  w )Nz)Error looking up nodedev from idstring=%sTr   )r   lookupNodedevByNamerh  r;   r   rT   )r   idstringrf  r   r   r   _lookupNodedevFromStringc  s   rk  c                   @   s>   e Zd ZdZdZdZdddZdd Zd	d
 Ze	dd Z
dS )r  r  zdevices.hostdevr   r  rs  )r  rr  c                 C   sh   |j dkrd|_||_d S |j dkrd|_||_d S |j dkr'd|_||_d S t|j|}|| d S )Nnetcapabilitiesmiscstorage)rq  r  net_interface	misc_charstorage_blockrk  r   set_from_nodedevrF  r   r   r   set_name_cb{  s   





zParserHostdev.set_name_cbc                 C   s   t |j|}||S r!   )rk  r   re  )r   r  r#   r"  rf  r   r   r   name_lookup_cb  s   
zParserHostdev.name_lookup_cbc                 C   sX   t |  t| dd | dd | jdd | j| jd | dd | jdd	dd
 d S )NTr  rq  r   rK  r  r  rr  rs  r  )r*  rB  r  r1  rt  ru  r3  r   r   r   r    s   
z!ParserHostdev._virtcli_class_initN)r)   r*   r+   r  r:  r  r  rt  ru  ro  r  r   r   r   r   r  r  s    r  c                   @   r  )r  launchSecurityrq  c                 C   sf   t |  | dd | dd | dd | dd | dd | dd | jdddd	 d S )
Nrq  cbitposreducedPhysBitsr]  sessiondhCertkernelHashesTr  ry  r3  r   r   r   r    s   
z(ParserLaunchSecurity._virtcli_class_initNr  r   r   r   r   r    r  r  c                 C   s   t |}|s
dg}g }tD ]4}t t| |j}|sq|D ]#}|r)|r)|d g}|D ]}||||d}	|	|}
|t |
7 }q+qq|S )z
    Iterate over VIRT_PARSERS, and launch the associated parser
    function for every value that was filled in on 'options', which
    came from argparse/the command line.

    @editing: If we are updating an existing guest, like from virt-xml
    Nr   )r   rC  )r   r  r  r  r  ri  )r`  r   instlistrC  r  r!  optlistr  r  	parserobjparseretr   r   r   parse_option_strings  s$   


r  c                 C   s`   d}t  D ](}t| |jsqtt| |j}|sq|D ]}|dks&|dkr,|  d}qq|S )zN
    Check if the user requested option introspection with ex: '--disk=?'
    FrY  rM  T)r  rd  r  r   r  r  r9  )r`  r  r!  r}  r  r   r   r   check_option_introspection  s   
r  c                 C   sB   | j dkrdS t D ]
}td|j qt  ttd dS )Nr
  Fz, z<You can see additional information with:

  osinfo-query os
T)r  r   list_osr   rU   	all_namesrE   )r`  r  r   r   r   check_osinfo_list  s   
r  )F)Tr!   )FT)FFFFFFF)TF)FFF)rS   )r0   r  ra   r   r   shutilrX   rV   r!  r   rS   r   buildconfigr   
connectionr   r  r   r   r   r	   r
   r   r   r   r   loggerr   r   rf  r   osdictr   ro  r   r   install.unattendedr   install.cloudinitr   whichr  rA  r   r,   r-   r.   r  r1   r/   rJ   rP   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r&  r,  rB  rP  ri  rn  rt  rz  r~  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rq  r  r*  r  r|  r@  r  r  r  r	  r  r  r  r  r  r  r
  r  r  r  r  r  r  r  rk  r  r  r  rr  r  r  r  rv  r  r  rw  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  r  r  r  r  r  r  r  r  r  rc  rh  rk  r  r  r  r  r  r   r   r   r   <module>   sZ  $
S*	(,	B	hL
[`7  +($"?)( ] ] .8e )3&	   ]H5C-N	8 1, 