
    S`                       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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&l6m7Z7 dd'l8m9Z9 dd(l8m:Z: dd)l8m;Z; dd*l8m<Z< dd+l=m>Z> dd,lm?Z? dd-lm@Z@ dd.lAmBZB dd/lAmCZC dd0lAmDZD dd1lAmEZE dd2lAmFZF dd3lAmGZG d d4lHmIZI  ej                  eK      ZLg d5ZMd6ZNd7ZOd8ZP G d9 d:eQ      ZR G d; d<eQ      ZS G d= d>eQ      ZT e	d?d@      ZU e	dAdB      ZVe j                   G dC dDe j                               ZYe j                   G dE dFe j                               ZZe j                   G dG dHe j                               Z[ G dI dJ      Z\dK Z] G dL dM      Z^ G dN dOe^      Z_ G dP dQe^      Z` G dR dS      Za G dT dUea      Zb G dV dWea      Zc G dX dY      Zd G dZ d[      Ze G d\ d]      Zfdtd^Zgd_ Zhd` Zida Zjdb Zkdc Zldd Zmde Zndf Zodg Zpdh Zqdi Zrdj Zsdk Ztdl Zudm Zv G dn do      Zw G dp dq      Zx G dr ds      Zyy)u    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)CompletedUnsuccessfully)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_optenv_fileextra_hosts	group_addinitipc	isolation	read_only
log_driver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_driverservice_startedservice_healthyservice_completed_successfullyc                       e Zd Zd Zy)
BuildErrorc                      || _         || _        y N)servicereason)selfrk   rl   s      1/usr/lib/python3/dist-packages/compose/service.py__init__zBuildError.__init__w   s        N__name__
__module____qualname__ro    rp   rn   rh   rh   v   s    rp   rh   c                       e Zd Zd Zy)NeedsBuildErrorc                     || _         y rj   rk   rm   rk   s     rn   ro   zNeedsBuildError.__init__}   	    rp   Nrq   ru   rp   rn   rw   rw   |   s    rp   rw   c                       e Zd Zy)NoSuchImageErrorN)rr   rs   rt   ru   rp   rn   r}   r}      s    rp   r}   ServiceNamezproject service numberConvergencePlanzaction containersc                   ,    e Zd ZdZdZdZdZed        Zy)ConvergenceStrategyzrEnumeration for all possible convergence strategies. Values refer to
    when containers should be recreated.
    r         c                 0    | t        |       j                  uS rj   )typeneverrm   s    rn   allows_recreatez#ConvergenceStrategy.allows_recreate   s    4:++++rp   N)	rr   rs   rt   __doc__changedalwaysr   propertyr   ru   rp   rn   r   r      s*     GFE, ,rp   r   c                       e Zd ZdZdZdZdZy)	ImageTypez5Enumeration for the types of images known to compose.r   r   r   N)rr   rs   rt   r   nonelocalallru   rp   rn   r   r      s    ?DE
Crp   r   c                       e Zd ZdZdZdZdZy)BuildActionz+Enumeration for the possible build actions.r   r   r   N)rr   rs   rt   r   r   forceskipru   rp   rn   r   r      s    5DEDrp   r   c                   D   e Zd Z	 	 	 	 	 	 	 	 	 	 	 	 	 d@dZd ZdAdZdBdZd Zd ZdCd	Z		 	 	 	 dDd
Z
ej                  ddfdZd Zd Zed        Zed        Zej(                  dfdZd ZdEdZd Zd ZdCdZ	 	 	 	 dFdZ	 	 dGdZd ZdHdZdIdZed        Z dIdZ!dCdZ"d Z#ed        Z$d  Z%d! Z&d" Z'd# Z(d$ Z)d% Z*dJd&Z+d' Z,dCd(Z-d) Z.d* Z/d+ Z0	 	 dEd,Z1d- Z2dJd.Z3d/ Z4	 	 dKd0Z5d1 Z6d2 Z7dHd3Z8ed4        Z9dCd5Z:d6 Z;d7 Z<d8 Z=dLd9Z>dJd:Z?d; Z@d< ZAd= ZBd> ZCd? ZDy)MServiceNFc                 L   || _         || _        || _        || _        |xs g | _        |xs g | _        |xs t        d       | _        |xs t        d       | _	        |xs t        d       | _        |xs i | _        |	xs g | _        |
| _        || _        || _        |xs g | _        y rj   )nameclientprojectuse_networkinglinksrb   IpcModeipc_modeNetworkModenetwork_modePidModepid_modenetworkssecrets	scale_numdefault_platformoptionsextra_labels)rm   r   r   r   r   r   rb   r   r   r   scaler   r   r   r   r   s                   rn   ro   zService.__init__   s    $ 	,[b
(.B 1GDM(=K,= 1GDM B}" 0(.Brp   c                 8    dj                  | j                        S )Nz<Service: {}>)formatr   r   s    rn   __repr__zService.__repr__   s    %%dii00rp   c                 \    |i }|j                  d j                  |      |xs g z   i       t        t        d  j                  j                  ||      D cg c]"  }t        j                   j                  |      $ c}            }|r|S |j                  d j                  |d      |xs g z   i       t        t         fdt        d  j                  j                  ||      D cg c]"  }t        j                   j                  |      $ c}                  S c c}w c c}w )Nlabelone_offr   filtersTr   legacyc                 :    | j                  j                        S rj   )has_legacy_proj_namer   )crm   s    rn   <lambda>z$Service.containers.<locals>.<lambda>   s    !00> rp   )updatelabelslistfilterr   
containersr'   from_ps)rm   stoppedr   r   r   	containerresults   `      rn   r   zService.containers   s(   ?GW!=2!NOPfT![[33 4 !$" dkk95$" #  MWT!JflXZ![\]>t%)[[%;%;# ' &< &)N*! %%dkk9=N* A+
 	
$"N*s   'D$.'D)c                     | j                  dj                  t        |      g      D ]  }|c S  t        dj                  | j                  |            )zReturn a :class:`compose.container.Container` for this service. The
        container must be active, and match `number`.
        {}={})r   zNo container found for {}_{})r   r   r   
ValueErrorr   )rm   numberr   s      rn   get_containerzService.get_container   sS     @VX^1_0`a 	I	 7>>tyy&QRRrp   c                 ^    | j                  d      }|D ]  } | j                  |fi |  |S )NTr   )r   start_container_if_stopped)rm   r   r   r   s       rn   startzService.start   s<    __T_2
 	:A+D++A99	:rp   c                     | j                   r5|dkD  r0t        j                  d| j                  d| j                   d       | j	                         r)|dkD  r#t        j                  d| j                  z         y y y )Nr   zThe "z." service is using the custom container name "ze". 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)rm   desired_nums     rn   show_scale_warningszService.show_scale_warnings   so    %%+/KK  99d&@&@B C
 ##%+/KK ^))$ % +:%rp   c                 T   | j                  |       | j                  d      }t        |      }|D ]T  }|j                  | j                        st
        j                  d|j                  z         | j                  ||d       V ||k(  rt
        j                  d       y||kD  r| j                  d      }|t        |      k7  ru|D cg c]  }|j                  r| }}|D cg c]  }| j                  |g      s| }}|D ]  }|j                           t        t        |      t        |      z
        }t        |t        d      	      }	| j!                  |	||dd       ||k  r2||z
  }
t        |t        d      	      }| j#                  ||
 d |       yyc c}w c c}w )
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 achievedNTr   key)r   r   lenr   r   r   infor   recreate_container
is_running_containers_have_divergedremover   setsortedr   _execute_convergence_start
_downscale)rm   r   timeoutrunning_containersnum_runningr   all_containersstopped_containersdivergent_containerssorted_containersnum_to_stopsorted_running_containerss               rn   r   zService.scale  s    	  -!__U_;,-# 	KA))$,,7HH?!&&HI##AwE#J		K +%HH@A$!__T_:Nc.11  .&Q\\A&" &  2(T5S5SUVTW5XA($ ( . AHHJ "&c.&9C@T<U&U!V &~:h;O P++!;t $%3K(."x()*% OO5{lmDgN %%&
(s   F F (F% F%c           	      v   | j                          | j                  ||xs | j                  |      ||      }d|v r|st        j	                  d|d   z         	 t        j                  | j                  fi |S # t        $ r3}t        d| j                  dt        |j                              d}~ww xY w)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 z: N)ensure_image_exists_get_container_create_options_next_container_numberr   r   r'   creater   r   r+   r   r6   explanation)rm   r   r   r   quietoverride_optionscontainer_optionsexs           rn   create_containerzService.create_container<  s     	  " >>Bd11'1B1	 ? 
 &&uHH]%6v%>>?	Z##DKKE3DEE 	Z&(,		3G3W(Y Z Z	Zs   A< <	B8.B33B8c                    | j                         r&|t        j                  k(  r| j                  |       y 	 | j	                          y # t
        $ r Y nw xY w| j                         s| j                  |       y |t        j                  k(  rt        |       | j                  |       t        j                  dj                  | j                               y )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imager}   pullr   rw   r   r   r   r   )rm   do_buildr   r   s       rn   r   zService.ensure_image_existsZ  s    8{/@/@#@JJ3J	JJL 		   "IIVI${'''!$''

s
++16$))+<	>s   A	 		AAc                     	 | j                   j                  | j                        S # t        $ r% t	        dj                  | j                              w xY wNzImage '{}' not found)r   inspect_distribution
image_namer   r}   r   r   s    rn   get_image_registry_datazService.get_image_registry_datar  sM    	S;;33DOODD 	S"#9#@#@#QRR	S	   $' .Ac                     	 | j                   j                  | j                        S # t        $ r% t	        dj                  | j                              w xY wr   )r   inspect_imager  r   r}   r   r   s    rn   r   zService.imagex  sM    	S;;,,T__== 	S"#9#@#@#QRR	Sr  c           	          | j                   j                  ddj                  | | j                  j	                  d                  S )Nr   z{project}_{s.name}z_-)sr   )r   getr   r   lstripr   s    rn   r  zService.image_name~  sC    ||)=)D)DDLL//5 *E *
  	rp   c                     | j                   j                  d      }|s,t        | j                  j                  d      r| j
                  }|S )Nplatform1.35)r   r  r   r   api_versionr   )rm   r  s     rn   r  zService.platform  s<    <<##J/K(?(?H,,Hrp   c                 n   | j                  d      }|rt        dg       S |st        dg       S |t        j                  u rt        d|      S |t        j                  u s| j                  |      rt        d|      S |D cg c]  }|j                  r| }}|rt        d|      S t        d|      S c c}w )NTr   r   r   r   recreatenoop)r   r   r   r   r   r   r   )rm   strategyr   r   r   r   s         rn   convergence_planzService.convergence_plan  s    __T_2
"9b11"8R00*000"7J77 /666..z:":z::(=1=="7J77vz22 >s    B2B2c                    d }	 | j                   }d}|D ]  }|j                  | j                        r%t        j                  d|j                  z         d}C|j                  j                  t        d       }||k7  sit        j                  d|j                  ||       d} |S # t        $ r4}t        j                  d| j                  t        |             Y d }~yd }~ww xY w)NzService %s has diverged: %sTFz$%s has diverged: Legacy project namez%s has diverged: %s != %s)config_hashr}   r   debugr   strr   r   r   r  r   )rm   r   r  ehas_divergedr   container_config_hashs          rn   r   z!Service._containers_have_diverged  s    	**K  	$A%%dll3		@166IJ#$%HHLL1BD$I!$3		/FF1;  $	$ -   	II-		3q6 	s   B% %	C".*CC"c           
      6     j                         } fd fd}t        t        |||z         D cg c]#  }t         j                   j
                  |      % c} fd|d      \  }	}
|
j                         D ]  }t        |       |	S c c}w )Nc                     r | j                   dddd}n| j                  |d      }s|j                          rsj                  |       |S )NT)r   r   )r   r   ru   )r   attach_log_streamstart_container)rk   nr   detachedr   r   rm   r   s      rn   create_and_startz=Service._execute_convergence_create.<locals>.create_and_start  s`    4G44bTbQab	#44AT4J	++-W$$Y/rp   c                     r(dj                  | j                  | j                  dg      S j                  | j                  | j                        S )N_run)joinr   rk   get_container_namer   )service_namer   rm   s    rn   get_namez5Service._execute_convergence_create.<locals>.get_name  sR    xx (( ((!  
 **<+?+?ATATUUrp   c                 *     | j                         S rj   )r   )r&  r   rm   s    rn   r   z5Service._execute_convergence_create.<locals>.<lambda>  s    !1$8K8K!L rp   Creating)r   r-   ranger~   r   r   valuesr+   )rm   r   r  r   r   r   ir'  indexr   errorserrorr   s   ` ````      @rn   _execute_convergence_createz#Service._execute_convergence_create  s    '')		 			V . #1a%i0 DLL$))U; M

