a
   )O                   @   s  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;e<Z=ej>G d)d* d*ej?Z@G d+d, d,ZAd-d. ZBd/d0 ZCd1d2 ZDd3d4 ZEd5d6 ZFd7d8 ZGd9d: ZHd;d< ZId=d> ZJd?d@ ZKG dAdB dBeLZMG dCdD dDeLZNG dEdF dFeLZOG dGdH dHeLZPG dIdJ dJeLZQdS )K    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                   @   s$   e Zd ZdZdZdZedd ZdS )OneOffFilterr   r      c                 C   s^   || j kr|dtd n<|| jkr<|dtd n|| jkrHntdt|d S )N{}={}TrueFalsezInvalid value for one_off: {})onlyappendformatr   excludeinclude
ValueErrorrepr)clsvaluelabels r8   3/usr/lib/python3.9/site-packages/compose/project.pyupdate_labels8   s    


zOneOffFilter.update_labelsN)__name__
__module____qualname__r2   r1   r.   classmethodr:   r8   r8   r8   r9   r)   2   s
   r)   c                   @   s  e Zd ZdZdQddZejdfddZedRdd	Z	e
d
d Zdd Zdd ZdSddZdTddZdd Zdd Zdd Zdd Zdd Zdd  ZdUd!d"Zdejfd#d$ZdVd%d&ZdWd'd(ZdXd)d*Zdejfd+d,ZdYd-d.Zd/d0 ZdZd1d2Zd[d3d4Zde j!e"j#fd5d6Z$d7d8 Z%d\d9d:Z&dde j!e"j#dddddddddddddddfd;d<Z'd=d> Z(d]d?d@Z)d^dAdBZ*d_dCdDZ+d`dEdFZ,dejfdGdHZ-ddejfdIdJZ.dKdL Z/dMdN Z0dOdP Z1dS )aProjectz#
    A collection of services.
    Nc                 C   sD   || _ || _|| _|pti | _|p,ti d| _|| _|p<g | _d S )NF)	nameservicesclientr(   volumesr   networksconfig_versionenabled_profiles)selfr@   rA   rB   rD   rC   rE   rF   r8   r8   r9   __init__H   s    zProject.__init__Fc                 C   s6   | j }|rtdd|}dt|g}t|| |S )Nz[_-] r+   )r@   resubr0   r   r)   r:   )rG   one_offlegacyr@   r7   r8   r8   r9   r7   R   s    zProject.labelsc                    s  |pg }|j o|j tk}t|||}t|j||}	t||| | |g ||	 |j |}
|jD ]>}t|}|r|t	||}ni }|
dd |
|}|
|}|
|t| }|
|}t|
|}|j tkr fdd|dg D |d< t|d |
ddpg |j}|
||d< |
||d	< t|}t|\}}|r\td
d| |
jt|
df|||||||||||
dd||d| q^|
S )zB
        Construct a Project from a config.Config object.
        rD   Nc                    s   g | ]}  |qS r8   )Znamespace_spec).0Zvolume_specrC   r8   r9   
<listcomp>|   s   z'Project.from_config.<locals>.<listcomp>rC   r@   secretsscaleZdevice_requestszIThe following deploy sub-keys are not supported and have been ignored: {}, platform)rB   projectuse_networkingrD   linksnetwork_modevolumes_fromrQ   pid_modeipc_moderT   default_platformextra_labels)versionr   r   r   Zfrom_servicesrA   r(   from_configdictr   pop	get_linksget_ipc_modeget_network_modelistkeysget_pid_modeget_volumes_fromgetget_secretsrQ   get_service_scaleget_device_requests)translate_credential_spec_to_security_opt)translate_deploy_keys_to_container_configlogwarningr0   joinr/   r!   )r5   r@   Zconfig_datarB   r\   r]   rF   rV   rD   Zproject_networksrU   service_dictZservice_networksrW   r[   rX   rZ   rY   rQ   ignored_keysr8   rO   r9   r_   [   s    








