o
    	bJ                     @   s  d dl Z d dlZd dlZddlmZ ddlmZmZmZmZ ddl	m
Z
 ddlmZ ddlmZ ddlm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dd  Zd!d" Zd#d$ Zd%d& Zd/d'd(Zd)d* Z d/d+d,Z!d-d. Z"dS )0    N   )cli)failfail_conflictingprint_stdoutprint_stderr)DeviceConsole)Guest)log)xmlutilc                 C   sX   	 | d }t j| t j  t j   }|dv rdS |dv r%dS tt	d q)Nr   z (y/n): )yyesT)nnoFzPlease enter 'yes' or 'no'.)
sysstdoutwriteflushstdinreadlinelowerstripr   _)msgprintmsginp r   +/usr/share/virt-manager/virtinst/virtxml.pyprompt_yes_or_no   s   
r   c                 C   s2   t | |dd}|rtd| |S td |S )NzOriginal XMLzAltered XMLzXML diff:
%sz(No XML diff, didn't generate any change.)r   diffr
   debug)origxmlnewxmlr   r   r   r   get_diff&   s   
r#   c                 C   s8   | j d u rd S t| j }| r||  d S d S N)
os_variantr   parse_os_variantget_nameset_os_name)optionsguestosdatar   r   r   set_os_variant0   s   
r,   c                 C   s&   t j|dd}t| |d }||kS )NT)inactiveparsexml)r   get_xmldescr	   get_xml)conndomainoriginal_xmlrawxmlnew_xmlr   r   r   defined_xml_is_unchanged9   s   r7   c                 C   s   t || }d }|d u rd}n| s"|dr&|dd   r&t|}|d urj|dkr6ttd|  |sAttd|j  t	|t
|k r\ttddt	||t	||jd  |dkrd|d8 }|| }|S |d	krv|d d  }|S ||| d
}| }|sttdd||f   |S )Nr   -r   zInvalid --edit option '%s'z No --%s objects found in the XMLzS'--edit %(number)s' requested but there's only %(max)s --%(type)s object in the XMLzV'--edit %(number)s' requested but there are only %(max)s --%(type)s objects in the XML)numbermaxtypeall)r*   z No matching objects found for %sz--%s %s)r   listifylookup_propisdigit
startswithintr   r   cli_arg_namelenabsngettextlookup_child_from_option_string)r*   action_nameeditvalparserclassobjlistidxinst	parserobjr   r   r   _find_objects_to_editC   sP   

rN   c                 C   s   g d}g }|D ]}| dd}t| |dvr|| qt|dkr3ttdddd	 |D   t|d
krKttdddd	 |D   d S d S )N)editz
add-deviceremove-devicez	build-xmlr8   r   )Fr   zOne of %s must be specified.z, c                 S      g | ]}d | qS z--r   .0cr   r   r   
<listcomp>|       z*check_action_collision.<locals>.<listcomp>r   zConflicting options %sc                 S   rR   rS   r   rT   r   r   r   rW      rX   )replacegetattrappendrC   r   r   join)r)   actions
collisionsclinameoptnamer   r   r   check_action_collisionq   s    

ra   c                 C   st   g }t jt jg D ]}t| |jr|| q	t|dkr#ttd t|dkr6ttddd |D   |d S )Nr   zNo change specified.r   zCOnly one change operation may be specified (conflicting options %s)c                 S   s   g | ]}|  qS r   )cli_flag_namerT   r   r   r   rW      rX   z*check_xmlopt_collision.<locals>.<listcomp>)	r   VIRT_PARSERS	ParserXMLrZ   rB   r[   rC   r   r   )r)   r^   rI   r   r   r   check_xmlopt_collision   s   
re   c                 C   sx   |j rt| d|j|}n| }|jr(|jdkr(|jdkr(ttd|j|jd  |jd ur3ttd tj|| |ddS )	NrO   1r<   zU'--edit %(option)s' doesn't make sense with --%(objecttype)s, just use empty '--edit')option
objecttypez2--os-variant/--osinfo is not supported with --editT)editing)	guest_propnamerN   rO   r   r   rB   r%   r   parse_option_strings)r*   r)   rI   rL   r   r   r   action_edit   s   
rl   c                 C   sr   | | sttd|j  t||  |r!|D ]}| | q|S t|| d }t	|}|D ]}|
|  q/|S )Nz!Cannot use --add-device with --%s)prop_is_listr   r   rB   r,   
add_devicer   rk   r   r=   set_defaults)r*   r)   rI   devsdevr   r   r   action_add_device   s   