F ]]_ 	.E&u--	. s   (Bc                 T    |(t        |      |kD  r j                  ||d         |d | } fd}t        ||d d      \  }}|j                         D ]  }	t	        |	       |<t        |      |k  r.|j                   j                  |t        |      z
               |S )Nc                 2    j                  |        S )N)r   attach_logsr   renew_anonymous_volumes)r   )r   r  r4  rm   r   r   s    rn   r  z7Service._execute_convergence_recreate.<locals>.recreate  s*    **7H$)CZ +  rp   c                     | j                   S rj   r   r   s    rn   r   z7Service._execute_convergence_recreate.<locals>.<lambda>  
    aff rp   
Recreating)r   r   r-   r+  r+   extendr0  )
rm   r   r   r   r  r   r4  r  r.  r/  s
   `  ````   rn   _execute_convergence_recreatez%Service._execute_convergence_recreate  s    Z5!8OOJuv.8#FU+J	 	 .	

F ]]_ 	.E&u--	. Z5!8d>>J'5  rp   c                     |(t        |      |kD  r j                  ||d  |       |d | }|rQ|D cg c]  }|j                  r| }}t        | fdd d      \  }}	|	j	                         D ]  }
t        |
       |<t        |      |k  r.|j                   j                  |t        |      z
  |             |S c c}w )Nc                 .    j                  |  d      S )NT)r3  r   )r   )r   r  rm   s    rn   r   z4Service._execute_convergence_start.<locals>.<lambda>
  s    $99!X]a9b rp   c                     | j                   S rj   r6  r7  s    rn   r   z4Service._execute_convergence_start.<locals>.<lambda>  s
    !&& rp   Starting)r   r   r   r-   r+  r+   r:  r0  )rm   r   r   r   r  r   r   r   r"  r.  r/  s   `   `      rn   r   z"Service._execute_convergence_start  s    Z5!8OOJuv.8#FU+J",AQALLqAGA(b 	IAv   2*5112 Z5!8d>>J'5   Bs   C C c                 2      fd}t        ||d d       y )Nc                 h    | j                  j                               | j                          y )Nr   )stopstop_timeoutr   )r   rm   r   s    rn   stop_and_removez+Service._downscale.<locals>.stop_and_remove  s(    NN4#4#4W#=N>rp   c                     | j                   S rj   r6  r7  s    rn   r   z$Service._downscale.<locals>.<lambda>   r8  rp   zStopping and removingr,   )rm   r   r   rE  s   ` ` rn   r   zService._downscale  s    	 	#		
rp   c
                 Z   |\  }
}||n| j                   }t        |t        d            }| j                  |       |
dv r| j	                  ||||
dk(  |	      S |sd }|
dk(  rC|r+| j                         d   }|D ]  }|j                  |        | j                  ||||||      S |
dk(  r| j                  |||||      S |
d	k(  rN|t        |      k7  r| j                  |||||      S |D ]$  }t        j                  d
|j                  z         & |S t        dj                  |
            )Nr   r   )r   r   r   )r   r   r  Idr   r  z%s is up-to-datezInvalid action: {})r   r   r   r   r0  r   reset_imager;  r   r   r   r   r   	Exceptionr   )rm   planr   r  r   scale_overriderescalereset_container_imager4  r   actionr   r   img_idr   s                  rn   execute_convergence_planz Service.execute_convergence_plan$  sw     $"0"<$..JJx,@A
  '**339,!1 4   EZ$ d+# *AMM&)*55E7He' 
 W22E7He  VJ'66w%    6+aff456 ,33F;<<rp   c                    |j                  | j                  |             |j                          | j                  |s|nd|j                  d      }|r|j                          |r| j                  |       |j                          |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.
        rB  NT)r   r   r   )rC  rD  rename_to_tmp_namer   r   r  r  r   )rm   r   r   r3  r   r4  new_containers          rn   r   zService.recreate_containerY  s     	t009:$$&--0GyT## . 

 ++-  /rp   c                 f    ||S t        | j                  j                  d            }||S t        S )Nstop_grace_period)r3   r   r  r   )rm   r   s     rn   rD  zService.stop_timeoutp  s8    N%dll&6&67J&KLNrp   c                     |j                   sG|s"t        j                  d|j                  z         |r|j	                          | j                  |      S y )NzStarting %s)r   r   r   r   r  r  )rm   r   r3  r   s       rn   r   z"Service.start_container_if_stoppedx  sH    ##78++-''	22 $rp   c                    | j                  ||       	 |j                          |S # t        $ rX}t        |j                        }d|v rt
        j                  d       t        dj                  | j                  |            d }~ww xY w)Nz/driver failed programming external connectivityz+Host is already in use by another containerzCannot start service {}: {})
connect_container_to_networksr   r   r6   r   r   warnr+   r   r   )rm   r   use_network_aliasesr   expls        rn   r  zService.start_container  s    **96IJ	^OO   	^'7D@DHFG&'D'K'KDIIW['\]]		^s   & 	BABBc                 b    t        t        | j                  j                         d d            S )Nc                 2    | d   j                  d      xs dS )Nr   priorityr   r  )ts    rn   r   z.Service.prioritized_networks.<locals>.<lambda>  s    adhhz27a rp   T)r   reverse)r   r   r   itemsr   s    rn   prioritized_networkszService.prioritized_networks  s,    ##%7
 	
rp   c                    |j                  d      }| j                  j                         D ]  \  }}||v r3t        ||      r| j                  j                  |j                  |       |r| j                  ||      ng }| j                  j                  |j                  |||j                  dd       |j                  dd       | j                  d      |j                  dd               y )NzNetworkSettings.Networksipv4_addressipv6_addressFlink_local_ips)aliasesrf  rg  r   rh  )
r  rd  rc  short_id_alias_existsr   !disconnect_container_from_networkid_get_aliasesconnect_container_to_network
_get_links)rm   r   r[  connected_networksnetworknetdefsri  s          rn   rY  z%Service.connect_container_to_networks  s    &]]+EF $ 9 9 ? ? A 	GW,,(G<==illGT?Rd'';XZGKK44g$[[>$[[>ooe,&{{+;TB 5 	rp   c                     | j                         D ]U  }t        j                  d|j                  z         |j	                  | j                  |             |j                          W y )NzRemoving %srB  )duplicate_containersr   r   r   rC  rD  r   )rm   r   r   s      rn   remove_duplicate_containersz#Service.remove_duplicate_containers  sQ    **, 	AHH]QVV+,FF4,,W5F6HHJ	rp   c              #      K   t        | j                  d      d       }t               }|D ]0  }|j                  |v r| |j	                  |j                         2 y w)NTr   c                 $    | j                  d      S )NCreatedr`  r7  s    rn   r   z.Service.duplicate_containers.<locals>.<lambda>  s    !%%	* rp   r   )r   r   r   r   add)rm   r   numbersr   s       rn   rt  zService.duplicate_containers  sZ     OODO)*


 % 	&Axx7"AHH%		&s   AA!c                 4    t        | j                               S rj   )r1   config_dictr   s    rn   r  zService.config_hash  s    ))+,,rp   c                      fd} j                    |        j                          j                  j                   j                  j
                   j                   j                   j                  D cg c]>  }t        |j                  t              r"|j                  j                  |j
                  f@ c}dS c c}w )Nc                  J    	  j                         d   S # t        $ r Y y w xY wNrH  )r   r}   r   s   rn   image_idz%Service.config_dict.<locals>.image_id  s+    zz|D))# s    	"")r   r  r   netr   r   r   rb   )r   get_link_namesr   rl  r   moder   r   rb   
