
Tc           @   s  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 Z d  d l m Z m	 Z	 d  d l
 m Z d  d l m Z m Z m Z m Z m Z m Z m Z d  d l m Z d  d l m Z d  d l m Z d  d l m Z m Z m Z m Z d  d	 l m  Z  d  d
 l! m" Z" d  d l# m$ Z$ d e% f d     YZ& d e f d     YZ' d e( f d     YZ) d e f d     YZ* d   Z+ d   Z, d S(   iN(   t   maybeDeferredt   succeed(   t   reactor(   t   SUCCESS_RESULTt   ERROR_RESULTt   DEPENDENCY_ERROR_RESULTt   POLICY_STRICTt   POLICY_ALLOW_INSTALLSt   POLICY_ALLOW_ALL_CHANGESt   UNKNOWN_PACKAGE_DATA_TIMEOUT(   t   create_file(   t   log_failure(   t   find_reporter_command(   t   PackageTaskHandlert   PackageTaskHandlerConfigurationt   PackageTaskErrort   run_task_handler(   t   FAILED(   t   ShutdownProcessProtocol(   t   REBOOT_REQUIRED_FILENAMEt   UnknownPackageDatac           B   s   e  Z d  Z RS(   s(   Raised when an ID or a hash isn't known.(   t   __name__t
   __module__t   __doc__(    (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR      s   t   PackageChangerConfigurationc           B   s   e  Z d  Z e d    Z RS(   s<   Specialized configuration for the Landscape package-changer.c         C   s   t  j j |  j d  S(   s@   The path to the directory we store server-generated packages in.t   binaries(   t   ost   patht   joint   package_directory(   t   self(    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyt   binaries_path#   s    (   R   R   R   t   propertyR   (    (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR       s   t   ChangePackagesResultc           B   s   e  Z d  Z d   Z RS(   s  Value object to hold the results of change packages operation.

    @ivar code: The result code of the requested changes.
    @ivar text: The output from Apt.
    @ivar installs: Possible additional packages that need to be installed
        in order to fulfill the request.
    @ivar removals: Possible additional packages that need to be removed
        in order to fulfill the request.
    c         C   s(   d  |  _ d  |  _ g  |  _ g  |  _ d  S(   N(   t   Nonet   codet   textt   installst   removals(   R   (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyt   __init__4   s    			(   R   R   R   R'   (    (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR!   )   s   	t   PackageChangerc           B   s   e  Z d  Z e Z d Z e d e d  Z	 d   Z
 d   Z d   Z d   Z d   Z d   Z d d	  Z e d d d d e d
  Z d   Z d   Z d   Z d   Z d   Z d   Z e d  Z d   Z e d    Z RS(   s%   Install, remove and upgrade packages.t   changerc   	      C   si   t  t |   j | | | |  | |  _ | d  k rS d d l m } |   |  _ n	 | |  _ | |  _ d  S(   Ni(   t   LandscapeReactor(	   t   superR(   R'   t   _process_factoryR"   t   landscape.reactorR*   t   _landscape_reactort   reboot_required_filename(	   R   t   storet   facadet   remotet   configt   process_factoryt   landscape_reactorR/   R*   (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR'   B   s    		c            su     j    s# t j d  t d  S  j   } | j   f d    | j   f d    | j   f d    | S(   sV   
        Handle our tasks and spawn the reporter if package data has changed.
        s-   The package-reporter hasn't run yet, exiting.c            s
     j    S(   N(   t   get_session_id(   t   x(   R   (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyt   <lambda>W   s    c            s
     j    S(   N(   t   handle_tasks(   R7   (   R   (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR8   X   s    c            s
     j    S(   N(   t   run_package_reporter(   R7   (   R   (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR8   Y   s    N(   t   update_stamp_existst   loggingt   warningR   R"   t   use_hash_id_dbt   addCallback(   R   t   result(    (   R   s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyt   runN   s    
c         C   s   |  j  d k r d St j   d k rZ t j t j d  j  t j t j	 d  j
  n  t   } |  j j d k	 r | d |  j j 7} n  t j |  d S(   sX   
        Run the L{PackageReporter} if there were successfully completed tasks.
        i    Nt	   landscapes    -c %s(   t   handled_tasks_countR   t   getuidt   setgidt   grpt   getgrnamt   gr_gidt   setuidt   pwdt   getpwnamt   pw_uidR   t   _configR3   R"   t   system(   R   t   command(    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR:   \   s    	c         C   s_   | j  } | d d k r> t |  j |  } | j |  j |  S| d d k r[ |  j |  Sd S(   sl   
        @param task: A L{PackageTask} carrying a message of
            type C{"change-packages"}.
        t   types   change-packagess   change-package-locksN(   t   dataR    t   handle_change_packagest
   addErrbackt   unknown_package_data_errort   handle_change_package_locks(   R   t   taskt   messageR@   (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyt   handle_taskl   s    	c         C   s   | j  t  t j d | j j d  | j t j   t k  r i d d 6| j	 d d 6t
 d 6d d 6} |  j j | |  j  St    d	 S(
   s}  Handle L{UnknownPackageData} data errors.

        If the task is older than L{UNKNOWN_PACKAGE_DATA_TIMEOUT} seconds,
        a message is sent to the server to notify the failure of the associated
        activity and the task will be removed from the queue.

        Otherwise a L{PackageTaskError} is raised and the task will be picked
        up again at the next run.
        s2   Package data not yet synchronized with server (%r)i    s   change-packages-resultRP   s   operation-ids   result-codes5   Package data has changed. Please retry the operation.s   result-textN(   t   trapR   R<   R=   t   valuet   argst	   timestampt   timeR	   RQ   R   t   _brokert   send_messaget   _session_idR   (   R   t   failureRV   RW   (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyRT   x   s    
	

c         C   s+   t  j j |  j j  p* t  j j |  j  S(   sT   
        Return a boolean indicating if the update-stamp stamp file exists.
        (   R   R   t   existsRM   t   update_stamp_filenamet   update_notifier_stamp(   R   (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR;      s    c         C   sS   |  j  j } x3 t j |  D]" } t j t j j | |   q W|  j j   d S(   s/   Remove any binaries and its associated channel.N(	   RM   R   R   t   listdirt   removeR   R   t   _facadet   clear_channels(   R   R   t   existing_deb_path(    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyt   _clear_binaries   s     c         C   s   |  j  j } |  j   | r i  } xJ | D]B \ } } } t t j j | d |  t j |   | | | <q) W|  j	 j
 |  |  j j |  |  j j d t  n  |  j j   d S(   s  Initialize the Apt channels as needed.

        @param binaries: A possibly empty list of 3-tuples of the form
            (hash, id, deb), holding the hash, the id and the content of
            additional Debian packages that should be loaded in the channels.
        s   %d.debt   force_reload_binariesN(   RM   R   Rj   R
   R   R   R   t   base64t   decodestringt   _storet   set_hash_idsRg   t   add_channel_deb_dirt   reload_channelst   Truet   ensure_channels_reloaded(   R   R   R   t   hash_idst   hasht   idt   deb(    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyt   init_channels   s    
c         C   s   | r |  j  j   n  | r, |  j  j   n  x |  j  j | f |  j  j | f |  j  j | f |  j  j | f g D] \ } } xr | D]j }	 |  j j |	  }
 |
 d k r t
 |	   n  |  j  j |
  } | d k r t
 |
   n  | |  q Wqo Wd S(   s  Mark packages for upgrade, installation or removal.

        @param upgrade: If C{True} mark all installed packages for upgrade.
        @param install: A list of package ids to be marked for installation.
        @param remove: A list of package ids to be marked for removal.
        @param hold: A list of package ids to be marked for holding.
        @param remove_hold: A list of package ids to be marked to have a hold
                            removed.
        @param reset: If C{True} all existing marks will be reset.
        N(   Rg   t   reset_markst   mark_global_upgradet   mark_installt   mark_removet	   mark_holdt   mark_remove_holdRn   t   get_id_hashR"   R   t   get_package_by_hash(   R   t   upgradet   installRf   t   holdt   remove_holdt   resett   mark_functiont   mark_idst   mark_idRu   t   package(    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyt   mark_packages   s"    c   
      C   s}  d d l  m } m } t   } d } xQ| j d k rx| d 7} y |  j j   | _ Wn| k
 r } t	 | _ | j
 d | _ q( | k
 rk} x | j D]z } |  j j |  } |  j j |  }	 |	 d k r t |   n  |  j j |  r| j j |	  q | j j |	  q W| d k r_|  j | |  r_|  j d | j d | j d t  qut | _ q( Xt | _ q( W| S(	   st  Perform the requested changes.

        @param policy: A value indicating what to do in case additional changes
            beside the ones explicitly requested are needed in order to fulfill
            the request (see L{complement_changes}).
        @return: A L{ChangePackagesResult} holding the details about the
            outcome of the requested changes.
        i(   t   DependencyErrort   TransactionErrori    i   R   Rf   R   N(   t   landscape.package.facadeR   R   R!   R#   R"   Rg   t   perform_changesR$   R   R[   t   packagest   get_package_hashRn   t   get_hash_idR   t   is_package_installedR&   t   appendR%   t   may_complement_changesR   t   FalseR   R   (
   R   t   policyR   R   R@   t   countt	   exceptionR   Ru   Rv   (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyt   change_packages   s2    	
	c         C   s:   | t  k r t S| t k r6 | j r6 | j r6 t Sn  t S(   sa  Decide whether or not we should complement the given changes.

        @param result: A L{PackagesResultObject} holding the details about the
            missing dependencies needed to complement the given changes.
        @param policy: It can be one of the following values:
            - L{POLICY_STRICT}, no additional packages will be marked.
            - L{POLICY_ALLOW_INSTALLS}, if only additional installs are missing
                they will be marked for installation.
        @return: A boolean indicating whether the given policy allows to
            complement the changes and retry.
        (   R   Rr   R   R%   R&   R   (   R   R@   R   (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR     s    c         C   s  |  j  | j d d   |  j d | j d t  d | j d d  d | j d d  d | j d d  d | j d d   |  j | j d	 t   } |  j   | j d
  o t j j	 |  j
  } | } |  j d | | d | } | r | j |  j  n  | S(   s$   Handle a C{change-packages} message.R   R   s   upgrade-allR   Rf   R   R   s   remove-holdR   s   reboot-if-necessaryt   stop_exchanger(    (    (    (    (    N(   Rx   t   getR   R   R   R   Rj   R   R   Rb   R/   t   _send_responseR"   R?   t   _reboot_later(   R   RW   R@   t   needs_rebootR   t   deferred(    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyRR     s     
	
c         C   s   |  j  j d |  j  d  S(   Ni   (   R.   t
   call_latert   _run_reboot(   R   R@   (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR   :  s    c         C   sz   t    } d } | j |  j  | j j |  j |  | j j t d  d d | d g } |  j j	 | d d | | j S(   sU   
        Create a C{ShutdownProcessProtocol} and return its result deferred.
        t   nows   Reboot failed.s   /sbin/shutdowns   -rs!   Landscape is rebooting the systemR[   (
   R   t   set_timeoutR.   R@   R?   t   _log_rebootRS   R   R,   t   spawnProcess(   R   t   protocolt   minutesR[   (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR   =  s    				c         C   s   t  j d |  d S(   s   Log the reboot.s/   Landscape is rebooting the system in %s minutesN(   R<   R=   (   R   R@   R   (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR   L  s    c            s   i d d 6| j  d  d 6} | j | d <| j rC | j | d <n  | j rb t | j  | d <n  | j r t | j  | d <n  t j d    j j	 |   j
 t  } | r t j d	  | j   f d
    n  | S(   s?   
        Create a response and dispatch to the broker.
        s   change-packages-resultRP   s   operation-ids   result-codes   result-texts   must-installs   must-removesB   Queuing response with change package results to exchange urgently.s*   stopping exchanger due to imminent reboot.c            s     j  j   S(   N(   R^   R   (   t   _(   R   (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR8   g  s    (   R   R#   R$   R%   t   sortedR&   R<   t   infoR^   R_   R`   Rr   R?   (   R   t   reboot_resultRW   t   package_change_resultR   t   responseR   (    (   R   s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR   Q  s    
			c         C   sK   i d d 6| j  d  d 6t d 6d d 6d d 6} |  j j | |  j t  S(	   sc   Handle a C{change-package-locks} message.

        Package locks aren't supported anymore.
        s   operation-resultRP   s   operation-idt   statuss*   This client doesn't support package locks.s   result-texti   s   result-code(   R   R   R^   R_   R`   Rr   (   R   RW   R   (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyRU   j  s    
c           C   s   t    S(   N(   t   find_changer_command(    (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyt   find_commandx  s    N(    (    (    (    (    (   R   R   R   R   t   config_factoryt
   queue_nameR   R"   R   R'   RA   R:   RX   RT   R;   Rj   Rx   R   Rr   R   R   R   RR   R   R   R   R   RU   t   staticmethodR   (    (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR(   ;   s0   
									/						c          C   s8   t  j j t  j j t j d   }  t  j j |  d  S(   Ni    s   landscape-package-changer(   R   R   t   dirnamet   abspatht   syst   argvR   (   R   (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR   }  s    %c         C   s2   t  j   t  j   k r% t  j   n  t t |   S(   N(   R   t   getpgrpt   getpidt   setsidR   R(   (   R[   (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyt   main  s    (-   R<   Rl   R]   R   R   RJ   RF   t   twisted.internet.deferR    R   t   twisted.internetR   t   landscape.constantsR   R   R   R   R   R   R	   t   landscape.lib.fsR
   t   landscape.lib.logR   t   landscape.package.reporterR   t   landscape.package.taskhandlerR   R   R   R   t   landscape.manager.managerR   t!   landscape.manager.shutdownmanagerR   t    landscape.monitor.rebootrequiredR   t	   ExceptionR   R   t   objectR!   R(   R   R   (    (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyt   <module>   s.   4"	 C	