o
    `?                     @   s   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 ddlm	Z	 ddl
mZ dd	lmZ dd
lmZ ddlmZ edd\ZZdd ZG dd de	ZdS )    N)Gio)GLib)Gtk)log   )
vmmGObject)vmmCreateConn)vmmConnectionManager)vmmInspection)
vmmSystray   c                    s    fdd}|S )ze
    Decorator to show a modal error dialog if an exception is raised
    from a startup routine
    c              
      sd   z | g|R i |W S  t y1 } z|  }| jjt||d |   W Y d }~d S d }~ww N)modal)	Exception	_can_exiterrshow_errstr_exit_app_if_no_windows)selfargskwargser   fn -/usr/share/virt-manager/virtManager/engine.pynewfn    s   z"_show_startup_error.<locals>.newfnr   )r   r   r   r   r   _show_startup_error   s   r   c                   @   s(  e Zd ZdZdZdZdZdZdZdZ	e
dd	 Zd
ejdg fiZdd Ze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- Z d.d/ Z!d0d1 Z"d2d3 Z#d4d5 Z$d6d7 Z%d8d9 Z&d:d; Z'e(d<d= Z)d>d? Z*e(d@dA Z+dS )B	vmmEnginemanagercreatoreditorperformanceconsoledeletesummaryc                 C   s   | j st | _ | j S N)	_instancer   )clsr   r   r   get_instance3   s   zvmmEngine.get_instanceapp-closingNc                 C   sb   t |  d| _d| _d | _|   d | _d| _d| _t	j
d| jdd| _d| j_td| _d S )NFr   zTick threadr   )nametargetr   Td   )r   __init___exiting_window_count_gtkapplication_init_gtk_application_timer_tick_counter_tick_thread_slow	threadingThread_handle_tick_queue_tick_threaddaemonqueuePriorityQueue_tick_queuer   r   r   r   r/   =   s   
zvmmEngine.__init__c                 C   s
   t  jS r'   )r	   r*   connsr?   r   r   r   	_connobjsP   s   
zvmmEngine._connobjsc                 C   s   d S r'   r   r?   r   r   r   _cleanupU   s   zvmmEngine._cleanupc                 C   s   t   t  | | j| j |   | j	  | 
  t| j }|s.td ntddt| |sA| | j | j s\|s^|  }|td | d| j dS dS dS )zU
        Actual startup routines if we are running a new instance of the app
        zNo stored URIs found.zLoading stored URIs:
%sz  
z'Checking for virtualization packages...  N)r   r*   r
   add_gsettings_handleconfig on_stats_update_interval_changed_timer_changed_cb_schedule_timerr:   start_ticklistrA   keysr   debugjoinsortedidle_add_autostart_connsget_conn_uris_get_managerset_startup_error_timeout_add_add_default_conn)r   skip_autostartcliuriurisr    r   r   r   _default_startup^   s2   
zvmmEngine._default_startupc                    s   ddl m} t td  jjjdur$ jjjpdtd  	 }|
 j}|r8|| dS  fdd} | dS )z
        If there's no cached connections, or any requested on the command
        line, try to determine a default URI and open it, first checking
        if libvirt is running
        r   )connectauthzProbed default URI=%sNz"Using test-options firstrun_uri=%sc                     s<    fdd} t  }|d |d|  |  d S )Nc                    s   |r
  | | d S d S r'   )_handle_conn_error)cConnectErrorr?   r   r   _open_completed   s   zJvmmEngine._add_default_conn.<locals>.idle_connect.<locals>._open_completedTopen-completed)r	   r*   add_connset_autoconnectconnect_onceopen)r`   connr   tryurir   r   idle_connect   s
   
z1vmmEngine._add_default_conn.<locals>.idle_connect)libr\   r   default_urir   rM   rE   CLITestOptionsfirstrun_urirS   setup_first_urirT   rP   )r   r\   r    msgri   r   rg   r   rW   ~   s   
	zvmmEngine._add_default_connc                    sh   j rdS t dd j D fdd  fdd fdd	}   |d
 dS )zQ
        We serialize conn autostart, so polkit/ssh-askpass doesn't spam
        Nc                 S   s   g | ]
}|  r| qS r   )get_autoconnectget_uri).0rf   r   r   r   
<listcomp>   s    z.vmmEngine._autostart_conns.<locals>.<listcomp>c                      s&    s	 d  d S   d d S Nr   )putpopr   )
auto_connsconnections_queuer   r   add_next_to_queue   s   z5vmmEngine._autostart_conns.<locals>.add_next_to_queuec                    s    |d urt d|j    d S )NzAutostart connection error: %s)r   rM   details)_connr_   )ry   r   r   conn_open_completed   s
   