rr   c                 C   s   | | sttd|j  |jd urttd t| dt||jd |}t|}|d d  D ]}t	
| |}|rHtd|  || q1|D ]}| | qK|S )Nz$Cannot use --remove-device with --%sz;--os-variant/--osinfo is not supported with --remove-devicerP   rQ   z"Found duplicate console device:
%s)rm   r   r   rB   r%   rN   rZ   r   r=   r   get_console_duplicater
   r    r1   r[   remove_device)r*   r)   rI   rp   rq   condupr   r   r   action_remove_device   s&   



rv   c                 C   s   |j sttd|j  |jd urttd ||}||r&| }n|| }t	
|||}t|}|D ]}|| q9|S )Nz"--build-xml not supported for --%sz7--os-variant/--osinfo is not supported with --build-xml)rj   r   r   rB   r%   r>   rm   new	__class__r   rk   r   r=   ro   )r2   r)   rI   r*   rL   rp   rq   r   r   r   action_build_xml   s   





ry   c                 C   s2   t | dd dkr
d S td|  | t  d S )NDEVICE_TYPEdiskzDoing setup for disk=%s)rZ   r
   r    build_storager   	get_meter)rq   r   r   r   setup_device   s   r~   c                 C   sX   |rt td|j sdS |dkr|D ]}t| q| | }ttd|j  |S )Nz!Define '%s' with the changed XML?Fhotplugz!Domain '%s' defined successfully.)r   r   namer~   	defineXMLr1   r   )r2   inactive_xmlobjrp   actionconfirmrq   domr   r   r   define_changes   s   
r   c              
   C   s   |rt td|j sdS |dkr|D ]}t| qz	| | }W n  tjyC } zttd|j|d  W Y d }~d S d }~ww t	td|j  |S )Nz Start '%s' with the changed XML?Fr   .Failed starting domain '%(domain)s': %(error)sr3   error!Domain '%s' started successfully.)
r   r   r   r~   	createXMLr1   libvirtlibvirtErrorr   r   )r2   xmlobjrp   r   r   rq   r   er   r   r   start_domain_transient   s&   
r   c                 C   sJ  |dkrt d}t d}t d}n!|dkr"t d}t d}t d}n|d	kr2t d
}t d}t d}|D ]n}| }|rJ|||  d }	t|	sJq4|dkrRt| z%|dkr_| |tj n|dkrk| |tj n|d	krv| 	|tj W n  tj
y }
 zdtjvrt|d|
i  W Y d }
~
nd }
~
ww t| |rtd q4d S )Nr   z7%(xml)s

Hotplug this device to the guest '%(domain)s'?zDevice hotplug successful.z*Error attempting device hotplug: %(error)s	hotunplugz;%(xml)s

Hotunplug this device from the guest '%(domain)s'?zDevice hotunplug successful.z,Error attempting device hotunplug: %(error)supdatez7%(xml)s

Update this device for the guest '%(domain)s'?zDevice update successful.z)Error attempting device update: %(error)s)xmlr3   $VIRTXML_TESTSUITE_UPDATE_IGNORE_FAILr    )r   r1   r   r   r~   attachDeviceFlagsr   VIR_DOMAIN_AFFECT_LIVEdetachDeviceFlagsupdateDeviceFlagsr   osenvironr   r   )r3   rp   r   r   msg_confirmmsg_successmsg_failrq   r   r   r   r   r   r   update_changes  sR   


