
    S`w                        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%l5m6Z6 dd&l5m7Z7 dd'l5m8Z8 dd(l9m:Z:  ejv                  e<      Z=ej|                   G d) d*ej~                               Z@ G d+ d,      ZAd- ZBd. ZCd/ ZDd0 ZEd1 ZFd2 ZGd3 ZHd4 ZId5 ZJd6 ZK G d7 d8eL      ZM G d9 d:eL      ZN G d; d<eL      ZO G d= d>eL      ZP G d? d@eL      ZQy)A    N)reduce)path)APIError)ImageNotFound)NotFound)
version_lt   )parallel)	UserError)ConfigurationError)V1)$get_container_name_from_network_mode)"get_service_name_from_network_mode)LABEL_ONE_OFF)LABEL_PROJECT)LABEL_SERVICE)	Container)build_networks)get_networks)ProjectNetworks)read_status)BuildAction)ContainerIpcMode)ContainerNetworkMode)ContainerPidMode)ConvergenceStrategy)IpcMode)NetworkMode)NoSuchImageError)parse_repository_tag)PidMode)Service)ServiceIpcMode)ServiceNetworkMode)ServicePidMode)filter_attached_for_up)microseconds_from_time_nano)truncate_string)ProjectVolumesc                   (    e Zd ZdZdZdZed        Zy)OneOffFilterr   r	      c                 <   || j                   k(  r&|j                  dj                  t        d             y || j                  k(  r&|j                  dj                  t        d             y || j
                  k(  ry t        dj                  t        |                  )N{}={}TrueFalsezInvalid value for one_off: {})onlyappendformatr   excludeinclude
ValueErrorrepr)clsvaluelabelss      1/usr/lib/python3/dist-packages/compose/project.pyupdate_labelszOneOffFilter.update_labels8   sr    CHHMM'..?@ckk!MM'..@Ackk!<CCDKPQQ    N)__name__
__module____qualname__r5   r4   r1   classmethodr<    r=   r;   r+   r+   2   s%    GGDR Rr=   r+   c                   D   e Zd ZdZ	 	 d+dZej                  dfdZe	 	 d,d       Z	e
d        Zd Zd	 Zd-dZd.dZd Zd Zd Zd Zd Zd Zd/dZdej                  fdZd/dZd/dZd/dZdej                  fdZ	 	 	 d0dZd Zd/dZ	 	 	 d1dZde jB                  e"jF                  fdZ$d Z%d/dZ&dd
e jB                  e"jF                  dddddd
d
ddddddddfd Z'd! Z(d2d"Z)	 	 d3d#Z*d4d$Z+d.d%Z,dej                  fd&Z-ddej                  fd'Z.d( Z/d) Z0d* Z1y)5Projectz#
    A collection of services.
    Nc                     || _         || _        || _        |xs t        i       | _        |xs t        i d      | _        || _        |xs g | _        y NF)	nameservicesclientr)   volumesr   networksconfig_versionenabled_profiles)selfrG   rH   rI   rK   rJ   rL   rM   s           r;   __init__zProject.__init__H   sP    	 4."4 >OB$>, 0 6Br=   Fc                     | j                   }|rt        j                  dd|      }dj                  t        |      g}t
        j                  ||       |S )Nz[_-] r.   )rG   resubr3   r   r+   r<   )rN   one_offlegacyrG   r:   s        r;   r:   zProject.labelsR   sH    yy66'2t,D..56""7F3r=   c                    |xs g }|j                   xr |j                   t        k7  }t        |||      }t        j                  |j
                  ||      }	t        j                  |||      }
 | |g ||	|
|j                   |      }|j
                  D ]  }t        |      }|rt        ||      }ni }|j                  dd       |j                  |      }|j                  |      }|j                  |t        |j                                     }|j!                  |      }t#        ||      }|j                   t        k7  r2|j%                  dg       D cg c]  }|
j'                  |       c}|d<   t)        |d   |j                  dd      xs g |j*                        }|j-                  |      |d<   |j/                  |      |d<   t1        |      }t3        |      \  }}|r3t4        j7                  dj9                  d	j;                  |                   |j
                  j=                  t?        |j                  d      f|||||||||||j                  d
d      ||d|        |S c c}w )zB
        Construct a Project from a config.Config object.
        rK   NrJ   rG   secretsscaledevice_requestszIThe following deploy sub-keys are not supported and have been ignored: {}, platform)rI   projectuse_networkingrK   linksnetwork_modevolumes_fromrW   pid_modeipc_moder[   default_platformextra_labels) versionr   r   r   from_servicesrH   r)   from_configdictr   pop	get_linksget_ipc_modeget_network_modelistkeysget_pid_modeget_volumes_fromgetnamespace_specget_secretsrW   get_service_scaleget_device_requests)translate_credential_spec_to_security_opt)translate_deploy_keys_to_container_configlogwarningr3   joinr2   r"   )r8   rG   config_datarI   rc   rd   rM   r]   rK   project_networksrJ   r\   service_dictservice_networksr^   rb   r_   ra   r`   volume_specrW   ignored_keyss                         r;   rg   zProject.from_config[   s    $)r%--K+2E2E2K!$V<*88   !,,T;GdB(8';CVCVXhi'00 8	L-L#/h#G #% Z.%%l3E++L9H"33d#3#8#8#:;L ++L9H+G\BL""b( (4'7'7	2'F+# **;7+Y'
 "V$  D17R##%G
 %,$=$=l$KL!.5.I.I,.WL*+D\RL)R*&L, ((.tyy/F(G
 ## $$V,$! #1-!-!-#%%)--j$?%5!-$ #$O8	t S+s   I+c                 T    | j                   D cg c]  }|j                   c}S c c}w N)rH   rG   )rN   services     r;   service_nameszProject.service_names   s    ,0MM::::s   %c                 `    | j                   D ]  }|j                  |k(  s|c S  t        |      )zo
        Retrieve a service by name. Raises NoSuchService
        if the named service does not exist.
        )rH   rG   NoSuchService)rN   rG   r   s      r;   get_servicezProject.get_service   s5    
 }} 	G||t#	 D!!r=   c                 H    | j                   }|D ]  }||vst        |       y)z
        Validate that the given list of service names only contains valid
        services. Raises NoSuchService if one of the names is invalid.
        N)r   r   )rN   r   valid_namesrG   s       r;   validate_service_nameszProject.validate_service_names   s1    
 ((! 	*D;&#D))	*r=   Tc                 D     j                   j                         |t        |      dk(  r6d} j                  D cg c]  }|j	                        r|j
                  ! }}|D cg c]  } j                  |       }} j                  D cg c]	  }||v s| }}|r2|D ]-  }|j                         D ]  }	|	vsj                  |	        / |rt         fd|g       }g }
