U
    ˆÓ]'Ç  ã                <   @   sÒ  d dl mZ d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dl	m
Z
 d dlmZ d dl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/m0Z0 ddl1m2Z2 dd l1m3Z3 dd!l1m4Z4 dd"lm5Z5 dd#lm6Z6 dd$lm7Z7 dd%lm8Z8 dd&lm9Z9 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=mAZA dd.l=mBZB dd/l=mCZC dd0l=mDZD dd1l=mEZE dd2l=mFZF dd3l=mGZG dd4l=mHZH dd5l=mIZI dd6l=mJZJ dd7l=mKZK d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsg<ZLeLdtdudvdwdxdydzd{d|d}d~dd€g ZMdZNd‚dƒgZOd„ZPe QeR¡ZSG d…d†„ d†e
d‡dˆƒƒZTG d‰dŠ„ dŠe
d‹dŒƒƒZUG ddŽ„ dŽe
ddƒƒZVG d‘d’„ d’e
d“d”ƒƒZWd)d•d–„ZXd—d˜„ ZYd™dš„ ZZd›dœ„ Z[ddž„ Z\d*d d¡„Z]d+d£d¤„Z^d,d¥d¦„Z_d§d¨„ Z`d-d©dª„Zad«d¬„ Zbd­d®„ Zcd.d¯d°„ZdG d±d²„ d²eeƒZfd/d³d´„Zgdµd¶„ Zhd·d¸„ Zid¹dº„ Zjd»d¼„ Zkd½d¾„ Zld¿dÀ„ ZmdÁdÂ„ ZndÃdÄ„ ZodÅdÆ„ ZpdÇdÈ„ ZqdÉdÊ„ ZrdËdÌ„ ZsdÍdÎ„ ZtdÏdÐ„ ZudÑdÒ„ ZvdÓdÔ„ ZwdÕdÖ„ Zxd×dØ„ ZyG dÙdÚ„ dÚezƒZ{dÛdÜ„ Z|dÝdÞ„ Z}dßdà„ Z~dádâ„ Zdãdä„ Z€dådæ„ Zdçdè„ Z‚dédê„ Zƒdëdì„ Z„dídî„ Z…dïdð„ Z†dñdò„ Z‡dódô„ Zˆdõdö„ Z‰d÷dø„ ZŠdùdú„ Z‹e Œe‹e(dû¡Ze Œe‹e(dN¡ZŽe Œe‹eŠdV¡Ze Œe‹düdý„ dþ¡Ze Œe‹eŠdl¡Z‘e Œe‹dÿdý„ d ¡Z’dd„ Z“dd„ Z”dd„ Z•dd„ Z–d	d
„ Z—dd„ Z˜dd„ Z™dd„ Zšdd„ Z›dd„ Zœdd„ Zdd„ Zždd„ ZŸdd„ Z dd„ Z¡dd „ Z¢d!d"„ Z£d#d$„ Z¤d%d&„ Z¥d0d'd(„Z¦dS (1  é    )Úabsolute_import)Úunicode_literalsN)Ú
namedtuple)Ú
attrgetter)Úcached_propertyé   )Útypesé   )Úconst)ÚCOMPOSEFILE_V1)ÚCOMPOSEFILE_V2_1)ÚCOMPOSEFILE_V2_3)ÚCOMPOSEFILE_V3_0)ÚCOMPOSEFILE_V3_4)Úbuild_string_dict©Ú	json_hash)Úparse_bytes)Úparse_nanoseconds_int)Ú
splitdrive)ÚComposeVersion)Úenv_vars_from_file)ÚEnvironment)Ú	split_env)ÚCircularReference)ÚComposeFileNotFound)ÚConfigurationError)ÚDuplicateOverrideFileFound)ÚVERSION_EXPLANATION)Ú!interpolate_environment_variables)Ú$get_container_name_from_network_mode)Ú"get_service_name_from_network_mode)Úsort_service_dicts)Ú	MountSpec)Úparse_extra_hosts)Úparse_restart_spec)ÚSecurityOpt)ÚServiceLink)ÚServicePort)ÚVolumeFromSpec)Ú
VolumeSpec)Úmatch_named_volumes)Úvalidate_against_config_schema)Úvalidate_config_section)Úvalidate_cpu)Úvalidate_credential_spec)Úvalidate_depends_on)Úvalidate_extends_file_path)Úvalidate_healthcheck)Úvalidate_links)Úvalidate_network_mode)Úvalidate_pid_mode)Úvalidate_service_constraints)Úvalidate_top_level_object)Úvalidate_ulimitsÚcap_addÚcap_dropZcgroup_parentZcommandÚ	cpu_countZcpu_percentZ
cpu_periodZ	cpu_quotaZcpu_rt_periodZcpu_rt_runtimeZ
cpu_sharesÚcpusZcpusetÚdetachÚdevice_cgroup_rulesÚdevicesÚdnsÚ
dns_searchZdns_optZ
domainnameZ
entrypointÚenv_fileÚenvironmentÚextra_hostsZ	group_addZhostnameÚhealthcheckÚimageZipcÚ	isolationÚlabelsÚlinksZmac_addressÚ	mem_limitÚmem_reservationZmemswap_limitZmem_swappinessÚnetZoom_score_adjZoom_kill_disableÚpidÚportsZ
privilegedZ	read_onlyÚrestartZruntimeÚsecretsÚsecurity_optÚshm_sizeZ
pids_limitZ
stdin_openZstop_signalÚsysctlsZttyÚuserZuserns_modeÚvolume_driverÚvolumesÚvolumes_fromÚworking_dirÚblkio_configÚbuildÚcontainer_nameÚcredential_specÚ
dockerfileZinitÚ
log_driverÚlog_optÚloggingÚnetwork_modeÚplatformÚscaleZstop_grace_period)zhttp://zhttps://zgit://zgithub.com/zgit@zdocker-compose.ymlzdocker-compose.yaml)zdocker-compose.override.ymlzdocker-compose.override.yamlc                       s"   e Zd ZdZd‡ fdd„	Z‡  ZS )ÚConfigDetailsac  
    :param working_dir: the directory to use for relative paths in the config
    :type  working_dir: string
    :param config_files: list of configuration files to load
    :type  config_files: list of :class:`ConfigFile`
    :param environment: computed environment values for this project
    :type  environment: :class:`environment.Environment`
     Nc                    s(   |d krt  |¡}tt| ƒ | |||¡S ©N)r   Zfrom_env_fileÚsuperrd   Ú__new__)ÚclsrX   Úconfig_filesrC   ©Ú	__class__© ú7/usr/lib/python3/dist-packages/compose/config/config.pyrg   ­   s    

   ÿzConfigDetails.__new__)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rg   Ú__classcell__rl   rl   rj   rm   rd   ¤   s   rd   Z_ConfigDetailsz$working_dir config_files environmentc                   @   sX   e Zd ZdZedd„ ƒZedd„ ƒZdd„ Zdd	„ Z	d
d„ Z
dd„ Zdd„ Zdd„ ZdS )Ú
ConfigFilez¢
    :param filename: filename of the config file
    :type  filename: string
    :param config: contents of the config file
    :type  config: :class:`dict`
    c                 C   s   | |t |ƒƒS re   )Ú	load_yaml)rh   Úfilenamerl   rl   rm   Úfrom_filename½   s    zConfigFile.from_filenamec                 C   s’   d| j krtS | j d }t|tƒr8t d | j¡¡ tS t|tj	ƒsTt
d | j¡ƒ‚|dkrnt
d | jt¡ƒ‚|dkr|tjS |dkrŠtjS t|ƒS )NÚversionzUnexpected type for "version" key in "{}". Assuming "version" is the name of a service, and defaulting to Compose file version 1.z3Version in "{}" is invalid - it should be a string.Ú1zVersion in "{}" is invalid. {}Ú2Ú3)ÚconfigÚV1Ú
isinstanceÚdictÚlogÚwarningÚformatru   ÚsixÚstring_typesr   r   r
   ZCOMPOSEFILE_V2_0r   r   )Úselfrw   rl   rl   rm   rw   Á   s4    


þÿÿ ÿÿzConfigFile.versionc                 C   s   |   ¡ | S re   ©Úget_service_dicts)r„   Únamerl   rl   rm   Úget_serviceá   s    zConfigFile.get_servicec                 C   s   | j tkr| jS | j di ¡S )NÚservices©rw   r|   r{   Úget©r„   rl   rl   rm   r†   ä   s    zConfigFile.get_service_dictsc                 C   s   | j tkri S | j di ¡S )NrV   rŠ   rŒ   rl   rl   rm   Úget_volumesç   s    zConfigFile.get_volumesc                 C   s   | j tkri S | j di ¡S )NÚnetworksrŠ   rŒ   rl   rl   rm   Úget_networksê   s    zConfigFile.get_networksc                 C   s   | j tjk ri S | j di ¡S )NrP   )rw   r
   ÚCOMPOSEFILE_V3_1r{   r‹   rŒ   rl   rl   rm   Úget_secretsí   s    zConfigFile.get_secretsc                 C   s   | j tjk ri S | j di ¡S )NÚconfigs)rw   r
   ÚCOMPOSEFILE_V3_3r{   r‹   rŒ   rl   rl   rm   Úget_configsð   s    zConfigFile.get_configsN)rn   ro   rp   rq   Úclassmethodrv   r   rw   rˆ   r†   r   r   r‘   r”   rl   rl   rl   rm   rs   µ   s   

rs   Z_ConfigFilezfilename configc                   @   s   e Zd ZdZdS )ÚConfigaq  
    :param version: configuration version
    :type  version: int
    :param services: List of service description dictionaries
    :type  services: :class:`list`
    :param volumes: Dictionary mapping volume names to description dictionaries
    :type  volumes: :class:`dict`
    :param networks: Dictionary mapping network names to description dictionaries
    :type  networks: :class:`dict`
    :param secrets: Dictionary mapping secret names to description dictionaries
    :type secrets: :class:`dict`
    :param configs: Dictionary mapping config names to description dictionaries
    :type configs: :class:`dict`
    N)rn   ro   rp   rq   rl   rl   rl   rm   r–   ô   s   r–   Z_Configz1version services volumes networks secrets configsc                   @   s   e Zd Zedd„ ƒZdS )ÚServiceConfigc                 C   s2   |st dƒ‚| tj |¡|r(tj |¡n|||ƒS )Nz!No working_dir for ServiceConfig.)Ú
ValueErrorÚosÚpathÚabspath)rh   rX   ru   r‡   r{   rl   rl   rm   Úwith_abs_paths  s    
üzServiceConfig.with_abs_pathsN)rn   ro   rp   r•   rœ   rl   rl   rl   rm   r—     s   r—   Z_ServiceConfigz working_dir filename name configc                    sš   |dgkr:t |rtj |¡nt ¡ td t tj	¡ƒg|ƒS |rR‡ fdd„|D ƒ}nt
ˆ ƒ}t d d |¡¡¡ t |rz|ntj |d ¡dd„ |D ƒ|ƒS )Nú-c                    s   g | ]}t j ˆ |¡‘qS rl   )r™   rš   Újoin©Ú.0Úf©Úbase_dirrl   rm   Ú
<listcomp>  s     zfind.<locals>.<listcomp>zUsing configuration files: {}ú,r   c                 S   s   g | ]}t  |¡‘qS rl   )rs   rv   rŸ   rl   rl   rm   r¤   #  s     )rd   r™   rš   r›   Úgetcwdrs   ÚyamlÚ	safe_loadÚsysÚstdinÚget_default_config_filesr   Údebugr   rž   Údirname)r£   Ú	filenamesrC   Zoverride_dirrl   r¢   rm   Úfind  s    
ýýr¯   c                 C   sV   | d }t |ƒ | dd … D ]4}t |ƒ |j|jkrtd |j|j|j|j¡ƒ‚qd S )Nr   r   zXVersion mismatch: file {0} specifies version {1} but extension file {2} uses version {3})r7   rw   r   r   ru   )ri   Ú	main_fileZ	next_filerl   rl   rm   Úvalidate_config_version(  s    ûÿr±   c                 C   sd   t t| ƒ\}}|sttƒ‚|d }t|ƒdkrLt dd |¡¡ t d|¡ tj ||¡gt	|ƒ S )Nr   r   z4Found multiple config files with supported names: %sú, z	Using %s
)
Úfind_candidates_in_parent_dirsÚSUPPORTED_FILENAMESr   Úlenr   r€   rž   r™   rš   Úget_default_override_file)r£   Ú
candidatesrš   Úwinnerrl   rl   rm   r«   8  s    r«   c                    s*   ‡ fdd„t D ƒ}t|ƒdkr&t|ƒ‚|S )Nc                    s0   g | ](}t j t j ˆ |¡¡rt j ˆ |¡‘qS rl   ©r™   rš   Úexistsrž   )r    Zoverride_filename©rš   rl   rm   r¤   H  s    þz-get_default_override_file.<locals>.<listcomp>r   )ÚDEFAULT_OVERRIDE_FILENAMESrµ   r   )rš   Zoverride_files_in_pathrl   r»   rm   r¶   G  s    
ÿr¶   c                    sN   ‡ fdd„| D ƒ}|sFt j ˆ d¡}t j |¡t j ˆ ¡krFt| |ƒS |ˆ fS )z¹
    Given a directory path to start, looks for filenames in the
    directory, and then each parent directory successively,
    until found.

    Returns tuple (candidates, path).
    c                    s&   g | ]}t j t j ˆ |¡¡r|‘qS rl   r¹   )r    ru   r»   rl   rm   r¤   X  s    ÿz2find_candidates_in_parent_dirs.<locals>.<listcomp>z..)r™   rš   rž   r›   r³   )r®   rš   r·   Z
parent_dirrl   r»   rm   r³   P  s    
r³   Fc                    s,   d‰ ‡ fdd„}|s|| dƒ || dƒ d S )Nz§Some services ({services}) use the '{key}' key, which will be ignored. Compose does not support '{key}' configuration - use `docker stack deploy` to deploy to a swarm.c                    sB   ‡ fdd„| D ƒ}|r>t  ˆjd tdd„ |D ƒƒ¡ˆ d¡ d S )Nc                    s   g | ]}|  ˆ ¡r|‘qS rl   )r‹   ©r    Ús©Úkeyrl   rm   r¤   k  s     
 zIcheck_swarm_only_config.<locals>.check_swarm_only_key.<locals>.<listcomp>r²   c                 s   s   | ]}|d  V  qdS )r‡   Nrl   r½   rl   rl   rm   Ú	<genexpr>o  s     zHcheck_swarm_only_config.<locals>.check_swarm_only_key.<locals>.<genexpr>)r‰   rÀ   )r   r€   r   rž   Úsorted)Úservice_dictsrÀ   r‰   ©Zwarning_templater¿   rm   Úcheck_swarm_only_keyj  s    þÿz5check_swarm_only_config.<locals>.check_swarm_only_keyÚdeployr’   rl   )rÃ   ÚcompatibilityrÅ   rl   rÄ   rm   Úcheck_swarm_only_configc  s    ÿ	
rÈ   Tc                    sÔ   t ˆ jƒ ‡ ‡fdd„ˆ jD ƒ}ˆ j|d‰ ˆ jd }tˆ jddƒ}tˆ jddƒ}tˆ jd	d
ˆ jƒ}tˆ jddˆ jƒ}tˆ ||ƒ}	|jtkr |	D ]}
t|
|ƒ qt	|	|ƒ |r¼|jt
kr¼tn|j}t||	||||ƒS )a  Load the configuration from a working directory and a list of
    configuration files.  Files are loaded in order, and merged on top
    of each other to create the final configuration.

    Return a fully interpolated, extended and validated configuration.
    c                    s   g | ]}t |ˆ jˆd ‘qS ))Úinterpolate)Úprocess_config_filerC   )r    Úconfig_file©Úconfig_detailsrÉ   rl   rm   r¤     s   ÿzload.<locals>.<listcomp>©ri   r   r   ZVolumer   ZNetworkr‘   ZSecretr”   r–   )r±   ri   Ú_replaceÚload_mappingrX   Úload_servicesrw   r|   r+   rÈ   ÚV3_0ÚV2_3r–   )rÍ   rÇ   rÉ   Zprocessed_filesr°   rV   rŽ   rP   r’   rÃ   Úservice_dictrw   rl   rÌ   rm   Úloadx  sF    
þ
  ÿ  ÿ   ÿ   ÿ

rÕ   c           	      C   sÒ   i }| D ]Ä}t ||ƒƒ  ¡ D ]®\}}|p*i ||< |s6q| d¡}|r€t||||jƒ t|tƒrn| d¡|d< n| d¡s€||d< d|kr˜t|d ƒ|d< d|kr°t|d ƒ|d< d|krt	||d ƒ|d< qq|S )NÚexternalr‡   Zdriver_optsrH   Úfile)
ÚgetattrÚitemsr‹   Úvalidate_externalrw   r}   r~   r   Úparse_labelsÚexpand_path)	ri   Zget_funcÚentity_typerX   ÚmappingrË   r‡   r{   rÖ   rl   rl   rm   rÐ   ¡  s,    


ÿrÐ   c              	   C   sN   |t k s|tkrJ|tk rJt| ¡ ƒdkrJtd | |d dd„ |D ƒ¡¡ƒ‚d S )Nr   zD{} {} declared as external but specifies additional attributes ({}).r²   c                 s   s   | ]}|d kr|V  qdS )rÖ   Nrl   ©r    Úkrl   rl   rm   rÁ   Å  s      z$validate_external.<locals>.<genexpr>)ÚV2_1rÒ   ÚV3_4rµ   Úkeysr   r   rž   )rÝ   r‡   r{   rw   rl   rl   rm   rÚ   À  s    (  þÿrÚ   c                    sd   ‡‡‡fdd„‰ ‡ fdd„}‡fdd„}dd„ ˆj D ƒ}|d	 }|d
d … D ]}|||ƒ}qL||ƒS )Nc                    s`   t  ˆjˆj| |¡}t|ˆˆjd}t| ¡ ƒ}|j|d}t	||ˆƒ t
||ˆjˆjˆ ƒ}|S )N©rC   ©r{   )r—   rœ   rX   ru   ÚServiceExtendsResolverrC   Úprocess_serviceÚrunrÏ   Úvalidate_serviceÚfinalize_servicerw   )Úservice_namerÔ   Úservice_namesÚservice_configÚresolver)rÇ   rÍ   rË   rl   rm   Úbuild_serviceÉ  s,    ü  ÿûz$load_services.<locals>.build_servicec                    s$   |   ¡ ‰ t‡‡ fdd„|  ¡ D ƒƒS )Nc                    s   g | ]\}}ˆ ||ˆƒ‘qS rl   rl   )r    r‡   rÔ   )rï   rì   rl   rm   r¤   á  s   ÿz9load_services.<locals>.build_services.<locals>.<listcomp>)rã   r"   rÙ   )rí   )rï   )rì   rm   Úbuild_servicesß  s    þz%load_services.<locals>.build_servicesc                    s&   t ˆ ƒt ˆƒB }‡ ‡‡fdd„|D ƒS )Nc              	      s,   i | ]$}|t ˆ  |i ¡ˆ |i ¡ˆjƒ“qS rl   )Úmerge_service_dicts_from_filesr‹   rw   )r    r‡   )ÚbaserË   Úoverriderl   rm   Ú
<dictcomp>è  s   ü 

