a
   ]&ߚL                   @   sx  d dl Z d dlZd dlZd dlZ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
 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 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$ 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/ ddlm0Z0 dd lm1Z1 dd!lm2Z2 dd"lm3Z3 dd#lm4Z4 dd$lm5Z5 dd%lm6Z6 dd&l7m8Z8 dd'l9m:Z: dd(l9m;Z; dd)l9m<Z< dd*l=m>Z> dd+l m?Z? dd,l m@Z@ dd-lAmBZB dd.lAmCZC dd/lAmDZD dd0lAmEZE dd1lAmFZF dd2lAmGZG d d3lHmIZI eJeKZLg d4ZMd5ZNd6ZOG d7d8 d8ePZQG d9d: d:ePZRG d;d< d<ePZSe
d=d>ZTe
d?d@ZUe jVG dAdB dBe jWZXe jVG dCdD dDe jWZYe jVG dEdF dFe jWZZG dGdH dHZ[dIdJ Z\G dKdL dLZ]G dMdN dNe]Z^G dOdP dPe]Z_G dQdR dRZ`G dSdT dTe`ZaG dUdV dVe`ZbG dWdX dXZcG dYdZ dZZdG d[d\ d\Zedd]d^Zfd_d` Zgdadb Zhdcdd Zidedf Zjdgdh Zkdidj Zldkdl Zmdmdn Zndodp Zodqdr Zpdsdt Zqdudv Zrdwdx Zsdydz Ztd{d| ZuG d}d~ d~ZvG dd dZwdS )    N)
namedtuple)OrderedDict)
attrgetter)APIError)ImageNotFound)NotFound)	LogConfig)Mount)version_gte)
version_lt)build_port_bindings)
split_port)convert_tmpfs_mounts   )__version__)const)progress_stream)DOCKER_CONFIG_KEYS)is_url)merge_environment)merge_labels)DependencyError)	MountSpec)ServicePort)
VolumeSpec)DEFAULT_TIMEOUT)IS_WINDOWS_PLATFORM)LABEL_CONFIG_HASH)LABEL_CONTAINER_NUMBER)LABEL_ONE_OFF)LABEL_PROJECT)LABEL_SERVICE)
LABEL_SLUG)LABEL_VERSION)NANOCPUS_SCALE)WINDOWS_LONGPATH_PREFIX)	Container)HealthCheckFailed)NoHealthCheckConfigured)OperationFailedErrorparallel_execute)stream_output)StreamOutputError)generate_random_id)	json_hash)parse_bytes)parse_seconds_float)truncate_id)unique_everseen)binarystr_to_unicode)-cap_addcap_dropcgroup_parent	cpu_countcpu_percent
cpu_period	cpu_quotacpu_rt_periodcpu_rt_runtime
cpu_sharescpuscpusetdevice_cgroup_rulesdevicesdevice_requestsdns
dns_searchdns_optZenv_fileextra_hosts	group_addinitZipc	isolation	read_only
log_driverZlog_opt	mem_limitmem_reservationmemswap_limitmem_swappinessoom_kill_disableoom_score_adjpid
pids_limit
privilegedrestartruntimesecurity_optshm_sizestorage_optsysctlsuserns_modevolumes_fromvolume_driverZservice_startedZservice_healthyc                   @   s   e Zd Zdd ZdS )
BuildErrorc                 C   s   || _ || _d S N)servicereason)selfra   rb    rd   3/usr/lib/python3.9/site-packages/compose/service.py__init__v   s    zBuildError.__init__N__name__
__module____qualname__rf   rd   rd   rd   re   r_   u   s   r_   c                   @   s   e Zd Zdd ZdS )NeedsBuildErrorc                 C   s
   || _ d S r`   ra   rc   ra   rd   rd   re   rf   |   s    zNeedsBuildError.__init__Nrg   rd   rd   rd   re   rk   {   s   rk   c                   @   s   e Zd ZdS )NoSuchImageErrorN)rh   ri   rj   rd   rd   rd   re   rn      s   rn   ServiceNamezproject service numberConvergencePlanzaction containersc                   @   s(   e Zd ZdZdZdZdZedd ZdS )ConvergenceStrategyzrEnumeration for all possible convergence strategies. Values refer to
    when containers should be recreated.
    r         c                 C   s   | t | juS r`   )typeneverrc   rd   rd   re   allows_recreate   s    z#ConvergenceStrategy.allows_recreateN)	rh   ri   rj   __doc__changedalwaysru   propertyrw   rd   rd   rd   re   rq      s   rq   c                   @   s   e Zd ZdZdZdZdZdS )	ImageTypez5Enumeration for the types of images known to compose.r   r   rr   N)rh   ri   rj   rx   nonelocalallrd   rd   rd   re   r|      s   r|   c                   @   s   e Zd ZdZdZdZdZdS )BuildActionz+Enumeration for the possible build actions.r   r   rr   N)rh   ri   rj   rx   r}   forceskiprd   rd   rd   re   r      s   r   c                   @   s>  e Zd Zd~ddZdd Zdd	d
ZdddZdd Zdd ZdddZ	dddZ
ejddfddZdd Zdd Zedd Zedd Zejdfdd Zd!d" Zdd#d$Zd%d& Zd'd( Zdd)d*Zdd,d-Zdd.d/Zd0d1 Zdd2d3Zdd4d5Zed6d7 Z dd8d9Z!dd:d;Z"d<d= Z#ed>d? Z$d@dA Z%dBdC Z&dDdE Z'dFdG Z(dHdI Z)dJdK Z*ddLdMZ+dNdO Z,ddPdQZ-dRdS Z.dTdU Z/dVdW Z0ddXdYZ1dZd[ Z2dd\d]Z3d^d_ Z4dd`daZ5dbdc Z6ddde Z7ddfdgZ8edhdi Z9ddjdkZ:dldm Z;dndo Z<dpdq Z=ddrdsZ>ddtduZ?dvdw Z@dxdy ZAdzd{ ZBd|d} ZCdS )ServiceNdefaultFr   c                 K   s   || _ || _|| _|| _|pg | _|p(g | _|p6td | _|pDtd | _	|pRt
d | _|p\i | _|	pfg | _|
| _|| _|| _|pg | _d S r`   )nameclientprojectuse_networkinglinksr]   IpcModeipc_modeNetworkModenetwork_modePidModepid_modenetworkssecrets	scale_numdefault_platformoptionsextra_labels)rc   r   r   r   r   r   r]   r   r   r   scaler   r   r   r   r   rd   rd   re   rf      s    



zService.__init__c                 C   s   d | jS )Nz<Service: {}>)formatr   rv   rd   rd   re   __repr__   s    zService.__repr__c              
      s   |d u ri }| d j|d|p"g  i ttd  fdd jj||dD }|rZ|S | d j|dd|prg  i tt fdd	td  fd
d jj||dD S )Nlabelone_offc                    s   g | ]}t  j|qS rd   r&   Zfrom_psr   .0	containerrv   rd   re   
<listcomp>   s   z&Service.containers.<locals>.<listcomp>r   filtersTr   legacyc                    s   |   jS r`   )has_legacy_proj_namer   crv   rd   re   <lambda>       z$Service.containers.<locals>.<lambda>c                    s   g | ]}t  j|qS rd   r   r   rv   rd   re   r      s   )updatelabelslistfilterr   
containers)rc   stoppedr   r   r   resultrd   rv   re   r      s,    
 zService.containersc                 C   s8   | j dt|gdD ]
}|  S td| j|dS )zReturn a :class:`compose.container.Container` for this service. The
        container must be active, and match `number`.
        {}={})r   zNo container found for {}_{}N)r   r   r   