zProject.from_configc                 C   s   dd | j D S )Nc                 S   s   g | ]
}|j qS r8   r@   rN   servicer8   r8   r9   rP          z)Project.service_names.<locals>.<listcomp>)rA   rG   r8   r8   r9   service_names   s    zProject.service_namesc                 C   s*   | j D ]}|j|kr|  S qt|dS )zo
        Retrieve a service by name. Raises NoSuchService
        if the named service does not exist.
        N)rA   r@   NoSuchService)rG   r@   rv   r8   r8   r9   get_service   s    


zProject.get_servicec                 C   s$   | j }|D ]}||vr
t|q
dS )z
        Validate that the given list of service names only contains valid
        services. Raises NoSuchService if one of the names is invalid.
        N)ry   rz   )rG   ry   Zvalid_namesr@   r8   r8   r9   validate_service_names   s    zProject.validate_service_namesTc                    s   j   |du st|dkr6d} fddjD }fdd|D fddjD }|r|D ]$}| D ]}| vrp | qpqd|rt fdd	|g }g fd
d|D  S )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
        Nr   Fc                    s   g | ]}|  r|jqS r8   )enabled_for_profilesr@   ru   )rF   r8   r9   rP      s   
z(Project.get_services.<locals>.<listcomp>c                    s   g | ]}  |qS r8   r{   rN   r@   rx   r8   r9   rP      rw   c                    s   g | ]}| v r|qS r8   r8   rN   s)unsortedr8   r9   rP      rw   c                    s    | | S N)_inject_deps)accr   )rF   rG   r8   r9   <lambda>   rw   z&Project.get_services.<locals>.<lambda>c                    s   g | ]}| vr  |qS r8   )r/   r   )uniquesr8   r9   rP      rw   )rF   copylenrA   Zget_profilesr/   r   )rG   ry   include_depsauto_enable_profilesrA   rv   Zprofiler8   )rF   rG   r   r   r9   get_services   s,    

zProject.get_servicesc                 C   s"   |  ||}|D ]}|  q|S r   )r   Zremove_duplicate_containers)rG   ry   r   rA   rv   r8   r8   r9   get_services_without_duplicate   s    
z&Project.get_services_without_duplicatec              	   C   s   g }d|v r| dg D ]h}d|v r6|dd\}}n
|d  }}z|| ||f W q ty~   td|d |f Y q0 q|d= |S )NrW   :r   z=Service "%s" has a link to service "%s" which does not exist.r@   )ri   splitr/   r{   rz   r   )rG   rr   rW   linkservice_nameZ	link_namer8   r8   r9   rb      s     

zProject.get_linksc                 C   s   | dd }|s8| jjr0|r(t|d S tdS td S t|}|rRt| |S t|}|rztt	
| j|W S  ty   tdj|d |dY n0 t|S )NrX   r   nonezRService '{name}' uses the network stack of container '{dep}' which does not exist.r@   r@   dep)ra   rD   rV   r   r   r#   r{   r   r   r   from_idrB   r   r   r0   )rG   rr   rD   rX   r   container_namer8   r8   r9   rd     s&    
zProject.get_network_modec                 C   s   | dd }|std S t|}|r2t| |S t|}|r|ztt| j	|W S  t
yz   tdj|d |dY n0 t|S )NpidzRService '{name}' uses the PID namespace of container '{dep}' which does not exist.r@   r   )ra   r    r   r$   r{   r   r   r   r   rB   r   r   r0   )rG   rr   rZ   r   r   r8   r8   r9   rg     s"    
zProject.get_pid_modec                 C   s   | dd }|std S t|}|r2t| |S t|}|r|ztt| j	|W S  t
yz   tdj|d |dY n0 t|S )NZipczRService '{name}' uses the IPC namespace of container '{dep}' which does not exist.r@   r   )ra   r   r   r"   r{   r   r   r   r   rB   r   r   r0   )rG   rr   r[   r   r   r8   r8   r9   rc   3  s"    
zProject.get_ipc_modec                 C   s   | dd }| dd }|s,|d u r(dS |S | dddkrL|d u rHdS |S | dd }|d urp|d urptd|d ur||}|d u rdS | di  d	|}t||}||k rtd
| |S )NrR   deployr   modeZ
replicatedreplicaszUBoth service.scale and service.deploy.replicas are set. Only one of them must be set.Z	placementZmax_replicas_per_nodez7Scale is limited to {} ('max_replicas_per_node' field).)ri   r   minro   rp   r0   )rG   rr   rR   deploy_dictr   Zmax_replicasr8   r8   r9   rk   H  s2    
zProject.get_service_scalec                 C   s   | dd }|sd S | dd }|r0| dd s4d S |d  d}|sJd S |D ]T}| dd}t|ts|dkrtd|d d	d|d< d
|v rN|d
 g|d
