
     #b &                        d 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
  ej        de            G d de          Z G d	 d
ee          Z G d dee          Z G d dee          Z G d d          ZddZd Zd ZdS )z Daemon runner library.     N   pidfile)DaemonContextu@   The ‘runner’ module is not a supported API for this library.c                       e Zd ZdZdS )DaemonRunnerErrorz3 Abstract base class for errors from DaemonRunner. N__name__
__module____qualname____doc__     //usr/lib/python3/dist-packages/daemon/runner.pyr   r      s        ====r   r   c                       e Zd ZdZdS )DaemonRunnerInvalidActionErrorz; Raised when specified action for DaemonRunner is invalid. Nr	   r   r   r   r   r      s        EEEEr   r   c                       e Zd ZdZdS )DaemonRunnerStartFailureErrorz, Raised when failure starting DaemonRunner. Nr	   r   r   r   r   r   #           6666r   r   c                       e Zd ZdZdS )DaemonRunnerStopFailureErrorz, Raised when failure stopping DaemonRunner. Nr	   r   r   r   r   r   '   r   r   r   c                   `    e Zd ZdZdZd Zd Zd ZddZd Z	d	 Z
d
 Zd Ze	eedZd Zd ZdS )DaemonRunnera3   Controller for a callable running in a separate background process.

        The first command-line argument is the action to take:

        * 'start': Become a daemon and call `app.run()`.
        * 'stop': Exit the daemon process specified in the PID file.
        * 'restart': Stop, then start.
        zstarted with pid {pid:d}c                    |                                   || _        t                      | _        |                     |           d| _        |j        t          |j        |j                  | _        | j        | j        _        dS )a"   Set up the parameters of a new runner.

            :param app: The application instance; see below.
            :return: ``None``.

            The `app` argument must have the following attributes:

            * `stdin_path`, `stdout_path`, `stderr_path`: Filesystem paths
              to open and replace the existing `sys.stdin`, `sys.stdout`,
              `sys.stderr`.

            * `pidfile_path`: Absolute filesystem path to a file that will
              be used as the PID file for the daemon. If ``None``, no PID
              file will be used.

            * `pidfile_timeout`: Used as the default acquisition timeout
              value supplied to the runner's PID lock file.

            * `run`: Callable that will be invoked when the daemon is
              started.
            N)	
parse_argsappr   daemon_context#_open_streams_from_app_stream_pathsr   pidfile_pathmake_pidlockfilepidfile_timeoutselfr   s     r   __init__zDaemonRunner.__init__7   sz    , 	+oo00555'+$c&9; ;DL&*l###r   c                     t          |j        d          | j        _        t          |j        d          | j        _        t          |j        dd          | j        _        dS )ab   Open the `daemon_context` streams from the paths specified.

            :param app: The application instance.

            Open the `daemon_context` standard streams (`stdin`,
            `stdout`, `stderr`) as stream objects of the appropriate
            types, from each of the corresponding filesystem paths
            from the `app`.
            rtzw+tr   )	bufferingN)open
stdin_pathr   stdinstdout_pathstdoutstderr_pathstderrr"   s     r   r   z0DaemonRunner._open_streams_from_app_stream_pathsX   s[     %)$>$>!%)#/5%A%A"%)!&5 &5 &5"""r   c                     t           j                            |d                   }d}d                    | j                                                  }d                    ||          }t          |           t          j	        |           dS )z Emit a usage message, then exit.

            :param argv: The command-line arguments used to invoke the
                program, as a sequence of strings.
            :return: ``None``.
            r      |zusage: {progname} {usage})prognameusageN)
ospathbasenamejoinaction_funcskeysformatemit_messagesysexit)r#   argvr2   usage_exit_codeaction_usagemessages         r   _usage_exitzDaemonRunner._usage_exitg   s     7##DG,,xx 1 6 6 8 899-44! 5 7 7W!!!!!r   Nc                     |t           j        }d}t          |          |k     r|                     |           t	          |d                   | _        | j        | j        vr|                     |           dS dS )a   Parse command-line arguments.

            :param argv: The command-line arguments used to invoke the
                program, as a sequence of strings.

            :return: ``None``.

            The parser expects the first argument as the program name, the
            second argument as the action to perform.

            If the parser fails to parse the arguments, emit a usage
            message and exit the program.
            Nr0   r   )r<   r>   lenrB   stractionr8   )r#   r>   min_argss      r   r   zDaemonRunner.parse_argsv   s}     <8Dt99xT"""$q'll;d///T""""" 0/r   c                    t          | j                  r| j                                         	 | j                                         nB# t
          j        $ r0}t          d                    | j                            }||d}~ww xY wt          j
                    }| j                            |          }t          |           | j                                         dS )z Open the daemon context and run the application.

            :return: ``None``.
            :raises DaemonRunnerStartFailureError: If the PID file cannot
                be locked by this process.
            z(PID file {pidfile.path!r} already lockedr   N)pid)is_pidfile_staler   