ýz9load_services.<locals>.merge_services.<locals>.<dictcomp>)Úset)rò   ró   Zall_service_names)rË   ©rò   ró   rm   Úmerge_servicesæ  s    ûz%load_services.<locals>.merge_servicesc                 S   s   g | ]}|  ¡ ‘qS rl   r…   )r    r×   rl   rl   rm   r¤   ð  s    z!load_services.<locals>.<listcomp>r   r   rÎ   )rÍ   rË   rÇ   rð   r÷   Zservice_configsrí   Znext_configrl   )rï   rÇ   rÍ   rË   rm   rÑ   È  s    
ÿrÑ   c                 C   s   t | j|||ƒS re   )r   rw   )rË   r{   ÚsectionrC   rl   rl   rm   Úinterpolate_config_sectionû  s    ürù   c                 C   s*   t | j||ƒ |r"t| j|||ƒS |S d S re   )r-   ru   r   rw   )rË   r{   rø   rC   rÉ   rl   rl   rm   Úprocess_config_section  s    ürú   c                 C   sä   t | |  ¡ d||ƒ}| jtkrªt| jƒ}||d< t | |  ¡ d||ƒ|d< t | |  ¡ d||ƒ|d< | jtj	kr„t | |  
¡ d||ƒ|d< | jtjkr®t | |  ¡ d	||ƒ|d
< n|}| j|d} t| ƒ |rà||kràtd || j¡ƒ‚| S )NÚservicer‰   ÚvolumerV   ÚnetworkrŽ   ZsecretrP   r{   r’   rå   ú3Cannot extend service '{}' in {}: Service not found)rú   r†   rw   r|   r~   r{   r   r   r
   r   r‘   r“   r”   rÏ   r,   r   r   ru   )rË   rC   rë   rÉ   r‰   Zprocessed_configrl   rl   rm   rÊ     sf    û