z7vmmEngine._autostart_conns.<locals>.conn_open_completedc                     sV   	   } | d u rd S jrd S | jvr   q j|  }|d |j q)NTra   )getr0   rA   rd   rP   re   )urirf   )ry   r|   rx   r   r   r   handle_queue   s   

z0vmmEngine._autostart_conns.<locals>.handle_queuezConn autostart thread)r0   r<   QueuerA   values_start_thread)r   r   r   )ry   rw   r|   rx   r   r   rQ      s   zvmmEngine._autostart_connsc                 C   s,   | j  std | j t  dS dS )z1
        Invoked after application.run()
        z Initial gtkapplication activatedN)_applicationget_windowsr   rM   
add_windowr   Window)r   ignorer   r   r   _on_gtk_application_activated   s   

z'vmmEngine._on_gtk_application_activatedc                 C   s`   t jddd| _| jd  | jd| j tjdt	j
d}|d| j | j| d S )Nzorg.virt-manager.virt-managerr   )application_idflagsactivatecli_command(sss))r   Applicationr   registerconnectr   r   SimpleActionnewr   VariantType_handle_cli_command
add_action)r   actionr   r   r   r3      s   
zvmmEngine._init_gtk_applicationc                 C   sv   |r|s| j }td|pd|pd|pdf}| j }|s#| || | jd| |r3td dS | j	d dS )z
        Public entrypoint from virt-manager cli. If app is already
        running, connect to it and exit, otherwise run our functional
        default startup.
        r    r   z!Connected to remote app instance.N)
CLI_SHOW_MANAGERr   Variantr   get_is_remoter[   activate_actionr   rM   run)r   r~   show_windowdomainrX   data	is_remoter   r   r   rI      s   

zvmmEngine.startc                 O   s   |}|}|    d S r'   )rH   )r   r   r   ignore1ignore2r   r   r   rG      s   zvmmEngine._timer_changed_cbc                 C   s>   | j  d }| jd ur| | j d | _| || j| _d S )NrC   )rE   get_stats_update_intervalr4   remove_gobject_timeoutrV   rJ   )r   intervalr   r   r   rH     s
   
zvmmEngine._schedule_timerc                 K   sT   | j  r| jstd d| _d S |  jd7  _| j |r tp!t| j||f d S )Nz,Tick is slow, not running at requested rate.Tr   )	r>   fullr6   r   rM   r5   ru   	PRIO_HIGHPRIO_LOW)r   objisprior   r   r   r   _add_obj_to_tick_queue  s   


