o
    S`w                     @   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 d S || jkr |dtd d S || jkr'd S tdt|)N{}={}TrueFalsezInvalid value for one_off: {})onlyappendformatr   excludeinclude
ValueErrorrepr)clsvaluelabels r8   1/usr/lib/python3/dist-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dUd%d&ZdUd'd(ZdUd)d*Zdejfd+d,Z			dVd-d.Zd/d0 ZdUd1d2Z			dWd3d4Zde j!e"j#fd5d6Z$d7d8 Z%dUd9d: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(dXd?d@Z)		dYdAdBZ*dZdCdDZ+dTdEdFZ,dejfdGdHZ-ddejfdIdJZ.dKdL Z/dMdN Z0dOdP Z1dS )[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)selfrA   rB   rC   rE   rD   rF   rG   r8   r8   r9   __init__H   s   zProject.__init__Fc                 C   s6   | j }|rtdd|}dt|g}t|| |S )Nz[_-] r+   )rA   resubr0   r   r)   r:   )rH   one_offlegacyrA   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rw fdd|dg D |d< t|d |
ddpg |j}|
||d< |
||d	< t|}t|\}}|rtd
d| |
jt|
df|||||||||||
dd||d| q/|
S )zB
        Construct a Project from a config.Config object.
        rE   Nc                       g | ]}  |qS r8   )namespace_spec).0volume_specrD   r8   r9   
<listcomp>|   s    z'Project.from_config.<locals>.<listcomp>rD   rA   secretsscaledevice_requestszIThe following deploy sub-keys are not supported and have been ignored: {}, platform)rC   projectuse_networkingrE   linksnetwork_modevolumes_fromrU   pid_modeipc_moderY   default_platformextra_labels)versionr   r   r   from_servicesrB   r(   from_configdictr   pop	get_linksget_ipc_modeget_network_modelistkeysget_pid_modeget_volumes_fromgetget_secretsrU   get_service_scaleget_device_requests)translate_credential_spec_to_security_opt)translate_deploy_keys_to_container_configlogwarningr0   joinr/   r!   )r5   rA   config_datarC   ra   rb   rG   r[   rE   project_networksrZ   service_dictservice_networksr\   r`   r]   r_   r^   rU   ignored_keysr8   rS   r9   re   [   s   









zProject.from_configc                 C   s   dd | j D S )Nc                 S      g | ]}|j qS r8   rA   rQ   servicer8   r8   r9   rT          z)Project.service_names.<locals>.<listcomp>)rB   rH   r8   r8   r9   service_names   s   zProject.service_namesc                 C   s&   | j D ]}|j|kr|  S qt|)zo
        Retrieve a service by name. Raises NoSuchService
        if the named service does not exist.
        )rB   rA   NoSuchService)rH   rA   r   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)r   r   )rH   r   valid_namesrA   r8   r8   r9   validate_service_names   s   zProject.validate_service_namesTc                    s   j   |du st|dkrd} fddjD }fdd|D fddjD }|rE|D ]}| D ]}| vrC | q8q2|rRt 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_profilesrA   r   )rG   r8   r9   rT      s    z(Project.get_services.<locals>.<listcomp>c                    rO   r8   r   rQ   rA   r   r8   r9   rT      s    c                       g | ]}| v r|qS r8   r8   rQ   s)unsortedr8   r9   rT          c                    s    | | S N)_inject_deps)accr   )rG   rH   r8   r9   <lambda>   s    z&Project.get_services.<locals>.<lambda>c                    s   g | ]}| vr  |qS r8   )r/   r   )uniquesr8   r9   rT      s    )rG   copylenrB   get_profilesr/   r   )rH   r   include_depsauto_enable_profilesrB   r   profiler8   )rG   rH   r   r   r9   get_services   s0   


zProject.get_servicesc                 C   s"   |  ||}|D ]}|  q|S r   )r   remove_duplicate_containers)rH   r   r   rB   r   r8   r8   r9   get_services_without_duplicate   s   
z&Project.get_services_without_duplicatec              	   C   s   g }d|v rA| dg D ]1}d|v r|dd\}}n|d }}z|| ||f W q ty=   td|d |f w |d= |S )Nr\   :r   z=Service "%s" has a link to service "%s" which does not exist.rA   )ro   splitr/   r   r   r   )rH   rz   r\   linkservice_name	link_namer8   r8   r9   rh      s"   