ûûûû
 ÿÿrÊ   c                   @   sJ   e Zd Zddd„Zedd„ ƒZdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dS )ræ   Nc                 C   s(   || _ |j| _|pg | _|| _|| _d S re   )rí   rX   Úalready_seenrË   rC   )r„   rí   rË   rC   rÿ   rl   rl   rm   Ú__init__J  s
    
zServiceExtendsResolver.__init__c                 C   s   | j j| j jfS re   )rí   ru   r‡   rŒ   rl   rl   rm   Ú	signatureQ  s    z ServiceExtendsResolver.signaturec                 C   s"   | j | jkrt| j| j g ƒ‚d S re   )r  rÿ   r   rŒ   rl   rl   rm   Údetect_cycleU  s    z#ServiceExtendsResolver.detect_cyclec                 C   s6   |   ¡  d| jjkr0| j|  ¡ Ž }| jj|dS | jS )NÚextendsrå   )r  rí   r{   Úresolve_extendsÚvalidate_and_construct_extendsrÏ   )r„   rÔ   rl   rl   rm   rè   Y  s
    zServiceExtendsResolver.runc                 C   s¸   | j jd }t|tƒsd|i}|  |¡}|d }|tj | jj	¡kr|z| j 
|¡}W q® tk
rx   td ||¡ƒ‚Y q®X n2t |¡}t| j|gƒ t|| j|d}| 
|¡}|||fS )Nr  rû   rþ   )rë   )rí   r{   r}   r~   Úget_extended_config_pathr™   rš   r›   rË   ru   rˆ   ÚKeyErrorr   r   rs   rv   r±   rÊ   rC   )r„   r  Zconfig_pathrë   rí   Zextends_fileZextended_filerl   rl   rm   r  b  s0    

 ÿÿ
  ÿ