|D cg c]  }||
vs|
j                  |       c} |
S c c}w c c}w c c}w c c}w )aM  
        Returns a list of this project's services filtered
        by the provided list of names, or all services if service_names is None
        or [].

        If include_deps is specified, returns a list including the dependencies for
        service_names, in order of dependency.

        Preserves the original order of self.services where possible,
        reordering as needed to resolve dependencies.

        Raises NoSuchService if any of the named services do not exist.

        Raises ConfigurationError if any service depended on is not enabled by active profiles
        r   Fc                 *    j                  | |      S r   )_inject_deps)accsrM   rN   s     r;   <lambda>z&Project.get_services.<locals>.<lambda>   s    t00a9IJ r=   )
rM   copylenrH   enabled_for_profilesrG   r   get_profilesr2   r   )rN   r   include_depsauto_enable_profilesr   rG   unsortedr   rH   profileuniquesrM   s   `          @r;   get_serviceszProject.get_services   s=   "  00557 C$6!$;#(   $}}//0@A M  8EEtD$$T*EE#}}>!XA>># 9&335 9G&66(//899
 JH $,Aq0@	A5 F>" 	Bs#   $D'D	DD,	D6Dc                 X    | j                  ||      }|D ]  }|j                           |S r   )r   remove_duplicate_containers)rN   r   r   rH   r   s        r;   get_services_without_duplicatez&Project.get_services_without_duplicate   s4    $$]LA 	2G//1	2r=   c           	         g }d|v r[|j                  dg       D ]C  }d|v r|j                  dd      \  }}n|d }}	 |j                  | j                  |      |f       E |d= |S # t        $ r t        d|d   d|d      w xY w)Nr^   :r	   z	Service "rG   z" has a link to service "z" which does not exist.)rq   splitr2   r   r   r   )rN   r}   r^   linkservice_name	link_names         r;   rj   zProject.get_links   s    l"$(("5 
I$;.2jja.@+L).2D)LILL$"2"2<"@)!LM
I W% % I,$0$8,HI IIs   "A$$Bc                    |j                  dd       }|s<| j                  j                  r|rt        |d         S t        d      S t        d       S t	        |      }|rt        | j                  |            S t        |      }|r*	 t        t        j                  | j                  |            S t        |      S # t        $ r  t        dj                  |d   |            w xY w)Nr_   r   nonezRService '{name}' uses the network stack of container '{dep}' which does not exist.rG   rG   dep)ri   rK   r]   r   r   r$   r   r   r   r   from_idrI   r   r   r3   )rN   r}   rK   r_   r   container_names         r;   rl   zProject.get_network_mode  s    #''=}}++3;{8A;/TVATTt$$9,G%d&6&6|&DEE=lK]+I,=,=dkk>,Z[[ <((  ](&&,f,v2FNf&[] ]]s   (B: :)C#c                 j   |j                  dd       }|st        d       S t        |      }|rt        | j	                  |            S t        |      }|r*	 t        t        j                  | j                  |            S t        |      S # t        $ r  t        dj                  |d   |            w xY w)NpidzRService '{name}' uses the PID namespace of container '{dep}' which does not exist.rG   r   )ri   r!   r   r%   r   r   r   r   r   rI   r   r   r3   )rN   r}   ra   r   r   s        r;   ro   zProject.get_pid_mode      ##E404= 9(C!$"2"2<"@AA=hG'	(9(9$++~(VWW x    (&&,f,v2FNf&[    (B	 	)B2c                 j   |j                  dd       }|st        d       S t        |      }|rt        | j	                  |            S t        |      }|r*	 t        t        j                  | j                  |            S t        |      S # t        $ r  t        dj                  |d   |            w xY w)NipczRService '{name}' uses the IPC namespace of container '{dep}' which does not exist.rG   r   )ri   r   r   r#   r   r   r   r   r   rI   r   r   r3   )rN   r}   rb   r   r   s        r;   rk   zProject.get_ipc_mode3  r   r   c                    |j                  dd       }|j                  dd       }|s|dS |S |j                  dd      dk7  r|dS |S |j                  dd       }||t        d      ||}|y|j                  di       j                  d	|      }t        ||      }||k  r$t        j	                  d
j                  |             |S )NrX   deployr	   mode
replicatedreplicaszUBoth service.scale and service.deploy.replicas are set. Only one of them must be set.	placementmax_replicas_per_nodez7Scale is limited to {} ('max_replicas_per_node' field).)rq   r   minrx   ry   r3   )rN   r}   rX   deploy_dictr   max_replicass         r;   rt   zProject.get_service_scaleH  s      $/"&&x61050??6<0L@1050??:t4!5$1  E="{B7;;# E<(%KKQXX r=   c                 j   |j                  dd       }|sy |j                  dd       }|r|j                  dd       sy |d   j                  d      }|sy |D ]Z  }|j                  dd      }t        |t              s(|dk7  rt        dj	                  |d         d	      d|d<   d
|v sR|d
   g|d
<   \ |S )Nr   	resourcesreservationsdevicescountallz$Invalid value "{}" for devices countz(expected integer or "all")capabilities)rq   
isinstanceintr   r3   )rN   r}   r   r   r   devr   s          r;   ru   zProject.get_device_requestsg  s    "&&x6OOK6		nd CN+//	: 
	<CGGGR(EeS)E>,>EEc'lS57 7  "G$'*>':&;N#
	< r=   c                      g fd} j                  |      } fd}t        j                  ||t        j                  d      d|d        S )Nc                 P     | j                   dddi}j                  |       y )NquietTrB   )startextend)r   service_containers
containersoptionss     r;   start_servicez$Project.start.<locals>.start_service  s+    !.!ET!EW!E01r=   c                     | j                         j                         D ch c]  \  }}j                  |      |f c}}S c c}}w r   get_dependency_configsitemsr   r   r   configrN   s      r;   get_depszProject.start.<locals>.get_deps  K     $+#A#A#C#I#I#KC !!#&/     ArG   Startingc                 $    | j                          S r   )r   )objs    r;   r   zProject.start.<locals>.<lambda>  s    s~~'7#7 r=   )
fail_check)r   r
   parallel_executeoperator
attrgetter)rN   r   r   r   rH   r   r   s   ` `   @r;   r   zProject.start  sY    
	2 $$]3	 	!!'7	
 r=   c                       j                  ||       fd}t        j                   j                  d|      t	        j
                  d      d|       y )NrT   c                     D ch c];  }| j                   j                  |j                         j                         v r|d f= c}S c c}w r   )r   r   get_dependency_names)	containerotherr   rN   s     r;   r   zProject.stop.<locals>.get_deps  sT    /9 Le (($$U]]3HHJK DM L L Ls   A A	stoprG   Stopping)r   r
   r   +build_container_operation_with_timeout_funcr   r   )rN   r   rT   r   r   r   s   `    @r;   r   zProject.stop  sR    __]G_D
	L 	!!<<VWM'	