isinstancesourcer   r   )rm   r  vs   `  rn   r|  zService.config_dict  s    	 || 
((*$$''**|| **j7.K '
 	
s   5AB=c                 `   | j                   j                  }| j                  j                  }| j                  j                  }| j	                         | j                         z   |r|gng z   |r|gng z   |r|gng z   t        | j                  j                  di       j                               z   S )N
depends_on)
r   r&  r   r   get_linked_service_namesget_volumes_from_namesr   r   r  keys)rm   net_namepid_namespaceipc_namespaces       rn   get_dependency_nameszService.get_dependency_names  s    $$112222--/++-.'(R1 %2-r; %2-r	;
 T\\%%lB7<<>?@	
rp   c                 
   | j                   j                  }| j                  j                  }| j                  j                  }| j	                         D ci c]  }|d  }}|j                  d | j                         D               |j                  |r|d ini        |j                  |r|d ini        |j                  |r|d ini        |j                  | j                  j                  di              | j                  j                  di       j                         D ]Z  \  }}|d   t        k(  rd ||<   |d   t        k(  rd ||<   ,|d   t        k(  rd ||<   ?t        dj                  |d                |S c c}w )Nc              3   $   K   | ]  }|d f 
 y wrj   ru   ).0r   s     rn   	<genexpr>z1Service.get_dependency_configs.<locals>.<genexpr>  s      
!T4L
s   r  	conditionc                      y)NTru   r  s    rn   r   z0Service.get_dependency_configs.<locals>.<lambda>  s    rp   c                 "    | j                         S rj   )
is_healthyr  s    rn   r   z0Service.get_dependency_configs.<locals>.<lambda>  s     rp   c                 "    | j                         S rj   )is_completed_successfullyr  s    rn   r   z0Service.get_dependency_configs.<locals>.<lambda>  s    )D)D)F rp   z%depends_on condition "{}" is invalid.)r   r&  r   r   r  r   r  r   r  rc  CONDITION_STARTEDCONDITION_HEALTHY CONDITION_COMPLETED_SUCCESSFULLYr   r   )rm   r  r  r  r   configssvcconfigs           rn   get_dependency_configszService.get_dependency_configs  s   $$112222 $(#@#@#B
D$J
 
 	 
%)%@%@%B
 	
 	8$'<t,2Ft,2Ft||''b9:<<++L"=CCE 	KCk"&77-$(997$(HHF !;BB{+ 	  5