ValueErrorr   )rc   numberr   rd   rd   re   get_container   s    zService.get_containerc                 K   s,   | j dd}|D ]}| j|fi | q|S )NTr   )r   start_container_if_stopped)rc   r   r   r   rd   rd   re   start   s    zService.startc                 C   sH   | j r$|dkr$td| j| j f  |  rD|dkrDtd| j  d S )Nr   zThe "%s" service is using the custom container name "%s". Docker requires each container to have a unique name. Remove the custom name to scale the service.zThe "%s" service specifies a port on the host. If multiple containers for this service are created on a single host, the port will clash.)custom_container_namelogwarningr   specifies_host_port)rc   desired_numrd   rd   re   show_scale_warnings   s    
zService.show_scale_warningsc                    s0    |  jdd}t|}|D ]2}| js4q"td|j   j||dd q"||krltd dS ||kr jdd}|t|krdd	 |D } fd
d	|D }|D ]}|	  qt
t|t| }t|tdd}	 |	||dd ||k r,|| }
t|tdd} ||
 d | dS )ar  
        Adjusts the number of containers to the specified number and ensures
        they are running.

        - creates containers until there are at least `desired_num`
        - stops containers until there are at most `desired_num` running
        - starts containers until there are at least `desired_num` running
        - removes all stopped containers
        Fr   z(Recreating container with legacy name %s)start_new_containerz)Desired container number already achievedNTc                 S   s   g | ]}|j s|qS rd   
is_runningr   r   rd   rd   re   r      s   z!Service.scale.<locals>.<listcomp>c                    s   g | ]}  |gr|qS rd   )_containers_have_divergedr   rv   rd   re   r   %  s   r   key)r   r   lenr   r   r   infor   recreate_containerremover   setsortedr   _execute_convergence_start
_downscale)rc   r   timeoutZrunning_containersZnum_runningr   Zall_containersZstopped_containersZdivergent_containersZsorted_containersZnum_to_stopZsorted_running_containersrd   rv   re   r     sD    





zService.scalec              
   K   s   |    | j||p| j|d||d}d|v rD|sDtd|d   ztj| jfi |W S  ty } z$t	d| j
t|jf W Y d}~n
d}~0 0 dS )zn
        Create a container for this service. If the image doesn't exist, attempt to pull
        it.
        r   )r   previous_containerr   zCreating %sz*Cannot create container for service %s: %sN)ensure_image_exists_get_container_create_options_next_container_numberr   r   r&   creater   r   r)   r   r4   explanation)rc   r   r   r   quietoverride_optionscontainer_optionsexrd   rd   re   create_container;  s    zService.create_containerc                 C   s   |   r"|tjkr"| j|d d S z|   W d S  tyB   Y n0 |   s\| j|d d S |tjkrnt| | j|d t	
d| j d S )N)cli)silentzImage for service {} was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.)can_be_builtr   r   buildimagern   pullr   rk   r   r   r   r   )rc   Zdo_buildr   r   rd   rd   re   r   Y  s&    
zService.ensure_image_existsc                 C   s8   z| j | jW S  ty2   td| jY n0 d S NzImage '{}' not found)r   Zinspect_distribution
image_namer   rn   r   rv   rd   rd   re   get_image_registry_dataq  s    zService.get_image_registry_datac                 C   s8   z| j | jW S  ty2   td| jY n0 d S r   )r   Zinspect_imager   r   rn   r   rv   rd   rd   re   r   w  s    zService.imagec                 C   s    | j ddj| | jddS )Nr   z{project}_{s.name}z_-)sr   )r   getr   r   lstriprv   rd   rd   re   r   }  s    zService.image_namec                 C   s(   | j d}|s$t| jjdr$| j}|S )Nplatform1.35)r   r   r
   r   api_versionr   )rc   r   rd   rd   re   r     s    zService.platformc                 C   s   | j dd}|rtdg S |s(tdg S |tju r<td|S |tju sP| |rZtd|S dd |D }|rvtd|S td	|S )
NTr   r   r   r   recreatec                 S   s   g | ]}|j s|qS rd   r   r   rd   rd   re   r     r   z,Service.convergence_plan.<locals>.<listcomp>noop)r   rp   rq   ru   rz   r   )rc   Zstrategyr   r   r   rd   rd   re   convergence_plan  s     





zService.convergence_planc              
   C   s   d }z
| j }W n: tyH } z"td| jt| W Y d }~dS d }~0 0 d}|D ]R}|| jrxtd|j  d}qR|j	t
d }||krRtd|j|| d}qR|S )NzService %s has diverged: %sTFz$%s has diverged: Legacy project namez%s has diverged: %s != %s)config_hashrn   r   debugr   strr   r   r   r   r   )rc   r   r   eZhas_divergedr   Zcontainer_config_hashrd   rd   re   r     s.    

z!Service._containers_have_divergedc                    sx     }fdd fdd}tfddt||| D  fdd|d	\}}	|	 D ]}
t|
qf|S )
Nc                    sL   r| j f ddd}n| j |dd} s6|  rHsH| |S )NT)r   r   )r   r   )r   attach_log_streamstart_container)ra   nr   )detachedr   r   rc   r   rd   re   create_and_start  s    
z=Service._execute_convergence_create.<locals>.create_and_startc                    s(    rd | j| jdgS | j| jS )N_run)joinr   ra   get_container_namer   service_name)r   rc   rd   re   get_name  s    z5Service._execute_convergence_create.<locals>.get_namec                    s   g | ]}t  j j|qS rd   )ro   r   r   )r   indexrv   rd   re   r     s   z7Service._execute_convergence_create.<locals>.<listcomp>c                    s    | j S r`   r   r   )r   rc   rd   re   r     r   z5Service._execute_convergence_create.<locals>.<lambda>ZCreating)r   r+   rangevaluesr)   )rc   r   r   r   r   r   ir   r   errorserrorrd   )r   r   r   r   rc   r   re   _execute_convergence_create  s    	
	
z#Service._execute_convergence_createc           
         s   |d ur4t ||kr4||d   |d | } fdd}t||dd d\}}| D ]}	t|	qf|d urt ||k r||t |   |S )Nc                    s   j |   dS )N)r   attach_logsr   renew_anonymous_volumes)r   r   r   r  rc   r   r   rd   re   r     s    z7Service._execute_convergence_recreate.<locals>.recreatec                 S   s   | j S r`   r   r   rd   rd   re   r     r   z7Service._execute_convergence_recreate.<locals>.<lambda>Z
