ó
¼S]c           @  s  d  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
 m Z m Z m Z d d l j j Z d d l m Z d d l m Z d d l m Z d d l m Z d	 Z d
 Z d e e f Z d e f d „  ƒ  YZ d e
 f d „  ƒ  YZ d S(   s   Redis-related providers.iÿÿÿÿ(   t   print_functionN(   t   EnvVarProvidert   ProviderAnalysist   shutdown_service_run_statet   delete_service_directory(   t   PROVIDE_MODE_DEVELOPMENT(   t   _new_error_recorder(   t
   py2_compat(   t   logged_subprocesst	   localhostië  s   redis://%s:%dt   _RedisProviderAnalysisc           B  s   e  Z d  Z d „  Z RS(   sK   Subtype of ProviderAnalysis with extra fields RedisProvider needs to track.c         C  s2   t  t |  ƒ j | | | ƒ | |  _ | |  _ d  S(   N(   t   superR
   t   __init__t   existing_scoped_instance_urlt   default_system_exists(   t   selft   configt   missing_to_configuret   missing_to_provideR   R   (    (    sU   lib/python2.7/site-packages/anaconda_project/requirements_registry/providers/redis.pyR   "   s    	(   t   __name__t
   __module__t   __doc__R   (    (    (    sU   lib/python2.7/site-packages/anaconda_project/requirements_registry/providers/redis.pyR
      s   t   RedisProviderc           B  sz   e  Z d  Z e d „  ƒ Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d „  Z d	 „  Z d
 „  Z d d „ Z RS(   sN   Runs a project-scoped Redis process (each project needing Redis gets its own).c         C  s    | j  d ƒ } t | ƒ d k r% d  Sy0 t | d j ƒ  ƒ } t | d j ƒ  ƒ } Wn t k
 ri d  SX| d k s‚ | d k r† d  S| | k r– d  S| | f S(   Nt   -i   i    i   (   t   splitt   lent   Nonet   intt   stript
   ValueError(   t   clst   st   piecest   lowert   upper(    (    sU   lib/python2.7/site-packages/anaconda_project/requirements_registry/providers/redis.pyt   _parse_port_range-   s    c         C  s   d | j  g S(   Nt   service_options(   t   env_var(   R   t   requirement(    (    sU   lib/python2.7/site-packages/anaconda_project/requirements_registry/providers/redis.pyt   _config_section=   s    c         C  s)  t  t |  ƒ j | | | | | ƒ } d | k s6 t ‚ |  j | ƒ } | j | d g d d ƒ} | d d k r‚ d | | d <n  d }	 d }
 d	 |	 |
 f } | j | d
 g d | ƒ} |  j | ƒ } | d k r	t d | | f d t	 j
 ƒ|	 | d <|
 | d <n | d | d <| d | d <| S(   s)   Override superclass to return our config.t   sourcet   scopet   defaultt   allt   unsett   find_iì  i1  s   %d-%dt
   port_ranges,   Invalid port_range '%s', should be like '%s't   filet
   lower_portt
   upper_porti    i   N(   R   R   t   read_configt   AssertionErrorR'   t	   get_valueR#   R   t   printt   syst   stderr(   R   R&   t   environt   local_state_filet   default_env_spec_namet	   overridesR   t   sectionR)   t   default_lower_portt   default_upper_portt   default_port_ranget   port_range_stringt   parsed_port_range(    (    sU   lib/python2.7/site-packages/anaconda_project/requirements_registry/providers/redis.pyR2   @   s*    	

c         C  si  |  j  | | | | d d ƒ} |  j | ƒ } | d }	 | d }
 d | k rZ | d }
 n  d | k rs | d }	 n  | j | d g d |
 |	 f ƒ d | k r@| d d k r¹ d } n8 | d d	 k rÒ d
 } n | d d k rë d } n d } | d k	 r| j | d g | ƒ n  | d d k r@| j | j d ƒ q@n  t t |  ƒ j | | | | | | ƒ d S(   s-   Override superclass to set our config values.R;   R1   R0   R.   s   %s-%sR(   t   find_allR+   t   find_projectt   projectt   find_systemt   systemR)   R8   N(	   R2   R   R'   t	   set_valuet   popR%   R   R   t   set_config_values_as_strings(   R   R&   R8   R9   R:   R;   t   valuesR   R<   R1   R0   R)   (    (    sU   lib/python2.7/site-packages/anaconda_project/requirements_registry/providers/redis.pyRI   ^   s.    

!			c         C  sD   d | k r< t  j d d d | d ƒ r< d j d | d ƒ Sd  Sd  S(   Nt   portt   hostR	   s   redis://localhost:{port}(   t   network_utilt   can_connect_to_sockett   formatR   (   R   t	   run_state(    (    sU   lib/python2.7/site-packages/anaconda_project/requirements_registry/providers/redis.pyt"   _previously_run_redis_url_if_alive†   s    (c         C  s   t  j d t d t ƒ S(   NRL   RK   (   RM   RN   t   _DEFAULT_SYSTEM_REDIS_HOSTt   _DEFAULT_SYSTEM_REDIS_PORT(   R   (    (    sU   lib/python2.7/site-packages/anaconda_project/requirements_registry/providers/redis.pyt   _can_connect_to_system_defaultŒ   s    c   
      C  sv   t  t |  ƒ j | | | | | ƒ } | j | j ƒ } |  j | ƒ } |  j ƒ  }	 t | j | j	 | j
 d | d |	 ƒS(   s?   Override superclass to store additional fields in the analysis.R   R   (   R   R   t   analyzet   get_service_run_stateR%   RQ   RT   R
   R   t   missing_env_vars_to_configuret   missing_env_vars_to_provide(
   R   R&   R8   R9   R:   R;   t   analysisRP   t   previoust
   systemwide(    (    sU   lib/python2.7/site-packages/anaconda_project/requirements_registry/providers/redis.pyRU      s    		c         C  s(   | j  j j r$ | j d t ƒ t Sd  S(   Ns    Found system default Redis at %s(   t   statusRY   R   t   infot   _DEFAULT_SYSTEM_REDIS_URL(   R   R&   t   contextt   frontend(    (    sU   lib/python2.7/site-packages/anaconda_project/requirements_registry/providers/redis.pyt   _provide_systemž   s    c           s:   ˆ j  j j ‰  ‡  ‡ ‡ ‡ f d †  } ˆ j ˆ j | ƒ S(   Nc      
     s  ˆ j  j j } | d  k	 r8 ˆ j d j d | ƒ ƒ | S|  j ƒ  ˆ j ˆ j ƒ } t	 j
 j | d ƒ } t	 j
 j | d ƒ } ˆ  d } ˆ  d } | } x6 | | k rÐ t j d d d	 | ƒ sÃ Pn  | d
 7} q› W| | k rˆ j d d j d | d | ƒ ƒ d  Sy t	 j | ƒ Wn! t k
 r(n t k
 r8n Xd d | d | d d d t | ƒ g	 } ˆ j d t | ƒ ƒ y1 t j d | d t j d t j ˆ j ƒ ƒ }	 Wn+ t k
 rÕ}
 ˆ j d t |
 ƒ ƒ d  SX|	 j ƒ  \ } } | d  k sút ‚ | j d d ƒ } d  } |	 j d k r#t  } t  } d } d } x | | k  rÊ| d } t! j" | ƒ | | 7} | s“t j d d d	 | ƒ r“t# } q“n  | s·t	 j
 j$ | ƒ r·t# } q·n  | r<| r<Pq<q<W| r| |  d	 <d j d	 | ƒ } d  d! t | ƒ d" g g |  d# <q#ˆ j d$ | ƒ n  | d  k rx3 | j% d% ƒ D]" } | d& k r?ˆ j | ƒ q?q?WyF t& j' | d' d( ƒ + } x! | j( ƒ  D] } ˆ j | ƒ qWWd  QXWnG t k
 rô}
 |
 j) t) j* k rõˆ j d) j d* | d+ |
 ƒ ƒ qõn Xˆ j d, j d- |	 j ƒ ƒ n  | S(.   Ns1   Using redis-server we started previously at {url}t   urls	   redis.pids	   redis.logR0   R1   RL   R	   RK   i   s/   All ports from {lower} to {upper} were in use, s,   could not start redis-server on one of them.R!   R"   s   redis-servers	   --pidfiles	   --logfiles   --daemonizet   yess   --ports	   Starting t   argsR7   t   envs    Error executing redis-server: %st   errorst   replacei    i
   g     @@s   redis://localhost:{port}s	   redis-clis   -pt   shutdownt   shutdown_commandssV   redis-server started successfully, but we timed out trying to connect to it on port %ds   
t    t   rs   utf-8s!   Failed to read {logfile}: {error}t   logfilet   errorsA   redis-server process failed or timed out, exited with code {code}t   code(+   R\   RY   R   R   R]   RO   t   cleart   ensure_service_directoryR%   t   ost   patht   joinRM   RN   Rm   t   removet   IOErrort   OSErrort   strt   reprR   t   Popent
   subprocesst   PIPER   t   env_without_unicodeR8   t	   Exceptiont   communicateR3   t   decodet
   returncodet   Falset   timet   sleept   Truet   existsR   t   codecst   opent	   readlinest   errnot   ENOENT(   RP   Rb   t   workdirt   pidfileRl   t
   LOWER_PORTt
   UPPER_PORTRK   t   commandt   popent   et   outt   errt   port_is_readyt   pidfile_is_readyt   MAX_WAIT_TIMEt   so_fart	   incrementt   linet   log(   R   R_   R`   R&   (    sU   lib/python2.7/site-packages/anaconda_project/requirements_registry/providers/redis.pyt   ensure_redis¦   sš    


	
	(


"&(   R\   RY   R   t   transform_service_run_stateR%   (   R   R&   R_   R`   R›   (    (   R   R_   R`   R&   sU   lib/python2.7/site-packages/anaconda_project/requirements_registry/providers/redis.pyt   _provide_project£   s    zc         C  s`  d | j  k s t ‚ d } | j j j d } t t |  ƒ j | | ƒ } | j  j	 | j
 d ƒ } t | j ƒ } t } | d k rÇ | d k sš | d k rÇ |  j | | | ƒ } | d k rÇ t } qÇ n  | d k r| d k së | d k r| j t k r|  j | | | ƒ } qn  | d k r:| rJ| j d ƒ qJn | | j  | j
 <| j d | j ƒ  ƒ S(	   s¶   Override superclass to start a project-scoped redis-server.

        If it locates or starts a redis-server, it sets the
        requirement's env var to that server's URL.

        t   PATHR(   RE   RB   RC   s*   Could not connect to system default Redis.Rf   N(   R8   R3   R   R\   RY   R   R   R   t   providet   getR%   R   R`   R   Ra   R„   t   modeR   R   Rm   t   copy_with_additionst
   pop_errors(   R   R&   R_   Rb   R(   t   super_resultR`   t   system_failed(    (    sU   lib/python2.7/site-packages/anaconda_project/requirements_registry/providers/redis.pyRŸ   "  s&    $$c         C  s&   t  | | j ƒ } t | | j ƒ | S(   s=   Override superclass to shut down any redis-server we started.(   R   R%   R   (   R   R&   R8   R9   R;   t   requirement_statusR\   (    (    sU   lib/python2.7/site-packages/anaconda_project/requirements_registry/providers/redis.pyt	   unprovideI  s    N(   R   R   R   t   classmethodR#   R'   R2   RI   RQ   RT   RU   Ra   R   RŸ   R   R§   (    (    (    sU   lib/python2.7/site-packages/anaconda_project/requirements_registry/providers/redis.pyR   *   s   			(						'(   R   t
   __future__R    R†   R‰   Rq   Rz   R6   R‚   t/   anaconda_project.requirements_registry.providerR   R   R   R   t3   anaconda_project.requirements_registry.network_utilt   requirements_registryRM   t   anaconda_project.provideR   t   anaconda_project.frontendR   t   anaconda_project.internalR   R   RR   RS   R^   R
   R   (    (    (    sU   lib/python2.7/site-packages/anaconda_project/requirements_registry/providers/redis.pyt   <module>   s$   "