r=   c                 f    | j                  |      }t        j                  t        |      |       |S r   )r   r
   parallel_pausereversedrN   r   r   r   s       r;   pausezProject.pause  s+    __]3
 4g>r=   c                 T    | j                  |      }t        j                  ||       |S r   )r   r
   parallel_unpauser   s       r;   unpausezProject.unpause  s&    __]3
!!*g6r=   c                 N    t        j                  | j                  |      |       y r   )r
   parallel_killr   )rN   r   r   s      r;   killzProject.kill  s    t}=wGr=   c                 T    t        j                  | j                  |d|      |       y )NT)stoppedrT   )r
   parallel_remover   )rN   r   rT   r   s       r;   remove_stoppedzProject.remove_stopped  s*      4 "1 "
	r=   c                 <   | j                  t        j                  |       |s| j                  |       | j	                  |t        j                         | j
                  j                          |r| j                  j                          | j                  |       y )N)rT   timeout)vrT   )	r   r+   r5   find_orphan_containersr   rK   removerJ   remove_images)rN   remove_image_typeinclude_volumesremove_orphansr   ignore_orphanss         r;   downzProject.down  sv     			,..	@''7o|7K7KLLL!,-r=   c                 H    | j                   D ]  }|j                  |        y r   )rH   remove_image)rN   r   r   s      r;   r   zProject.remove_images  s$    }} 	4G  !23	4r=   c                     | j                  |      D cg c]  }|j                   }}| j                  |d      }t        j                  || j                  d|      t        j                  d      d       |S c c}w )NTr   restartrG   