z5ServiceExtendsResolver.validate_and_construct_extendsc                 C   sb   t t tj |¡|||¡| j| j| jg | j	d}| 
¡ }t|ƒ}t|||ƒ t|| jj| jjƒS )N)rÿ   rC   )ræ   r—   rœ   r™   rš   r­   rË   rÿ   r  rC   rè   rç   Úvalidate_extended_service_dictÚmerge_service_dictsrí   r{   rw   )r„   Zextended_config_pathrÔ   rë   rî   rí   Zother_service_dictrl   rl   rm   r  |  s.    
üøýýz&ServiceExtendsResolver.resolve_extendsc                 C   s4   | j j}t| j j||ƒ d|kr0t| j|d ƒS |S )z¸Service we are extending either has a value for 'file' set, which we
        need to obtain a full path too or we are extending from a service
        defined in our own file.
        r×   )rí   ru   r1   r‡   rÜ   rX   )r„   Zextends_optionsru   rl   rl   rm   r  ”  s    ýz/ServiceExtendsResolver.get_extended_config_path)N)rn   ro   rp   r   Úpropertyr  r  rè   r  r  r  rl   rl   rl   rm   ræ   I  s   

	ræ   c                    sT   i }|   dg ¡D ]}| t|ƒ¡ q| t|   d¡ƒ¡ t‡ fdd„t |¡D ƒƒS )zjUnpack any environment variables from an env_file, if set.
    Interpolate environment values if set.
    rB   rC   c                 3   s   | ]\}}t ||ˆ ƒV  qd S re   ©Úresolve_env_var©r    rà   Úvrä   rl   rm   rÁ   ¬  s     z&resolve_environment.<locals>.<genexpr>)r‹   Úupdater   Úparse_environmentr~   r‚   Ú	iteritems)rÔ   rC   ÚenvrB   rl   rä   rm   Úresolve_environment£  s
    r  c                    s$   t | ƒ}t‡ fdd„t |¡D ƒƒS )Nc                 3   s   | ]\}}t ||ˆ ƒV  qd S re   r  r  rä   rl   rm   rÁ   ±  s     z%resolve_build_args.<locals>.<genexpr>)Úparse_build_argumentsr~   r‚   r  )Z	buildargsrC   Úargsrl   rä   rm   Úresolve_build_args¯  s    r  c                 C   sŒ   d||f }d| kr t d| ƒ‚d| kr4t d| ƒ‚d| krTt| d ƒrTt d| ƒ‚d| krtt| d ƒrtt d	| ƒ‚d
| krˆt d| ƒ‚d S )Nz!Cannot extend service '%s' in %s:rI   z+%s services with 'links' cannot be extendedrW   z2%s services with 'volumes_from' cannot be extendedrL   z4%s services with 'net: container' cannot be extendedra   z;%s services with 'network_mode: service' cannot be extendedÚ
depends_onz0%s services with 'depends_on' cannot be extended)r   r    r!   )rÔ   ru   rû   Zerror_prefixrl   rl   rm   r  ´  s.    ÿÿÿÿÿr  c                 C   s   | j | j }}t|||ƒ t|ƒ t| ƒ t| ƒ t| |ƒ t| |ƒ t| |ƒ t	| |ƒ t
| ƒ t| ƒ | d¡sŒt|ƒrŒtdj|dƒ‚d S )NrF   zÅService '{name}' contains uppercase characters which are not valid as part of an image name. Either use a lowercase service name or use the `image` field to set a custom name for the service image.©r‡   )r{   r‡   r6   Úvalidate_pathsr.   r8   r4   r5   r0   r3   r2   r/   r‹   Úhas_uppercaser   r   )rí   rì   rË   rÔ   rë   rl   rl   rm   ré   Î  s"    



ýÿré   c                    sâ   | j ‰ t| jƒ}d|kr6‡ fdd„t|d ƒD ƒ|d< d|krHt|ˆ ƒ d|krl| d¡d krltˆ |ƒ|d< d|krˆtt|d ƒƒ|d< d|kr t	|d ƒ|d< t
|ƒ}d	D ]}||kr¬t|| ƒ||< q¬tttt|ƒƒƒƒ}|S )
NrB   c                    s   g | ]}t ˆ |ƒ‘qS rl   )rÜ   )r    rš   ©rX   rl   rm   r¤   é  s   ÿz#process_service.<locals>.<listcomp>rZ   rV   rU   rS   rH   )r@   rA   Útmpfs)rX   r~   r{   Úto_listÚprocess_build_sectionr‹   Úresolve_volume_pathsr   Úparse_sysctlsrÛ   Úprocess_depends_onÚprocess_security_optÚprocess_blkio_configÚprocess_portsÚprocess_healthcheck)rí   rÔ   Úfieldrl   r  rm   rç   ä  s,    


þ