< qN|S )Nr   	resourcesreservationsdevicescountallz$Invalid value "{}" for devices countz(expected integer or "all")Zcapabilities)ri   
isinstanceintr   r0   )rG   rr   r   r   r   devr   r8   r8   r9   rl   g  s*    
zProject.get_device_requestsc                    sL   g   fdd} |}fdd}tj||tdd|dd d	  S )
Nc                    s"   | j f ddi} | d S )NquietT)startextend)rv   Zservice_containers)
containersoptionsr8   r9   start_service  s    z$Project.start.<locals>.start_servicec                    s    fdd|    D S )Nc                    s   h | ]\}}  ||fqS r8   r~   rN   r   configrx   r8   r9   	<setcomp>  s   z2Project.start.<locals>.get_deps.<locals>.<setcomp>Zget_dependency_configsitemsrv   rx   r8   r9   get_deps  s    

zProject.start.<locals>.get_depsr@   ZStartingc                 S   s
   |    S r   )r   )objr8   r8   r9   r     rw   zProject.start.<locals>.<lambda>)Z
fail_check)r   r	   parallel_executeoperator
attrgetter)rG   ry   r   r   rA   r   r8   )r   r   rG   r9   r     s    
	zProject.startc                    s@   j ||d  fdd}t d|tdd| d S )NrL   c                    s    fddD S )Nc                    s*   h | ]"} j |j  v r|d fqS r   )rv   r{   get_dependency_names)rN   other)	containerrG   r8   r9   r     s   z1Project.stop.<locals>.get_deps.<locals>.<setcomp>r8   r   r   rG   r   r9   r     s    zProject.stop.<locals>.get_depsstopr@   ZStopping)r   r	   r   +build_container_operation_with_timeout_funcr   r   )rG   ry   rL   r   r   r8   r   r9   r     s    
zProject.stopc                 K   s   |  |}tt|| |S r   )r   r	   Zparallel_pausereversedrG   ry   r   r   r8   r8   r9   pause  s    
zProject.pausec                 K   s   |  |}t|| |S r   )r   r	   Zparallel_unpauser   r8   r8   r9   unpause  s    
zProject.unpausec                 K   s   t | || d S r   )r	   Zparallel_killr   )rG   ry   r   r8   r8   r9   kill  s    zProject.killc                 K   s   t | j|d|d| d S )NT)stoppedrL   )r	   Zparallel_remover   )rG   ry   rL   r   r8   r8   r9   remove_stopped  s
    zProject.remove_stoppedc                 C   sT   | j tj|d |s| | | j|tjd | j  |rF| j  | | d S )N)rL   timeout)vrL   )	r   r)   r2   find_orphan_containersr   rD   removerC   remove_images)rG   remove_image_typeZinclude_volumesremove_orphansr   ignore_orphansr8   r8   r9   down  s    