Restarting)r   rG   r   r
   r   r   r   r   )rN   r   r   r   r   s        r;   r  zProject.restart  sv    )-):):=)IJAJJ__]D_A
!!<<YP'		
  Ks   A9c           
        	
 g }| j                  |      D ]I  }|j                         r|j                  |       %
r(t        j	                  d|j
                  z         K r.|rt        j                  d       rt        j                  d       	
f
d}|rt        j                  ||t        j                  d      dd      \  }}t        |      rYd	j                  |j                         D cg c]%  }t        |t              r|j!                  d
      n|' c}      }t#        |      y |D ]
  } ||        y c c}w )Nz%s uses an image, skippingzJFlag '--parallel' is ignored when building with COMPOSE_DOCKER_CLI_BUILD=1zJFlag '--compress' is ignored when building with COMPOSE_DOCKER_CLI_BUILD=1c                 :   
 | j                  	

       y r   )build)r   
build_argscliforce_rmgzipmemoryno_cacheprogresspullrmsilents    r;   build_servicez$Project.build.<locals>.build_service  s$    MM(D(FJbRXZ]_ghr=   rG   Building   limit
utf-8)r   can_be_builtr2   rx   inforG   ry   r
   r   r   r   r   rz   valuesr   bytesdecodeProjectError)rN   r   r  r  r  r  r
  r  parallel_buildr  r  r  r  rH   r   r  _errorsecombined_errorss     `````` ````       r;   r	  zProject.build  s;    ((7 	FG##%(5DE		F  9 : 9 :	i 	i  11##F+IAv 6{"&))NTmmo-IJAu)=AHHW%1D- # #?33	  $ 'g&'-s   *Ec                     | j                  |d      }|D ]  }|j                  |        | j                  ||      }|D ]#  }|j                  ||j                     dd       % y )NTr   )do_buildF)detachedr   )r   ensure_image_exists_get_convergence_plansexecute_convergence_planrG   )rN   r   strategyr(  rH   svcplansr   s           r;   createzProject.create	  s     66}SW6X 	7C##X#6	7++Hh? 	G,,gll# - 	r=   c              #   L  K   d }t        |xs | j                        }| j                  j                  d| j	                         id      D ]E  }d|vr	 t        j                  | j                  |d         }|j                  |vr; |||       G y # t        $ r Y Tw xY ww)Nc                     t         j                   j                  | d         }|j                  t        | d               }|d| d   |j                  |j
                  |j                  | d   d|dS )	NtimetimeNanomicrosecondr   statusfrom)rG   imager3  typeactionidr   
attributesr   )datetimefromtimestampreplacer'   r=  r   rG   )eventr   r3  s      r;   build_container_eventz>Project._legacy_event_processor.<locals>.build_container_event  s}    $$225=AD<<7j8IJ   D #/ll$,,%NN"6] ' r=   labelTfiltersr  r7  r=  )	setr   rI   eventsr:   r   r   r   r   )rN   r   rC  rB  r   s        r;   _legacy_event_processorzProject._legacy_event_processor  s     	$ M?T-?-?@[[''dkkm, ( 
 	:E u$ &--dkk5;G	   5'y99%	:  s*   AB$#B8B$	B!B$ B!!B$c                      t         j                  j                  d      r j                  |      S  fd fd} ||rt	        |            S  j
                        S )Nz1.22c                    | d   d   }t         j                   j                  | d         }|j                  t        | d               }d }	 t	        j
                  j                  | d         }|d| d   | d   d	   |j                  t              |j                         D ci c]  \  }}|j                  d
      s|| c}}|dS # t        $ r Y dw xY wc c}}w )NActor
Attributesr3  r4  r5  r=  r   r7  IDzcom.docker.compose.r:  )r?  r@  rA  r'   r   r   rI   r   rq   r   r   
startswith)rB  container_attrsr3  r   kr   rN   s         r;   rC  z-Project.events.<locals>.build_container_eventI  s    #Gn\:O$$225=AD<<7j8IJ   D I%--dkk5;G	 #/GnT**..}=%4%:%:%<!Q<<(=> qD ' 	  s   #C	 $C		CCc              3      K   j                   j                  dj                         id      D ]5  }|j                  d      dk7  r	 |d   d   t           | vr+	  |       7 y # t
        $ r Y Dw xY ww)NrD  TrE  Typer   rL  rM  )rI   rH  r:   rq   r   KeyError)r   rB  rC  rN   s     r;   