Recreatingr   r   r+   r   r)   extendr  )
rc   r   r   r   r   r   r  r   r   r  rd   r  re   _execute_convergence_recreate  s"    
z%Service._execute_convergence_recreatec           
         s   |d ur4t ||kr4||d  | |d | }|r|dd |D }t| fdddd d\}}| D ]}	t|	qn|d urt ||k r||t |  | |S )Nc                 S   s   g | ]}|j s|qS rd   r   r   rd   rd   re   r     r   z6Service._execute_convergence_start.<locals>.<listcomp>c                    s   j |   ddS )NT)r  r   )r   r   r   rc   rd   re   r   	  r   z4Service._execute_convergence_start.<locals>.<lambda>c                 S   s   | j S r`   r  r   rd   rd   re   r   
  r   ZStartingr  )
rc   r   r   r   r   r   r   r   r   r  rd   r  re   r     s$    
z"Service._execute_convergence_startc                    s$    fdd}t ||dd d d S )Nc                    s   | j  d |   d S )Nr   )stopstop_timeoutr   r  rc   r   rd   re   stop_and_remove  s    z+Service._downscale.<locals>.stop_and_removec                 S   s   | j S r`   r  r   rd   rd   re   r     r   z$Service._downscale.<locals>.<lambda>zStopping and removingr*   )rc   r   r   r  rd   r  re   r     s    zService._downscaleTc
                 C   s  |\}
}|d ur|n| j }t|tdd}| | |
dv rT| j||||
dk|	dS |s\d }|
dkr|r|  d }|D ]}|| qx| ||||||S |
dkr| |||||S |
d	kr|t	|kr| |||||S |D ]}t
d
|j  q|S td|
d S )Nr   r   )r   r   r   )r   r   r   Idr   r   z%s is up-to-datezInvalid action: {})r   r   r   r   r  r   Zreset_imager
  r   r   r   r   r   	Exceptionr   )rc   Zplanr   r   r   Zscale_overrideZrescaleZreset_container_imager  r   actionr   r   Zimg_idr   rd   rd   re   execute_convergence_plan#  sH    




z Service.execute_convergence_planc                 C   sZ   |j | |d |  | j|s&|nd|jdd}|r@|  |rN| | |  |S )zRecreate a container.

        The original container is renamed to a temporary name so that data
        volumes can be copied to the new container, before the original
        container is removed.
        r  NT)r   r   r   )r  r  Zrename_to_tmp_namer   r   r   r   r   )rc   r   r   r  r   r  Znew_containerrd   rd   re   r   X  s    	

zService.recreate_containerc                 C   s,   |d ur|S t | jd}|d ur(|S tS )Nstop_grace_period)r1   r   r   r   r  rd   rd   re   r  o  s    zService.stop_timeoutc                 C   s4   |j s0|std|j  |r&|  | |S d S )NzStarting %s)r   r   r   r   r   r   )rc   r   r  r   rd   rd   re   r   w  s    z"Service.start_container_if_stoppedc              
   C   sp   |  || z|  W nR tyj } z:t|j}d|v rDtd td| j	|W Y d }~n
d }~0 0 |S )Nz/driver failed programming external connectivityz+Host is already in use by another containerzCannot start service {}: {})
connect_container_to_networksr   r   r4   r   r   warnr)   r   r   )rc   r   use_network_aliasesr   Zexplrd   rd   re   r     s    

(zService.start_containerc                 C   s   t t| j dd ddS )Nc                 S   s   | d  dpdS )Nr   priorityr   r   )trd   rd   re   r     r   z.Service.prioritized_networks.<locals>.<lambda>T)r   reverse)r   r   r   itemsrv   rd   rd   re   prioritized_networks  s    zService.prioritized_networksc                 C   s   | d}| j D ]z\}}||v r@t||r0q| j|j| |rP| ||ng }| jj|j||| dd | dd | 	d| dd d qd S )NzNetworkSettings.Networksipv4_addressipv6_addressFlink_local_ips)aliasesr  r   r   r!  )
r   r  r  short_id_alias_existsr   Z!disconnect_container_from_networkid_get_aliasesZconnect_container_to_network
_get_links)rc   r   r  Zconnected_networksnetworkZnetdefsr"  rd   rd   re   r    s    




z%Service.connect_container_to_networksc                 C   s<   |   D ].}td|j  |j| |d |  qd S )NzRemoving %sr  )duplicate_containersr   r   r   r  r  r   )rc   r   r   rd   rd   re   remove_duplicate_containers  s    z#Service.remove_duplicate_containersc                 c   sJ   t | jdddd d}t }|D ]"}|j|v r8|V  q"||j q"d S )NTr   c                 S   s
   |  dS )NZCreatedr  r   rd   rd   re   r     r   z.Service.duplicate_containers.<locals>.<lambda>r   )r   r   r   r   add)rc   r   numbersr   rd   rd   re   r(    s    

zService.duplicate_containersc                 C   s   t |  S r`   )r/   config_dictrv   rd   rd   re   r     s    zService.config_hashc                    s<    fdd} j |    jj j jdd  jD dS )Nc                      s(   z   d W S  ty"   Y d S 0 d S Nr  )r   rn   rd   rv   rd   re   image_id  s    z%Service.config_dict.<locals>.image_idc                 S   s&   g | ]}t |jtr|jj|jfqS rd   )
isinstancesourcer   r   moder   vrd   rd   re   r     s   z'Service.config_dict.<locals>.<listcomp>)r   r.  r   netr   r   r]   )r   get_link_namesr   r$  r   r   r]   )rc   r.  rd   rv   re   r,    s    zService.config_dictc                 C   sh   | j j}| jj}| jj}|  |   |r0|gng  |r>|gng  |rL|gng  t| jdi 	  S )N
depends_on)
r   r   r   r   get_linked_service_namesget_volumes_from_namesr   r   r   keys)rc   net_namepid_namespaceipc_namespacerd   rd   re   get_dependency_names  s    zService.get_dependency_namesc                 C   s   | j j}| jj}| jj}dd |  D }|dd |  D  ||rR|d ini  ||rh|d ini  ||r~|d ini  || jdi  | jdi 	 D ]N\}}|d t
krdd ||< q|d tkrd	d ||< qtd
|d q|S )Nc                 S   s   i | ]
}|d qS r`   rd   r   r   rd   rd   re   
<dictcomp>  s   z2Service.get_dependency_configs.<locals>.<dictcomp>c                 s   s   | ]}|d fV  qd S r`   rd   r>  rd   rd   re   	<genexpr>  s   z1Service.get_dependency_configs.<locals>.<genexpr>r6  Z	conditionc                 S   s   dS )NTrd   r   rd   rd   re   r     r   z0Service.get_dependency_configs.<locals>.<lambda>c                 S   s   |   S r`   )
is_healthyrA  rd   rd   re   r     r   z%depends_on condition "{}" is invalid.)r   r   r   r   r7  r   r8  r   r   r  CONDITION_STARTEDCONDITION_HEALTHYr   r   )rc   r:  r;  r<  ZconfigsZsvcconfigrd   rd   re   get_dependency_configs  s0    
zService.get_dependency_configsc                 C   s   dd | j D S )Nc                 S   s   g | ]\}}|j qS rd   r  )r   ra   r   rd   rd   re   r      r   z4Service.get_linked_service_names.<locals>.<listcomp>r   rv   rd   rd   re   r7    s    z Service.get_linked_service_namesc                 C   s   dd | j D S )Nc                 S   s   g | ]\}}|j |fqS rd   r  )r   ra   aliasrd   rd   re   r     r   z*Service.get_link_names.<locals>.<listcomp>rG  rv   rd   rd   re   r5    s    zService.get_link_namesc                 C   s   dd | j D S )Nc                 S   s    g | ]}t |jtr|jjqS rd   )r/  r0  r   r   )r   r   rd   rd   re   r     r   z2Service.get_volumes_from_names.<locals>.<listcomp>r]   rv   rd   rd   re   r8    s    zService.get_volumes_from_namesc              
   C   sd   |rd S t | jdd| jddid| jdd| jdddid}dd |D }|sXd	S t|d	 S )