r   c                 C   s   |   }| j| j|d}|jdk}|tju }|r |s ttd |r6|r-g }t|| nt	|||}d}n|j
rCt||||}d}n|jrNt|||}d}|  }	t||	}
|
s`ttd |jrj|
rit|
 n|jrqt|	 |||fS )z
    Parse the command line device/XML arguments, and apply the changes to
    a copy of the passed in xmlobj.

    :returns: (list of device objects, action string, altered xmlobj)
    )r2   r/   rQ   z"--xml can only be used with --editr   r   r   zENo XML diff was generated. The requested changes will have no effect.)r1   rx   r2   rO   r   rd   r   r   parse_xmlclirl   rn   rr   rt   rv   r#   r
   warning
print_diffr   	print_xml)orig_xmlobjr)   rI   rp   r!   r   has_edit	is_xmlclir   r"   r   r   r   r   prepare_changes:  s:   



r   c                  C   s  t jdtddd} t | d | jddtdd	 | td
}|jdddtdd |jddtdd |jddtdd |jddtdd | td}|jddtdd | }|jddtdd |jdddtdd  |jd d! |jd"dtd#d |jd$dtd%d |jd&dtd'd |jd(dtd)d t j| d*d+ | td,}t j	|dd- t 
| t | t | t | t j|dd- t | t | t | t | | td.}t j|d*d*d*d/ t |  |  S )0Nz%(prog)s [options]z,Edit libvirt XML using command line options.T)introspection_epilogvirt-xmlr3   ?zDomain name, id, or uuid)nargshelpzXML actionsz--editrQ   zEdit VM XML. Examples:
--edit --disk ...     (edit first disk device)
--edit 2 --disk ...   (edit second disk device)
--edit all --disk ... (edit all disk devices)
--edit target=hda --disk ... (edit disk 'hda')
)r   defaultr   z--remove-device
store_truezRemove specified device. Examples:
--remove-device --disk 1 (remove first disk)
--remove-device --disk all (remove all disks)
--remove-device --disk /some/path)r   r   z--add-devicez6Add specified device. Example:
--add-device --disk ...z--build-xmlzWOutput built device XML. Domain is optional but recommended to ensure optimal defaults.zOutput options--updatezApply changes to the running VM.
With --add-device, this is a hotplug operation.
With --remove-device, this is a hotunplug operation.
With --edit, this is an update device operation.z--definezKForce defining the domain. Only required if a --print option was specified.z--no-definedefinestore_falsezForce not defining the domain.)destr   r   )r   --startzStart the domain.z--print-diffz/Only print the requested change, in diff formatz--print-xmlz3Only print the requested change, in full XML formatz	--confirmz/Require confirmation before saving any results.F)virtinstallzXML options)editexamplezMiscellaneous Options)promptprintxmldryrun)r   setupParserr   add_connect_optionadd_argumentadd_argument_groupadd_mutually_exclusive_groupro   add_os_variant_optionadd_disk_optionadd_net_optionadd_gfx_optionadd_metadata_optionadd_memory_optionvcpu_cli_optionsadd_xml_optionadd_guest_xml_optionsadd_boot_optionsadd_device_optionsadd_misc_optionsautocomplete
parse_args)parseractgoutgdefine_ggmiscr   r   r   r   m  s|   










r   c              
   C   s  t   t }|js|js|js|jrd|_t d|j	|j t 
|r&dS t |r-dS d |_|js^|js^tjjsXtj sX|jrHttd |jrQttd tj |_nttd |jsv|jsv|jrn|jsmd|_n|jd u rvd|_|jr|jsd|_t| t|}|jr|jsttd|j  t |j| } d }d }d }|jrt | |j\}}}nt| |jd	}t|}|jrt | |||}|D ]}t!|"  qdS d }d}	|jr	|jr|j#rt$d
d |rt%|||\}}
}t&|||
|j d}	nt'(td |js	dS |" }t%||||d\}}
}|js+|j#r)t)| |||
|j dS t*| |||
|j}|s9dS |j#roz|+  W n  t,j-yc } zttd|j.|d  W Y d }~nd }~ww t!td|j.  dS |r}|	s}t!td dS t/| ||rt'(td dS )NFr   r   z%Can't use --confirm with stdin input.z$Can't use --update with stdin input.zA domain must be specifiedTz#Don't know how to --update for --%sr.   r   r   z0The VM is not running, --update is inapplicable.)rp   r   r   r   z?Changes will take effect after the domain is fully powered off.zhXML did not change after domain define. You may have changed a value that libvirt is setting by default.)0r   earlyLoggingr   r   r   r   	build_xmlquietsetupLoggingr    check_option_introspectioncheck_osinfo_liststdinxmlr3   r   r   closedisattyr   r   r   readr   ra   re   rj   rB   getConnectionconnectget_domain_and_guestr	   boolry   r   r1   startr   r   r   r
   r   r   r   creater   r   r   r7   )r2   r)   rI   r3   active_xmlobjr   vm_is_runningrp   rq   performed_updater   dummyr4   xmlobj_to_definer   r   r   r   r   main  s   





r   c               
   C   s   z	t t  W d S  ty" }  zt | j W Y d } ~ d S d } ~ w ty8   tjddd tt	d Y d S  t
yN } zt| W Y d }~d S d }~ww )Nr   T)exc_infozAborted at user request)r   exitr   
SystemExitcodeKeyboardInterruptr
   r    r   r   	Exceptionr   )sys_emain_er   r   r   runcli9  s   r   r$   )#r   r   r   r   r   r   r   r   r   devicesr   r*   r	   loggerr
   r   r   r#   r,   r7   rN   ra   re   rl   rr   rv   ry   r~   r   r   r   r   r   r   r   r   r   r   r   <module>   s8   
	
.
/3
N~