U
    ]&                     @   s   d dl mZ d dl mZ d dlm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 G dd deZdd ZdS )    )absolute_import)unicode_literals)reduceN)ImageNotFound   )LABEL_CONTAINER_NUMBER)LABEL_ONE_OFF)LABEL_PROJECT)LABEL_SERVICE)
LABEL_SLUG)LABEL_VERSION)truncate_id)ComposeVersionc                   @   sL  e Zd ZdZdud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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e	d%d& Ze	d'd( Ze	d)d* Ze	d+d, Ze	d-d. Ze	d/d0 Ze	d1d2 Ze	d3d4 Ze	d5d6 Ze	d7d8 Z e	d9d: Z!e	d;d< Z"e	d=d> Z#e	d?d@ Z$dAdB Z%dCdD Z&dvdFdGZ'dHdI Z(dJdK Z)dLdM Z*dNdO Z+dPdQ Z,dRdS Z-dTdU Z.dVdW Z/dXdY Z0dZd[ Z1d\d] Z2d^d_ Z3d`da Z4dbdc Z5ddde Z6dfdg Z7dhdi Z8djdk Z9dldm Z:dndo Z;dpdq Z<drds Z=dtS )w	Containerzf
    Represents a Docker container, constructed from the output of
    GET /containers/:id:/json.
    Fc                 C   s   || _ || _|| _d | _d S N)client
dictionaryhas_been_inspected
log_stream)selfr   r   r    r   3/usr/lib/python3/dist-packages/compose/container.py__init__   s    zContainer.__init__c                 K   s:   t |}|dkrdS |d |d d| d}| ||f|S )zW
        Construct a container object from the output of GET /containers/json.
        NIdImage/)r   r   Name)get_container_name)clsr   r   kwargsnameZnew_dictionaryr   r   r   from_ps   s    zContainer.from_psc                 C   s   | || |ddS )NT)r   )inspect_container)r   r   idr   r   r   from_id.   s    zContainer.from_idc                 K   s   |j f |}| ||d S Nr   )Zcreate_containerr$   )r   r   optionsZresponser   r   r   create2   s    zContainer.createc                 C   s
   | j d S r%   r   r   r   r   r   r#   7   s    zContainer.idc                 C   s
   | j d S )Nr   r(   r)   r   r   r   image;   s    zContainer.imagec                 C   s   | j | jS r   )r   inspect_imager*   r)   r   r   r   image_config?   s    zContainer.image_configc                 C   s   | j d d S )N   )r#   r)   r   r   r   short_idC   s    zContainer.short_idc                 C   s   | j d dd  S )Nr   r   r(   r)   r   r   r   r    G   s    zContainer.namec                 C   s   | j tS r   )labelsgetr	   r)   r   r   r   projectK   s    zContainer.projectc                 C   s   | j tS r   )r/   r0   r
   r)   r   r   r   serviceO   s    zContainer.servicec                 C   sB   | j d| j| jr8d| j| jd k	r0| jn| jS | j S d S )N{0}_{1})r    
startswithformatr1   r2   numberslugr)   r   r   r   name_without_projectS   s     zContainer.name_without_projectc                 C   s4   | j r
d S | jt}|s,td| jtt|S )Nz'Container {0} does not have a {1} label)one_offr/   r0   r   
ValueErrorr5   r.   int)r   r6   r   r   r   r6   Z   s     zContainer.numberc                 C   s   | j s
d S t| j S r   )	full_slugr   r)   r   r   r   r7   f   s    zContainer.slugc                 C   s   | j tS r   )r/   r0   r   r)   r   r   r   r<   l   s    zContainer.full_slugc                 C   s   | j tdkS )NTrue)r/   r0   r   r)   r   r   r   r9   p   s    zContainer.one_offc                 C   s   |    | dpi S )NzNetworkSettings.Ports)inspect_if_not_inspectedr0   r)   r   r   r   portst   s    zContainer.portsc                    s,   dd  d  fddtt| jD S )Nc                    s   |s
 gS  fdd|D S )Nc                    s    g | ]}d j f d i|qS )z{HostIp}:{HostPort}->{private}private)r5   ).0Zpubr@   r   r   
<listcomp>~   s   zGContainer.human_readable_ports.<locals>.format_port.<locals>.<listcomp>r   )r@   Zpublicr   rB   r   format_port{   s
    
z3Container.human_readable_ports.<locals>.format_portz, c                 3   s   | ]}d   | V  qdS ),N)join)rA   itemrD   r   r   	<genexpr>   s   z1Container.human_readable_ports.<locals>.<genexpr>)rF   sortedsixZ	iteritemsr?   r)   r   rH   r   human_readable_portsy   s    zContainer.human_readable_portsc                 C   s   |  dpi S )NzConfig.Labelsr0   r)   r   r   r   r/      s    zContainer.labelsc                 C   s
   |  dS )NzConfig.StopSignalrM   r)   r   r   r   stop_signal   s    zContainer.stop_signalc                 C   s   |  dpd S )NzHostConfig.LogConfigrM   r)   r   r   r   
log_config   s    zContainer.log_configc                 C   s@   | j r
dS | jrdS | jr.| dr(dS | jS d| d S d S )NZPausedZ
RestartingzState.GhostZGhostzExit %sState.ExitCode)	is_pausedis_restarting
is_runningr0   human_readable_health_statusr)   r   r   r   human_readable_state   s    zContainer.human_readable_statec                 C   s*   |  dpg }|  dpg }d|| S )NzConfig.Entrypointz
Config.Cmd )r0   rF   )r   Z
entrypointcmdr   r   r   human_readable_command   s    z Container.human_readable_commandc                    s(   dd  t  fdd| dp g D S )Nc                 S   s   d| kr|  ddS | d fS )N=r   )split)varr   r   r   	parse_env   s    z(Container.environment.<locals>.parse_envc                 3   s   | ]} |V  qd S r   r   )rA   r[   r\   r   r   rI      s     z(Container.environment.<locals>.<genexpr>z
Config.Env)dictr0   r)   r   r]   r   environment   s    zContainer.environmentc                 C   s
   |  dS )NrP   rM   r)   r   r   r   	exit_code   s    zContainer.exit_codec                 C   s
   |  dS )NzState.RunningrM   r)   r   r   r   rS      s    zContainer.is_runningc                 C   s
   |  dS )NzState.RestartingrM   r)   r   r   r   rR      s    zContainer.is_restartingc                 C   s
   |  dS )NzState.PausedrM   r)   r   r   r   rQ      s    zContainer.is_pausedc                 C   s
   |  dS )NzHostConfig.LogConfig.TyperM   r)   r   r   r   
log_driver   s    zContainer.log_driverc                 C   s   | j }| p|dkS )N)z	json-fileZjournald)ra   )r   Zlog_typer   r   r   has_api_logs   s    zContainer.has_api_logsc                 C   s8   d}|  d}|dkr |d7 }n|dk	r4|d| 7 }|S )z; Generate UP status string with up time and health
        ZUpzState.Health.StatusZstartingz (health: starting)Nz (%s)rM   )r   Zstatus_stringZcontainer_statusr   r   r   rT      s    

z&Container.human_readable_health_statusc                 C   s   | j r| jdddd| _dS )z`A log stream can only be attached if the container uses a json-file
        log driver.
        T)stdoutstderrstreamN)rb   attachr   r)   r   r   r   attach_log_stream   s    zContainer.attach_log_streamc                 C   s$   |    dd }t||d| jS )zReturn a value from the container or None if the value is not set.

        :param key: a string using dotted notation for nested dictionary
                    lookups
        c                 S   s   | pi  |S r   rM   )r   keyr   r   r   	get_value   s    z Container.get.<locals>.get_value.)r>   r   rZ   r   )r   rh   ri   r   r   r   r0      s    zContainer.gettcpc                 C   s,   | j d||f }|r(djf |d S d S )Nz%s/%sz{HostIp}:{HostPort}r   )r?   r0   r5   )r   ZportZprotocolr   r   r   get_local_port   s    zContainer.get_local_portc                 C   s(   |  dD ]}|d |kr