ÿrç   c                 C   s„   t | d tjƒr$t|| d ƒ| d< n\t | d tƒr€d| d kr\| d d }t||ƒ| d d< d| d kr€t| d d ƒ| d d< d S )NrZ   ÚcontextrH   )r}   r‚   rƒ   Úresolve_build_pathr~   rÛ   )rÔ   rX   rš   rl   rl   rm   r    s    r  c                 C   sP   d| kr| S g }| d D ]*}t |tƒr2| |¡ q| t |¡¡ q|| d< | S )NrN   )r}   r(   ÚappendÚextendÚparse)rÔ   rN   Zport_definitionrl   rl   rm   r$    s    
r$  c                 C   s4   d| kr0t | d tƒs0tdd„ | d D ƒƒ| d< | S )Nr  c                 S   s   g | ]}|d dif‘qS )Ú	conditionÚservice_startedrl   )r    Zsvcrl   rl   rm   r¤   "  s    z&process_depends_on.<locals>.<listcomp>)r}   r~   ©rÔ   rl   rl   rm   r!     s
    ÿr!  c                 C   sÞ   |   d¡s| S dD ]X}|| d kr| d   |g ¡D ]6}|  dd¡}t|ƒ|d< |d d kr2td |¡ƒ‚q2qdD ]h}|| d krp| d   |g ¡D ]F}zt|  dd¡ƒ|d< W q tk
rÔ   td |  d¡¡ƒ‚Y qX qqp| S )NrY   )Údevice_read_bpsÚdevice_write_bpsÚrater   z$Invalid format for bytes value: "{}")Údevice_read_iopsÚdevice_write_iopsz5Invalid IOPS value: "{}". Must be a positive integer.)r‹   r   r   r   Úintr˜   )rÔ   r&  r  r1  rl   rl   rm   r#  (  s&    
ÿr#  c                 C   sd   d| kr| S | d }d|kr,|d= dg|d< dD ].}||ks0t || tjƒrNq0t|| ƒ||< q0| S )NrE   ÚdisableZNONEZtest)ZintervalZtimeoutZstart_period)r}   r‚   Zinteger_typesr   )rÔ   Zhcr&  rl   rl   rm   r%  A  s    
r%  c           	      C   sÌ   d| krÈg }|  d¡}|  d¡}| d D ]8}t|tƒrL| t |||¡¡ q(| t |||¡¡ q(g }dd„ |D ƒ}|D ]0}ttt	dƒ|ƒƒ 
|j¡dkrx| | ¡ ¡ qx|rÀtdd	 |¡ ƒ‚|| d< | S )
NrV   ZCOMPOSE_CONVERT_WINDOWS_PATHSZCOMPOSE_FORCE_WINDOWS_HOSTc                 S   s"   g | ]}t |tƒr| ¡ n|‘qS rl   )r}   r#   Zas_volume_spec©r    r  rl   rl   rm   r¤   _  s     z,finalize_service_volumes.<locals>.<listcomp>Úinternalr   zDuplicate mount points: [%s]r²   )Zget_booleanr}   r~   r)  r#   r+  r*   ÚlistÚmapr   Úcountr7  Úreprr   rž   )	rÔ   rC   Zfinalized_volumesZ	normalizeZwin_hostr  Zduplicate_mountsZmountsZmountrl   rl   rm   Úfinalize_service_volumesS  s&    


ÿr<  c           	         sd  t | jƒ}d|ksd|kr4t||ƒ|d< | dd ¡ d|krX‡ ‡fdd„|d D ƒ|d< t||ƒ}d|kr | d¡}t|ƒ}|r˜|ˆ kr˜d |¡|d< n||d< d	|kr¸t|d	 ƒ|d	< d
|krÐt|d
 ƒ|d
< d|krîdd„ |d D ƒ|d< d|krdd„ |d D ƒ|d< t	|| j
|ƒ |rRt|ƒ}t|ƒ\}}|rRt d d |¡¡¡ | j|d< t|ƒS )NrC   rB   rW   c                    s   g | ]}t  |ˆ ˆ¡‘qS rl   )r)   r+  )r    Zvf©rì   rw   rl   rm   r¤   u  s   ÿz$finalize_service.<locals>.<listcomp>rL   z
service:{}ra   rŽ   rO   rP   c                 S   s   g | ]}t j |¡‘qS rl   )r   ÚServiceSecretr+  r½   rl   rl   rm   r¤   ‹  s    r’   c                 S   s   g | ]}t j |¡‘qS rl   )r   r—   r+  )r    Úcrl   rl   rm   r¤     s    z_The following deploy sub-keys are not supported in compatibility mode and have been ignored: {}r²   r‡   )r~   r{   r  Úpopr<  r    r   Úparse_networksr%   Únormalize_buildrX   Ú)translate_credential_spec_to_security_optÚ)translate_deploy_keys_to_container_configr   r€   rž   r‡   Únormalize_v1_service_format)	rí   rì   rw   rC   rÇ   rÔ   ra   r[   Úignored_keysrl   r=  rm   rê   m  sR    
þ


ÿ

ÿ
ÿÿÿ
rê   c                 C   sj   d| kr:| d   d¡|d< d| d kr:t| d d ƒ|d< d| krf| d   d¡|d< d| d krfdgS g S )NÚlimitsÚmemoryrJ   r<   ÚreservationsrK   zresources.reservations.cpus)r‹   Úfloat)Zresources_dictrÔ   rl   rl   rm   Ú+translate_resource_keys_to_container_config¥  s    rK  c                 C   s:   zddddœ|  W S  t k
r4   td | ¡ƒ‚Y nX d S )NÚalwaysZnoú
on-failure)ÚanyZnonerM  zInvalid restart policy "{}")r  r   r   r  rl   rl   rm   Úconvert_restart_policy±  s    ýürO  c                 C   s(   d| krdj | d dS dj | d dS )Nr×   zfile://{file})r×   zregistry://{registry}Úregistry)rP  )r   )r\   rl   rl   rm   Ú'convert_credential_spec_to_security_opt¼  s    rQ  c                 C   s:   g }d| kr*t | d ƒ}| dj|d¡ |r6|| d< | S )Nr\   zcredentialspec={spec})ÚspecrQ   )rQ  r)  r   )rÔ   ÚresultrR  rl   rl   rm   rC  Â  s    rC  c                    sô   d| kr| d= d| kr| d= d| kr,| g fS | d ‰ ‡ fdd„dD ƒ}dˆ krjˆ   dd	¡d	krjˆ d | d
< dˆ krÎtˆ d   dd¡ƒˆ d   dd¡dœ| d< ˆ d  ¡ D ]$}|dkr¨|dkr¨| d |¡¡ q¨| tˆ   di ¡| ƒ¡ | d= | |fS )Nr\   r’   rÆ   c                    s   g | ]}|ˆ kr|‘qS rl   rl   rß   ©Zdeploy_dictrl   rm   r¤   Ù  s   ÿz=translate_deploy_keys_to_container_config.<locals>.<listcomp>)Úendpoint_moderH   Úupdate_configÚrollback_configÚ	placementÚreplicasÚmodeZ
replicatedrc   Úrestart_policyr,  rN  Zmax_attemptsr   )ÚNameZMaximumRetryCountrO   zrestart_policy.{}Ú	resources)r‹   rO  rã   r)  r   r*  rK  )rÔ   rF  rà   rl   rT  rm   rD  Ï  s6    
ÿþ

 ÿÿrD  c                 C   s   d| ksd| kr\d| kr i | d< d| kr>| d | d d< | d= d| kr\| d | d d< | d= d| krŒ|   di ¡| d< | d  d|  d¡i¡ | S )Nr^   r_   r`   ÚdriverÚoptionsr]   rZ   )r‹   r  r@  r.  rl   rl   rm   rE  õ  s      ÿrE  c                 C   s:   t | ||ƒ}d|kr"|d |d< nd| kr6| d |d< |S )z³When merging services from multiple files we need to merge the `extends`
    field. This is not handled by `merge_service_dicts()` which is used to
    perform the `extends`.
    r  )r	  )rò   ró   rw   Znew_servicerl   rl   rm   rñ   	  s    rñ   c                   @   sD   e Zd ZdZdd„ Zdd„ Zddd„Zdd	d
„Zdd„ Zdd„ Z	dS )Ú	MergeDictz>A dict-like object responsible for merging two dicts into one.c                 C   s   || _ || _d S re   rö   )r„   rò   ró   rl   rl   rm   r     s    zMergeDict.__init__c                 C   s   || j kp|| jkS re   rö   ©r„   r&  rl   rl   rm   Úneeds_merge  s    zMergeDict.needs_mergeNc                 C   s4   |   |¡sd S || j ||¡| j ||¡ƒ| |< d S re   )rb  rò   r‹   ró   )r„   r&  Z
merge_funcÚdefaultrl   rl   rm   Úmerge_field   s    
þzMergeDict.merge_fieldc                 C   sP   |   |¡sd S |d krdd„ }|| j |¡ƒ| |< | |  || j |¡ƒ¡ d S )Nc                 S   s   | pi S re   rl   ©Úmrl   rl   rm   Ú
parse_func-  s    z+MergeDict.merge_mapping.<locals>.parse_func)rb  rò   r‹   r  ró   )r„   r&  rg  rl   rl   rm   Úmerge_mapping(  s    
zMergeDict.merge_mappingc                    sb   ‡ fdd„}|   |¡sd S || j |g ¡ƒ}| || j |g ¡ƒ¡ dd„ t| ¡ ƒD ƒ| |< d S )Nc                    s   t ‡ fdd„| D ƒdƒS )Nc                 3   s   | ]}ˆ |ƒV  qd S re   rl   ©r    Úitem©rg  rl   rm   rÁ   5  s     zHMergeDict.merge_sequence.<locals>.parse_sequence_func.<locals>.<genexpr>rd  )Ú
to_mapping)Úseqrk  rl   rm   Úparse_sequence_func4  s    z5MergeDict.merge_sequence.<locals>.parse_sequence_funcc                 S   s   g | ]}|  ¡ ‘qS rl   )r;  ri  rl   rl   rm   r¤   <  s     z,MergeDict.merge_sequence.<locals>.<listcomp>©rb  rò   r‹   r  ró   rÂ   Úvalues)r„   r&  rg  rn  Úmergedrl   rk  rm   Úmerge_sequence3  s    
zMergeDict.merge_sequencec                 C   s(   |   |¡r$| j || j |¡¡| |< d S re   )rb  ró   r‹   rò   ra  rl   rl   rm   Úmerge_scalar>  s    
zMergeDict.merge_scalar)N)N)
rn   ro   rp   rq   r   rb  rd  rh  rr  rs  rl   rl   rl   rm   r`    s   