NTr   Fr   r   r   c                 S   s   g | ]}|j d ur|j qS r`   r   r   rd   rd   re   r     r   z2Service._next_container_number.<locals>.<listcomp>r   )	itertoolschain_fetch_containersr   max)rc   r   r   r+  rd   rd   re   r     s    	zService._next_container_numberc                    s2    fddt d fdd jjf i |D S )Nc                    s.   zt  j| d W S  ty(   Y d S 0 d S r-  )r&   Zfrom_idr   r   r  rv   rd   re   soft_inspect  s    z/Service._fetch_containers.<locals>.soft_inspectc                    s   g | ]} |qS rd   rd   r   )rN  rd   re   r      s   z-Service._fetch_containers.<locals>.<listcomp>)r   r   r   )rc   Zfetch_optionsrd   )rc   rN  re   rL    s    zService._fetch_containersc                 C   s.   t | jh|r|jhnt B t|ddB S )Nr"  rd   )r   r   short_idr   r   )rc   r'  r   rd   rd   re   r%  %  s    zService._get_aliasesc                 C   sp   | j s
i S | j | jj }| |i d}|drD|d|d d< |dr`|d|d d< d| jj|iiS )N)ZAliases
IPAMConfigr  rP  ZIPv4Addressr   ZIPv6AddressZEndpointsConfig)r   r   r$  r%  r   )rc   r'  Zendpointrd   rd   re   build_default_networking_config,  s    

z'Service.build_default_networking_configc                 C   s   i }| j D ]>\}}| D ],}|j||p,|j< |j||j< |j||j< qq
|r|  D ](}|j|| j< |j||j< |j||j< qV| jdpg D ](}d|vr|}n|d\}}|||< qdd | D S )Nexternal_links:c                 S   s   g | ]\}}||fqS rd   rd   )r   container_namerH  rd   rd   re   r   S  s   z&Service._get_links.<locals>.<listcomp>)r   r   r   Zname_without_projectr   r   splitr  )rc   link_to_selfr   ra   Z	link_namer   Zexternal_linkrd   rd   re   r&  =  s&    
zService._get_linksc                 C   s   dd | j D S )Nc                 S   s   g | ]}t |qS rd   )build_volume_from)r   specrd   rd   re   r   Y  r   z-Service._get_volumes_from.<locals>.<listcomp>rI  rv   rd   rd   re   _get_volumes_fromX  s    zService._get_volumes_fromc                    s&  | o
| }|rt  nd } fddtD }|dg }|| |ds`  j|||d< |dd t j	j
drd|v rd	|vrd
|d v r|d d
}	|	d |d< |	d |d	< t j	j
drd jv r d |d< d|v sd jv rtt|dg  j|d< d|v s"|r>tt|dg | |d< t  t jd|d|d< t jd|d|d<  |||\}} j|d< t|di  j|d j ||rƈ jnd ||d< tD ]}
||
d  qֈ j||d|d<   }|r||d< t|d |d< |S )Nc                    s"   i | ]}| j v r| j | qS rd   r   )r   krv   rd   re   r?  d  s   z9Service._get_container_create_options.<locals>.<dictcomp>volumesr   detachTz1.23hostnameZ
domainname.r   rr   z1.25r  r  portsexposeenvironmentr   r   r   Zhost_confignetworking_config) r.   r   popr   r   r   r   
setdefaultr   r   r   	partitionr
   r   r  build_container_portsformatted_portsr   r   r   _parse_proxy_configr   _build_container_volume_optionsr   build_container_labelsr   r   r   HOST_CONFIG_KEYS_get_container_host_configrQ  format_environment)rc   r   r   r   r   Zadd_config_hashslugr   Zoverride_volumespartsr   rc  rd   rv   re   r   [  s    








	
z%Service._get_container_create_optionsc           
      C   s  g }g }d|v r8dd | dD }dd | dD }t|| j dpJg ||\}}|d | dd |ppi D |d< t| jjd	rd
d |D pd |d< nR| j dpg |d< |D ]8}|jr|d |j	 q||
  i |d |j	< q|  }	|	rjt| jjd	r>|dd |	D  |d dd |	D  n,| dpLg |d< |d dd |	D  tt||d< ||fS )Nr\  c                 S   s   g | ]}t |tr|qS rd   )r/  r   r2  rd   rd   re   r     s   z;Service._build_container_volume_options.<locals>.<listcomp>c                 S   s   g | ]}t |tr|qS rd   )r/  r   r2  rd   rd   re   r     r   tmpfsrb  c                 S   s   i | ]}|j i qS rd   )internalr2  rd   rd   re   r?    r   z;Service._build_container_volume_options.<locals>.<dictcomp>z1.30c                 S   s   g | ]}t |qS rd   build_mountr2  rd   rd   re   r     r   mountsc                 s   s   | ]}|  V  qd S r`   )legacy_reprr2  rd   rd   re   r@    r   z:Service._build_container_volume_options.<locals>.<genexpr>c                 s   s   | ]}|j i fV  qd S r`   targetr2  rd   rd   re   r@    s   c                 S   s   g | ]}t |qS rd   rs  r2  rd   rd   re   r     r   binds)r   merge_volume_bindingsr   r   r
   r   r   Zis_tmpfsappendrx  rv  get_secret_volumesr   r	  r   r3   )
rc   r   r   r   container_volumescontainer_mountsry  affinitymZsecret_volumesrd   rd   re   rj    s@    
z'Service._build_container_volume_optionsc           
   <   C   sd  t | jfi |}|dd }t|dd }t|}d }t|dtr\|d}d|d< |drzdd |dD nd }d }	d|v rt|dt }	| j	j
| j|d	tt|d
g |d|  |dd| jj|d|d|d|d|d|d|d|d|d|d|d|dt|d||d|d| jj|| jj|d|d|d|d |d!|d"|d#|d$|d%|d&|d'|dd ||d(|d)|d*|	|d+|d,|d-|d.|d/|d0|d1|d2|d3|d4|d5|d6|d7|d8|d9d:9S );Nloggingblkio_configrI   TrX   c                 S   s   g | ]
}|j qS rd   )value)r   ord   rd   re   r     s   z6Service._get_container_host_config.<locals>.<listcomp>r?   )rV  r`  ry  rU   FrB   rC   rD   rF   rE   rV   rW   r5   r6   rM   rN   rO   ulimitsrG   rK   r7   r;   rY   r[   rT   rq  rQ   rR   rP   rH   r\   rJ   r8   r9   r^   r@   r>   rZ   weightweight_devicedevice_read_bpsdevice_read_iopsdevice_write_bpsdevice_write_iopsru  rA   r:   r<   r=   )9r   Zport_bindingsry  r]   rU   r   rB   rC   rD   rF   rE   Zrestart_policyrW   r5   r6   rM   rN   rO   r  
log_configrG   rK   r   rX   r   r7   r;   rY   r[   rT   rq  rQ   rR   rP   rH   r\   rI   	init_pathrJ   r8   r9   	nano_cpusr^   Zcpuset_cpusr>   rZ   Zblkio_weightZblkio_weight_devicer  r  r  r  ru  rA   r:   r<   r=   )dictr   r   convert_blkio_configget_log_configr/  r   intr$   r   Zcreate_host_configr&  r   rh  rY  r   r1  build_ulimitsr   r   )
rc   r   r   r   logging_dictr  r  r  rX   r  rd   rd   re   rm    s    