zProject.downc                 C   s   | j D ]}|| qd S r   )rA   Zremove_image)rG   r   rv   r8   r8   r9   r     s    
zProject.remove_imagesc                 K   sD   dd |  |D }| j|dd}t|| d|tdd |S )Nc                 S   s   g | ]
}|j qS r8   rt   r   r8   r8   r9   rP     rw   z#Project.restart.<locals>.<listcomp>Tr   restartr@   Z
Restarting)r   r   r	   r   r   r   r   r   r8   r8   r9   r     s    
zProject.restartc              
      s   g }|  |D ],}| r&|| q	std|j  qrftd |rXtd rftd  	f
dd}|rtj||t	
ddd	d
\}}t|rddd | D }t|n|D ]}|| qd S )Nz%s uses an image, skippingvBuilding with native build. Learn about native build in Compose here: https://docs.docker.com/go/compose-native-build/zJFlag '--parallel' is ignored when building with COMPOSE_DOCKER_CLI_BUILD=1zJFlag '--compress' is ignored when building with COMPOSE_DOCKER_CLI_BUILD=1c                    s    |   	
 d S r   )buildr   

build_argscliforce_rmgzipmemoryno_cacheprogresspullrmsilentr8   r9   build_service  s    z$Project.build.<locals>.build_servicer@   ZBuilding   limit
c                 S   s$   g | ]}t |tr|d n|qS utf-8r   bytesdecoderN   er8   r8   r9   rP     s   z!Project.build.<locals>.<listcomp>)r   can_be_builtr/   ro   infor@   rp   r	   r   r   r   r   rq   valuesProjectError)rG   ry   r   r   r   r   r   r   Zparallel_buildr   r   r   r   rA   rv   r   _errorscombined_errorsr8   r   r9   r     s8    





zProject.buildc                 C   sT   | j |dd}|D ]}|j|d q| ||}|D ]}|j||j ddd q4d S )NTr   )do_buildF)detachedr   )r   ensure_image_exists_get_convergence_plansexecute_convergence_planr@   )rG   ry   strategyr   rA   svcplansrv   r8   r8   r9   create  s    zProject.createc              	   c   s   dd }t |p| j}| jjd|  iddD ]T}d|vr<q.zt| j|d }W n tyh   Y q.Y n0 |j|vrvq.|||V  q.d S )Nc                 S   sL   t j | d }|jt| d d}|d| d |j|j|j| d d|dS )	NtimetimeNanoZmicrosecondr   statusfrom)r@   imager   typeactionidrv   Z
attributesr   )datetimefromtimestampreplacer&   r  rv   r@   )eventr   r   r8   r8   r9   build_container_event  s    
z>Project._legacy_event_processor.<locals>.build_container_eventlabelTfiltersr   r   r  )	setry   rB   eventsr7   r   r   r   rv   )rG   ry   r	  r  r   r8   r8   r9   _legacy_event_processor  s    



zProject._legacy_event_processorc                    sH   t jjdr|S fdd  fdd}||r@t|njS )Nz1.22c                    s   | d d }t j | d }|jt| d d}d }zt j| d }W n ty\   Y n0 |d| d | d d	 |t	d
d |
 D |dS )NActor
Attributesr   r   r   r  r   r   ZIDc                 S   s    i | ]\}}| d s||qS )zcom.docker.compose.)
startswith)rN   kr   r8   r8   r9   
<dictcomp>_  s   
zAProject.events.<locals>.build_container_event.<locals>.<dictcomp>r  )r  r  r  r&   r   r   rB   r   ri   r   r   )r  Zcontainer_attrsr   r   rx   r8   r9   r	  K  s(    

z-Project.events.<locals>.build_container_eventc              	   3   sp   j jd iddD ]R}|ddkr,qz|d d t | vrFW qW n ty^   Y qY n0  |V  qd S )Nr
  Tr  Typer   r  r  )rB   r  r7   ri   r   KeyError)ry   r  r	  rG   r8   r9   