yield_loopz"Project.events.<locals>.yield_loopd  s     ++ $++-0 ,  3
 99V$3W~l3MB-W  X ,E223   s*   AA9
A*A9*	A63A95A66A9)r   rI   api_versionrI  rG  r   )rN   r   rU  rC  s   `  @r;   rH  zProject.eventsD  sT    dkk--v6//>>	6	3  #m,VV4CUCUVVr=   c           
         	
  j                          |s j                  |       	i 	 j                  ||      }|D ]  }|j                  |||         j	                  ||||r|ng       t        |||d       
	f
d} fd}t        j                  ||t        j                  d      d |      \  }}|rt        d      |D cg c]  }|	|D ]  }|  c}}S c c}}w )	Nr'  )r(  r  r  )always_recreate_depsrT   c                     | j                   S r   rG   r   s    r;   r   zProject.up.<locals>.<lambda>  s
    GLL r=   c                    
 | j                  | j                     
xs | vj                  | j                        		      S )N)r   r)  scale_overriderescaler   reset_container_imagerenew_anonymous_volumesoverride_options)r,  rG   rq   )r   r)  ra  r/  r`  r^  r_  r]  services_to_attachr   r   s    r;   dozProject.up.<locals>.do  sY    33gll#!Hg5G&G-11',,?&;(?!1 4 
 
r=   c                     | j                         j                         D ch c]  \  }}j                  |      |f c}}S c c}}w r   r   r   s      r;   r   zProject.up.<locals>.get_deps  r   r   rG   z1Encountered errors while bringing up the project.)
initializer   r   r*  r+  r&   r
   r   r   r   r   )rN   r   
start_depsr-  r(  r   r)  r   r   r]  r^  r   rX  r_  r`  r  r  rT   attach_dependenciesra  rH   r.  rc  r   resultsr#  svc_containersr   r/  rb  s   `    ``  ``` ``    `        @@r;   upz
Project.upv  s>   , 	''7!N66# 7 %  	OC##Xf##N	O++!5%,M"	 , 
 4(	*	 		 #33'
 C  #*
)+	
  

 	
 
s   C3c                 l    | j                   j                          | j                  j                          y r   )rK   re  rJ   rN   s    r;   re  zProject.initialize  s"      "!r=   c           	         i }|D ]>  }|j                         D cg c]  }||v r||   j                  dv r| }}|xr |j                  |v }	|r|j                  rt        j                  d|j                  dj                  |             t        |j                  ddddgi            }
t        |j                               }t        d	 |j                         D              }||z  }|s|
s|r!|j                  t        j                  |	      }n%|j                  ||	      }n|j                  ||	      }|||j                  <   A |S c c}w )
N)recreater0  z%s has upstream changes (%s)rZ   Tr7  createdexited)r   rF  c              3   >   K   | ]  }|j                  d         yw)zHostConfig.LinksN)rq   ).0cs     r;   	<genexpr>z1Project._get_convergence_plans.<locals>.<genexpr>  s     )b!%%0B*C)bs   )r   r<  rG   allows_recreaterx   debugrz   anyr   get_link_namesconvergence_planr   always)rN   rH   r-  rX  rT   r/  r   rG   updated_dependencies
is_one_offcontainers_stoppedservice_has_linkscontainer_has_linksshould_recreate_for_linksplans                  r;   r+  zProject._get_convergence_plans  sc    	'G $88:$5=d""&<< $  $ !<W\\W%<J#(@(@		8!,,))$89; &)&&thT\H]=^&_&a"$'(>(>(@$A!&))bWM_M_Ma)b&b#,=@S,S)'+=AZ"334G4N4NPZ[D"33HjID//*E"&E',,3	'6 5$s   E	c                    | j                  ||      }|r| j                  ||       y g }|D ]  }	 |j                  ||        t        |      r4t        j                  dj                  dj                  |                   y y # t        t        f$ r0 |j                         r|j                  |j                         n Y w xY w)N)r  WSome service image(s) must be built from source by running:
    docker-compose build {} )r   parallel_pullr  r   r   r  r2   rG   r   rx   ry   r3   rz   )	rN   r   ignore_pull_failuresr  r  r   rH   
must_buildr   s	            r;   r  zProject.pull  s    $$]LAx7 J# LL!5fLE : :#VCHHZ$89;  &x0 ++-"))',,7 8s   B<CCc           	        	
 |sdnd 	g 
	
fd}t        j                  ||t        j                  d      	d      \  }}t	        
      r3t
        j                  dj                  dj                  
                   t	        |      rYdj                  |j                         D cg c]%  }t        |t              r|j                  d	      n|' c}      }t        |      y c c}w )