z"Service._get_container_host_configc                    s   dd   fdd| j D S )Nc                 S   sV   | d j }|d u r(dtj| d j}ntj|sBdtj|}td| d |ddS )Nsecretz{}/{}ZbindfileT)rK   )	rx  r   r   ZSECRETS_PATHr0  ospathisabsr   )r  rx  rd   rd   re   
build_spec1  s    
z.Service.get_secret_volumes.<locals>.build_specc                    s   g | ]} |qS rd   rd   )r   r  r  rd   re   r   :  r   z.Service.get_secret_volumes.<locals>.<listcomp>)r   rv   rd   r  re   r|  0  s    	zService.get_secret_volumesc                 C   s   t tjd}|s&tj}td| j  | j	di }|	di 
 }|rR|| |   D ]\}}||| q^t|	d}| jrt| jjdrtd|	s| jnt|
}|j|| j|||||	dd | ||	d	d ||	d
d |	dd |	drt|	dnd |	dd d|r*t|nd i||	d| j	dd | jd}ztt||}W n4 ty } zt| t|W Y d }~n
d }~0 0 | j  d }|D ]4}d|v rt !d|	dd}|r|"d}q|d u rt| |r|nd|S )NwzBuilding %sr   argscontextr   zEImpossible to perform platform-targeted builds for API version < 1.35
dockerfiler   r'  rx  rY   rG   memoryrJ   )r  tagrmforcermr   nocacher  
cache_fromr   	buildargsr   rx  shmsizerG   container_limitsgziprJ   r   streamzSuccessfully built ([0-9a-f]+) r   ZUnknown)#openr  devnullsysstdoutr   r   r   r   r   copyr   ri  r  re  rewrite_build_pathr   r   r   r   r)   _CLIBuilderr   r   get_cache_fromr0   r   r,   r-   r_   r   closeresearchgroup)rc   Zno_cacher   Zforce_rmr  Zbuild_args_overrider  r  r   r   progressZoutput_stream
build_optsZ
build_argsr[  r3  r  ZbuilderZbuild_outputZ
all_eventsr   r.  Zeventmatchrd   rd   re   r   <  sf    





$


zService.buildc                 C   s&   | dd }|d ur"dd |D }|S )Nr  c                 S   s   g | ]}|r|qS rd   rd   )r   r  rd   rd   re   r     r   z*Service.get_cache_from.<locals>.<listcomp>r  )rc   r  r  rd   rd   re   r    s    zService.get_cache_fromc                 C   s
   d| j v S )Nr   rZ  rv   rd   rd   re   r     s    zService.can_be_builtc                 C   sF   |s
| j ntdd| j }dt|dt| jdt|r>dndgS )Nz[_-]r  r   TrueFalse)r   r  subr   r    r!   r   r   )rc   r   r   Z	proj_namerd   rd   re   r     s
    
zService.labelsc                 C   s   | j dS )NrT  r   r   rv   rd   rd   re   r     s    zService.custom_container_namec                 C   sZ   | j r|d u r| j S t| j|||}dd | jdg D }||v rVtd| j||S )Nc                 S   s   g | ]}| d d qS )rS  r   rU  )r   linkrd   rd   re   r     r   z.Service.get_container_name.<locals>.<listcomp>rR  z3Service {} has a self-referential external link: {})r   build_container_namer   r   r   r   r   r   )rc   r   r   ro  rT  Zext_links_originsrd   rd   re   r     s    
zService.get_container_namec              
   C   s   |r|t jkrdS |t jkr,| jdr,dS td| j z| j	| j W dS  t
yp   td| j Y dS  ty } ztd| j| W Y d }~dS d }~0 0 d S )NFr   zRemoving image %sTzImage %s not found.z)Failed to remove image for service %s: %s)r|   r}   r~   r   r   r   r   r   r   remove_imager   r   r   r  r   )rc   Z
image_typer   rd   rd   re   r    s    zService.remove_imagec                    s(   dd  t  fdd| jdg D S )Nc                 S   s\   t | tr| d}nt| \}}|d u r.dS |d }t |tsDdS |\}}|d urXdS dS )NZ	publishedFr   T)r/  r  r   r   tuple)bindingZexternal_bindingsr   Zexternal_binding	host_portrd   rd   re   has_host_port  s    

z2Service.specifies_host_port.<locals>.has_host_portc                 3   s   | ]} |V  qd S r`   rd   )r   r  r  rd   re   r@    r   z.Service.specifies_host_port.<locals>.<genexpr>r`  )anyr   r   rv   rd   r  re   r     s    zService.specifies_host_portc              
   c   s   zl| j j|fi |}|rXttjd }t||E d H  W d    qj1 sL0    Y  nt|tjE d H  W n> tt	fy } z"|s nt