yield_loopf  s    


z"Project.events.<locals>.yield_loop)r   rB   api_versionr  r  ry   )rG   ry   r  r8   r  r9   r  F  s
    
zProject.eventsc              
      s   |rt d   |s$| d u r0i j||d}|D ]}|j|||d qBj||||rj|ng dt|||dd  	
f
dd}fd	d
}t	||t
dd |\}}|rtddd |D S )Nr   r   )r   r   r   )always_recreate_depsrL   c                 S   s   | j S r   rt   r   r8   r8   r9   r     rw   zProject.up.<locals>.<lambda>c                    s2   | j | j 	 p| v| jd	S )N)r   r   scale_overriderescaler   reset_container_imagerenew_anonymous_volumesoverride_options)r   r@   ri   r   )
r   r  r   r  r  r  r  services_to_attachr   r   r8   r9   do  s    

zProject.up.<locals>.doc                    s    fdd|    D S )Nc                    s   h | ]\}}  ||fqS r8   r~   r   rx   r8   r9   r     s   z/Project.up.<locals>.get_deps.<locals>.<setcomp>r   r   rx   r8   r9   r     s    

zProject.up.<locals>.get_depsr@   z1Encountered errors while bringing up the project.c                 S   s"   g | ]}|d ur|D ]}|qqS r   r8   )rN   Zsvc_containersr   r8   r8   r9   rP     s   zProject.up.<locals>.<listcomp>)ro   r   
initializer   r   r   r   r%   r	   r   r   r   r   )rG   ry   Z
start_depsr   r   r   r   r   r   r  r  r   r  r  r  r   r   rL   Zattach_dependenciesr  rA   r   r!  r   resultsr   r8   )r   r  r   r  r  r  r  rG   r   r   r   r9   upx  sR    


z
Project.upc                 C   s   | j   | j  d S r   )rD   r"  rC   rx   r8   r8   r9   r"    s    
zProject.initializec                    s   i  |D ]} fdd|  D }|o.|j|v }|r|jrtd|jd| t|jddddgid	}t| }	td
d | D }
|	|
A }|s|s|r|	t
j|}q|	||}n|	||}| |j< q S )Nc                    s&   g | ]}| v r | j d v r|qS ))Zrecreater   )r  r   r   r8   r9   rP     s   z2Project._get_convergence_plans.<locals>.<listcomp>z%s has upstream changes (%s)rS   Tr   ZcreatedZexited)r   r  c                 s   s   | ]}| d V  qdS )zHostConfig.LinksN)ri   rN   cr8   r8   r9   	<genexpr>  rw   z1Project._get_convergence_plans.<locals>.<genexpr>)r   r@   Zallows_recreatero   debugrq   anyr   Zget_link_namesZconvergence_planr   always)rG   rA   r   r  rL   rv   Zupdated_dependenciesZ
is_one_offZcontainers_stoppedZservice_has_linksZcontainer_has_linksZshould_recreate_for_linksZplanr8   r%  r9   r     s.    

zProject._get_convergence_plansc           	   
   C   s   |  ||}|r | j||d nng }|D ]F}z|j||d W q( ttfyl   | rf||j n Y q(0 q(t|rt	
dd| d S )N)r   WSome service image(s) must be built from source by running:
    docker-compose build {} )r   parallel_pullr   r   r   r   r/   r@   r   ro   rp   r0   rq   )	rG   ry   ignore_pull_failuresr.  r   r   rA   