r`  c                 C   sœ  t | |ƒ}| dt¡ | dt¡ | dt¡ | dt¡ | dt¡ | dt¡ | dtj	¡ | dt
jj	¡ | d	t
jj	¡ | d
t
jj	¡ | dt¡ |jdti d dD ]}| |t¡ q°dD ]}|j|tg d qÆdD ]}| |t¡ qà|jdti d t|| |ƒ |jdti d |jdti d |jdti d ttƒt|ƒ D ]}| |¡ qN|tkrxt|| |ƒ n| d¡r”t|| |ƒ|d< t |ƒS )NrC   rH   ZulimitsrS   r  Zstorage_optrI   rP   r’   rQ   rD   rŽ   ©rc  )rV   r?   )r9   r:   ZexposeZexternal_linksrW   r>   )r@   rA   rB   r  r`   rY   rE   rÆ   rZ   )!r`  rh  r  rÛ   Úparse_flat_dictr   Úparse_depends_onrr  r'   r+  r   r>  r—   r&   r$   rd  Úmerge_networksÚmerge_path_mappingsÚmerge_unique_items_listsÚmerge_list_or_stringÚmerge_loggingÚmerge_portsÚmerge_blkio_configÚmerge_healthchecksÚmerge_deployrõ   ÚALLOWED_KEYSrs  r|   Úlegacy_v1_merge_image_or_buildrb  Úmerge_buildr~   )rò   ró   rw   Úmdr&  rl   rl   rm   r	  C  s>    

r	  c                 C   s.   dd„ |D ƒ}dd„ | D ƒ} t tƒ  | |¡ƒS )Nc                 S   s   g | ]}t |ƒ‘qS rl   ©Ústr)r    Úorl   rl   rm   r¤   q  s     z,merge_unique_items_lists.<locals>.<listcomp>c                 S   s   g | ]}t |ƒ‘qS rl   r„  ©r    Úbrl   rl   rm   r¤   r  s     )rÂ   rõ   Úunionrö   rl   rl   rm   ry  p  s    ry  c                 C   s(   |  d¡dkr|S |  ¡ }| |¡ |S )NZdisabledT)r‹   Úcopyr  ©rò   ró   rS  rl   rl   rm   r~  v  s
    
r~  c                 C   sj   dd„ }d}|   |¡sd S || j |g ¡ƒ}| || j |g ¡ƒ¡ dd„ t| ¡ dd„ dD ƒ| |< d S )	Nc                 S   s(   g }| D ]}|  t |¡¡ qt|dƒS )Nrd  )r*  r(   r+  rl  )rm  Zaccrj  rl   rl   rm   rn    s    z(merge_ports.<locals>.parse_sequence_funcrN   c                 S   s   g | ]}|‘qS rl   rl   ri  rl   rl   rm   r¤   Œ  s     zmerge_ports.<locals>.<listcomp>c                 S   s   | j S re   )Útarget©Úxrl   rl   rm   Ú<lambda>Œ  ó    zmerge_ports.<locals>.<lambda>r¿   ro  )rƒ  rò   ró   rn  r&  rq  rl   rl   rm   r|  ~  s    
r|  c                 C   s’   dd„ }t ||ƒ||ƒƒ}| d¡ | d¡ | d¡ | d¡ | d¡ | d¡ | d	t¡ |jd
tg d | dt¡ | dt¡ t|ƒS )Nc                 S   s$   |   di ¡}t|tjƒr d|iS |S )NrZ   r'  )r‹   r}   r‚   rƒ   )rû   Zbuild_configrl   rl   rm   Úto_dict  s    zmerge_build.<locals>.to_dictr'  r]   rý   rŒ  rR   rG   r  Z
cache_fromrt  rH   rD   )	r`  rs  rh  r  rd  ry  rÛ   r$   r~   )Úoutputrò   ró   r‘  rƒ  rl   rl   rm   r‚    s    