z vmmEngine._add_obj_to_tick_queuec                 C   s   | j |dfi | d S )NT)r   )r   rf   r   r   r   r   schedule_priority_tick  s   z vmmEngine.schedule_priority_tickc                 C   s&   | j  D ]}| j|dddd qdS )NFT)stats_updatepollvmr   )rA   r   r   )r   rf   r   r   r   rJ     s
   zvmmEngine._tickc                 C   s`   	 | j  \}}}}z
|jdi | W n ty'   tjd| dd Y nw d }| j   q)NTzError polling connection %s)exc_infor   )r>   r}   tick_from_enginer   r   rM   rq   	task_done)r   r   r   rf   r   r   r   r   r9   "  s   

zvmmEngine._handle_tick_queuec                 C   s    |  j d7  _ td| j  dS )=
        Public function, called by toplevel windows
        r   z window counter incremented to %sN)r1   r   rM   r?   r   r   r   increment_window_counter7  s   z"vmmEngine.increment_window_counterc                 C   s(   |  j d8  _ td| j  |   dS )r   r   z window counter decremented to %sN)r1   r   rM   r   r?   r   r   r   decrement_window_counter>  s   z"vmmEngine.decrement_window_counterc                 C   s   t   S )z
        We don't use window tracking here: systray isn't a window and even
        when 'show' has been requested it may not be embedded in a visible
        tray area, so we have to check it separately.
        )r   r*   is_embeddedr?   r   r   r   _systray_is_embeddedG  s   zvmmEngine._systray_is_embeddedc                 C   s   | j dko	|   S rt   )r1   r   r?   r   r   r   r   O  s   
zvmmEngine._can_exitc                 C   s,   | j rd S |  rtd |   d S d S )Nz%No windows found, requesting app exit)r0   r   r   rM   exit_appr?   r   r   r   r   S  s   
z!vmmEngine._exit_app_if_no_windowsc                    s*    j rdS d _  fdd} | dS )zQ
        Public call, manager/details/... use this to force exit the app
        NTc                     s|   z7t     d     jjjr+ j } |  j	 | D ]}t
d| q"t
d W  j  d S  j  w )Nr+   zLEAK: %szExiting app normally.)r	   r*   cleanupemitrE   rl   
leak_debugget_objectsremove
object_keyr   rM   r   quit)objsr,   r?   r   r   _do_exitc  s   


z$vmmEngine.exit_app.<locals>._do_exit)r0   rP   )r   r   r   r?   r   r   Z  s
   zvmmEngine.exit_appc                 C   sd   |  rt|}| j|  D ] }|| kr|  S || kr%|  S || kr/|  S qdS )zn
        Lookup a VM by a string passed in on the CLI. Can be either
        ID, domain name, or UUID
        N)isdigitintrA   list_vmsget_idget_nameget_uuid)r   r~   clistrvmr   r   r   _find_vm_by_cli_str  s   zvmmEngine._find_vm_by_cli_strc                 C   s   |  ||}|std||f ddlm} |d |}|| jkr&|  n|| j| jfv r3|	  n	|| j
kr<|  |  || jkrSddlm} ||| d S d S )Nz%s does not have VM '%s'r   )vmmVMWindow)vmmDeleteDialog)r   RuntimeErrorvmwindowr   r*   CLI_SHOW_DOMAIN_PERFORMANCEactivate_performance_pageCLI_SHOW_DOMAIN_EDITORCLI_SHOW_DOMAIN_DELETEactivate_config_pageCLI_SHOW_DOMAIN_CONSOLEactivate_console_pageshowr%   r   show_instance)r   r~   r   pager   r   rz   r   r   r   r   _cli_show_vm_helper  s(   




zvmmEngine._cli_show_vm_helperc                 C   s   ddl m} |d S )Nr   )
vmmManager)r    r   r*   )r   r   r   r   r   rS     s   
zvmmEngine._get_managerc                 C   s   t d| || jkr|  }|| |  d S || jkr-ddlm} |	d | d S || j
krCddlm} |	d | j|  d S || j| j| j| jfv rX| ||| d S td| )NzLaunching requested window '%s'r   )vmmCreateVM)vmmHostzUnknown cli window command '%s')r   rM   r   rS   set_initial_selectionr   CLI_SHOW_DOMAIN_CREATORcreatevmr   r   CLI_SHOW_HOST_SUMMARYhostr   rA   r   r   r   r   r   r   )r   r~   r   r   r    r   r   r   r   r   _launch_cli_window  s(   



zvmmEngine._launch_cli_windowc                 C   s2   |\}}}|   }| jj||||d |   d S r   )r   r   r   r   )r   r{   r_   ro   rz   titler   r   r   r   r]     s   
zvmmEngine._handle_conn_errorc                    s   |}|d |d pj |d td s(td    d S jvt   	 rC
j d S  fdd} d|    d S )	Nr   r      z6processing cli command uri=%s show_window=%s domain=%sz1No cli action requested, launching default windowc                    sD   |rrt d t   | d S  d S )NzRemoving failed uri=%s)r   rM   r	   r*   remove_connr]   r   )_cr_   rf   conn_is_newr   r   r   r~   r   r   r`     s   z6vmmEngine._handle_cli_command.<locals>._open_completedra   )r   r   rM   rS   r   rA   r	   r*   rb   	is_activerP   r   rd   re   )r   	actionobjvariantr   r`   r   r   r   r     s*   

	zvmmEngine._handle_cli_command),__name__
__module____qualname__r   r   r   r   r   r   r   classmethodr*   r   	RUN_FIRST__gsignals__r/   propertyrA   rB   r[   rW   rQ   r   r3   rI   rG   rH   r   r   rJ   r9   r   r   r   r   r   r   r   r   rS   r   r   r]   r   r   r   r   r   r   *   sT    

	  0		%
r   )r<   r7   gi.repositoryr   r   r   virtinstr   	baseclassr   
createconnr   connmanagerr	   lib.inspectionr
   systrayr   ranger   r   r   r   r   r   r   r   <module>   s    