must_buildrv   r8   r8   r9   r     s    
zProject.pullc                    s   |sdnd g  fdd}t j||tddd\}}tr\tdd t|rd	d
d |	 D }t
|d S )NZPullingc              	      s   | j  ddd}|d u rd S zTtj }|d u r8td|D ]0}d|vrJq<t|}|| jt|dd  q<W n. t	t
fy   |  r| j n Y n0 d S )NT)streamz2ParallelStreamWriter has not yet been instantiatedr   c                 S   s   | S r   r8   r   r8   r8   r9   r      rw   z=Project.parallel_pull.<locals>.pull_service.<locals>.<lambda>)r   r	   ZParallelStreamWriterZget_instanceRuntimeErrorr   writer@   r'   r   r   r   r/   )rv   Zstrmwriterr  r   r/  msgr0  r8   r9   pull_service  s$    

z+Project.parallel_pull.<locals>.pull_servicer@   r   r   r,  r-  r   c                 S   s$   g | ]}t |tr|d n|qS r   r   r   r8   r8   r9   rP   5  s   z)Project.parallel_pull.<locals>.<listcomp>)r	   r   r   r   r   ro   rp   r0   rq   r   r   )rG   rA   r/  r   r8  r   r   r   r8   r6  r9   r.    s&    

zProject.parallel_pullc           	      C   sj   t  }| j|ddD ]P}t|j\}}}|r:|||fn||df}||vr|| || qd S )NFr   Zlatest)r  r   r   
image_namerq   pushadd)	rG   ry   Zignore_push_failuresZunique_imagesrv   ZrepotagsepZservice_image_namer8   r8   r9   r:  :  s     
zProject.pushc                    s   t td  fdd jj|d j|didD }|r<|S t t fddtd  fdd jj|d j|d	d
idD S )Nc                    s   g | ]}t  j|qS r8   r   Zfrom_psrB   rN   r   rx   r8   r9   rP   F  s   z/Project._labeled_containers.<locals>.<listcomp>r
  r   )r   r  c                    s   |   jS r   )Zhas_legacy_proj_namer@   )r'  rx   r8   r9   r   O  rw   z-Project._labeled_containers.<locals>.<lambda>c                    s   g | ]}t  j|qS r8   r>  r?  rx   r8   r9   rP   O  s   T)rL   rM   )re   filterrB   r   r7   )rG   r   rL   Zctnrsr8   rx   r9   _labeled_containersE  s    
zProject._labeled_containersc                    s@   r|   n| j| ||}fdd  fdd|D S )Nc                    s   | j t v S r   )r7   ri   r   r   )ry   r8   r9   matches_service_names^  s    z1Project.containers.<locals>.matches_service_namesc                    s   g | ]} |r|qS r8   r8   r&  )rB  r8   r9   rP   a  rw   z&Project.containers.<locals>.<listcomp>)r|   ry   rA  )rG   ry   r   rL   r   r8   )rB  ry   r9   r   V  s    zProject.containersc              	      s    fdd}t | }|sd S |rl|D ]B}td|j z|  W n tyZ   Y n0 |jdd q&n tdd	dd	 |D  d S )
Nc                  3   sB   t    jdd } | D ] }|jt}| jvr|V  qd S )NTr   )r  rA  r7   ri   r   ry   )r   ctnrr   rx   r8   r9   _findd  s
    