s   
F c                 `    | j                   D cg c]  \  }}|j                   c}}S c c}}w rj   r   r   )rm   rk   r"  s      rn   r  z Service.get_linked_service_names  s"    15<'1<<<s   *c                 d    | j                   D cg c]  \  }}|j                  |f c}}S c c}}w rj   r  )rm   rk   aliass      rn   r  zService.get_link_names  s'    <@JJG.'5u%GGGs   ,c                     | j                   D cg c]3  }t        |j                  t              s|j                  j                  5 c}S c c}w rj   )rb   r  r  r   r   )rm   r  s     rn   r  zService.get_volumes_from_names	  s2    '+'8'8Z!JqxxQX<YZZZs
   A
A
c                 <   |ry t        j                  | j                  dd| j                  d      i      | j                  dd| j                  dd      i            }|D cg c]  }|j                  |j                   }}|sdS t        |      dz   S c c}w )NTr   Fr   r   r   r   )	itertoolschain_fetch_containersr   r   max)rm   r   r   r   rz  s        rn   r   zService._next_container_number  s    __"" $++e+"<= #  %% $++eD+"IJ & 	

 &0H1883G188HHq5S\A%55 Is   %B7Bc           	            fd}t        d   j                  j                  di |D cg c]
  } ||       c}      S c c}w )Nc                 j    	 t        j                  j                  | d         S # t        $ r Y y w xY wr  )r'   from_idr   r   )r   rm   s    rn   soft_inspectz/Service._fetch_containers.<locals>.soft_inspect  s5     ((ioFF s   "& 	22ru   )r   r   r   )rm   fetch_optionsr  r   s   `   rn   r  zService._fetch_containers  sM    	 d3T[[33DmD
 #
  	 
s   A
c           	          t        | j                  h|r|j                  hn	t               z  t        |j	                  dd            z        S )Nri  ru   )r   r   short_idr   r  )rm   rq  r   s      rn   rm  zService._get_aliases)  sG    YYK%.i  !CE;Ir*+,
 	
rp   c                 `   | j                   si S | j                   | j                  j                     }| j                  |      i d}|j	                  d      r|j	                  d      |d   d<   |j	                  d      r|j	                  d      |d   d<   d| j                  j                  |iiS )N)Aliases
IPAMConfigrf  r  IPv4Addressrg  IPv6AddressEndpointsConfig)r   r   rl  rm  r  )rm   rq  endpoints      rn   build_default_networking_configz'Service.build_default_networking_config0  s    }}I-- 1 1 4 45((1

 ;;~&4;KK4OH\"=1;;~&4;KK4OH\"=1!D$5$5$8$8(#CDDrp   c                    i }| j                   D ]i  \  }}|j                         D ]Q  }|j                  ||xs |j                  <   |j                  ||j                  <   |j                  ||j                  <   S k |r`| j                         D ]M  }|j                  || j                  <   |j                  ||j                  <   |j                  ||j                  <   O | j                  j                  d      xs g D ]"  }d|vr|}n|j                  d      \  }}|||<   $ |j                         D cg c]	  \  }}||f c}}S c c}}w )Nexternal_links:)r   r   r   name_without_projectr   r  splitrc  )	rm   link_to_selfr   rk   	link_namer   external_linkcontainer_namer  s	            rn   ro  zService._get_linksA  sP   "&** 	GGY$//1 G	3<>>i/7<<0(1inn%8Ai445G	G !__. G	#,>>dii (1inn%8Ai445G
 "\\--.>?E2 	-M-')	+8+>+>s+C(y,E)	- ,1;;=
' N#
 	
 
s   4Ec                 R    | j                   D cg c]  }t        |       c}S c c}w rj   )rb   build_volume_from)rm   specs     rn   _get_volumes_fromzService._get_volumes_from\  s"    484E4EFD!$'FFFs   $c           	         | xr | }|r
t               nd }t        D ci c]   }|| j                  v r|| j                  |   " }}|j                  dg       }	|j	                  |       |j                  d      s | j                  | j                  ||      |d<   |j                  dd       t        | j                  j                  d      r3d|v r/d|vr+d|d   v r$|d   j                  d      }
|
d	   |d<   |
d
   |d<   t        | j                  j                  d      r"d| j                  v r| j                  d       |d<   d|v sd| j                  v r2t        t!        |j                  dg             | j                        |d<   d|v s|	r*t#        t%        |j                  dg       |	z               |d<   t'        | j)                         t'        | j                  j                  d      |j                  d                  |d<   t+        | j                  j                  d      |j                  d            |d<   | j-                  |||      \  }}| j.                  |d<   t1        |j                  di       | j3                  |      | j4                  z   ||r| j6                  nd |      |d<   t8        D ]  }|j                  |d         | j;                  ||      |d<   | j=                         }|r||d<   t?        |d         |d<   |S c c}w )Nvolumesr   detachTz1.23hostname
domainname.r   r   z1.25rV  rD  portsexposeenvironmentr   r   r   host_confignetworking_config) r0   r   r   popr   r  r%  r   
setdefaultr   r   r  	partitionr   rD  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_configr  format_environment)rm   r   r   r   r   add_config_hashslugkr   override_volumespartsr   r  s                rn   r   z%Service._get_container_create_options_  sU     ';?/?+?'.!#D (>1+< t||A> > ,//	2>  !12 $$V,(,(?(?		6SW(Xf%$$Xt4 t{{..7//$55(44%j1;;C@E,1!Hj).3Ahl+//8#t||3040A0A$0Gn-''8t||+C)> 1 5 5gr BC*g& ))-=+/!%%i47GG1 ,i( ,=$$&  / $$]3,
-( '3LLX&  *',(# /3.R.R 13C/
++ &*__'"&<!!(B/KKK(4+<+<< /DT'
(# $ 	-C!!#t,	- ,0+J+J ,K ,-( !@@B5F12+=m,,.-(  [>s   %L
c                    g }g }d|v r^|j                  d      D cg c]  }t        |t              s| }}|j                  d      D cg c]  }t        |t              s| }}t	        || j
                  j                  d      xs g ||      \  }}|d   j                  |       |xs i D ci c]  }|j                  i  c}|d<   t        | j                  j                  d      r!|D cg c]  }t        |       c}xs d |d<   n| j
                  j                  d      xs g |d<   |D ]^  }	|	j                  r|d   j                  |	j                         .|j                  |	j                                i |d   |	j                  <   ` | j!                         }
|
rt#        | j                  j                  d      r4|j%                  d |
D               |d   j                  d |
D               nC|j                  d      xs g |d<   |d   j%                  |
D cg c]  }t        |       c}       t'        t)        |            |d<   ||fS c c}w c c}w c c}w c c}w c c}w )	Nr  tmpfsr  z1.30mountsc              3   <   K   | ]  }|j                           y wrj   )legacy_reprr  r  s     rn   r  z:Service._build_container_volume_options.<locals>.<genexpr>  s     EQ]]_Es   c              3   8   K   | ]  }|j                   i f  y wrj   )targetr  s     rn   r  z:Service._build_container_volume_options.<locals>.<genexpr>  s      4'(QXXrN4s   binds)r  r  r   r   merge_volume_bindingsr   r   internalr   r   r  build_mountis_tmpfsappendr  r  get_secret_volumesr   r:  r   r5   )rm   r   r   r   container_volumescontainer_mountsr  r  affinitymsecret_volumess              rn   r  z'Service._build_container_volume_options  sX   )),00;!z!Z?X! ! ,=+@+@+KhazZ[]fOghh/t||//8>B@R
x 	-(//9@Q@WUW'X1

B'X)$t{{..7BR)SQ+a.)S)[W[X& )-(8(8(A(GRW%% @::$W-44QXX>LL1=?%i0:@ 002$++116:EnEE!),33 4,:4  .>-A-A(-K-Qr * *11>2Za;q>2Z[ %))?$@! "222M!  i (Y)S( 3[s(   III!I1I/I$!I)c                 	   t        | j                  fi |}|j                  dd       }t        |j                  dd             }t	        |      }d }t        |j                  d      t              r|j                  d      }d|d<   |j                  d      r)|j                  d      D cg c]  }|j                   c}nd }	d }
d|v r!t        |j                  d      t        z        }
 | j                  j                  dEi d| j                  |      d	t        t        |j                  d
g                   d|j                  d      d| j                         d|j                  dd      d| j                   j"                  d|j                  d      d|j                  d      d|j                  d      d|j                  d      d|j                  d      d|j                  d      d|j                  d      d|j                  d      d|j                  d      d|j                  d      d|j                  d      d|j                  d      dt%        |j                  d            d|d|j                  d      d |j                  d       d!| j&                  j"                  d|	d"| j(                  j"                  d#|j                  d#      d$|j                  d$      d%|j                  d%      d&|j                  d&      d'|j                  d'      d(|j                  d(      d)|j                  d)      d*|j                  d*      d+|j                  d+      d,|j                  d,      d-|j                  d-      d|j                  dd       d.|d/|j                  d/      d0|j                  d0      d1|j                  d1      d2|
d3|j                  d3      d4|j                  d5      d6|j                  d6      d7|j                  d7      d8|j                  d9      d:|j                  d;      d<|j                  d<      d=|j                  d=      d>|j                  d>      d?|j                  d?      d@|j                  d@      dA|j                  dA      dB|j                  dB      dC|j                  dC      dD|j                  dD      S c c}w )FNloggingblkio_configrL   Tr]   rA   r   )r  port_bindingsr  r  rb   rZ   Fr   rD   rE   rF   rH   rG   restart_policyr[   r\   r7   r8   rR   rS   rT   ulimits
log_configrJ   rO   r   r   r9   r=   r^   r`   rY   r  rV   rW   rU   rK   ra   	init_pathrN   r:   r;   	nano_cpusrc   cpuset_cpusrB   r@   r_   blkio_weightweightblkio_weight_deviceweight_devicedevice_read_bpsdevice_read_iopsdevice_write_bpsdevice_write_iopsr  rC   r<   r>   r?   ru   )dictr   r  convert_blkio_configget_log_configr  r  valueintr%   r   create_host_configro  r   r  r  r   r  build_ulimitsr   r   )rm   r   r   r   logging_dictr  r  r  or]   r  s              rn   r  z"Service._get_container_host_config  sq   t||8'78{{9d3+GKK,MN#L1
	gkk&)3/F+I"GFO [[( %[[8