t| W Y d }~n
d }~0 0 d S )Nr  )r   r   r  r  r  r,   r  r  r-   r   r   r  r   )rc   repoZpull_kwargsr   ignore_pull_failuresoutputr  r   rd   rd   re   _do_pull  s    0zService._do_pullc           	      C   s   d| j vrd S t| j d \}}}|p(dd| jd}|sPtd| j||| |d rnt| jj	drnt
d| ||||}|r|S t|S )	Nr   latestT)r  r  r   zPulling {} ({}{}{})...r   r   zDImpossible to perform platform-targeted pulls for API version < 1.35)r   parse_repository_tagr   r   r   r   r   r   r   r   r)   r  r   Zget_digest_from_pull)	rc   r  r   r  r  r  	separatorkwargsZevent_streamrd   rd   re   r     s"    
zService.pullc              
   C   s   d| j vsd| j vrd S t| j d \}}}|p2d}td| j||| | jj||dd}zt	t
|tjW S  ty } z"|s ntt| W Y d }~n
d }~0 0 d S )Nr   r   r  zPushing {} ({}{}{})...T)r  r  )r   r  r   r   r   r   r   pushr   Zget_digest_from_pushr,   r  r  r-   r  r   )rc   Zignore_push_failuresr  r  r  r  r   rd   rd   re   r    s    
zService.pushc                 C   s\   d}|   D ]J}|  |d}|du r6t| jq|dkrDd}q|dkrt|jq|S )z Check that all containers for this service report healthy.
            Returns false if at least one healthcheck is pending.
            If an unhealthy container is detected, raise a HealthCheckFailed
            exception.
        TzState.Health.StatusNZstartingFZ	unhealthy)r   inspectr   r(   r   r'   rO  )rc   r   Zctnrstatusrd   rd   re   rB  	  s    
zService.is_healthyc                 C   s   | j }d|jvri S t|d|j}|jd ||jd dpBi }ddddd}i }| D ].\}}||vrpq^| ||| < |||  < q^|S )	NZproxiesZ_original_base_urlr   Z	FTP_PROXYZ
HTTP_PROXYZHTTPS_PROXYZNO_PROXY)ZftpProxyZ	httpProxyZ
httpsProxyZnoProxy)r   Z_general_configsgetattrZbase_urlr   r  lower)rc   r   Zdocker_hostZproxy_configZ	permittedr   r[  r3  rd   rd   re   ri    s(    

zService._parse_proxy_configc                 C   s   d| j vrg S | j dS )Nprofilesr  rv   rd   rd   re   get_profiles4  s    
zService.get_profilesc                 C   s6   d| j vrdS | j d}|D ]}||v r dS qdS )Nr  TFr  )rc   Zenabled_profilesZservice_profilesZprofilerd   rd   re   enabled_for_profiles:  s    
zService.enabled_for_profiles)Nr   FNNNNNr   NNNN)FFNN)r   )N)FNNF)FN)N)NFTNTFFN)NFTF)FF)T)T)N)F)N)FN)F)
FFFNNFTFFN)FF)N)FFF)F)Drh   ri   rj   rf   r   r   r   r   r   r   r   r   r}   r   r   r   r{   r   r   rq   ry   r   r   r  r
  r   r   r  r   r  r   r   r  r  r)  r(  r   r,  r=  rF  r7  r5  r8  r   rL  r%  rQ  r&  rY  r   rj  rm  r|  r   r  r   r   r   r   r  r   r  r   r  rB  ri  r  r  rd   rd   rd   re   r      s                
"

	
;    



&
    
5  








  
X,
Q  
E




r   c                 C   s    |  dj|dpd}| j|v S )Nz&NetworkSettings.Networks.{net}.Aliases)r4  rd   )r   r   rO  )r   r'  r"  rd   rd   re   r#  G  s    
r#  c                   @   s,   e Zd Zdd Zedd Zedd ZdS )r   c                 C   s
   || _ d S r`   _moderc   r1  rd   rd   re   rf   N  s    zIpcMode.__init__c                 C   s   | j S r`   r  rv   rd   rd   re   r1  Q  s    zIpcMode.modec                 C   s   d S r`   rd   rv   rd   rd   re   r   U  s    zIpcMode.service_nameNrh   ri   rj   rf   r{   r1  r   rd   rd   rd   re   r   M  s
   
r   c                   @   s,   e Zd Zdd Zedd Zedd ZdS )ServiceIpcModec                 C   s
   || _ d S r`   rl   rm   rd   rd   re   rf   [  s    zServiceIpcMode.__init__c                 C   s   | j jS r`   ra   r   rv   rd   rd   re   r   ^  s    zServiceIpcMode.service_namec                 C   s0   | j  }|rd|d j S td| j  d S )N
container:r   z[Service %s is trying to use reuse the IPC namespace of another service that is not running.ra   r   r$  r   r   r   rc   r   rd   rd   re   r1  b  s    
zServiceIpcMode.modeNrh   ri   rj   rf   r{   r   r1  rd   rd   rd   re   r  Z  s
   
r  c                   @   s   e Zd Zdd ZdS )ContainerIpcModec                 C   s   || _ d|j| _d S Nzcontainer:{}r   r   r$  r  rc   r   rd   rd   re   rf   p  s    zContainerIpcMode.__init__Nrg   rd   rd   rd   re   r  o  s   r  c                   @   s,   e Zd Zdd Zedd Zedd ZdS )r   c                 C   s
   || _ d S r`   r  r  rd   rd   re   rf   v  s    zPidMode.__init__c                 C   s   | j S r`   r  rv   rd   rd   re   r1  y  s    zPidMode.modec                 C   s   d S r`   rd   rv   rd   rd   re   r   }  s    zPidMode.service_nameNr  rd   rd   rd   re   r   u  s
   
r   c                   @   s,   e Zd Zdd Zedd Zedd ZdS )ServicePidModec                 C   s
   || _ d S r`   rl   rm   rd   rd   re   rf     s    zServicePidMode.__init__c                 C   s   | j jS r`   r  rv   rd   rd   re   r     s    zServicePidMode.service_namec                 C   s0   | j  }|rd|d j S td| j  d S )Nr  r   z[Service %s is trying to use reuse the PID namespace of another service that is not running.r  r  rd   rd   re   r1    s    
zServicePidMode.modeNr  rd   rd   rd   re   r    s
   
r  c                   @   s   e Zd Zdd ZdS )ContainerPidModec                 C   s   || _ d|j| _d S r  r  r  rd   rd   re   rf     s    zContainerPidMode.__init__Nrg   rd   rd   rd   re   r    s   r  c                   @   s,   e Zd ZdZdZdd Zedd ZeZdS )r   z,A `standard` network mode (ex: host, bridge)Nc                 C   s
   || _ d S r`   r   )rc   r   rd   rd   re   rf     s    zNetworkMode.__init__c                 C   s   | j S r`   r  rv   rd   rd   re   r$    s    zNetworkMode.id	rh   ri   rj   rx   r   rf   r{   r$  r1  rd   rd   rd   re   r     s   
r   c                   @   s4   e Zd ZdZdZdd Zedd Zedd ZdS )	ContainerNetworkModez5A network mode that uses a container's network stack.Nc                 C   s
   || _ d S r`   r  r  rd   rd   re   rf     s    zContainerNetworkMode.__init__c                 C   s   | j jS r`   r   r$  rv   rd   rd   re   r$    s    zContainerNetworkMode.idc                 C   s   d| j j S )Nr  r  rv   rd   rd   re   r1    s    zContainerNetworkMode.moder  rd   rd   rd   re   r    s   