|  S q
d S )NZMountsZDestinationrM   )r   Z
mount_destZmountr   r   r   	get_mount   s    
zContainer.get_mountc                 K   s   | j j| jf|S r   )r   startr#   r   r&   r   r   r   rn      s    zContainer.startc                 K   s   | j j| jf|S r   )r   stopr#   ro   r   r   r   rp      s    zContainer.stopc                 K   s   | j j| jf|S r   )r   pauser#   ro   r   r   r   rq      s    zContainer.pausec                 K   s   | j j| jf|S r   )r   unpauser#   ro   r   r   r   rr      s    zContainer.unpausec                 K   s   | j j| jf|S r   )r   killr#   ro   r   r   r   rs      s    zContainer.killc                 K   s   | j j| jf|S r   )r   restartr#   ro   r   r   r   rt      s    zContainer.restartc                 K   s   | j j| jf|S r   )r   Zremove_containerr#   ro   r   r   r   remove  s    zContainer.removec                 K   s   | j j| j|f|S r   )r   Zexec_creater#   )r   Zcommandr&   r   r   r   create_exec  s    zContainer.create_execc                 K   s   | j j|f|S r   )r   Z
exec_start)r   Zexec_idr&   r   r   r   
start_exec  s    zContainer.start_execc                 C   s.   | j | js*| j| jd| j| j  dS )zpRename the container to a hopefully unique temporary container name
        by prepending the short id.
        r3   N)r    r4   r.   r   renamer#   r5   r)   r   r   r   rename_to_tmp_name  s
     zContainer.rename_to_tmp_namec                 C   s   | j s|   d S r   )r   inspectr)   r   r   r   r>     s    z"Container.inspect_if_not_inspectedc                 C   s   | j | jddS )NZ