AGG
.2 	 	WGKK/.@AI-t{{-- <
//w/7<
-GR 89<

 ++g&<
 //1<
 {{<7<
 **//<
 KK	*<
 $KK(9:<
 E"<
 KK	*<
 {{<0<
 #;;y1<
 KK	*<
  KK	*!<
" [[,#<
$ kk+.%<
& $KK(9:'<
( "++o6)<
* "'++i"89+<
, "-<
.  M2/<
0 kk+.1<
2 ]]''3<
4 &5<
6 ]]''7<
8 "++o69<
: kk+.;<
< [[,=<
> KK	*?<
@ {{<0A<
B ++g&C<
D %[[);<E<
F "++o6G<
H #;;'78I<
J kk+.K<
L  M2M<
N VT*O<
P  Q<
R kk+.S<
T kk+.U<
V  M2W<
X  Y<
Z "++o6[<
\  H-]<
^ {{<0_<
`  M2a<
b &))(3c<
d !- 0 0 Ae<
f ),,->?g<
h *--.@Ai<
j *--.@Ak<
l +../BCm<
n ;;x(o<
p !(,A Bq<
r {{<0s<
t "++o6u<
v #;;'78w<
 <	

s   *S6c                 R    d }| j                   D cg c]
  } ||       c}S c c}w )Nc                 "   | d   j                   }|.dj                  t        j                  | d   j                        }n?t
        j                  j                  |      s dj                  t        j                  |      }t        d| d   |d      S )Nsecretz{}/{}bindfileT)rO   )	r  r   r   SECRETS_PATHr  ospathisabsr   )r  r  s     rn   
build_specz.Service.get_secret_volumes.<locals>.build_spec5  ss    H%,,F~ (:(:F8<L<S<STWW]]6* (:(:FCVVF^VtLLrp   )r   )rm   r  r  s      rn   r  zService.get_secret_volumes4  s'    	M 26>v
6">>>s   $c                    t        t        j                  d      }|s2t        j                  }t
        j                  d| j                  z         | j                  j                  di       }|j                  di       j                         }|r|j                  |       | j                         j                         D ]  \  }}|j                  ||        t        |j                  d            }| j                   r+t#        | j$                  j&                  d      rt)        d      |	st+        | j$                        n
t-        |
      }|j/                  | || j0                  |||||j                  dd       | j3                  |      |j                  d	d       ||j                  d
d       |j                  dd       |j                  d      rt5        |j                  d            nd |j                  dd       d|rt5        |      nd i||j                  d| j                  j                  dd             | j                   |      S )NwzBuilding %sr   argscontextr  zEImpossible to perform platform-targeted builds for API version < 1.35
dockerfiler   rq  r  r^   rJ   memoryrN   )rk   r  tagrmforcermr   nocacher   
cache_fromr   	buildargsr   r  shmsizerJ   container_limitsgziprN   r  output_stream)openr  devnullsysstdoutr   r   r   r   r  copyr   r  rc  r  rewrite_build_pathr  r   r   r  r+   _ClientBuilder_CLIBuilderr   r  get_cache_fromr2   )rm   no_cacher   force_rmr!  build_args_overrider*  r#  r   r   progressr+  
build_opts
build_argsr  r  r  builders                     rn   r   zService.build@  s   RZZ-JJMHH]TYY./\\%%gr2
^^FB/446
12,,.446 	(DAq!!!Q'	( "*..";<==Z(?(?H&W  69.-k(>S}}!~~lD9**:6>>(D1 #	48>>(D1?I~~j?YK
z :;_c"}d;+f-T  nn[$,,2B2B;PT2UV]]'-  ) 	)rp   c                 \    |j                  dd       }||D cg c]  }|s|	 }}|S c c}w )Nr&  r`  )rm   r9  r&  r"  s       rn   r4  zService.get_cache_fromo  s8    ^^L$7
!)3;#s#;J; <s   ))c                     d| j                   v S )Nr   )r   r   s    rn   r   zService.can_be_builtu  s    $,,&&rp   c                    |s| j                   n t        j                  dd| j                         }dj                  t        |      dj                  t
        | j                        dj                  t        |rd      gS d      gS )Nz[_-] r   TrueFalse)r   resubr   r!   r"   r   r    )rm   r   r   	proj_names       rn   r   zService.labelsx  sn    (.DLLBFF7B4U	NN=)4NN=$))4NN=G&I
 	
 BII
 	
rp   c                 8    | j                   j                  d      S )Nr  r   r  r   s    rn   r   zService.custom_container_name  s    || 011rp   c                 <   | j                   r|| j                   S t        | j                  |||      }| j                  j	                  dg       D cg c]  }|j                  d      d    }}||v r%t        dj                  | j                  |            |S c c}w )Nr  r  r   z3Service {} has a self-referential external link: {})	r   build_container_namer   r   r  r  r   r   r   )rm   r&  r   r  r  linkext_links_originss          rn   r%  zService.get_container_name  s    %%$,----LL,
 =ALL<L<LM]_a<bcDTZZ_Q/cc..!ELLII~ 
  ds   Bc                    |r|t         j                  k(  ry|t         j                  k(  r| j                  j	                  d      ryt
        j                  d| j                         	 | j                  j                  | j                         y# t        $ r# t
        j                  d| j                         Y yt        $ r+}t
        j                  d| j                  |       Y d }~yd }~ww xY w)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   )rm   