r  c                   @   s4   e Zd ZdZdd Zedd ZeZedd ZdS )	ServiceNetworkModez3A network mode that uses a service's network stack.c                 C   s
   || _ d S r`   rl   rm   rd   rd   re   rf     s    zServiceNetworkMode.__init__c                 C   s   | j jS r`   r  rv   rd   rd   re   r$    s    zServiceNetworkMode.idc                 C   s0   | j  }|rd|d j S td| j  d S )Nr  r   z[Service %s is trying to use reuse the network stack of another service that is not running.)ra   r   r$  r   r   r  rd   rd   re   r1    s    
zServiceNetworkMode.modeN)	rh   ri   rj   rx   rf   r{   r$  r   r1  rd   rd   rd   re   r    s   
r  c                 C   s>   |  d|g}|r&|dt|g n|t| d|S )Nz-_r   r   )r   r	  r2   r{  r   r   )r   ra   r   ro  bitsrd   rd   re   r    s
    r  c                 C   sh   d}d}|| v r*|  |d\}}|||fS | d }}|| v r^|  |d\}}d|v r^| d }}|||fS )a  Splits image identification into base image path, tag/digest
    and it's separator.

    Example:

    >>> parse_repository_tag('user/repo@sha256:digest')
    ('user/repo', 'sha256:digest', '@')
    >>> parse_repository_tag('user/repo:v1')
    ('user/repo', 'v1', ':')
    rS  @r   r  /)rsplit)Z	repo_pathZtag_separatorZdigest_separatorr  r  rd   rd   re   r    s    


r  c                 C   st   i }t dd | D }|rdt|| ||\}}t| ||j |dd |D  |sV|rddd|j i}t| |fS )z
        Return a list of volume bindings for a container. Container data volumes
        are replaced by those from the previous container.
        Anonymous mounts are updated in place.
    c                 s   s   | ]}|j rt|V  qd S r`   )externalbuild_volume_bindingr   volumerd   rd   re   r@    s   z(merge_volume_bindings.<locals>.<genexpr>c                 s   s   | ]}t |V  qd S r`   )r  r  rd   rd   re   r@    s   zaffinity:container=)r   get_container_data_volumeswarn_on_masked_volumera   r   r$  r   r   )r\  rq  r   ru  r  Zvolume_bindingsZold_volumesZ
old_mountsrd   rd   re   rz     s    
rz  c                 C   s
  g }|p
g }dd |  dpi D }dd | jd  dp<i D }t|| D ]n}|jrZqN|jt| v rnqN| |j}|sqN| dsqN|jd	d |D v rqN|j|d d
}|| qNd}	|D ]:}|j	dkrq| |j
}
|
r|
 dsq|
d |_d}	q||	fS )z
        Find the container data volumes that are in `volumes_option`, and return
        a mapping of volume bindings for those volumes.
        Anonymous volume mounts are updated in place instead.
    c                 S   s   i | ]}|d  |qS )ZDestinationrd   )r   mountrd   rd   re   r?  &  s   z.get_container_data_volumes.<locals>.<dictcomp>ZMountsc                 S   s   g | ]}t |qS rd   )r   parser  rd   rd   re   r   +  s   z.get_container_data_volumes.<locals>.<listcomp>ZContainerConfigZVolumesNamec                 S   s   g | ]
}|j qS rd   rw  )r   r  rd   rd   re   r   F  r   )r  Fr  T)r   Zimage_configr   r  rr  r   r9  _replacer{  rt   rx  r0  )r   volumes_optionZtmpfs_optionZmounts_optionr\  r~  Zimage_volumesr  r  Zupdated_mountsZ
ctnr_mountrd   rd   re   r    s@    


r  c                 C   sX   dd |D }| D ]@}|j r|j|v r||j|j krtdj||j|j d qd S )Nc                 S   s   i | ]}|j |jqS rd   )rr  r  r  rd   rd   re   r?  ]  s   z)warn_on_masked_volume.<locals>.<dictcomp>zService "{service}" is using volume "{volume}" from the previous container. Host mapping "{host_path}" has no effect. Remove the existing containers (with `docker-compose rm {service}`) to use the host volume mapping.)ra   r  Z	host_path)r  rr  r   r   r   r   )r  r}  ra   r  rd   rd   re   r  \  s"    r  c                 C   s   | j |  fS r`   )rr  repr)Zvolume_specrd   rd   re   r  r  s    r  c                 C   sn   t | jtrL| jjdd}|s4d| j j| jS |d }d|j| jS t | jtrjd| jj| jS dS )z
    volume_from can be either a service or a container. We want to return the
    container.id and format it into a string complete with the mode.
    Tr   z{}:{}r   N)	r/  r0  r   r   r   r   r$  r1  r&   )Zvolume_from_specr   r   rd   rd   re   rW  v  s    