z-Project.find_orphan_containers.<locals>._findz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.rS   c                 S   s   g | ]}d  |jqS )z{})r0   r@   )rN   rC  r8   r8   r9   rP   {  rw   z2Project.find_orphan_containers.<locals>.<listcomp>)
re   ro   r   r0   r@   r   r   r   rp   rq   )rG   r   rD  ZorphansrC  r8   rx   r9   r   c  s"    
zProject.find_orphan_containersc                 C   sn   |  }t|dkrX| jtt|ddd}|D ]$}||s0tdj|j|jdq0ng }|	| || S )Nr   TF)ry   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}".)Zdep_namer   )
r   r   r   re   r  r}   r   r0   r@   r/   )rG   r   rv   rF   Z	dep_namesZdep_servicesr   r8   r8   r9   r     s"    

	
zProject._inject_depsc                    s    fdd}|S )Nc                    sD     }|dd u r0| j}|d |d< t|  f i |S )Nr   )r   ri   r{   rv   Zstop_timeoutgetattr)r   Z_optionsrv   	operationr   rG   r8   r9    container_operation_with_timeout  s
    z]Project.build_container_operation_with_timeout_func.<locals>.container_operation_with_timeoutr8   )rG   rH  r   rI  r8   rG  r9   r     s    z3Project.build_container_operation_with_timeout_func)NNNN)NNN)NFT)NF)N)N)N)N)FNF)N)NFFFNNFFTFFN)N)FN)NFTFF)FF)NF)2r;   r<   r=   __doc__rH   r)   r1   r7   r>   r_   propertyry   r{   r|   r   r   rb   rd   rg   rc   rk   rl   r   r   r   r   r   r   r   r   r   r   r   Zchangedr   r   r   r  r  r$  r"  r   r   r.  r:  rA  r   r   r   r   r8   r8   r8   r9   r?   D   s     

	  K


1




	   

   
,
)
3
Z
   

-
r?   c                 C   s:   g }d| v r*t | d }|dj|d |r6|| d< | S )Ncredential_speczcredentialspec={spec})specZsecurity_opt)'convert_credential_spec_to_security_optr/   r0   )rr   resultrM  r8   r8   r9   rm     s    rm   c                 C   sj   d| v r:| d  d|d< d| d v r:t| d d |d< d| v rf| d  d|d< d| d v rfdgS g S )NZlimitsr   Z	mem_limitZcpusr   Zmem_reservationzresources.reservations.cpus)ri   float)Zresources_dictrr   r8   r8   r9   +translate_resource_keys_to_container_config  s    rQ  c                 C   s8   zdddd|  W S  t y2   td| Y n0 d S )Nr+  no
on-failure)r*  r   rS  zInvalid restart policy "{}")r  r   r0   rt   r8   r8   r9   convert_restart_policy  s    rT  c                 C   s(   d| v rdj | d dS dj | d dS )Nfilezfile://{file})rU  zregistry://{registry}registry)rV  )r0   )rL  r8   r8   r9   rN    s    rN  c                    s   d| v r| d= d| v r| d= d| vr,| g fS | d   fdddD }d v rt  d dd	 d d
dd| d<  d  D ]$}|dkr|d
kr|d| q|t di |  | d= | |fS )NrL  Zconfigsr   c                    s   g | ]}| v r|qS r8   r8   )rN   r  r   r8   r9   rP     s   z=translate_deploy_keys_to_container_config.<locals>.<listcomp>)Zendpoint_moder7   Zupdate_configZrollback_configZrestart_policyZ	conditionr*  Zmax_attemptsr   )NameZMaximumRetryCountr   zrestart_policy.{}r   )rT  ri   rf   r/   r0   r   rQ  )rr   rs   r  r8   rW  r9   rn     s0    

rn   c                    s4    dd }|sg S fdd  fdd|D S )NrY   c                    s   | j dkr4z| j | jdW S  ty2   Y n0 | j dkrpzt j| j}| j|dW S  tyn   Y n0 t	d
d | jd S )Nrv   )sourcer   zWService "{}" mounts volumes from "{}", which is not the name of a service or container.r@   )r  _replacer{   rY  rz   r   r   rB   r   r   r0   )rM  r   )rU   rr   r8   r9   build_volume_from  s"    

z+get_volumes_from.<locals>.build_volume_fromc                    s   g | ]} |qS r8   r8   )rN   Zvf)r[  r8   r9   rP     rw   z$get_volumes_from.<locals>.<listcomp>)ra   )rU   rr   rY   r8   )r[  rU   rr   r9   rh     s
    rh   c                 C   s   g }|D ]}| |j}|s0tdj| |jd| drRtdj| |jd q|jsd|jsd|jrztdj| |jd | d}t	