image_typer  s      rn   rL  zService.remove_image  s    Z9>>9(T\\-=-=g-F$doo6	KK$$T__5 	KK-t? 	IIA499aP	s   '%B )C+8C+ !C&&C+c                 f    d t        fd| j                  j                  dg       D              S )Nc                     t        | t              r| j                  d      }nt        |       \  }}|y|d   }t        |t              sy|\  }}|yy)N	publishedFr   T)r  r	  r  r   tuple)bindingexternal_bindingsr"  external_binding	host_ports        rn   has_host_portz2Service.specifies_host_port.<locals>.has_host_port  sj    '4($+KK$<!'1'':$$ !(  13 .6 ,LAy$rp   c              3   .   K   | ]  } |        y wrj   ru   )r  rR  rV  s     rn   r  z.Service.specifies_host_port.<locals>.<genexpr>  s     Wg=)Ws   r  )anyr   r  )rm   rV  s    @rn   r   zService.specifies_host_port  s-    	0 W9I9I'SU9VWWWrp   c              #     K   	  | j                   j                  |fi |}|r8t        t        j                  d      5 }t        ||      E d {    d d d        y t        |t        j                        E d {    y 7 0# 1 sw Y   y xY w7 # t        t        f$ r+}|s t        j                  t        |             Y d }~y d }~ww xY ww)Nr  )r   r   r,  r  r-  r.   r.  r/  r/   r   r   r/  r  )rm   repopull_kwargsr   ignore_pull_failuresoutputr-  r  s           rn   _do_pullzService._do_pull  s     	"%T[[%%d:k:F"**c* >g,VW===> > )<<< >> > =!8, 	"'		#a&!!		"s{   C9B B A>B B CB 8B9B =C>B  B	B C	B C!C>CCCc                    d| j                   vry t        | j                   d         \  }}}|xs dd| j                  d}|s1t        j	                  dj                  | j                  |||             |d   r+t        | j                  j                  d      rt        d      | j                  ||||      }|r|S t        j                  |      S )	Nr   latestT)r"  streamr  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   get_digest_from_pull)	rm   r\  r   ra  rZ  r"  	separatorkwargsevent_streams	            rn   r   zService.pull  s    $,,&3DLL4IJc9?(

 HH-44TYYiQTUV**T[[-D-Df"M&V  }}T66;OP33LAArp   c                    d| j                   vsd| j                   vry t        | j                   d         \  }}}|xs d}t        j                  dj	                  | j
                  |||             | j                  j                  ||d      }	 t        j                  t        |t        j                              S # t        $ r+}|s t        j                  t        |             Y d }~y d }~ww xY w)Nr   r   r`  zPushing {} ({}{}{})...T)r"  ra  )r   rb  r   r   r   r   r   pushr   get_digest_from_pushr.   r.  r/  r/   r/  r  )rm   ignore_push_failuresrZ  r"  rd  r]  r  s          rn   rh  zService.push  s    $,,&'*E3DLL4IJc9oX)00D)SQR!!$C!=	""77fcjj13 3  	"'		#a&!!		"s   ,B= =	C1!C,,C1c                     d}| j                         D ]\  }|j                          |j                  d      }|t        | j                        |dk(  rd}C|dk(  sIt        |j                         |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.StatusstartingF	unhealthy)r   inspectr  r*   r   r)   r  )rm   r   ctnrstatuss       rn   r  zService.is_healthy  sv     OO% 	7DLLNXX34F~-dii88:%;&'66	7 rp   c                     d}| j                  d      D ]X  }|j                          |j                  d      dk7  rd}*|j                  dk7  s:t	        |j
                  |j                         |S )a   Check that all containers for this service has completed successfully
            Returns false if at least one container does not exited and
            raises CompletedUnsuccessfully exception if at least one container
            exited with non-zero exit code.
        Tr   zState.StatusexitedFr   )r   rn  r  	exit_coder(   r  )rm   r   ro  s      rn   r  z!Service.is_completed_successfully	  sl     OODO1 	MDLLNxx'831$-dmmT^^LL	M rp   c                 r   | j                   }d|j                  vri S t        |d|j                        }|j                  d   j	                  ||j                  d   j	                  d            xs i }ddddd}i }|j                         D ](  \  }}||vr|x|||   <   |||   j                         <   * |S )	Nproxies_original_base_urldefault	FTP_PROXY
HTTP_PROXYHTTPS_PROXYNO_PROXY)ftpProxy	httpProxy
httpsProxynoProxy)r   _general_configsgetattrbase_urlr  rc  lower)rm   r   docker_hostproxy_config	permittedr   r  r  s           rn   r  zService._parse_proxy_config  s    F333If&:FOOL..y9==00;??	J
  	
 $%'!	
	  &&( 	DDAq	!BCCF9Q< 6)A,*<*<*>#?	D
 rp   c                 X    d| j                   vrg S | j                   j                  d      S )NprofilesrF  r   s    rn   get_profileszService.get_profiles1  s(    T\\)I||
++rp   c                 r    d| j                   vry| j                   j                  d      }|D ]  }||v s y y)Nr  TFrF  )rm   enabled_profilesservice_profilesprofiles       rn   enabled_for_profileszService.enabled_for_profiles7  sF    T\\)<<++J7' 	G**	 rp   )Nrw  FNNNNNr   NNNN)FFNN)r   rj   )FNNF)FN)NFTNTFFN)NFTF)FF)T)F)
FFFNNFTFFN)FFF)Err   rs   rt   ro   r   r   r   r   r   r   r   r   r   r   r  r   r   r  r  r   r   r  r   r0  r;  r   r   rQ  r   rD  r   r  rd  rY  ru  rt  r  r|  r  r  r  r  r  r   r  rm  r  ro  r  r   r  r  r  r   r4  r   r   r   r%  rL  r   r^  r   rh  r  r  r  r  r  ru   rp   rn   r   r      s     ! /D1
2S
%8Ov "',0 $$	Z< ,7+;+;Eu >0SS  
   )<(C(CU 32:$L6,

 EJ<@EJQU3=j bf38.3	 
 
(& - -
*
B=H[6
E"
6G #V!p*3XO
b
? bfEI-)^'
 2 2 "X6"B."$$2,
rp   r   c                 h    | j                  dj                  |            xs d}| j                  |v S )Nz&NetworkSettings.Networks.{net}.Aliases)r  ru   )r  r   r  )r   rq  ri  s      rn   rj  rj  D  s?    mm077G7DF LIK ((rp   c                   2    e Zd Zd Zed        Zed        Zy)r   c                     || _         y rj   _moderm   r  s     rn   ro   zIpcMode.__init__K  	    
rp   c                     | j                   S rj   r  r   s    rn   r  zIpcMode.modeN      zzrp   c                      y rj   ru   r   s    rn   r&  zIpcMode.service_nameR      rp   Nrr   rs   rt   ro   r   r  r&  ru   rp   rn   r   r   J  /        rp   r   c                   2    e Zd Zd Zed        Zed        Zy)ServiceIpcModec                     || _         y rj   ry   rz   s     rn   ro   zServiceIpcMode.__init__X  r{   rp   c                 .    | j                   j                  S rj   rk   r   r   s    rn   r&  zServiceIpcMode.service_name[      ||   rp   c                     | j                   j                         }|rd|d   j                  z   S t        j	                  d| j
                  z         y )N
container:r   z[Service %s is trying to use reuse the IPC namespace of another service that is not running.rk   r   rl  r   r   r&  rm   r   s     rn   r  zServiceIpcMode.mode_  Q    \\,,.
*Q-"2"22269=9J9JL	
 rp   Nrr   rs   rt   ro   r   r&  r  ru   rp   rn   r  r  W  /     ! ! 	 	rp   r  c                       e Zd Zd Zy)ContainerIpcModec                 R    || _         dj                  |j                        | _        y Nzcontainer:{}r   r   rl  r  rm   r   s     rn   ro   zContainerIpcMode.__init__m      "#**9<<8
