B
    `G0                 @   sB  d Z ddlmZmZmZ eZddlZddlZddl	Z	ddl
mZmZ ddlmZmZmZmZmZ ddlmZ ddlmZ dd	lm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"dd Z#dd  Z$d8d!d"Z%d#d$ Z&d%d& Z'd'd( Z(d)d* Z)d+d, Z*d9d.d/Z+d0d1 Z,d2d3 Z-d:d4d5Z.d6d7 Z/dS );z2Functions for accessing docker via the docker cli.    )absolute_importdivisionprint_functionN   )open_binary_fileread_text_file)ApplicationErrorcommon_environmentdisplayfind_executableSubprocessError)urlparse)run_command)EnvironmentConfigi   c               C   s   t dddS )z
    :rtype: bool
    dockerF)required)r    r   r   Q/home/dcms/DCMS/lib/python3.7/site-packages/ansible_test/_internal/docker_util.pydocker_available%   s    r   c              C   s   yt jS  tk
r   Y nX tjd} | r| dry,t| d dd }t	j
d| dd W q tk
r   d}t	d	|   Y qX nd}t	j
d
dd |t _|S )z*Return the hostname of the Docker service.ZDOCKER_HOSTztcp://r   :r   zDetected Docker host: %s)	verbosity	localhostzQCould not parse DOCKER_HOST environment variable "%s", falling back to localhost.z*Assuming Docker is available on localhost.)get_docker_hostnamehostnameAttributeErrorosenvironget
startswithr   splitr
   info
ValueErrorwarning)Zdocker_hostr   r   r   r   r   ,   s     r   c              C   sx   yt jS  tk
r   Y nX d} d}tj| rXt| }tj| \}}|dkrX|}|t _|rtt	j
d| dd |S )z
    :rtype: str | None
    z/proc/self/cpusetN)z/dockerz	/azpl_jobz*Detected execution in Docker container: %sr   )r   )get_docker_container_idcontainer_idr   r   pathexistsr   r   stripr
   r    )r%   r$   contentsZcgroup_pathZcgroup_namer   r   r   r#   E   s    r#   c             C   sV   t | |}|d d }|d}|r:t| }|| d }n|d }|sRtd| |S )zS
    :type args: EnvironmentConfig
    :type container_id: str
    :rtype: str
    r   NetworkSettingsNetworksZ	IPAddressz,Cannot retrieve IP address for container: %s)docker_inspectr   !get_docker_preferred_network_namer   )argsr$   resultsZnetwork_settingsnetworksZnetwork_name	ipaddressr   r   r   get_docker_container_ipf   s    

r1   c             C   sD   t | |}|std| t|dkr<td|d|f |d S )z
    Return the network name of the specified container.
    Raises an exception if zero or more than one network is found.
    z*No network found for Docker container: %s.r   zGFound multiple networks for Docker container %s instead of only one: %sz, r   )get_docker_networksr   lenjoin)r-   r$   r/   r   r   r   get_docker_network_name}   s    
r5   c             C   s*   d}| j r| j }nt }|r&t| |}|S )a  
    Return the preferred network name for use with Docker. The selection logic is:
    - the network selected by the user with `--docker-network`
    - the network of the currently running docker container (if any)
    - the default docker network (returns None)
    N)Zdocker_networkr#   r5   )r-   networkZcurrent_container_idr   r   r   r,      s    
r,   c             C   s   | o
| dkS )z@Return True if the network being used is a user-defined network.Zbridger   )r6   r   r   r   is_docker_user_defined_network   s    r7   c             C   s0   t | |}|d d d}|dkr(dS t|S )z[
    :param args: EnvironmentConfig
    :param container_id: str
    :rtype: list[str]
    r   r)   r*   N)r+   r   sorted)r-   r$   r.   r/   r   r   r   r2      s
    
r2   c          	   C   s   d|ksd|kr0t | |r0tjd| dd dS | jsHtd|  dS xRtdd	D ]D}yt| d
|g dS  tk
r   td|  t	d Y qTX qTW t
d| dS )z<
    :type args: EnvironmentConfig
    :type image: str
    @r   z=Skipping docker pull of existing image with tag or digest: %s   )r   Nz8Skipping docker pull for "%s". Image may be out-of-date.r   
   pullzLFailed to pull docker image "%s". Waiting a few seconds before trying again.   z!Failed to pull docker image "%s".)docker_imagesr
   r    docker_pullr"   rangedocker_commandr   timesleepr   )r-   image
_iterationr   r   r   r?      s    r?   c          	   C   s<   t |*}t| |dd| dt gdg|dd W dQ R X dS )zi
    :type args: EnvironmentConfig
    :type container_id: str
    :type src: str
    :type dst: str
    ddzof=%szbs=%sz-iT)optionsstdincaptureN)r   docker_execBUFFER_SIZE)r-   r$   srcdstZsrc_fdr   r   r   
docker_put   s    
rN   c          	   C   s>   t |d*}t| |dd| dt gdg|dd W dQ R X dS )	zi
    :type args: EnvironmentConfig
    :type container_id: str
    :type src: str
    :type dst: str
    wbrF   zif=%szbs=%sz-iT)rG   stdoutrI   N)r   rJ   rK   )r-   r$   rL   rM   Zdst_fdr   r   r   
docker_get   s    rQ   c             C   s   |sg }|sg }t | }t|r.|d|g xvtddD ]h}yt| dg| |g | ddS  tk
r } z&t| td|  t	
d W dd}~X Y q:X q:W td	| dS )
z
    :type args: EnvironmentConfig
    :type image: str
    :type options: list[str] | None
    :type cmd: list[str] | None
    :rtype: str | None, str | None
    z	--networkr   r=   runT)rI   zKFailed to run docker image "%s". Waiting a few seconds before trying again.Nz Failed to run docker image "%s".)r,   r7   extendr@   rA   r   r
   errorr"   rB   rC   r   )r-   rD   rG   cmdr6   rE   exr   r   r   
docker_run   s    
 rW   c          
   C   s   y t | d|ddgddd\}}W n\ tk
r| } z>d|jkr@g S d|jkrht | d|ddgddd\}}n|W d	d	}~X Y nX |d
rt|S dd | D S )zZ
    :param args: CommonConfig
    :param image: str
    :rtype: list[dict[str, any]]
    Zimagesz--formatz
{{json .}}T)rI   alwayszno such imagezfunction "json" not definedjsonN[c             S   s   g | ]}t |qS r   )rY   loads).0liner   r   r   
<listcomp>   s    z!docker_images.<locals>.<listcomp>)rA   r   stderrr   rY   r[   
splitlines)r-   rD   rP   _dummyrV   r   r   r   r>     s     



r>   c          
   C   sP   yt | dd|gdd W n2 tk
rJ } zd|jkr6n|W dd}~X Y nX dS )zC
    :type args: EnvironmentConfig
    :type container_id: str
    Zrmz-fT)rI   zno such containerN)rA   r   r_   )r-   r$   rV   r   r   r   	docker_rm#  s    
rb   c             C   s   | j r
g S y t| d|gddd }t|S  tk
r } z8d|jkrJg S yt|jS  tk
rn   |Y nX W dd}~X Y nX dS )zZ
    :type args: EnvironmentConfig
    :type container_id: str
    :rtype: list[dict]
    inspectT)rI   r   zno such imageN)explainrA   rY   r[   r   r_   rP   	Exception)r-   r$   rP   rV   r   r   r   r+   1  s    

r+   c             C   s   t | dd||gdd dS )z]
    :param args: EnvironmentConfig
    :param container_id: str
    :param network: str
    r6   Z
disconnectT)rI   N)rA   )r-   r$   r6   r   r   r   docker_network_disconnectF  s    rf   c             C   sz   | j r
g S y"t| dd|gddd }t|S  tk
rt } z*yt|jS  tk
rb   |Y nX W dd}~X Y nX dS )zU
    :type args: EnvironmentConfig
    :type network: str
    :rtype: list[dict]
    r6   rc   T)rI   r   N)rd   rA   rY   r[   r   rP   re   )r-   r6   rP   rV   r   r   r   docker_network_inspectO  s    
rg   Fc             C   s*   |sg }t | dg| |g | |||dS )z
    :type args: EnvironmentConfig
    :type container_id: str
    :type cmd: list[str]
    :type options: list[str] | None
    :type capture: bool
    :type stdin: BinaryIO | None
    :type stdout: BinaryIO | None
    :rtype: str | None, str | None
    exec)rI   rH   rP   )rA   )r-   r$   rU   rG   rI   rH   rP   r   r   r   rJ   b  s    rJ   c             C   s$   t | dddgddd\}}t|S )z>
    :param args: CommonConfig
    :rtype: dict[str, any]
    r    z--formatz
{{json .}}T)rI   rX   )rA   rY   r[   )r-   rP   ra   r   r   r   docker_infos  s    ri   c             C   s$   t | dddgddd\}}t|S )z>
    :param args: CommonConfig
    :rtype: dict[str, any]
    versionz--formatz
{{json .}}T)rI   rX   )rA   rY   r[   )r-   rP   ra   r   r   r   docker_version|  s    rk   c          	   C   s"   t  }t| dg| |||||dS )z
    :type args: CommonConfig
    :type cmd: list[str]
    :type capture: bool
    :type stdin: file | None
    :type stdout: file | None
    :type always: bool
    :rtype: str | None, str | None
    r   )envrI   rH   rP   rX   )docker_environmentr   )r-   rU   rI   rH   rP   rX   rl   r   r   r   rA     s    
rA   c              C   s$   t  } | tdd tjD  | S )z 
    :rtype: dict[str, str]
    c             s   s&   | ]}| d r|tj| fV  qdS )ZDOCKER_N)r   r   r   )r\   keyr   r   r   	<genexpr>  s    z%docker_environment.<locals>.<genexpr>)r	   updatedictr   r   )rl   r   r   r   rm     s    rm   )N)NFNN)FNNF)0__doc__
__future__r   r   r   type__metaclass__rY   r   rB   ior   r   utilr   r	   r
   r   r   httpr   Zutil_commonr   configr   rK   r   r   r#   r1   r5   r,   r7   r2   r?   rN   rQ   rW   r>   rb   r+   rf   rg   rJ   ri   rk   rA   rm   r   r   r   r   <module>   sB   !
 	
		