zProject.get_linksc                 C   s   | dd }|s| jjr|rt|d S tdS td S t|}|r)t| |S t|}|rLz
tt	
| j|W S  tyK   tdj|d |dw t|S )Nr]   r   nonezRService '{name}' uses the network stack of container '{dep}' which does not exist.rA   rA   dep)rg   rE   r[   r   r   r#   r   r   r   r   from_idrC   r   r   r0   )rH   rz   rE   r]   r   container_namer8   r8   r9   rj     s(   
zProject.get_network_modec                 C      | dd }|std S t|}|rt| |S t|}|r<z
tt| j	|W S  t
y;   tdj|d |dw t|S )NpidzRService '{name}' uses the PID namespace of container '{dep}' which does not exist.rA   r   )rg   r    r   r$   r   r   r   r   r   rC   r   r   r0   )rH   rz   r_   r   r   r8   r8   r9   rm     $   
zProject.get_pid_modec                 C   r   )NipczRService '{name}' uses the IPC namespace of container '{dep}' which does not exist.rA   r   )rg   r   r   r"   r   r   r   r   r   rC   r   r   r0   )rH   rz   r`   r   r   r8   r8   r9   ri   3  r   zProject.get_ipc_modec                 C   s   | dd }| dd }|s|d u rdS |S | dddkr&|d u r$dS |S | dd }|d ur8|d ur8td|d ur>|}|d u rDdS | di  d	|}t||}||k r_td
| |S )NrV   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).)ro   r   minru   rv   r0   )rH   rz   rV   deploy_dictr   max_replicasr8   r8   r9   rq   H  s2   
zProject.get_service_scalec                 C   s   | dd }|s
d S | dd }|r| dd sd S |d  d}|s%d S |D ]*}| dd}t|tsF|dkrBtd|d d	d|d< d
|v rQ|d
 g|d
< q'|S )Nr   	resourcesreservationsdevicescountallz$Invalid value "{}" for devices countz(expected integer or "all")capabilities)ro   
isinstanceintr   r0   )rH   rz   r   r   r   devr   r8   r8   r9   rr   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 dddi} | d S )NquietTr8   )startextend)r   service_containers)
containersoptionsr8   r9   start_service  s   z$Project.start.<locals>.start_servicec                        fdd|    D S )Nc                       h | ]\}}  ||fqS r8   r   rQ   r   configr   r8   r9   	<setcomp>      z2Project.start.<locals>.get_deps.<locals>.<setcomp>get_dependency_configsitemsr   r   r8   r9   get_deps     

zProject.start.<locals>.get_depsrA   Startingc                 S   s
   |    S r   )r   )objr8   r8   r9   r     s   
 zProject.start.<locals>.<lambda>)
fail_check)r   r	   parallel_executeoperator
attrgetter)rH   r   r   r   rB   r   r8   )r   r   rH   r9   r     s   
	zProject.startc                    s@   j ||d  fdd}t d|tdd| d S )NrM   c                    s    fddD S )Nc                    s*   h | ]} j |j  v r|d fqS r   )r   r   get_dependency_names)rQ   other)	containerrH   r8   r9   r     s
    z1Project.stop.<locals>.get_deps.<locals>.<setcomp>r8   r   r   rH   r   r9   r     s   zProject.stop.<locals>.get_depsstoprA   Stopping)r   r	   r   +build_container_operation_with_timeout_funcr   r   )rH   r   rM   r   r   r8   r   r9   r     s   