r‚  c                 C   s  t | pi |pi ƒ}| d¡ | d¡ | d¡ | dt¡ | d¡ | d¡ | d¡ | d¡r¬t |j d¡pti |j d¡p‚i ƒ}| d	¡ |jd
t	i d t
|ƒ|d< | d¡rt |j d¡pÈi |j d¡pÖi ƒ}|jdtg d |jdtg d t
|ƒ|d< t
|ƒS )NrZ  rU  rY  rH   rV  rW  r[  r]  rG  rI  rt  rX  ZconstraintsZpreferences)r`  rs  rh  rÛ   rb  rò   r‹   ró   rd  Úmerge_reservationsr~   ry  Úmerge_unique_objects_lists)rò   ró   rƒ  Zresources_mdZplacement_mdrl   rl   rm   r  ¤  s&    






"
"r  c                 C   s¾   i }t | ƒt |ƒB }t| tƒr,dd„ | D ƒn| } t|tƒrHdd„ |D ƒn|}|D ]h}t|  |¡pbi | |¡pni ƒ}| dtg ¡ | dtg ¡ | d¡ | d¡ | d¡ t|ƒ||< qP|S )	Nc                 S   s   i | ]
}|i “qS rl   rl   rß   rl   rl   rm   rô   ¾  s      z"merge_networks.<locals>.<dictcomp>c                 S   s   i | ]
}|i “qS rl   rl   rß   rl   rl   rm   rô   ¿  s      ÚaliasesZlink_local_ipsZpriorityZipv4_addressZipv6_address)	rõ   r}   r8  r`  r‹   rd  ry  rs  r~   )rò   ró   Zmerged_networksZall_network_namesZnetwork_namerƒ  rl   rl   rm   rw  »  s    


rw  c                 C   s6   t | |ƒ}| d¡ | d¡ | dtjj¡ t|ƒS )Nr<   rH  Zgeneric_resources)r`  rs  rr  r   ZGenericResourcer+  r~   ©rò   ró   rƒ  rl   rl   rm   r“  Ë  s
    


r“  c                 C   s>   t dd„ | | D ƒƒ}dd„ tdd„ | ¡ D ƒdd„ dD ƒS )	Nc                 s   s   | ]}t |ƒ|fV  qd S re   r   ©r    Úirl   rl   rm   rÁ   Ô  s     z-merge_unique_objects_lists.<locals>.<genexpr>c                 S   s   g | ]}|d  ‘qS )r   rl   r—  rl   rl   rm   r¤   Õ  s     z.merge_unique_objects_lists.<locals>.<listcomp>c                 S   s   g | ]\}}||f‘qS rl   rl   r  rl   rl   rm   r¤   Õ  s     c                 S   s   | d S )Nr   rl   r  rl   rl   rm   r  Õ  r  z,merge_unique_objects_lists.<locals>.<lambda>r¿   )r~   rÂ   rÙ   r‹  rl   rl   rm   r”  Ó  s    r”  c                 C   s>   t | |ƒ}| d¡ dd„ }dD ]}|j||g d q t|ƒS )NZweightc                 S   s@   t dd„ | D ƒƒ}|D ]}|||d < qtt| ¡ ƒdd„ dS )Nc                 s   s   | ]}|d  |fV  qdS )rš   Nrl   r‡  rl   rl   rm   rÁ   Ý  s     zAmerge_blkio_config.<locals>.merge_blkio_limits.<locals>.<genexpr>rš   c                 S   s   | d S )Nrš   rl   r  rl   rl   rm   r  á  r  z@merge_blkio_config.<locals>.merge_blkio_limits.<locals>.<lambda>r¿   )r~   rÂ   r8  rp  )rò   ró   Úindexr†  rl   rl   rm   Úmerge_blkio_limitsÜ  s    z.merge_blkio_config.<locals>.merge_blkio_limits)r/  r2  r0  r3  Zweight_devicert  )r`  rs  rd  r~   )rò   ró   rƒ  rš  r&  rl   rl   rm   r}  Ø  s    