break_lockr   r(   lockfileAlreadyLockedr   r:   r4   getpidstart_messager;   r   run)r#   excerrorrI   rA   s        r   _startzDaemonRunner._start   s     DL)) 	&L##%%%	!$$&&&&% 	! 	! 	!1>EE $ F . ./ /E S 		! ikk$+++44Ws   A	 	B+BBc                     | j                                         }	 t          j        |t          j                   dS # t          $ r,}t          d                    ||                    }||d}~ww xY w)z Terminate the daemon process specified in the current PID file.

            :return: ``None``.
            :raises DaemonRunnerStopFailureError: If terminating the daemon
                fails with an OS error.
            z"Failed to terminate {pid:d}: {exc})rI   rQ   N)	r   read_pidr4   killsignalSIGTERMOSErrorr   r:   )r#   rI   rQ   rR   s       r   _terminate_daemon_processz&DaemonRunner._terminate_daemon_process   s     l##%%	!GC((((( 	! 	! 	!08??S @ * *+ +E S 		!s   < 
A2'A--A2c                    | j                                         s*t          d                    | j                             }|t	          | j                   r| j                                          dS |                                  dS )z Exit the daemon process specified in the current PID file.

            :return: ``None``.
            :raises DaemonRunnerStopFailureError: If the PID file is not
                already locked.
            z$PID file {pidfile.path!r} not lockedr   N)r   	is_lockedr   r:   rJ   rK   rZ   )r#   rR   s     r   _stopzDaemonRunner._stop   s     |%%'' 	0:AA $ B . ./ /E KDL)) 	-L##%%%%%**,,,,,r   c                 V    |                                   |                                  dS )z Stop, then start. N)r]   rS   )r#   s    r   _restartzDaemonRunner._restart   s     

r   )startstoprestartc                     	 | j         | j                 }n8# t          $ r+ t          d                    | j                            }|w xY w|S )ad   Get the function for the specified action.

            :return: The function object corresponding to the specified
                action.
            :raises DaemonRunnerInvalidActionError: if the action is
               unknown.

            The action is specified by the `action` attribute, which is set
            during `parse_args`.
            zUnknown action: {action!r})rF   )r8   rF   KeyErrorr   r:   )r#   funcrR   s      r   _get_action_funczDaemonRunner._get_action_func   sm    	$T[1DD 	 	 	2077#{ 8 , ,- -E K		
 s	    5A
c                 D    |                                  } ||            dS )z Perform the requested action.

            :return: ``None``.

            The action is specified by the `action` attribute, which is set
            during `parse_args`.
            N)rf   )r#   re   s     r   	do_actionzDaemonRunner.do_action   s&     $$&&T




r   N)r
   r   r   r   rO   r$   r   rB   r   rS   rZ   r]   r_   r8   rf   rh   r   r   r   r   r   +   s          /M3 3 3B5 5 5" " "# # # #2  0! ! ! - - -$    L  (	 	 	 	 	r   r   c                     |t           j        }|                    d                    |                      |                                 dS )z@ Emit a message to the specified stream (default `sys.stderr`). Nz
{message}
)rA   )r<   r.   writer:   flush)rA   streams     r   r;   r;      sB    ~
LL%%g%66777
LLNNNNNr   c                 ,   t          | t                    s%t          d                    |                     }|t          j                            |           s%t          d                    |                     }|t          j        | |          }|S )z= Make a PIDLockFile instance with the given filesystem path. zNot a filesystem path: {path!r})r5   zNot an absolute path: {path!r})	
isinstancerE   
ValueErrorr:   r4   r5   isabsr   TimeoutPIDLockFile)r5   acquire_timeoutrR   rL   s       r   r    r       s    dC   <CC D    7== ;BB C    )$@@HOr   c                     d} | j                     }|3	 t          j        |t          j                   n# t
          $ r d}Y nw xY w|S )u    Determine whether a PID file is stale.

        :return: ``True`` iff the PID file is stale; otherwise ``False``.

        The PID file is “stale” if its contents are valid but do not
        match the PID of a currently-running process.
        FNT)rU   r4   rV   rW   SIG_DFLProcessLookupError)r   resultpidfile_pids      r   rJ   rJ     sf     F"'"$$K	GK0000! 	 	 	FFF	 Ms   5 AAri   )r   errnor4   rW   r<   warningsrL    r   daemonr   warnDeprecationWarning	Exceptionr   rp   r   RuntimeErrorr   r   r   r;   r    rJ   r   r   r   <module>r      s      				  



         ! ! ! ! ! ! J  
> > > > >	 > > >F F F F F%6
 F F F7 7 7 7 7$5| 7 7 77 7 7 7 7#4l 7 7 7F F F F F F F FR         r   