zProject.stopc                 K   s   |  |}tt|| |S r   )r   r	   parallel_pausereversedrH   r   r   r   r8   r8   r9   pause  s   
zProject.pausec                 K   s   |  |}t|| |S r   )r   r	   parallel_unpauser   r8   r8   r9   unpause  s   
zProject.unpausec                 K   s   t | || d S r   )r	   parallel_killr   )rH   r   r   r8   r8   r9   kill  s   zProject.killc                 K   s   t | j|d|d| d S )NT)stoppedrM   )r	   parallel_remover   )rH   r   rM   r   r8   r8   r9   remove_stopped  s
   zProject.remove_stoppedc                 C   sT   | j tj|d |s| | | j|tjd | j  |r#| j  | | d S )N)rM   timeout)vrM   )	r   r)   r2   find_orphan_containersr   rE   removerD   remove_images)rH   remove_image_typeinclude_volumesremove_orphansr   ignore_orphansr8   r8   r9   down  s   


zProject.downc                 C   s   | j D ]}|| qd S r   )rB   remove_image)rH   r   r   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   r}   r8   r~   r   r8   r8   r9   rT     r   z#Project.restart.<locals>.<listcomp>Tr   restartrA   
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r.|r'td r.td  	f
dd}|rdtj||t	
dddd	\}}t|rbd
dd | D }t|d S |D ]}|| qfd S )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                    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_servicerA   Building   limit
c                 S   $   g | ]}t |tr|d n|qS utf-8r   bytesdecoderQ   er8   r8   r9   rT          z!Project.build.<locals>.<listcomp>)r   can_be_builtr/   ru   inforA   rv   r	   r   r   r   r   rw   valuesProjectError)rH   r   r  r  r   r   r   r   parallel_buildr  r  r   r  rB   r   r  _errorscombined_errorsr8   r   r9   r     s<   




zProject.buildc                 C   sT   | j |dd}|D ]}|j|d q	| ||}|D ]}|j||j ddd qd S )NTr   )do_buildF)detachedr   )r   ensure_image_exists_get_convergence_plansexecute_convergence_planrA   )rH   r   strategyr  rB   svcplansr   r8   r8   r9   create	  s   zProject.createc              	   c   s    dd }t |p
| j}| jjd|  iddD ](}d|vrqzt| j|d }W n	 ty3   Y qw |j|vr:q|||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microsecondr   statusfrom)rA   imager'  typeactionidr   
attributesr   )datetimefromtimestampreplacer&   r1  r   rA   )eventr   r'  r8   r8   r9   build_container_event  s   
z>Project._legacy_event_processor.<locals>.build_container_eventlabelTfiltersr  r+  r1  )	setr   rC   eventsr7   r   r   r   r   )rH   r   r7  r6  r   r8   r8   r9   _legacy_event_processor  s$   


zProject._legacy_event_processorc                    sJ   t jjdr|S fdd  fdd}||r!t|S 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w |d| d | d d	 |t	d
d |
 D |dS )NActor
Attributesr'  r(  r)  r1  r   r+  IDc                 S   s    i | ]\}}| d s||qS )zcom.docker.compose.)
startswith)rQ   kr   r8   r8   r9   
<dictcomp>]  s    zAProject.events.<locals>.build_container_event.<locals>.<dictcomp>r.  )r3  r4  r5  r&   r   r   rC   r   ro   r   r   )r6  container_attrsr'  r   r   r8   r9   r7  I  s*   

z-Project.events.<locals>.build_container_eventc              	   3   sn    j jd iddD ]'}|ddkrqz|d d t | vr$W qW n	 ty.   Y qw  |V  qd S )Nr8  Tr9  Typer   r>  r?  )rC   r<  r7   ro   r   KeyError)r   r6  r7  rH   r8   r9   
yield_loopd  s    

z"Project.events.<locals>.yield_loop)r   rC   api_versionr=  r;  r   )rH   r   rH  r8   rG  r9   r<  D  s
   
zProject.eventsc              
      s      |s| d u ri j||d}|D ]
}|j|||d qj||||r.|ng dt|||dd  	
f
dd}fdd	}t||t	d
d |\}}|rdt
ddd |D S )Nr  )r  r  r   )always_recreate_depsrM   c                 S      | j S r   r~   r   r8   r8   r9   r     s    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"  rA   ro   r   )
r  rP  r%  rO  rM  rN  rL  services_to_attachr   r   r8   r9   do  s   