rp   Nrq   ru   rp   rn   r  r  l      9rp   r  c                   2    e Zd Zd Zed        Zed        Zy)r   c                     || _         y rj   r  r  s     rn   ro   zPidMode.__init__s  r  rp   c                     | j                   S rj   r  r   s    rn   r  zPidMode.modev  r  rp   c                      y rj   ru   r   s    rn   r&  zPidMode.service_namez  r  rp   Nr  ru   rp   rn   r   r   r  r  rp   r   c                   2    e Zd Zd Zed        Zed        Zy)ServicePidModec                     || _         y rj   ry   rz   s     rn   ro   zServicePidMode.__init__  r{   rp   c                 .    | j                   j                  S rj   r  r   s    rn   r&  zServicePidMode.service_name  r  rp   c                     | j                   j                         }|rd|d   j                  z   S t        j	                  d| j
                  z         y )Nr  r   z[Service %s is trying to use reuse the PID namespace of another service that is not running.r  r  s     rn   r  zServicePidMode.mode  r  rp   Nr  ru   rp   rn   r  r    r  rp   r  c                       e Zd Zd Zy)ContainerPidModec                 R    || _         dj                  |j                        | _        y r  r  r  s     rn   ro   zContainerPidMode.__init__  r  rp   Nrq   ru   rp   rn   r  r    r  rp   r  c                   .    e Zd ZdZdZd Zed        ZeZy)r   z,A `standard` network mode (ex: host, bridge)Nc                     || _         y rj   r   )rm   r   s     rn   ro   zNetworkMode.__init__  s
    (rp   c                     | j                   S rj   r  r   s    rn   rl  zNetworkMode.id  s       rp   	rr   rs   rt   r   r&  ro   r   rl  r  ru   rp   rn   r   r     s*    6L) ! ! Drp   r   c                   :    e Zd ZdZdZd Zed        Zed        Zy)ContainerNetworkModez5A network mode that uses a container's network stack.Nc                     || _         y rj   )r   r  s     rn   ro   zContainerNetworkMode.__init__  s	    "rp   c                 .    | j                   j                  S rj   r   rl  r   s    rn   rl  zContainerNetworkMode.id  s    ~~   rp   c                 4    d| j                   j                  z   S )Nr  r  r   s    rn   r  zContainerNetworkMode.mode  s    dnn////rp   r  ru   rp   rn   r  r    s7    ?L# ! ! 0 0rp   r  c                   :    e Zd ZdZd Zed        ZeZed        Zy)ServiceNetworkModez3A network mode that uses a service's network stack.c                     || _         y rj   ry   rz   s     rn   ro   zServiceNetworkMode.__init__  r{   rp   c                 .    | j                   j                  S rj   r  r   s    rn   rl  zServiceNetworkMode.id  r  rp   c                     | j                   j                         }|rd|d   j                  z   S t        j	                  d| j                  z         y )Nr  r   z[Service %s is trying to use reuse the network stack of another service that is not running.)rk   r   rl  r   r   r  s     rn   r  zServiceNetworkMode.mode  sN    \\,,.
*Q-"2"222 >AEJ 	Krp   N)	rr   rs   rt   r   ro   r   rl  r&  r  ru   rp   rn   r  r    s7    = ! ! L rp   r  c                     | j                  d      |g}|r|j                  dt        |      g       n|j                  t	        |             dj                  |      S )Nz-_r#  r"  )r	  r:  r4   r  r  r$  )r   rk   r   r  bitss        rn   rH  rH    sL    NN4 '*DUK-./CK 88D>rp   c                     d}d}|| v r| j                  |d      \  }}|||fS | d}}|| v r| j                  |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', ':')
    r  @r   r?  /)rsplit)	repo_pathtag_separatordigest_separatorrZ  r"  s        rn   rb  rb    s     M9$$$%5q9	cS***2#D	!$$]A6	c#:!2#Dm##rp   c                    i }t        d | D              }|rUt        || ||      \  }}t        | ||j                         |j	                  d |D               |s|rdd|j
                  z   i}t        |j                               |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              3   J   K   | ]  }|j                   rt        |        y wrj   )externalbuild_volume_bindingr  volumes     rn   r  z(merge_volume_bindings.<locals>.<genexpr>  s$      "?? 	V$"s   !#c              3   2   K   | ]  }t        |        y wrj   )r  r  s     rn   r  z(merge_volume_bindings.<locals>.<genexpr>  s      
-3 (
s   zaffinity:container=)r   get_container_data_volumeswarn_on_masked_volumerk   r   rl  r   r+  )r  r  r   r  r  volume_bindingsold_volumes
old_mountss           rn   r  r    s     H! "" O "<#
Z 	g{4F4N4NO 
7B
 	
 *,c4F4I4I.IJH&&()833rp   c                 6   g }|xs g }| j                  d      xs i D ci c]  }|d   |
 }}| j                  d   j                  d      xs i D cg c]  }t        j                  |       }}t	        ||z         D ]  }|j
                  r|j                  t        |      j                         v r6|j                  |j                        }|sT|j                  d      sf|j                  |D 	cg c]  }	|	j                   c}	v r|j                  |d         }|j                  |        d}
|D ]M  }|j                  dk7  r|j                  |j                        }|r|j                  d      sB|d   |_        d	}
O ||
fS c c}w c c}w c c}	w )
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.
    MountsDestinationContainerConfigVolumesName)r  Fr  T)r  image_configr   parser   r  r  r   r  r  _replacer  r   r  )r   volumes_optiontmpfs_optionmounts_optionr  mountr  r  image_volumesr  updated_mounts
ctnr_mounts               rn   r  r    s    G#)rN ]]8,2 	me#  	0155i@FB 	 M  n}45 ?? ??2<@EEGG $$V__5  yy  ???Aqxx?? %-8v58 N 	::!%))%,,7
!7!&)	 N""g
6 @s   FF4Fc                 d   |D ci c]  }|j                   |j                   }}| D ]  }|j                  s|j                   |v s|j                  |j                         |j                  k7  sHt        j	                  dj                  ||j                   |j                                y c c}w )NzService "{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.)rk   r  	host_path)r  r  r  r   r   r   )r  r  rk   r  s       rn   r  r  Y  s     () 	() ) ! ,#44!%%foo6&//IKK2 f //  +,,	)s   B-c                 :    | j                   | j                         fS rj   )r  repr)volume_specs    rn   r  r  o  s    !1!1!333rp   c                    t        | j                  t              r| j                  j                  d      }|s>dj	                  | j                  j                         j                  | j                        S |d   }dj	                  |j                  | j                        S t        | j                  t              r0dj	                  | j                  j                  | j                        S y)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   {}:{}r   N)	r  r  r   r   r   r   rl  r  r'   )volume_from_specr   r   s      rn   r  r  s  s    
 "))73%,,777E
>> ''88:== %%' ' qM	~~ill,<,A,ABB	$++Y	7~~.5588:J:O:OPP 
8rp   c           	      D   i }| j                   rP| j                  | j                     j                         D ]&  \  }}|| j                   v s| j                   |   ||<   ( t	        d| j                  | j
                  | j                  | j                  | j                  d|S )N)r   r  r  rO   consistencyru   )	r   options_mapr   rc  r
   r  r  rO   r  )
mount_specre  optionsdk_names       rn   r  r    s    F * 6 6z G M M O 	>FH+++#-#5#5f#=x 	>  __Z%6%6z?P?P&&J4J4JNT rp   c                     t        | xs i       }|j                  d |D               |t        |      |t        <   |	||t        <   t
        |t        <   |r!t        j                  d|z         ||t        <   |S )Nc              3   @   K   | ]  }|j                  d d        yw)r  r   N)r  )r  r   s     rn   r  z)build_container_labels.<locals>.<genexpr>  s     B%%++c1%Bs   zAdded config hash: %s)
r	  r   r  r   r#   r   r$   r   r  r   )label_optionsservice_labelsr   r  r  r   s         rn   r  r    sw    -%2&F
MMB>BB),V%&!z'F=		)K78$/ !Mrp   c                     | sy g }| j                         D ]b  \  }}t        |t              r|j                  |||d       ,t        |t              s=d|i}|j                  |       |j                  |       d |S )N)r   softhardr   )rc  r  r  r  r	  r   )ulimit_configr  
limit_namesoft_hard_valuesulimit_dicts        rn   r  r    s    G(5(;(;(= ($
$&,NNJ8HRbcd($/!:.K/0NN;'( Nrp   c                 t    | r| j                  dd      nd}| r| j                  dd       nd }t        ||      S )Ndriverr?  r   )r   r  )r  r	   )r  rP   log_optionss      rn   r  r    sA    3?!!(B/RJ7C,""9d3K rp   c                 T    d }| j                         D cg c]  } || 	 c}S c c}w )Nc                 r    || S t        |t              r|j                  d      }dj                  | |      S )Nzutf-8z{key}={value}r   r  )r  bytesdecoder   r  s     rn   
format_envz&format_environment.<locals>.format_env  s:    =JeU#LL)E%%#U%;;rp   )rc  )r  r  items      rn   r  r    s+    < +6*;*;*=>$J>>>s   %c                     g }| D ]C  }t        |t              r |j                  |j                                3|j                  |       E |S rj   )r  r   r  r  )r  r   ports      rn   r  r    sH    F  dK(MM$**,-MM$	 
 Mrp   c                     g }| |j                  dg       z   }|D ]Q  }t        |      \  }}|D ]<  }t        |      }d|v rt        |j	                  d            }|j                  |       > S |S )Nr  r  )r  r   r  rQ  r  r  )container_portsr   r  	all_ports