r}  c                 C   sj   t | |ƒ}| d¡ | d¡|  d¡ks6|  d¡d krH| ddd„ ¡ n| d¡rb| di ¡|d< t|ƒS )Nr^  r_  c                 S   s   | pi S re   rl   re  rl   rl   rm   r  ð  r  zmerge_logging.<locals>.<lambda>)r`  rs  r‹   rh  r~   r–  rl   rl   rm   r{  ì  s    

"
r{  c                 C   sr   |   dd ¡ |   dd ¡ d|kr.|d | d< n@d|krD|d | d< n*d|krZ|d | d< nd|krn|d | d< d S )NrF   rZ   )r@  )r’  rò   ró   rl   rl   rm   r  ö  s    r  c                 C   s   t | ƒ}| t |ƒ¡ |S re   )r  r  )rò   ró   r  rl   rl   rm   Úmerge_environment  s    r›  c                 C   s   t | ƒ}| t |ƒ¡ |S re   )rÛ   r  )rò   ró   rH   rl   rl   rm   Úmerge_labels	  s    rœ  c                 C   s    d| kr|   dd¡S | dfS d S )Nú=r   Ú )Úsplit)Zkvpairrl   rl   rm   Úsplit_kv  s    r   c                    sN   |si S t |tƒr(t‡ fdd„|D ƒƒS t |tƒr:t|ƒS td||f ƒ‚d S )Nc                 3   s   | ]}ˆ |ƒV  qd S re   rl   )r    Úe©Ú
split_funcrl   rm   rÁ     s     z%parse_dict_or_list.<locals>.<genexpr>z"%s "%s" must be a list or mapping,)r}   r8  r~   r   )r£  Z	type_nameZ	argumentsrl   r¢  rm   Úparse_dict_or_list  s    

ÿÿr¤  zbuild argumentsc                 C   s   | d fS re   rl   ©rà   rl   rl   rm   r  )  r  r  rŽ   c                 C   s   | ddifS )Nr,  r-  rl   r¥  rl   rl   rm   r  ,  r  r  c                 C   s&   | si S t | tƒrt| ƒS tdƒ‚d S )NzInvalid type: expected mapping)r}   r~   r   ©Údrl   rl   rm   ru  0  s
    
ru  c                 C   s4   |d k	r| |fS |r(| |kr(| ||  fS | d fS d S re   rl   )rÀ   ÚvalrC   rl   rl   rm   r  :  s
    r  c                    s   ‡ fdd„|d D ƒS )Nc                    s   g | ]}t ˆ |ƒ‘qS rl   )Úresolve_volume_path)r    rü   r  rl   rm   r¤   D  s   ÿz(resolve_volume_paths.<locals>.<listcomp>rV   rl   )rX   rÔ   rl   r  rm   r  C  s    
þr  c                 C   s¨   t |tƒr>| dd¡ d¡r:|d dkr:t| |d ƒ|d< |S d }t|ƒ\}}|d k	r¤|\}}|d krj|S | d¡r~t| |ƒ}tj |¡}d 	|||ržd| nd¡S |S )	NÚsourcerž  )Ú.ú~ÚtypeZbindr«  z{}:{}{}ú:)
r}   r~   r‹   Ú
startswithrÜ   Úsplit_path_mappingr™   rš   Ú
expanduserr   )rX   rü   Zmount_paramsÚcontainer_pathZ	host_pathrZ  rl   rl   rm   r©  J  s    


r©  c                 C   sf   d| krbi }t | d tjƒr,|  d¡|d< n.| | d ¡ d|krZtt| d¡|ƒƒ|d< || d< d S )NrZ   r'  r  )r}   r‚   rƒ   r@  r  r   r  r‹   )rÔ   rX   rC   rZ   rl   rl   rm   rB  _  s    ÿrB  c                 C   s   t |ƒr|S t| |ƒS re   )Úis_urlrÜ   )rX   Ú
build_pathrl   rl   rm   r(  p  s    r(  c                 C   s
   |   t¡S re   )r¯  ÚDOCKER_VALID_URL_PREFIXES)r´  rl   rl   rm   r³  v  s    r³  c                 C   sx   d| krt|   di ¡}t|tjƒr&|}n t|tƒrBd|krB|d }nd S t|ƒsttj |¡rht 	|tj
¡sttd| ƒ‚d S )NrZ   r'  zNbuild path %s either does not exist, is not accessible, or is not a valid URL.)r‹   r}   r‚   rƒ   r~   r³  r™   rš   rº   ÚaccessÚR_OKr   )rÔ   rZ   r´  rl   rl   rm   r  z  s$    
ÿ
þþÿÿr  c                 C   s   t | ƒ}| t |ƒ¡ t|ƒS re   )Údict_from_path_mappingsr  Úpath_mappings_from_dict)rò   ró   r§  rl   rl   rm   rx    s    rx  c                 C   s   | rt dd„ | D ƒƒS i S d S )Nc                 s   s   | ]}t |ƒV  qd S re   )r°  r6  rl   rl   rm   rÁ   —  s     z*dict_from_path_mappings.<locals>.<genexpr>)r~   )Zpath_mappingsrl   rl   rm   r¸  •  s    r¸  c                 C   s   dd„ t |  ¡ ƒD ƒS )Nc                 S   s   g | ]}t |ƒ‘qS rl   )Újoin_path_mappingr6  rl   rl   rm   r¤     s     z+path_mappings_from_dict.<locals>.<listcomp>)rÂ   rÙ   r¦  rl   rl   rm   r¹  œ  s    r¹  c                 C   s„   t | tƒr|  d¡| fS t| ƒ\}}d|krx| dd¡\}}t|ƒ\}}d}d|krd| dd¡\}}|| || |ffS | dfS dS )zµ
    Ascertain if the volume_path contains a host path as well as a container
    path. Using splitdrive so windows absolute paths won't cause issues with
    splitting on ':'.
    rŒ  r®  r   N)r}   r~   r‹   r   rŸ  Úrsplit)Zvolume_pathZdriveZvolume_configÚhostÚ	containerZcontainer_driver²  rZ  rl   rl   rm   r°     s    
r°  c                 C   s:   |   dg ¡}g }|D ]}| t |¡¡ q|r6|| d< | S )NrQ   )r‹   r)  r&   r+  )rÔ   Zsecurity_optsrS  Úvaluerl   rl   rm   r"  ¶  s    r"  c                 C   sP   | \}}t |tƒr|S |d kr"|S |\}}d ||f¡}|rH|d| 7 }|S d S )Nr®  )r}   r~   rž   )Zpairr½  r¼  rZ  rS  rl   rl   rm   rº  À  s    
rº  c                 C   s   t j t j | t j |¡¡¡S re   )r™   rš   r›   rž   r±  )rX   rš   rl   rl   rm   rÜ   Î  s    rÜ   c                 C   s   t | ƒt |ƒ S re   )r  rö   rl   rl   rm   rz  Ò  s    rz  c                 C   s&   | d krg S t | tjƒr| gS | S d S re   )r}   r‚   rƒ   )r¾  rl   rl   rm   r  Ö  s
    r  c                    s   ‡ fdd„| D ƒS )Nc                    s   i | ]}t |ˆ ƒ|“qS rl   )rØ   ri  ©Ú	key_fieldrl   rm   rô   à  s      zto_mapping.<locals>.<dictcomp>rl   )ZsequencerÀ  rl   r¿  rm   rl  ß  s    rl  c                 C   s   t dd„ | D ƒƒS )Nc                 s   s   | ]}|t jkV  qd S re   )ÚstringZascii_uppercase)r    Úcharrl   rl   rm   rÁ   ä  s     z has_uppercase.<locals>.<genexpr>)rN  r  rl   rl   rm   r  ã  s    r  c              
   C   s²   z<t j| |rdnd|d}t |¡W  5 Q R £ W S Q R X W np ttjtfk
r¬ } zJ|d krtt| ddd W Y ¢.S t|ddƒd	 |j	j
 }td
 ||¡ƒ‚W 5 d }~X Y nX d S )NÚrbÚr)Úencodingz	utf-8-sigF)rÅ  Úbinaryro   rž  r«  z{}: {})ÚioÚopenr§   r¨   ÚIOErrorZ	YAMLErrorÚUnicodeDecodeErrorrt   rØ   rk   rn   r   r   )ru   rÅ  rÆ  Zfhr¡  Z
error_namerl   rl   rm   rt   ç  s    "rt   )N)F)FT)N)F)NT)N)NT)§Z
__future__r   r   Ú	functoolsrÇ  r`   r™   rÁ  r©   Úcollectionsr   Úoperatorr   r‚   r§   r   rž  r   r
   r   r|   r   rá   r   rÓ   r   rÒ   r   râ   Zutilsr   r   r   r   r   rw   r   rC   r   r   r   Úerrorsr   r   r   r   r   Úinterpolationr   Zsort_servicesr    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   Z
validationr+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   r8   ZDOCKER_CONFIG_KEYSr€  rµ  r´   r¼   Z	getLoggerrn   r   rd   rs   r–   r—   r¯   r±   r«   r¶   r³   rÈ   rÕ   rÐ   rÚ   rÑ   rù   rú   rÊ   Úobjectræ   r  r  r  ré   rç   r  r$  r!  r#  r%  r<  rê   rK  rO  rQ  rC  rD  rE  rñ   r~   r`  r	  ry  r~  r|  r‚  r  rw  r“  r”  r}  r{  r  r›  rœ  r   r¤  Úpartialr  r  rÛ   rA  r   rv  ru  r  r  r©  rB  r(  r³  r  rx  r¸  r¹  r°  r"  rº  rÜ   rz  r  rl  r  rt   rl   rl   rl   rm   Ú<module>   sÂ  Ä?ó	þ
?	)3	8Z#8&--
  ÿ
	
	