zProject.up.<locals>.doc                    r   )Nc                    r   r8   r   r   r   r8   r9   r     r   z/Project.up.<locals>.get_deps.<locals>.<setcomp>r   r   r   r8   r9   r     r   zProject.up.<locals>.get_depsrA   z1Encountered errors while bringing up the project.c                 S   s"   g | ]}|d ur|D ]}|q
qS r   r8   )rQ   svc_containersr   r8   r8   r9   rT     s    zProject.up.<locals>.<listcomp>)
initializer   r   r   r!  r%   r	   r   r   r   r  )rH   r   
start_depsr#  r  r   r  r   r   rL  rM  r   rJ  rN  rO  r  r   rM   attach_dependenciesrP  rB   r$  rR  r   resultsr  r8   )r  rP  r%  rO  rM  rN  rL  rH   rQ  r   r   r9   upv  sN   

z
Project.upc                 C   s   | j   | j  d S r   )rE   rT  rD   r   r8   r8   r9   rT    s   
zProject.initializec                    s   i  |D ]f} fdd|  D }|o|j|v }|r_|jr_td|jd| t|jddddgid	}t| }	td
d | D }
|	|
A }|sP|sP|rX|	t
j|}n|	||}n|	||}| |j< q S )Nc                    s&   g | ]}| v r | j d v r|qS ))recreater&  )r0  r   r%  r8   r9   rT     s    z2Project._get_convergence_plans.<locals>.<listcomp>z%s has upstream changes (%s)rX   Tr+  createdexited)r   r:  c                 s   s    | ]}| d V  qdS )zHostConfig.LinksN)ro   rQ   cr8   r8   r9   	<genexpr>  s    z1Project._get_convergence_plans.<locals>.<genexpr>)r   rA   allows_recreateru   debugrw   anyr   get_link_namesconvergence_planr   always)rH   rB   r#  rJ  rM   r   updated_dependencies
is_one_offcontainers_stoppedservice_has_linkscontainer_has_linksshould_recreate_for_linksplanr8   rZ  r9   r!    s.   

zProject._get_convergence_plansc           	   
   C   s   |  ||}|r| j||d d S g }|D ]"}z	|j||d W q ttfy7   | r4||j n Y qw t|rIt	
dd| d S 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/   rA   r   ru   rv   r0   rw   )	rH   r   ignore_pull_failuresro  r  r   rB   
must_buildr   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|rBd	d
d |	 D }t
|d S )NPullingc              	      s   | j  ddd}|d u rd S z+tj }|d u rtd|D ]}d|vr%qt|}|| jt|dd  qW d S  t	t
fyP   |  rO| j Y d S  w )NT)streamz2ParallelStreamWriter has not yet been instantiatedr+  c                 S   s   | S r   r8   r   r8   r8   r9   r     s    z=Project.parallel_pull.<locals>.pull_service.<locals>.<lambda>)r  r	   ParallelStreamWriterget_instanceRuntimeErrorr   writerA   r'   r   r   r  r/   )r   strmwriterr6  r+  rp  msgrq  r8   r9   pull_service  s(   
z+Project.parallel_pull.<locals>.pull_servicerA   r  r	  rm  rn  r  c                 S   r  r  r  r  r8   r8   r9   rT   /  r  z)Project.parallel_pull.<locals>.<listcomp>)r	   r   r   r   r   ru   rv   r0   rw   r  r  )rH   rB   rp  r  r}  r  r  r  r8   r{  r9   ro    s(   

zProject.parallel_pullc           	      C   sj   t  }| j|ddD ](}t|j\}}}|r|||fn||df}||vr2|| || q
d S )NFr  latest)r;  r   r   
image_namerw   pushadd)	rH   r   ignore_push_failuresunique_imagesr   repotagsepservice_image_namer8   r8   r9   r  4  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                       g | ]	}t  j|qS r8   r   from_psrC   rQ   r   r   r8   r9   rT   @      z/Project._labeled_containers.<locals>.<listcomp>r8  r   )r   r:  c                    s   |   jS r   )has_legacy_proj_namerA   )r^  r   r8   r9   r   I  s    z-Project._labeled_containers.<locals>.<lambda>c                    r  r8   r  r  r   r8   r9   rT   I  r  T)rM   rN   )rk   filterrC   r   r7   )rH   r   rM   ctnrsr8   r   r9   _labeled_containers?  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   ro   r   r   )r   r8   r9   matches_service_namesX  s   z1Project.containers.<locals>.matches_service_namesc                    s   g | ]} |r|qS r8   r8   r]  )r  r8   r9   rT   [  r   z&Project.containers.<locals>.<listcomp>)r   r   r  )rH   r   r   rM   r   r8   )r  r   r9   r   P  s   zProject.containersc              	      s    fdd}t | }|sd S |r7|D ]!}td|j z|  W n	 ty-   Y nw |jdd qd S tdd	dd	 |D  d S )
Nc                  3   sD    t    jdd } | D ]}|jt}| jvr|V  qd S )NTr   )r;  r  r7   ro   r   r   )r   ctnrr   r   r8   r9   _find^  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.rX   c                 S   s   g | ]}d  |jqS )z{})r0   rA   )rQ   r  r8   r8   r9   rT   u  r   z2Project.find_orphan_containers.<locals>.<listcomp>)
rk   ru   r  r0   rA   r   r   r   rv   rw   )rH   r   r  orphansr  r8   r   r9   r   ]  s(   
zProject.find_orphan_containersc                 C   sn   |  }t|dkr,| jtt|ddd}|D ]}||s*tdj|j|jdqng }|	| || 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   rk   r;  r   r   r0   rA   r/   )rH   r   r   rG   	dep_namesdep_servicesr   r8   r8   r9   r   y  s&   



