ó
Á£ô_c           @  s9  d  Z  d d l m 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 e j e ƒ Z d „  Z d „  Z d „  Z d „  Z e ƒ  Z d „  Z d „  Z g  Z d „  Z d „  Z d „  Z d „  Z d „  Z  d „  Z! d „  Z" d S(   s;   Facilities for implementing hooks that call shell commands.iÿÿÿÿ(   t   print_functionN(   t   List(   t   Set(   t   errors(   t   util(   t
   filesystem(   t   misc(   t   osc         C  sD   t  |  j d ƒ t  |  j d ƒ t  |  j d ƒ t  |  j d ƒ d S(   s#   Check hook commands are executable.t   pret   postt   deployt   renewN(   t   validate_hookt   pre_hookt	   post_hookt   deploy_hookt
   renew_hook(   t   config(    (    s;   /usr/lib/python2.7/site-packages/certbot/_internal/hooks.pyt   validate_hooks   s    c         C  sB   t  j |  ƒ s2 t j |  ƒ t  j |  ƒ s2 d Sn  t j j |  ƒ S(   sÁ   Extract the program run by a shell command.

    :param str shell_cmd: command to be executed

    :returns: basename of command or None if the command isn't found
    :rtype: str or None

    N(   R   t
   exe_existst	   plug_utilt   path_surgeryt   NoneR   t   patht   basename(   t	   shell_cmd(    (    s;   /usr/lib/python2.7/site-packages/certbot/_internal/hooks.pyt   _prog   s
    	c         C  sŠ   |  r† |  j  d d ƒ d } t | ƒ s† t j d } t j j | ƒ r\ d j | | ƒ } n d j | | | ƒ } t j	 | ƒ ‚ q† n  d S(   s‹   Check that a command provided as a hook is plausibly executable.

    :raises .errors.HookCommandNotFound: if the command is not found
    i   i    t   PATHs3   {1}-hook command {0} exists, but is not executable.s>   Unable to find {2}-hook command {0} in the PATH.
(PATH is {1})N(
   t   splitR   R   R   t   environR   t   existst   formatR   t   HookCommandNotFound(   R   t	   hook_namet   cmdR   t   msg(    (    s;   /usr/lib/python2.7/site-packages/certbot/_internal/hooks.pyR   *   s    c         C  s_   |  j  d k r? |  j r? x$ t |  j ƒ D] } t | ƒ q( Wn  |  j } | r[ t | ƒ n  d S(   så  Run pre-hooks if they exist and haven't already been run.

    When Certbot is running with the renew subcommand, this function
    runs any hooks found in the config.renewal_pre_hooks_dir (if they
    have not already been run) followed by any pre-hook in the config.
    If hooks in config.renewal_pre_hooks_dir are run and the pre-hook in
    the config is a path to one of these scripts, it is not run twice.

    :param configuration.NamespaceConfig config: Certbot settings

    R   N(   t   verbt   directory_hookst
   list_hookst   renewal_pre_hooks_dirt   _run_pre_hook_if_necessaryR   (   R   t   hookR"   (    (    s;   /usr/lib/python2.7/site-packages/certbot/_internal/hooks.pyR   <   s    	c         C  s=   |  t  k r t j d |  ƒ n t d |  ƒ t  j |  ƒ d S(   sÑ   Run the specified pre-hook if we haven't already.

    If we've already run this exact command before, a message is logged
    saying the pre-hook was skipped.

    :param str command: pre-hook to be run

    s*   Pre-hook command already run, skipping: %ss   pre-hookN(   t   executed_pre_hookst   loggert   infot	   _run_hookt   add(   t   command(    (    s;   /usr/lib/python2.7/site-packages/certbot/_internal/hooks.pyR(   T   s    	c         C  sx   |  j  } |  j d k r^ |  j rH x$ t |  j ƒ D] } t | ƒ q1 Wn  | rt t | ƒ qt n | rt t d | ƒ n  d S(   s…  Run post-hooks if defined.

    This function also registers any executables found in
    config.renewal_post_hooks_dir to be run when Certbot is used with
    the renew subcommand.

    If the verb is renew, we delay executing any post-hooks until
    :func:`run_saved_post_hooks` is called. In this case, this function
    registers all hooks found in config.renewal_post_hooks_dir to be
    called followed by any post-hook in the config. If the post-hook in
    the config is a path to an executable in the post-hook directory, it
    is not scheduled to be run twice.

    :param configuration.NamespaceConfig config: Certbot settings

    R   s	   post-hookN(   R   R$   R%   R&   t   renewal_post_hooks_dirt   _run_eventuallyR-   (   R   R"   R)   (    (    s;   /usr/lib/python2.7/site-packages/certbot/_internal/hooks.pyR   d   s    		c         C  s    |  t  k r t  j |  ƒ n  d S(   sú   Registers a post-hook to be run eventually.

    All commands given to this function will be run exactly once in the
    order they were given when :func:`run_saved_post_hooks` is called.

    :param str command: post-hook to register to be run

    N(   t
   post_hookst   append(   R/   (    (    s;   /usr/lib/python2.7/site-packages/certbot/_internal/hooks.pyR1   †   s    	c          C  s"   x t  D] }  t d |  ƒ q Wd S(   sG   Run any post hooks that were saved up in the course of the 'renew' verbs	   post-hookN(   R2   R-   (   R"   (    (    s;   /usr/lib/python2.7/site-packages/certbot/_internal/hooks.pyt   run_saved_post_hooks“   s    c         C  s)   |  j  r% t |  j  | | |  j ƒ n  d S(   s  Run post-issuance hook if defined.

    :param configuration.NamespaceConfig config: Certbot settings
    :param domains: domains in the obtained certificate
    :type domains: `list` of `str`
    :param str lineage_path: live directory path for the new cert

    N(   R   t   _run_deploy_hookt   dry_run(   R   t   domainst   lineage_path(    (    s;   /usr/lib/python2.7/site-packages/certbot/_internal/hooks.pyR   ™   s    		c         C  s    t  ƒ  } |  j rR x= t |  j ƒ D]) } t | | | |  j ƒ | j | ƒ q" Wn  |  j rœ |  j | k r€ t j	 d |  j ƒ qœ t |  j | | |  j ƒ n  d S(   s]  Run post-renewal hooks.

    This function runs any hooks found in
    config.renewal_deploy_hooks_dir followed by any renew-hook in the
    config. If the renew-hook in the config is a path to a script in
    config.renewal_deploy_hooks_dir, it is not run twice.

    If Certbot is doing a dry run, no hooks are run and messages are
    logged saying that they were skipped.

    :param configuration.NamespaceConfig config: Certbot settings
    :param domains: domains in the obtained certificate
    :type domains: `list` of `str`
    :param str lineage_path: live directory path for the new cert

    s0   Skipping deploy-hook '%s' as it was already run.N(
   t   setR%   R&   t   renewal_deploy_hooks_dirR5   R6   R.   R   R+   R,   (   R   R7   R8   t   executed_dir_hooksR)   (    (    s;   /usr/lib/python2.7/site-packages/certbot/_internal/hooks.pyR   §   s    				c         C  sN   | r t  j d |  ƒ d Sd j | ƒ t j d <| t j d <t d |  ƒ d S(   s  Run the specified deploy-hook (if not doing a dry run).

    If dry_run is True, command is not run and a message is logged
    saying that it was skipped. If dry_run is False, the hook is run
    after setting the appropriate environment variables.

    :param str command: command to run as a deploy-hook
    :param domains: domains in the obtained certificate
    :type domains: `list` of `str`
    :param str lineage_path: live directory path for the new cert
    :param bool dry_run: True iff Certbot is doing a dry run

    s)   Dry run: skipping deploy hook command: %sNt    t   RENEWED_DOMAINSt   RENEWED_LINEAGEs   deploy-hook(   R+   t   warningt   joinR   R   R-   (   R/   R7   R8   R6   (    (    s;   /usr/lib/python2.7/site-packages/certbot/_internal/hooks.pyR5   Ç   s    	c         C  s(   t  j |  | d t j ƒ  ƒ\ } } | S(   sÜ   Run a hook command.

    :param str cmd_name: the user facing name of the hook being run
    :param shell_cmd: shell command to execute
    :type shell_cmd: `list` of `str` or `str`

    :returns: stderr if there was anyt   env(   R   t   execute_commandR   t   env_no_snap_for_external_calls(   t   cmd_nameR   t   errt   _(    (    s;   /usr/lib/python2.7/site-packages/certbot/_internal/hooks.pyR-   ß   s    $c           sa   ‡  f d †  t  j ˆ  ƒ Dƒ } g  | D]+ } t j | ƒ r& | j d ƒ r& | ^ q& } t | ƒ S(   sÒ   List paths to all hooks found in dir_path in sorted order.

    :param str dir_path: directory to search

    :returns: `list` of `str`
    :rtype: sorted list of absolute paths to executables in dir_path

    c         3  s$   |  ] } t  j j ˆ  | ƒ Vq d  S(   N(   R   R   R@   (   t   .0t   f(   t   dir_path(    s;   /usr/lib/python2.7/site-packages/certbot/_internal/hooks.pys	   <genexpr>ô   s    t   ~(   R   t   listdirR   t   is_executablet   endswitht   sorted(   RI   t   allpathsR   t   hooks(    (   RI   s;   /usr/lib/python2.7/site-packages/certbot/_internal/hooks.pyR&   ë   s    	8(#   t   __doc__t
   __future__R    t   loggingt   acme.magic_typingR   R   t   certbotR   R   t   certbot.compatR   R   R   t   certbot.pluginsR   t	   getLoggert   __name__R+   R   R   R   R   R9   R*   R(   R   R2   R1   R4   R   R   R5   R-   R&   (    (    (    s;   /usr/lib/python2.7/site-packages/certbot/_internal/hooks.pyt   <module>   s4   											 		