ó
½-'Nc           @   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 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 m Z m Z 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(   iÿÿÿÿN(   t   maybeDeferredt   succeed(   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   find_reporter_command(   t   PackageTaskHandlert   PackageTaskHandlerConfigurationt   PackageTaskErrort   run_task_handler(   t	   SUCCEEDEDt   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 Smart.
    @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__0   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 d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d d „ Z e d d e d „ Z d	 „  Z d
 „  Z d „  Z d „  Z e d „  ƒ Z RS(   s%   Install, remove and upgrade packages.t   changerc            s_   ˆ  j  ƒ  s# t j d ƒ t d ƒ Sˆ  j ƒ  } | 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   handle_tasks(   t   x(   R   (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyt   <lambda>G   s    c            s
   ˆ  j  ƒ  S(   N(   t   run_package_reporter(   R'   (   R   (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR(   H   s    N(   t   smart_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   run>   s    
c         C   sª   |  j  d k r d S|  j j ƒ  t j ƒ  d k rg 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_countt   _facadet   deinitR   t   getuidt   setgidt   grpt   getgrnamt   gr_gidt   setuidt   pwdt   getpwnamt   pw_uidR
   t   _configt   configR   t   system(   R   t   command(    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR)   K   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_task_   s    	c         C   s‡   | j  t ƒ t j d | j j d ƒ | j t j ƒ  t k  rz i d d 6| j	 d d 6t
 d 6d d 6} |  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-resultRB   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   RC   R   t   _brokert   send_messageR   (   R   t   failureRH   RI   (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyRF   k   s    
	

c         C   s   t  j j |  j j ƒ S(   sT   
        Return a boolean indicating if the smart-update stamp file exists.
        (   R   R   t   existsR>   t   smart_update_stamp_filename(   R   (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR*   ‚   s    c         C   sÏ   |  j  j } x3 t j | ƒ D]" } t j t j j | | ƒ ƒ q W| r¾ i  } xJ | D]B \ } } } t t j j | d | ƒ t j	 | ƒ ƒ | | | <qU W|  j
 j | ƒ |  j j | ƒ n  |  j j ƒ  d S(   s  Initialize the Smart 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.debN(   R>   R   R   t   listdirt   removeR   R   R	   t   base64t   decodestringt   _storet   set_hash_idsR3   t   add_channel_deb_dirt   ensure_channels_reloaded(   R   R   R   t   existing_deb_patht   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  | rU x6 |  j  j ƒ  D]" } | j r, |  j  j | ƒ q, q, Wn  x§ | |  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 Wqz 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 reset: If C{True} all existing marks will be reset.
        N(   R3   t   reset_markst   get_packagest	   installedt   mark_upgradet   mark_installt   mark_removeRY   t   get_id_hashR   R   t   get_package_by_hash(
   R   t   upgradet   installRV   t   resett   packaget   idst	   mark_funcR`   R_   (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyt   mark_packages    s     	c         C   s€  d d l  m } m } m } t ƒ  } d } xN| j d k r{| d 7} y |  j j ƒ  | _	 Wn| | f k
 r‘ } t
 | _ | j d | _	 q. | k
 rn} x| | j D]q } |  j j | ƒ }	 |  j j |	 ƒ }
 |
 d k rï t |	 ƒ ‚ n  | j r| j j |
 ƒ qª | j j |
 ƒ qª W| d k rb|  j | | ƒ rb|  j d | j d | j d t ƒ qx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   TransactionErrort
   SmartErrori    i   Rl   RV   Rm   N(   t   landscape.package.facadeRr   Rs   Rt   R   R   R   R3   t   perform_changesR    R   RM   t   packagest   get_package_hashRY   t   get_hash_idR   Re   R"   t   appendR!   t   may_complement_changesRq   t   FalseR   R   (   R   t   policyRr   Rs   Rt   R/   t   countt	   exceptionRn   R_   R`   (    (    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   t   TrueR   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 | j d t ƒ | j d d ƒ | j d d ƒ ƒ |  j | j d t ƒ ƒ } i d d 6| j d ƒ d 6} | j | d	 <| j r® | j | d
 <n  | j rÍ t	 | j ƒ | d <n  | j
 rì t	 | j
 ƒ | d <n  t j d ƒ |  j j | t ƒ S(   s$   Handle a C{change-packages} message.R   s   upgrade-allRl   RV   R}   s   change-packages-resultRB   s   operation-ids   result-codes   result-texts   must-installs   must-removesB   Queuing response with change package results to exchange urgently.(    (    (    (   Rb   t   getRq   R|   R€   R   R   R    R!   t   sortedR"   R+   t   infoRP   RQ   R   (   R   RI   R/   t   response(    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyRD   þ   s     
			c         C   s¹   x* | j  d d ƒ D] } |  j j | Œ  q Wx* | j  d d ƒ D] } |  j j | Œ  q@ W|  j j ƒ  i d d 6| j  d ƒ d 6t d 6d d 6d	 d
 6} t j d ƒ |  j j	 | t
 ƒ S(   s   Handle a C{change-package-locks} message.

        Create and delete package locks as requested by the given C{message}.
        t   createt   deletes   operation-resultRB   s   operation-idt   statuss#   Package locks successfully changed.s   result-texti    s   result-codesG   Queuing message with change package locks results to exchange urgently.(    (    (   R‚   R3   t   set_package_lockt   remove_package_lockt   save_configR   R+   R„   RP   RQ   R   (   R   RI   t   lockR…   (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyRG     s    

c           C   s   t  ƒ  S(   N(   t   find_changer_command(    (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyt   find_command.  s    (    (    (    (   R   R   R   R   t   config_factoryt
   queue_nameR0   R)   RJ   RF   R*   Rb   R|   R   Rq   R€   R{   RD   RG   t   staticmethodRŽ   (    (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyR$   7   s   						0			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   3  s    %c         C   s2   t  j ƒ  t  j ƒ  k r% t  j ƒ  n  t t |  ƒ S(   N(   R   t   getpgrpt   getpidt   setsidR   R$   (   RM   (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyt   main8  s    (%   R+   RW   RO   R”   R   R;   R7   t   twisted.internet.deferR    R   t   landscape.constantsR   R   R   R   R   R   R   t   landscape.lib.fsR	   t   landscape.package.reporterR
   t   landscape.package.taskhandlerR   R   R   R   t   landscape.manager.managerR   t	   ExceptionR   R   t   objectR   R$   R   R™   (    (    (    s=   /usr/lib/python2.7/dist-packages/landscape/package/changer.pyt   <module>   s$   4"	ü	