zProject._inject_depsc                    s    fdd}|S )Nc                    sD     }|dd u r| j}|d |d< t|  di |S )Nr   r8   )r   ro   r   r   stop_timeoutgetattr)r   _optionsr   	operationr   rH   r8   r9    container_operation_with_timeout  s
   z]Project.build_container_operation_with_timeout_func.<locals>.container_operation_with_timeoutr8   )rH   r  r   r  r8   r  r9   r     s   z3Project.build_container_operation_with_timeout_func)NNNN)NNN)NFTr@   r   )FNF)NFFFNNFFTFFN)FN)NFTFF)FF)2r;   r<   r=   __doc__rI   r)   r1   r7   r>   re   propertyr   r   r   r   r   rh   rj   rm   ri   rq   rr   r   r   r   r   r   r   r   r   r   r   r   changedr   r   r&  r=  r<  rX  rT  r!  r  ro  r  r  r   r   r   r   r8   r8   r8   r9   r?   D   s    

	K



1



	


*

)3
V
 


-r?   c                 C   s:   g }d| v rt | d }|dj|d |r|| d< | S )Ncredential_speczcredentialspec={spec})specsecurity_opt)'convert_credential_spec_to_security_optr/   r0   )rz   resultr  r8   r8   r9   rs     s   rs   c                 C   sj   d| v r| d  d|d< d| d v rt| d d |d< d| v r3| d  d|d< d| d v r3dgS g S )Nlimitsr   	mem_limitcpusr   mem_reservationzresources.reservations.cpus)ro   float)resources_dictrz   r8   r8   r9   +translate_resource_keys_to_container_config  s   r  c                 C   s0   z	dddd|  W S  t y   td| w )Nre  no
on-failure)rb  r   r  zInvalid restart policy "{}")rF  r   r0   r~   r8   r8   r9   convert_restart_policy  s   r  c                 C   s(   d| v rdj | d dS dj | d dS )Nfilezfile://{file})r  zregistry://{registry}registry)r  )r0   )r  r8   r8   r9   r    s   r  c                    s   d| v r| d= d| v r| d= d| vr| g fS | d   fdddD }d v rUt  d dd	 d d
dd| d<  d  D ]}|dkrT|d
krT|d| qB|t di |  | d= | |fS )Nr  configsr   c                    r   r8   r8   )rQ   rB  r   r8   r9   rT     s    z=translate_deploy_keys_to_container_config.<locals>.<listcomp>)endpoint_moder7   update_configrollback_configrestart_policy	conditionrb  max_attemptsr   )NameMaximumRetryCountr   zrestart_policy.{}r   )r  ro   rl   r/   r0   r   r  )rz   r|   rB  r8   r  r9   rt     s2   