t|stdj| |d |||d	 q|S )
Nz8Service "{service}" uses an undefined secret "{secret}" )rv   secretZ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 filerU  zwService "{service}" uses an undefined secret file "{secret_file}", the following file should be created "{secret_file}")rv   secret_file)r\  rU  )ri   rY  r   r0   ro   rp   uidgidr   r   isfilestrr/   )rv   Zservice_secretsZsecret_defsrQ   r\  Z
secret_defr]  r8   r8   r9   rj   
  s:    

rj   c                 C   s   i }t  }t  }| jD ]v}zt|||j< W q ty\ } z||j W Y d }~qd }~0  ty } z||j W Y d }~qd }~0 0 q|s|rt	|||S r   )
r  rA   get_image_digestr@   	NeedsPushr;  r9  	NeedsPullr   MissingDigests)rU   Zdigests
needs_push
needs_pullrv   r   r8   r8   r9   get_image_digests0  s    
 $
rh  c                 C   sv   d| j vrtdj| dt| j d \}}}|dkr@| j d S t| }|rP|S d| j vrht| j| jt| jd S )Nr   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.r2  @r   )	r   r
   r0   r   
get_digestrd  r9  r@   rc  )rv   r   	separatordigestr8   r8   r9   rb  C  s    


rb  c                 C   s   d }z |   }|d r"|d d }W nh ty   z0|  }|d d r`dj| j|d d d}W n$ ty   tdj| jdY n0 Y n0 |S )	NZRepoDigestsr   Z
Descriptorrl  z{image_name}@{digest})r9  rl  zaDigest not found for service '{service}'. Repository does not exist or may require 'docker login'r   )r   r   Zget_image_registry_datar0   r9  r
   r@   )rv   rl  r   Zdistributionr8   r8   r9   rj  Z  s(    

rj  c                   @   s   e Zd Zdd ZdS )re  c                 C   s   || _ || _d S r   )rf  rg  )rG   rf  rg  r8   r8   r9   rH   u  s    zMissingDigests.__init__Nr;   r<   r=   rH   r8   r8   r8   r9   re  t  s   re  c                   @   s   e Zd Zdd ZdS )rc  c                 C   s
   || _ d S r   )r9  )rG   r9  r8   r8   r9   rH   {  s    zNeedsPush.__init__Nrm  r8   r8   r8   r9   rc  z  s   rc  c                   @   s   e Zd Zdd ZdS )rd  c                 C   s   || _ || _d S r   )r9  r   )rG   r9  r   r8   r8   r9   rH     s    zNeedsPull.__init__Nrm  r8   r8   r8   r9   rd    s   rd  c                   @   s   e Zd Zdd Zdd ZdS )rz   c                 C   s*   t |tr|d}|| _d| j | _d S )Nr   zNo such service: %s)r   r   r   r@   r7  )rG   r@   r8   r8   r9   rH     s    

zNoSuchService.__init__c                 C   s   | j S r   r7  rx   r8   r8   r9   __str__  s    zNoSuchService.__str__N)r;   r<   r=   rH   ro  r8   r8   r8   r9   rz     s   rz   c                   @   s   e Zd Zdd ZdS )r   c                 C   s
   || _ d S r   rn  )rG   r7  r8   r8   r9   rH     s    zProjectError.__init__Nrm  r8   r8   r8   r9   r     s   r   )Rr  enumZloggingr   rJ   	functoolsr   osr   Zdocker.errorsr   r   r   Zdocker.utilsr   rI   r	   Z
cli.errorsr
   r   r   Zconfig.configr   Zconfig.sort_servicesr   r   constr   r   r   r   r   Znetworkr   r   r   Zprogress_streamr   rv   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   Zutilsr%   r&   r'   Zvolumer(   Z	getLoggerr;   ro   uniqueEnumr)   r?   rm   rQ  rT  rN  rn   rh   rj   rh  rb  rj  	Exceptionre  rc  rd  rz   r   r8   r8   r8   r9   <module>   s   
      e!&