o
    ϴf^                  	   @   s  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mZm	Z	 d dl
mZmZmZmZmZmZmZ dZg dZdZdZdZd	Ze ZeeeZed
defdefdefdefdefgZde fddZ!de fddZ"			d0de	e de	e de	ee#  ddfddZ$	d1dede	ee#  ddfddZ%dede	e fddZ&dee fd d!Z'd"d# Z(d$ej)fd%d&Z*		'd2d(ede	e d)e fd*d+Z+d(efd,d-Z,d(edefd.d/Z-dS )3    N)List
NamedTupleOptional)apiaptevent_logger
exceptionsmessagessystemutilz/usr/bin/snap)g      ?g      ?g      @z
proxy.httpzproxy.httpsz/run/snapd.socketz/v2/snaps/{}SnapPackagenameversionrevisionchannel	publisherreturnc                   C   s   dt  v S )z(Returns whether or not snap is installedsnapd)r   get_installed_packages_names r   r   //usr/lib/python3/dist-packages/uaclient/snap.pyis_snapd_installed!   s   r   c                   C   s   t dd t D S )z3Returns whether or not snapd is installed as a snapc                 s   s    | ]}|j d kV  qdS )r   Nr   ).0snapr   r   r   	<genexpr>(   s    z/is_snapd_installed_as_a_snap.<locals>.<genexpr>)anyget_installed_snapsr   r   r   r   is_snapd_installed_as_a_snap&   s   r   
http_proxyhttps_proxyretry_sleepsc                 C   sx   t  s
td dS | s|rttjjdd | r(tj	dddd| g|d |r:tj	dddd	|g|d dS dS )
a  
    Configure snap to use http and https proxies.

    :param http_proxy: http proxy to be used by snap. If None, it will
                       not be configured
    :param https_proxy: https proxy to be used by snap. If None, it will
                        not be configured
    :param retry_sleeps: Optional list of sleep lengths to apply between
        retries. Specifying a list of [0.5, 1] tells subp to retry twice
        on failure; sleeping half a second before the first retry and 1 second
        before the second retry.
    z6Skipping configure snap proxy. snapd is not installed.Nr   )servicesetr
   zproxy.http={}r!   zproxy.https={})
r   LOGdebugeventinfor	   SETTING_SERVICE_PROXYformatr
   subp)r   r    r!   r   r   r   configure_snap_proxy+   s    

r,   protocol_typec                 C   s4   t  s
td dS tjdddd| g|d dS )a  
    Unset snap configuration settings for http and https proxies.

    :param protocol_type: String either http or https
    :param retry_sleeps: Optional list of sleep lengths to apply between
        retries. Specifying a list of [0.5, 1] tells subp to retry twice
        on failure; sleeping half a second before the first retry and 1 second
        before the second retry.
    z8Skipping unconfigure snap proxy. snapd is not installed.Nr   unsetr
   zproxy.{}r$   )r   r%   r&   r
   r+   r*   )r-   r!   r   r   r   unconfigure_snap_proxyP   s   

r/   keyc                 C   s8   zt ddd| g\}}| W S  tjy   Y dS w )z
    Gets the config value from snap.
    :param protocol: can be any valid snap config option
    :return: the value of the snap config option, or None if not set
    r   getr
   N)r
   r+   stripr   ProcessExecutionError)r0   out_r   r   r   get_config_option_valuee   s   
r6   c                  C   sR   t g d\} }|  }|dd  }g }|D ]}| d }|t| q|S )N)r   listz--colorneverz	--unicoder8      r   )r
   r+   
splitlinessplitappendget_snap_info)r4   r5   appssnapsliner   r   r   r   r   r   s   r   c               
   C   s   t tjjdd z	tt  W n tj	y. }  zt
dt|  W Y d } ~ nd } ~ ww ztjg dtjd W d S  tjyH   t w )Nzstandard Ubuntur   z<Trying to install snapd. Ignoring apt-get update failure: %s)zapt-getinstallz--assume-yesr   r$   )r'   r(   r	   APT_UPDATING_LISTr*   r   update_sources_listget_system_sources_filer   UbuntuProErrorr%   r&   strr
   r+   APT_RETRIESr3   CannotInstallSnapdError)er   r   r   install_snapd   s$   rJ   progressc              
   C   sv   zt jtdddgdd W d S  tjy: } ztdt| r.t	
d | dtj n W Y d }~d S d }~ww )	Nwaitr
   zseed.loadedTcapturezunknown command .*waitz9Detected version of snapd that does not have wait commandr(   )r
   r+   SNAP_CMDr   r3   researchrF   lowerr%   warningemitr	   SNAPD_DOES_NOT_HAVE_WAIT_CMD)rK   rI   r   r   r   run_snapd_wait_cmd   s   rV   Fr   classic_confinement_supportc                 C   s@   t d| g}|r|dg7 }|r|d|g7 }tj|dtd d S )NrA   z	--classicz--channel={}T)rN   r!   )rO   r*   r
   r+   SNAP_INSTALL_RETRIES)r   r   rW   cmdr   r   r   install_snap   s   


rZ   c                 C   s   t jtd| gdd d S )NrefreshTrM   )r
   r+   rO   r   r   r   r   refresh_snap   s   r]   c           
   
   C   s  t  t jt j}|t tjd}||_t	
| }zzj|dt	
|  | }| jddd}zt|}W n  tjyZ } ztjd|||d tjd
||d	d }~ww |jd
kr|jdkrv|di ddkrvtj| d|di d}tj|dW n ty   t w W |  |  n	|  |  w |di }	t|	dd|	dd|	dd|	dd|	di dddS )N	localhostGETzutf-8ignore)errorsz]JSONDecodeError while parsing result of snap api call to %s, returning None. output was: "%s")exc_infozSNAPD API {})sourcer4      i  resultkindzsnap-not-foundr\   message)errorr    r   r   r   r   username)r   r   r   r   r   )socketAF_UNIXSOCK_STREAMconnectSNAPD_SOCKET_PATHhttpclientHTTPConnectionsockSNAPD_SNAPS_APIr*   requestgetresponsereaddecodejsonloadsJSONDecodeErrorr%   rS   r   InvalidJsonstatusr1   SnapNotInstalledErrorUnexpectedSnapdAPIErrorConnectionRefusedErrorSnapdAPIConnectionRefusedcloser   )
r   	snap_sockconnurlresponser4   datarI   	error_msg	snap_infor   r   r   r=      s\   











r=   )NNN)N)NF).http.clientrp   ry   loggingrP   rk   typingr   r   r   uaclientr   r   r   r   r	   r
   r   rO   rX   HTTP_PROXY_OPTIONHTTPS_PROXY_OPTIONro   rt   get_event_loggerr'   	getLoggerreplace_top_level_logger_name__name__r%   rF   r   boolr   r   floatr,   r/   r6   r   rJ   ProgressWrapperrV   rZ   r]   r=   r   r   r   r   <module>   sz    $

&