rW  c                 C   s`   i }| j r<| j| j  D ] \}}|| j v r| j | ||< qtf | j| j| j| j| jd|S )N)rt   rx  r0  rK   consistency)	r   Zoptions_maprt   r  r	   rx  r0  rK   r  )Z
mount_specr  optionZsdk_namerd   rd   re   rt    s    
rt  c                 C   sj   t | pi }|dd |D  |d ur4t||t< |d urD||t< t|t< |rftd|  ||t	< |S )Nc                 s   s   | ]}| d dV  qdS )r  r   Nr  )r   r   rd   rd   re   r@    r   z)build_container_labels.<locals>.<genexpr>zAdded config hash: %s)
r  r   r   r   r"   r   r#   r   r   r   )Zlabel_optionsZservice_labelsr   r   ro  r   rd   rd   re   rk    s    rk  c                 C   sf   | sd S g }|   D ]L\}}t|tr:||||d qt|trd|i}|| || q|S )N)r   ZsoftZhardr   )r  r/  r  r{  r  r   )Zulimit_configr  Z
limit_nameZsoft_hard_valuesZulimit_dictrd   rd   re   r    s    


r  c                 C   s4   | r|  ddnd}| r$|  dd nd }t||dS )NZdriverr  r   )rt   rE  )r   r   )r  rL   Zlog_optionsrd   rd   re   r    s    r  c                    s   dd   fdd|   D S )Nc                 S   s.   |d u r| S t |tr |d}dj| |dS )Nzutf-8z{key}={value}r   r  )r/  bytesdecoder   r  rd   rd   re   
format_env  s
    

z&format_environment.<locals>.format_envc                    s   g | ]} | qS rd   rd   )r   itemr  rd   re   r     r   z&format_environment.<locals>.<listcomp>)r  )rb  rd   r  re   rn    s    rn  c                 C   s6   g }| D ](}t |tr&||  q|| q|S r`   )r/  r   r{  rv  )r`  r   portrd   rd   re   rh    s    
rh  c                 C   s`   g }| | dg  }|D ]B}t|\}}|D ],}t|}d|v rNt|d}|| q,q|S )Nra  r  )r   r   r   r  rU  r{  )Zcontainer_portsr   r`  Z	all_portsZ
port_rangeZinternal_ranger   r  rd   rd   re   rg    s    rg  c                 C   sh   i }| d u r|S |  d|d< dD ]@}|| vr0q"g }| | D ]}|dd | D  q<|||< q"|S )Nr  )r  r  r  r  r  c                 S   s   i | ]\}}|  |qS rd   )
capitalize)r   r[  r3  rd   rd   re   r?    r   z(convert_blkio_config.<locals>.<dictcomp>)r   r{  r  )r  r   ZfieldZarrr  rd   rd   re   r    s    
r  c                 C   s*   t r&t| s&| ts&ttj|  } | S r`   )r   r   
startswithr%   r  r  normpath)r  rd   rd   re   r    s    r  c                   @   s   e Zd Zdd ZdddZdS )	r  c                 C   s
   || _ d S r`   )	_progress)rc   r  rd   rd   re   rf     s    z_CLIBuilder.__init__NFTc           $      c   s  |rt j||}t }t }|d| |d| |d| |	d| |d| |d|
d |d| |	d	| |d
| j |	d|
 |d| |d| |d| ||g}d}d}tj|tjdd^} | j }!|!sq |!|rd}td|!iV  q|   | jdkr:t W d   n1 sP0    Y  t|*}"|" }!|!dd  }#W d   n1 s0    Y  t | |stdd||#iV  dS )a  
        Args:
            path (str): Path to the directory containing the Dockerfile
            buildargs (dict): A dictionary of build arguments
            cache_from (:py:class:`list`): A list of images used for build
                cache resolution
            container_limits (dict): A dictionary of limits applied to each
                container created by the build process. Valid keys:
                - memory (int): set memory limit for build
                - memswap (int): Total memory (memory + swap), -1 to disable
                    swap
                - cpushares (int): CPU shares (relative weight)
                - cpusetcpus (str): CPUs in which to allow execution, e.g.,
                    ``"0-3"``, ``"0,1"``
            custom_context (bool): Optional if using ``fileobj``
            decode (bool): If set to ``True``, the returned stream will be
                decoded into dicts on the fly. Default ``False``
            dockerfile (str): path within the build context to the Dockerfile
            encoding (str): The encoding for a stream. Set to ``gzip`` for
                compressing
            extra_hosts (dict): Extra hosts to add to /etc/hosts in building
                containers, as a mapping of hostname to IP address.
            fileobj: A file object to use as the Dockerfile. (Or a file-like
                object)
            forcerm (bool): Always remove intermediate containers, even after
                unsuccessful builds
            isolation (str): Isolation technology used during build.
                Default: `None`.
            labels (dict): A dictionary of labels to set on the image
            network_mode (str): networking mode for the run commands during
                build
            nocache (bool): Don't use the cache when set to ``True``
            platform (str): Platform in the format ``os[/arch[/variant]]``
            pull (bool): Downloads any updates to the FROM image in Dockerfiles
            quiet (bool): Whether to return the status
            rm (bool): Remove intermediate containers. The ``docker build``
                command now defaults to ``--rm=true``, but we have kept the old
                default of `False` to preserve backward compatibility
            shmsize (int): Size of `/dev/shm` in bytes. The size must be
                greater than 0. If omitted the system uses 64MB
            squash (bool): Squash the resulting images layers into a
                single layer.
            tag (str): A tag to add to the final image
            target (str): Name of the build-stage to build in a multi-stage
                Dockerfile
            timeout (int): HTTP timeout
            use_config_proxy (bool): If ``True``, and if the docker client
                configuration file (``~/.docker/config.json`` by default)
                contains a proxy configuration, the corresponding environment
                variables will be set in the container being built.
        Returns:
            A generator for the build output.
        z--build-argz--cache-fromz--filez
--force-rmz--labelz--memoryr  z	--networkz
--no-cachez
--progressz--pullz--tagz--targetz	--iidfilezSuccessfully built FT)r  Zuniversal_newlinesr  r   NrS  r   z{}{}
)r  r  r   tempfileZmktemp_CommandBuilder
add_paramsadd_listadd_argadd_flagr   r  r   
subprocessPopenPIPEr  readliner	  jsondumpsZcommunicate
returncoder-   r  rU  stripr   r   )$rc   r  r  r   Zfileobjr  r  r   Zcustom_contextencodingr   r  r  r  r  r  r  r  r   r  rx  r   ZsquashrG   r   rJ   Zuse_config_proxyZiidfileZcommand_builderr  Z
magic_wordZappearplinefr.  rd   rd   re   r     sN    =

&
2
z_CLIBuilder.build)NFNFFNFNFFNNFNFNNNNNNNNNT)rh   ri   rj   rf   r   rd   rd   rd   re   r    s           r  c                   @   s<   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd ZdS )r  c                 C   s   ddg| _ d S )NZdockerr   _argsrv   rd   rd   re   rf   t  s    z_CommandBuilder.__init__c                 C   s   |r| j |t|g d S r`   )r  r	  r   )rc   r   r  rd   rd   re   r  w  s    z_CommandBuilder.add_argc                 C   s   |r| j |g d S r`   r  r	  )rc   r   flagrd   rd   re   r  {  s    z_CommandBuilder.add_flagc                 C   s2   |r.|  D ] \}}| j|d||g qd S )Nr   )r  r  r	  r   )rc   r   paramsr   valrd   rd   re   r    s    z_CommandBuilder.add_paramsc                 C   s"   |r|D ]}| j ||g qd S r`   r   )rc   r   r   r#  rd   rd   re   r    s    z_CommandBuilder.add_listc                 C   s
   | j | S r`   r  )rc   r  rd   rd   re   r     s    z_CommandBuilder.buildN)	rh   ri   rj   rf   r  r  r  r  r   rd   rd   rd   re   r  s  s   r  )N)xenumrJ  r  r  r  r  r  r  r  collectionsr   r   operatorr   Zdocker.errorsr   r   r   Zdocker.typesr   r	   Zdocker.utilsr
   r   Zdocker.utils.portsr   r   Zdocker.utils.utilsr   r  r   r   r   rE  r   r   r   r   Zconfig.errorsr   Zconfig.typesr   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r   r&   r   r'   r(   r)   Zparallelr+   r,   r-   Zutilsr.   r/   r0   r1   r2   r3   Zcompose.cli.utilsr4   Z	getLoggerrh   r   rl  rC  rD  r  r_   rk   rn   ro   rp   uniqueEnumrq   r|   r   r   r#  r   r  r  r   r  r  r   r  r  r  r  rz  r  r  r  rW  rt  rk  r  r  rn  rh  rg  r  r  r  r  rd   rd   rd   re   <module>   s   
0

         )
?

r