port_rangeinternal_ranger"  r  s           rn   r  r    s~    E'++h";;I 
&z2" 	Dt9Dd{TZZ_-LL		 Lrp   c           
         i }| |S | j                  d      |d<   dD ]Y  }|| vrg }| |   D ]C  }|j                  |j                         D ci c]  \  }}|j                         | c}}       E |||<   [ |S c c}}w )Nr  )r  r  r  r  r  )r  r  rc  
capitalize)r  r   fieldarrr  r  r  s          rn   r
  r
    s    F#''1F8 	 $ ' 	EDJJdjjlCda)CD	Eu	 M Ds   A;c                     t         rFt        |       s;| j                  t              s&t        t        j
                  j                  |       z   } | S rj   )r   r   
startswithr&   r  r  normpath)r  s    rn   r1  r1    s5    6$<H_8`&)9)9$)??Krp   c                   b    e Zd Zd Zdddddddddddddddddddddddddej
                  fdZy)r2  c                     || _         y rj   )r   )rm   r   s     rn   ro   z_ClientBuilder.__init__  s	    rp   NFTc                    | j                   j                  ||||||||||||||||||      }	 t        t        ||            }| j                   j                          d } |D ]A  }!d|!v st        j                  d|!j                  dd            }"|"s1|"j                  d      } C | t        ||r!      d      | S # t        $ r}t        |t        |            d }~ww xY w)N)r  r"  r%  r#  r   r$  r   r   r&  r'  r   r  r(  rJ   r)  r*  rN   r  ra  zSuccessfully built ([0-9a-f]+)r?  r   Unknown)r   r   r   r.   r/   rh   r  closerB  searchr  group)#rm   rk   r  r"  r   fileobjr%  r#  r   custom_contextencodingr   r$  r   r)  r  r'  r*  r(  r   r&  r  r   squashrJ   r  rN   use_config_proxyr+  build_output
all_eventsr  r  eventmatchs#                                      rn   r   z_ClientBuilder.build  s    {{((!!%#-% ) (	.mL-HIJ 	 	.E5 		"CUYYxY[E\]${{1~H		. WzeIIyII' ! 	.Wc!f--	.s   B> >	C!CC!rr   rs   rt   ro   r.  r/  r   ru   rp   rn   r2  r2    sN     (,5$t"Ttdd4dtdd#3::1rp   r2  c                   b    e Zd Zd Zdddddddddddddddddddddddddej
                  fdZy)r3  c                     || _         y rj   )	_progress)rm   r8  s     rn   ro   z_CLIBuilder.__init__7  s	    !rp   NFTc                    |r?t         j                  j                  |      r t         j                  j                  ||      }t	        j
                         }t               }|j                  d|       |j                  d|       |j                  d|       |j                  d|       |j                  d|       |j                  d|j                  d             |j                  d|       |j                  d	|       |j                  d
| j                         |j                  d|       |j                  d|       |j                  d|       |j                  d|       |j                  d|       |j                  d|       |rjt        |t              r2|j                         D  cg c]  \  }} dj!                  ||        }}} |D ]#  }|j                  ddj!                  |             % |j#                  |g      }!t%        j&                  |!|t(        j*                  d      5 }"|"j-                          |"j.                  dk7  rt1        |d      	 ddd       t3        |      5 }#|#j5                         }$|$j7                  d      d   j9                         }%ddd       t        j:                  |       %S c c} }w # 1 sw Y   lxY w# 1 sw Y   2xY w)ah  
        Args:
            service (str): Service to be built
            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.
            output_stream (writer): stream to use for build logs
        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
--platformz--isolationr  z
--add-hostz{}T)r/  stderruniversal_newlinesr   zBuild failedNr  r   )r  r  isdirr$  tempfilemktemp_CommandBuilder
add_paramsadd_listadd_argadd_flagr  r7  r  r	  rc  r   r   
subprocessPopenr.  r9  communicate
returncoderh   r,  readliner  stripr   )&rm   rk   r  r"  r   r+  r%  r#  r   r,  r-  r   r$  r   r)  r  r'  r*  r(  r   r&  r  r   r.  rJ   r  rN   r/  r+  iidfilecommand_builderhostipr  pfliner  s&                                         rn   r   z_CLIBuilder.build:  sn   ~ "''---dJ7J//#)+""=)<  <*5  w7""9f5
,<,@,@,JK\:  w7dnn=  40-
F3W5h7y9+t,HSHYHYH[\HD"w~~dB7\\# I''dkk$6GHI $$dV,d=157 	::;MMO||q  .99 !	: '] 	2a::<Dzz#q)//1H	2 			'# ]	: 	:	2 	2s   ,J>,,K,3KKKr4  ru   rp   rn   r3  r3  6  sO    " (,5$t"Ttdd4dtdd#3::grp   r3  c                   0    e Zd Zd Zd Zd Zd Zd Zd Zy)r>  c                     ddg| _         y )Ndockerr   _argsr   s    rn   ro   z_CommandBuilder.__init__  s    (
rp   c                 V    |r'| j                   j                  |t        |      g       y y rj   )rT  r:  r  )rm   r   r  s      rn   rA  z_CommandBuilder.add_arg  s%    JJtSZ01 rp   c                 B    |r| j                   j                  |g       y y rj   rT  r:  )rm   r   flags      rn   rB  z_CommandBuilder.add_flag  s    JJtf% rp   c                     |rF|j                         D ]2  \  }}| j                  j                  |dj                  ||      g       4 y y )Nr   )rc  rT  r:  r   )rm   r   paramsr   vals        rn   r?  z_CommandBuilder.add_params  sG    "LLN DS

!!4S)A"BCD rp   c                 R    |r%|D ]  }| j                   j                  ||g       ! y y rj   rW  )rm   r   r+  r[  s       rn   r@  z_CommandBuilder.add_list  s/     /

!!4+./ rp   c                      | j                   |z   S rj   rS  )rm   r  s     rn   r   z_CommandBuilder.build  s    zzD  rp   N)	rr   rs   rt   ro   rA  rB  r?  r@  r   ru   rp   rn   r>  r>    s!    )2&D
/
!rp   r>  rj   )zenumr  r  r  rB  rC  r.  r<  collectionsr   r   operatorr   docker.errorsr   r   r   docker.typesr	   r
   docker.utilsr   r   docker.utils.portsr   r   docker.utils.utilsr   r?  r   r   r   r  r   r   r   r   config.errorsr   config.typesr   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r   r'   r.  r(   r)   r*   r+   parallelr-   r.   r/   utilsr0   r1   r2   r3   r4   r5   compose.cli.utilsr6   	getLoggerrr   r   r  r  r  r  rJ  rh   rw   r}   r~   r   uniqueEnumr   r   r   r   rj  r   r  r  r   r  r  r   r  r  rH  rb  r  r  r  r  r  r  r  r  r  r  r  r  r
  r1  r2  r3  r>  ru   rp   rn   <module>rn     sv      	 	  
  " #  " ' " "  $ # 2 ) 3    &  %   * # % $ " & $ )          ! *   + % + ( & * . %   &  " 2 g!. ` & % #C   i 
	y 	 (@A.0CD 
,$)) 
, 
, 		   $))  Y Yx$)
 
W *9w 9
 
W *9w 9 0 0" 4$<4:<#~,,4Q$
 &?
&5 5pk k\! !rp   