NPullingc                    | j                  dd      }|y 	 t        j                  j                         }|t	        d      |D ]:  }d|vrt        |      }|j                  | j                  t        |      d        < y # t        t        f$ r/ | j                         rj                  | j                         Y y  w xY w)NT)streamz2ParallelStreamWriter has not yet been instantiatedr7  c                     | S r   rB   r   s    r;   r   z=Project.parallel_pull.<locals>.pull_service.<locals>.<lambda>  s    a r=   )r  r
   ParallelStreamWriterget_instanceRuntimeErrorr   writerG   r(   r   r   r  r2   )r   strmwriterrB  r7  r  msgr  s        r;   pull_servicez+Project.parallel_pull.<locals>.pull_service  s    << 4d4<HD|!66CCE>&'[\\! Eu, (/FLLW\\?6+BK	 "8, '')%%gll3	s   A*B :CCrG   r  r  r  r  r  r  )r
   r   r   r   r   rx   ry   r3   rz   r  r   r  r  r   )rN   rH   r  r  r  r"  r#  r$  r%  r  r  s     `      @@r;   r  zProject.parallel_pull  s    %i4
	. --'
	6 z?KK 6 457 v;"iiJP--/)EFZ5%9!q@) O //	 )s   )*C&c                    t               }| j                  |d      D ]j  }t        |j                        \  }}}|r|j	                  ||f      n|j	                  |df      }||vsI|j                  |       |j                  |       l y )NFr'  latest)rG  r   r    