StatusCode   )r   waitr#   r0   r)   r   r   r   r|     s    zContainer.waitc                 O   s   | j j| jf||S r   )r   logsr#   r   argsr   r   r   r   r}     s    zContainer.logsc                 C   s   | j | j| _d| _| jS )NT)r   r"   r#   r   r   r)   r   r   r   rz     s    zContainer.inspectc                 C   s.   z| j | j W n tk
r(   Y dS X dS )NFT)r   r+   r*   r   r)   r   r   r   image_exists#  s
    zContainer.image_existsc                 C   s   |   s|| jd< dS )zu If this container's image has been removed, temporarily replace the old image ID
            with `img_id`.
        r   N)r   r   )r   Zimg_idr   r   r   reset_image+  s    zContainer.reset_imagec                 O   s   | j j| jf||S r   )r   rf   r#   r~   r   r   r   rf   2  s    zContainer.attachc                 C   s"   t | jtt dk o | j|kS )Nz1.21.0)r   r/   r0   r   r1   )r   Zproject_namer   r   r   has_legacy_proj_name5  s    zContainer.has_legacy_proj_namec                 C   s   d| j | jd d f S )Nz<Container: %s (%s)>   )r    r#   r)   r   r   r   __repr__;  s    zContainer.__repr__c                 C   s    t | t |krdS | j|jkS )NF)typer#   )r   otherr   r   r   __eq__>  s    zContainer.__eq__c                 C   s
   | j  S r   )r#   __hash__r)   r   r   r   r   C  s    zContainer.__hash__N)F)rk   )>__name__
__module____qualname____doc__r   classmethodr!   r$   r'   propertyr#   r*   r,   r.   r    r1   r2   r8   r6   r7   r<   r9   r?   rL   r/   rN   rO   rU   rX   r_   r`   rS   rR   rQ   ra   rb   rT   rg   r0   rl   rm   rn   rp   rq   rr   rs   rt   ru   rv   rw   ry   r>   r|   r}   rz   r   r   rf   r   r   r   r   r   r   r   r   r      s   
































	r   c                 C   sJ   |  ds|  dsd S d| kr(| d S t| d dd d}|dd S )Nr   ZNamesc                 S   s   t | dS )Nr   )lenrZ   )nr   r   r   <lambda>N      z$get_container_name.<locals>.<lambda>)rh   r   )r0   minrZ   )Z	containerZshortest_namer   r   r   r   G  s    r   )Z
__future__r   r   	functoolsr   rK   Zdocker.errorsr   Zconstr   r   r	   r
   r   r   Zutilsr   versionr   objectr   r   r   r   r   r   <module>   s      6