rt   c                    s4    dd }|s
g S fdd  fdd|D S )Nr^   c                    s   | j dkrz| j | jdW S  ty   Y nw | j dkr8zt j| j}| j|dW S  ty7   Y nw t	d
d | j)Nr   )sourcer   zWService "{}" mounts volumes from "{}", which is not the name of a service or container.rA   )r/  _replacer   r  r   r   r   rC   r   r   r0   )r  r   )rZ   rz   r8   r9   build_volume_from  s(   

z+get_volumes_from.<locals>.build_volume_fromc                    s   g | ]} |qS r8   r8   )rQ   vf)r  r8   r9   rT     s    z$get_volumes_from.<locals>.<listcomp>)rg   )rZ   rz   r^   r8   )r  rZ   rz   r9   rn     s
   rn   c                 C   s   g }|D ]W}| |j}|stdj| |jd| dr)tdj| |jd q|js2|js2|jr=tdj| |jd | d}t	
t|sStdj| |d |||d	 q|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  )ro   r  r   r0   ru   rv   uidgidr   r   isfilestrr/   )r   service_secretssecret_defsrU   r  
secret_defr  r8   r8   r9   rp     s>   

rp   c                 C   s   i }t  }t  }| jD ]:}z	t|||j< W q ty. } z||j W Y d }~qd }~w tyE } z||j W Y d }~qd }~ww |sJ|rOt	|||S r   )
r;  rB   get_image_digestrA   	NeedsPushr  r  	NeedsPullr   MissingDigests)rZ   digests
needs_push
needs_pullr   r  r8   r8   r9   get_image_digests*  s    

r  c                 C   sr   d| j vrtdj| dt| j d \}}}|dkr | j d S t| }|r(|S d| j vr4t| j| jt| j)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.rt  @r   )	r   r
   r0   r   
get_digestr  r  rA   r  )r   r  	separatordigestr8   r8   r9   r  =  s   



r  c                 C   s   d }z|   }|d r|d d }W |S W |S  tyL   z|  }|d d r8dj| j|d d d}W Y |S W Y |S  tyK   tdj| jdw 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   )r-  r   get_image_registry_datar0   r  r
   rA   )r   r  r-  distributionr8   r8   r9   r  T  s6   

	
r  c                   @      e Zd Zdd ZdS )r  c                 C      || _ || _d S r   )r  r  )rH   r  r  r8   r8   r9   rI   o     
zMissingDigests.__init__Nr;   r<   r=   rI   r8   r8   r8   r9   r  n      r  c                   @   r  )r  c                 C   
   || _ d S r   )r  )rH   r  r8   r8   r9   rI   u     
zNeedsPush.__init__Nr  r8   r8   r8   r9   r  t  r  r  c                   @   r  )r  c                 C   r  r   )r  r   )rH   r  r   r8   r8   r9   rI   z  r  zNeedsPull.__init__Nr  r8   r8   r8   r9   r  y  r  r  c                   @   s   e Zd Zdd Zdd ZdS )r   c                 C   s*   t |tr
|d}|| _d| j | _d S )Nr  zNo such service: %s)r   r  r  rA   r|  )rH   rA   r8   r8   r9   rI     s   

zNoSuchService.__init__c                 C   rK  r   r|  r   r8   r8   r9   __str__  s   zNoSuchService.__str__N)r;   r<   r=   rI   r  r8   r8   r8   r9   r     s    r   c                   @   r  )r  c                 C   r  r   r  )rH   r|  r8   r8   r9   rI     r  zProjectError.__init__Nr  r8   r8   r8   r9   r    r  r  )Rr3  enumloggingr   rK   	functoolsr   osr   docker.errorsr   r   r   docker.utilsr   rJ   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;   ru   uniqueEnumr)   r?   rs   r  r  r  rt   rn   rp   r  r  r  	Exceptionr  r  r  r   r  r8   r8   r8   r9   <module>   s    
      _!&