image_namerz   pushadd)	rN   r   ignore_push_failuresunique_imagesr   repotagsepservice_image_names	            r;   r  zProject.push4  s    ((U(K 	6G1'2D2DEND#s:=4+!6388TS[L\C]!612!!"45	6r=   c                     t        t        d  j                  j                  |d j	                  |      i      D cg c]"  }t        j                   j                  |      $ c}            }|r|S t        t         fdt        d  j                  j                  |d j	                  |d      i      D cg c]"  }t        j                   j                  |      $ c}                  S c c}w c c}w )NrD  r   )r   rF  c                 :    | j                  j                        S r   )has_legacy_proj_namerG   )rs  rN   s    r;   r   z-Project._labeled_containers.<locals>.<lambda>I  s    Q%;%;DII%F r=   T)rT   rU   )rm   filterrI   r   r:   r   from_ps)rN   r   rT   r   ctnrss   `    r;   _labeled_containerszProject._labeled_containers?  s    VD![[33 $++g+">? 4 A#B dkk95#B C 
 LFFt![[33 $++gd+"KL 4 NVO dkk95VO IP 
  	#BVOs   'C0:'C5c                     r| j                         n| j                  | j                  ||      }fd}|D cg c]  } ||      s| c}S c c}w )Nc                 F    | j                   j                  t              v S r   )r:   rq   r   )r   r   s    r;   matches_service_namesz1Project.containers.<locals>.matches_service_namesX  s    ##''6-GGr=   )r   r   r  )rN   r   r   rT   r   r  rs  s    `     r;   r   zProject.containersP  sU    ''6 ..M--gw?
	H &Ba)>q)ABBBs   AAc                      fd}t         |             }|sy |rY|D ]S  }t        j                  dj                  |j                               	 |j                          |j                  d       U y t        j                  dj                  dj                  |D cg c]  }dj                  |j                         c}                   y # t        $ r Y {w xY wc c}w )Nc               3      K   t        j                         j                  d      z         } | D ]4  }|j                  j                  t              }|j
                  vs1| 6 y w)NTr  )rG  r  r:   rq   r   r   )r   ctnrr   rN   s      r;   _findz-Project.find_orphan_containers.<locals>._find^  sb     T557$:R:R[_:R:``aJ" #{{}=t'9'99Js   AA*#A*zRemoving orphan container "{}"T)forcezFound orphan containers ({}) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up.rZ   z{})
rm   rx   r  r3   rG   r   r   r   ry   rz   )rN   r   r  orphansr  s   `    r;   r   zProject.find_orphan_containers]  s    	 uw- (9@@KLIIK $'( KK8 9?II'J$t{{4995JK9		    Ks   C"C	CCc                 L   |j                         }t        |      dkD  ro| j                  t        t	        |            dd      }|D ]C  }|j                  |      rt        dj                  |j                  |j                               ng }|j                  |       ||z   S )Nr   TF)r   r   r   zService "{dep_name}" was pulled in as a dependency of service "{service_name}" but is not enabled by the active profiles. You may fix this by adding a common profile to "{dep_name}" and "{service_name}".)dep_namer   )
r   r   r   rm   rG  r   r   r3   rG   r2   )rN   r   r   rM   	dep_namesdep_servicesr   s          r;   r   zProject._inject_depsy  s    002	y>A,,"3y>2!%* - L $ 	//0@A,=
  M 	 LG$\!!r=   c                       fd}|S )Nc                     j                         }|j                  d      /j                  | j                        }|j	                  d       |d<    t        |       di |S )Nr   rB   )r   rq   r   r   stop_timeoutgetattr)r   _optionsr   	operationr   rN   s      r;    container_operation_with_timeoutz]Project.build_container_operation_with_timeout_func.<locals>.container_operation_with_timeout  s_    ||~H||I&.**9+<+<=&-&:&:4&@#079i0<8<<r=   rB   )rN   r  r   r  s   ``` r;   r   z3Project.build_container_operation_with_timeout_func  s    	= 0/r=   )NNNN)NNN)NFTrF   r   )FNF)NFFFNNFFTFFN)FN)NFTFF)FF)2r>   r?   r@   __doc__rO   r+   r4   r:   rA   rg   propertyr   r   r   r   r   rj   rl   ro   rk   rt   ru   r   r   r   r   r   r   r   r   r  r	  r   changedr   r   r0  rI  rH  rj  re  r+  r  r  r  r  r   r   r   r   rB   r=   r;   rD   rD   D   s    \`"&7 *11%  X\%)I IV ; ;	"*/b"),!*!*>24 "&|/C/C 
"

H ,09M9M  ! .&4 \`\a&'T $,,!!	$':R0Wf '//$$ %!&#($ 'T
l"@ _d;.+0Z	6 +09M9M " (,ULDXDX C8"40r=   rD   c                 ~    g }d| v r/t        | d         }|j                  dj                  |             |r|| d<   | S )Ncredential_speczcredentialspec={spec})specsecurity_opt)'convert_credential_spec_to_security_optr2   r3   )r}   resultr  s      r;   rv   rv     sM    FL(6|DU7VW-44$4?@'-^$r=   c                     d| v r2| d   j                  d      |d<   d| d   v rt        | d   d         |d<   d| v r!| d   j                  d      |d<   d| d   v rdgS g S )Nlimitsr  	mem_limitcpusr   mem_reservationzresources.reservations.cpus)rq   float)resources_dictr}   s     r;   +translate_resource_keys_to_container_configr    s    >!$28$<$@$@$J[!^H--#()A&)I#JL '*8*H*L*LX*V&'^N33122Ir=   c                 d    	 dddd|    S # t         $ r t        dj                  |             w xY w)Nrz  no
on-failure)rw  r   r  zInvalid restart policy "{}")rT  r   r3   rZ  s    r;   convert_restart_policyr    sO    M&
 	 	
  M !>!E!Ed!KLLMs    $/c                 ^    d| v rdj                  | d         S dj                  | d         S )Nfilezfile://{file})r  zregistry://{registry}registry)r  )r3   )r  s    r;   r  r    s<     %%?6+B%CC"))?:3N)OOr=   c                    d| v r| d= d| v r| d= d| vr| g fS | d   }dD cg c]  }||v r|
 }}d|v r{t        |d   j                  dd            |d   j                  dd	      d
| d<   |d   j                         D ].  }|dk7  s	|dk7  s|j                  dj	                  |             0 |j                  t        |j                  di       |              | d= | |fS c c}w )Nr  configsr   )endpoint_moder:   update_configrollback_configrestart_policy	conditionrw  max_attemptsr   )NameMaximumRetryCountr  zrestart_policy.{}r   )r  rq   rn   r2   r3   r   r  )r}   r   rQ  r   s       r;   rw   rw     s;   L(*+L #|#Rx(KR 	
L 
 ;&*;7G+H+L+L[Z_+`a!,-=!>!B!B>ST!U#
Y -.335 	CAKA$7##$7$>$>q$AB	C 3OOK,l	

 	X%%)s   C c                 t     j                  dd       }|sg S  fd}|D cg c]
  } ||       c}S c c}w )Nr`   c                    | j                   dk(  r,	 | j                  j                  | j                              S | j                   dk(  r=	 t        j                  j                  | j                        }| j                  |      S t        dj                  d   | j                              # t        $ r Y w xY w# t        $ r Y Bw xY w)Nr   )sourcer   zWService "{}" mounts volumes from "{}", which is not the name of a service or container.rG   )r;  _replacer   r  r   r   r   rI   r   r   r3   )r  r   r\   r}   s     r;   build_volume_fromz+get_volumes_from.<locals>.build_volume_from  s    99	!}}G,?,?,L}MM 99#%--gnndkkJ	}}I}66 !))/V$* 	 !   s#   *B1 ;C  1	B=<B= 	CC)ri   )r\   r}   r`   r  vfs   ``   r;   rp   rp     s>    ##ND9L	( -99bb!999s   5c                    g }|D ]E  }|j                  |j                        }|s&t        dj                  | |j                              |j                  d      r1t        j                  dj                  | |j                               |j                  s|j                  s|j                  r0t        j                  dj                  | |j                               |j                  d      }t        j                  t        |            s&t        j                  dj                  | |             |j                  ||d	       H |S )
Nz8Service "{service}" uses an undefined secret "{secret}" )r   secretexternalzService "{service}" uses secret "{secret}" which is external. External secrets are not available to containers created by docker-compose.zService "{service}" uses secret "{secret}" with uid, gid, or mode. These fields are not supported by this implementation of the Compose filer  zwService "{service}" uses an undefined secret file "{secret_file}", the following file should be created "{secret_file}")r   secret_file)r  r  )rq   r  r   r3   rx   ry   uidgidr   r   isfilestrr2   )r   service_secretssecret_defsrW   r  
secret_defr  s          r;   rs   rs     s)   G! @ __V]]3
$N>@ @ >>*%KK **0&&*WY ::v{{KK55;V#FMM 6< 6 !nnV,{{3{+,KKGGMv# HN H 	&+>?=@@ Nr=   c                 `   i }t               }t               }| j                  D ]  }	 t        |      ||j                  <    |s|rt        ||      |S # t        $ r%}|j                  |j                         Y d }~Yd }~wt        $ r%}|j                  |j                         Y d }~d }~ww xY wr   )
rG  rH   get_image_digestrG   	NeedsPushr  r  	NeedsPullr   MissingDigests)r\   digests
needs_push
needs_pullr   r$  s         r;   get_image_digestsr  *  s    GJJ## +	+$4W$=GGLL!+ ZZ44N  	)NN1<<(( 	+NN1>>**	+s#   A	B-A<<B-B((B-c                 X   d| j                   vrt        dj                  |             t        | j                   d         \  }}}|dk(  r| j                   d   S t	        |       }|r|S d| j                   vr t        | j                  | j                        t        | j                        )Nr9  zService '{s.name}' doesn't define an image tag. An image name is required to generate a proper image digest. Specify an image repo and tag with the 'image' option.r  @r	  )	r   r   r3   r    
get_digestr  r  rG   r  )r   r"  	separatordigests       r;   r  r  =  s    goo%//5vv/@B 	B
 +7??7+CDOAq)Cw'' Fgoo%**GLL99
G&&
''r=   c                 B   d }	 | j                         }|d   r|d   d   }|S # t        $ rr 	 | j                         }|d   d   r#dj                  | j                  |d   d         }Y |S # t        $ r& t        dj                  | j                              w xY ww xY w)	NRepoDigestsr   
Descriptorr  z{image_name}@{digest})r  r  zaDigest not found for service '{service}'. Repository does not exist or may require 'docker login'r[  )r9  r   get_image_registry_datar3   r  r   rG   )r   r  r9  distributions       r;   r  r  T  s    F/ =)!,F  M  /	/"::<LL)(3077&11'5h? 8  M   	/J-/ /	//s   # 	B;A++/BBc                       e Zd Zd Zy)r  c                      || _         || _        y r   )r  r  )rN   r  r  s      r;   rO   zMissingDigests.__init__o  s    $$r=   Nr>   r?   r@   rO   rB   r=   r;   r  r  n  s    %r=   r  c                       e Zd Zd Zy)r  c                     || _         y r   )r  )rN   r  s     r;   rO   zNeedsPush.__init__u  s	    $r=   Nr  rB   r=   r;   r  r  t  s    %r=   r  c                       e Zd Zd Zy)r  c                      || _         || _        y r   )r  r   )rN   r  r   s      r;   rO   zNeedsPull.__init__z  s    $(r=   Nr  rB   r=   r;   r  r  y  s    )r=   r  c                       e Zd Zd Zd Zy)r   c                 |    t        |t              r|j                  d      }|| _        d| j                  z  | _        y )Nr  zNo such service: %s)r   r  r  rG   r  )rN   rG   s     r;   rO   zNoSuchService.__init__  s1    dE";;w'D	(4994r=   c                     | j                   S r   r  rl  s    r;   __str__zNoSuchService.__str__  s    xxr=   N)r>   r?   r@   rO   r  rB   r=   r;   r   r     s    5r=   r   c                       e Zd Zd Zy)r   c                     || _         y r   r  )rN   r  s     r;   rO   zProjectError.__init__  s	    r=   Nr  rB   r=   r;   r   r     s    r=   r   )Rr?  enumloggingr   rR   	functoolsr   osr   docker.errorsr   r   r   docker.utilsr   rQ   r
   
cli.errorsr   r   r   config.configr   config.sort_servicesr   r   constr   r   r   r   r   networkr   r   r   progress_streamr   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   utilsr&   r'   r(   volumer)   	getLoggerr>   rx   uniqueEnumr+   rD   rv   r  r  r  rw   rp   rs   r  r  r  	Exceptionr  r  r  r   r   rB   r=   r;   <module>r"     s=       	   " ' " #  ! &  F D         # ! $ (   % ) % (    % )   # ' # ) . " "g! R499 R R"V0 V0r
	MP&B:8#L&(.4%Y %%	 %
)	 )I 9 r=   