ó
æ”\c           @   s¥   d  d l  m Z d  d l Td d l Z d  d l  m Z d d l m Z d d l j	 Z	 d d l
 Z
 d d l Z d d l Z e j j ƒ  Z d e j f d „  ƒ  YZ d S(	   i   (   t   base(   t   *iÿÿÿÿN(   t
   exceptions(   t   commandst   BootloaderPluginc           B   s  e  Z d  Z d „  Z d „  Z d „  Z e d „  ƒ Z d „  Z d „  Z	 d „  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 „  Z d „  Z d „  Z e d ƒ d „  ƒ Z e d ƒ d „  ƒ Z e d ƒ d „  ƒ Z e d d e d d ƒd  „  ƒ Z e d! d e d d ƒd" „  ƒ Z e d# d e d d ƒd$ „  ƒ Z  d% „  Z! RS(&   sÁ   
	Plugin for tuning bootloader options.

	Currently only grub2 is supported and reboot is required to apply the tunings.
	These tunings are unloaded only on profile change followed by reboot.
	c         O   sP   t  j j t j ƒ s' t j d ƒ ‚ n  t t |  ƒ j	 | | Ž  t
 ƒ  |  _ d  S(   Ns4   Required GRUB2 template not found, disabling plugin.(   t   ost   patht   isfilet   constst   GRUB2_TUNED_TEMPLATE_PATHR   t   NotSupportedPluginExceptiont   superR   t   __init__R   t   _cmd(   t   selft   argst   kwargs(    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyR      s    c         C   sR   t  | _ t | _ t  |  _ t  |  _ d  |  _ d |  _ d |  _	 |  j
 ƒ  |  _ d  S(   Nt    (   t   Falset   _has_dynamic_tuningt   Truet   _has_static_tuningt   update_grub2_cfgt   _initrd_remove_dirt   Nonet   _initrd_dst_img_valt   _cmdline_valt   _initrd_valt   _get_grub2_cfg_filest   _grub2_cfg_file_names(   R   t   instance(    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _instance_init   s    							c         C   s   d  S(   N(    (   R   R   (    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _instance_cleanup'   s    c         C   s.   i d  d 6d  d 6d  d 6d  d 6d  d 6d  d 6S(   Nt   grub2_cfg_filet   initrd_dst_imgt   initrd_add_imgt   initrd_add_dirt   initrd_remove_dirt   cmdline(   R   (   t   cls(    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _get_config_options*   s    c      	   C   s©  |  j  ƒ  j ƒ  } g  } xm | D]e } t | ƒ j d ƒ rJ | j | ƒ q | | k rg | | | | <q t j d | |  j j f ƒ q W| j	 ƒ  d } xå | D]Ý } | | } | d k sŸ | d k rÍ qŸ n  | d } | d j ƒ  } | d k r| d k r| d | 7} qŸ | d k rn| d k rnxQ | j ƒ  D]2 }	 t j |	 ƒ }
 t j d	 |
 d
 d | ƒ } q5WqŸ | d | 7} qŸ W| j ƒ  } | d k r¥| | d <n  | S(   sS   Merge provided options with plugin default options and merge all cmdline.* options.R&   s$   Unknown option '%s' for plugin '%s'.R   i    i   t   +t    t   -s   (\A|\s)s	   (?=\Z|\s)N(   R(   t   copyt   strt
   startswitht   appendt   logt   warnt	   __class__t   __name__t   sortR   t   stript   splitt   ret   escapet   sub(   R   t   optionst	   effectivet   cmdline_keyst   keyR&   t   valt   opt   valst   pt   regex(    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _get_effective_options5   s6    !


$c         C   s@   g  } x3 t  j D]( } t j j | ƒ r | j | ƒ q q W| S(   N(   R   t   GRUB2_CFG_FILESR   R   t   existsR/   (   R   t	   cfg_filest   f(    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyR   U   s
    c         C   s   |  j  j t j | ƒ S(   N(   R   t   add_modify_option_in_fileR   t   BOOT_CMDLINE_FILE(   R   t   d(    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _patch_bootcmdline\   s    c         C   sÁ   |  j  s t j d ƒ d  S|  j i d t j 6d t j 6ƒ xF |  j  D]; } |  j j | i d d t j	 6d d t j
 6d t ƒqE W|  j d  k	 r½ t j d |  j ƒ |  j j |  j ƒ n  d  S(   Ns   cannot find grub.cfg to patchR   s   set\s+t   adds   removing initrd image '%s'(   R   R0   t   infoRK   R   t   BOOT_CMDLINE_TUNED_VARt   BOOT_CMDLINE_INITRD_ADD_VARR   RH   t   GRUB2_TUNED_VARt   GRUB2_TUNED_INITRD_VARR   R   R   t   unlink(   R   RG   (    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _remove_grub2_tuning_   s    	!9c         C   s?   | r; t  j d ƒ |  j ƒ  |  j i d d 6d d 6ƒ n  d  S(   Ns/   removing grub2 tuning previously added by TunedR   t   tuned_paramst   tuned_initrd(   R0   RM   RS   t   _update_grubenv(   R   R   t   full_rollback(    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _instance_unapply_staticj   s    
c         C   sñ   t  j d ƒ t j d t j d d | d t j ƒ} t j d t j d | d t j ƒ} t j d t j d d | d t j ƒ} t j d t j d | d t j ƒ} t j t j d d | d t j ƒ} t j t j	 d d | d t j ƒS(	   Ns   unpatching grub.cfgs
   ^\s*set\s+s   \s*=.*
R   t   flagss    *\$s   \ns   \n+(
   R0   t   debugR7   R9   R   RP   t	   MULTILINERQ   t   GRUB2_TEMPLATE_HEADER_BEGINt   GRUB2_TEMPLATE_HEADER_END(   R   t	   grub2_cfgt   cfg(    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _grub2_cfg_unpatchp   s    )%)%%c         C   sI  t  j d ƒ d t j d } xD | D]< } | d |  j j | ƒ d |  j j | | ƒ d 7} q% W| t j d 7} t j d | | d	 t j	 ƒ} i t j
 d
 6t j d 6} x” | D]Œ } t j d | d d | | | d	 t j	 ƒ} t j d | d | | d d | d	 t j	 ƒ} t j d | d d | d	 t j	 ƒ} qµ W| S(   Ns   initial patching of grub.cfgs   \1\n\ns   
s   set s   ="s   "
s   \ns+   ^(\s*###\s+END\s+[^#]+/00_header\s+### *)\nRY   t   linuxt   initrds   ^(\s*s   (16|efi)?\s+.*)$s   \1 $s   (?:16|efi)?\s+\S+rescue.*)\$s    *(.*)$s   \1\2s   (?:16|efi)?\s+\S+rescue.*) +$s   \1(   R0   RZ   R   R\   R   R8   R]   R7   R9   R[   RP   RQ   (   R   R^   RJ   t   st   optt   d2t   i(    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _grub2_cfg_patch_initialy   s    :.2*c         C   s,  |  j  j t j ƒ } t | ƒ d k r? t j d t j ƒ t Si t j d 6t j	 d 6} t } x“ | D]‹ } t
 j d | d | | d | d t
 j ƒd  k rf t } | d	 d
 k rÄ | d
 7} n  | | d | d | d | | d 7} qf qf W| r(t j d t j ƒ |  j  j t j | ƒ n  t S(   Ni    s   cannot read '%s't   GRUB_CMDLINE_LINUX_DEFAULTt   GRUB_INITRD_OVERLAYs   ^[^#]*\bs
   \s*=.*\\\$s   \b.*$RY   iÿÿÿÿs   
s   ="${s   :+$s    }\$s   "
s   patching '%s'(   R   t	   read_fileR   t   GRUB2_DEFAULT_ENV_FILEt   lenR0   RM   R   RP   RQ   R7   t   searchR[   R   R   RZ   t   write_to_file(   R   t   grub2_default_envRJ   t   writeRf   (    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _grub2_default_env_patch‹   s     51c         C   s²  t  j d ƒ |  j s' t  j d ƒ t Sxz|  j D]o} |  j j | ƒ } t | ƒ d k rp t  j d | ƒ t St  j d | ƒ | } t } x€ | D]x } t j	 d | d d | | d	 | d
 t j
 ƒ\ } } | d k  st j d | | d
 t j
 ƒd  k r” t } q” q” Wt t j d t j | d
 t j
 ƒƒ t t j d t j | d
 t j
 ƒƒ k rit } n  | r|  j |  j | ƒ | ƒ } n  |  j j | | ƒ q1 W|  j ƒ  t S(   Ns   patching grub.cfgs   cannot find grub.cfg to patchi    s   cannot patch %ss+   adding boot command line parameters to '%s's	   \b(set\s+s   \s*=).*$s   \1s   "RY   i   s   \$s   \1"(   R0   RZ   R   RM   R   R   Rj   Rl   R7   t   subnR[   Rm   R   R   t   findallR   RP   RQ   Rg   R`   Rn   Rq   (   R   RJ   RG   R^   t   grub2_cfg_newt   patch_initialRd   t   nsubs(    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _grub2_cfg_patchž   s0    	81%+	
c         C   sR   |  j  i |  j t j 6|  j t j 6ƒ |  j i |  j t j 6|  j t j 6ƒ d  S(   N(	   Rw   R   R   RP   R   RQ   RK   RN   RO   (   R   (    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _grub2_update»   s    'c         C   s   t  j j t j ƒ S(   N(   R   R   RE   R   t   BLS_ENTRIES_PATH(   R   (    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _has_bls¿   s    c         C   sœ   t  j d t | ƒ ƒ g  | j ƒ  D]( \ } } d t | ƒ t | ƒ f ^ q$ } |  j j d d d g | ƒ \ } } | d k r˜ t  j d | ƒ t St S(   Ns   updating grubenv, setting %ss   %s=%ss   grub2-editenvR+   t   seti    s   cannot update grubenv: '%s'(	   R0   RZ   R-   t   itemsR   t   executeR1   R   R   (   R   RJ   t   optiont   valuet   lt   rct   out(    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyRV   Â   s    ;%c         C   s†   |  j  j ƒ  } | d k r t St j d t j ƒ |  j  j t j d g d i | d 6ƒ\ } } | d k r‚ t j d | ƒ t St	 S(   NR   s4   running kernel update hook '%s' to patch BLS entriesRL   t   envt   KERNEL_INSTALL_MACHINE_IDi    s   cannot patch BLS entries: '%s'(
   R   t   get_machine_idR   R0   RZ   R   t   KERNEL_UPDATE_HOOK_FILER}   R1   R   (   R   t
   machine_idR   R‚   (    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _bls_entries_patch_initialË   s    .c         C   sP   t  j d ƒ |  j ƒ  rL |  j i |  j d 6|  j d 6ƒ rL |  j ƒ  rL t St S(   Ns   updating BLSRT   RU   (	   R0   RZ   Rz   RV   R   R   Rˆ   R   R   (   R   (    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _bls_updateÖ   s    #c         C   s=   |  j  d  k r9 t j j t j t j j | ƒ ƒ |  _  n  d  S(   N(   R   R   R   R   t   joinR   t   BOOT_DIRt   basename(   R   t   name(    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _init_initrd_dst_imgÞ   s    c         C   s   t  j j t j ƒ S(   N(   R   R   t   isdirR   t   PETITBOOT_DETECT_DIR(   R   (    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _check_petitbootâ   s    c         C   sé   |  j  ƒ  r t j d ƒ n  t j d |  j ƒ t j j |  j ƒ } |  j j	 | |  j ƒ sa t
 St |  _ |  j j d ƒ j ƒ  } d } t | ƒ } | rÍ t j d d | ƒ } t | ƒ | k  rÍ | } qÍ n  t j j | | ƒ |  _ t S(   Nsk   Detected Petitboot which doesn't support initrd overlays. The initrd overlay will be ignored by bootloader.s   installing initrd image as '%s's   /proc/cmdlinet   /s   ^\s*BOOT_IMAGE=\s*(\S*/).*$s   \1(   R‘   R0   R1   RM   R   R   R   RŒ   R   R,   R   R   R   Rj   t   rstripRl   R7   R9   RŠ   R   (   R   t   imgt   img_namet   curr_cmdlinet   initrd_grubpatht   lcR   (    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _install_initrdå   s     	R!   c         C   s5   | r
 d  S| r1 | d  k	 r1 t | ƒ g |  _ n  d  S(   N(   R   R-   R   (   R   t   enablingR   t   verifyt   ignore_missing(    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _grub2_cfg_file÷   s    R"   c         C   sy   | r
 d  S| ru | d  k	 ru t | ƒ |  _ |  j d k r> t S|  j d d k ru t j j t j |  j ƒ |  _ qu n  d  S(   NR   i    R’   (	   R   R-   R   R   R   R   RŠ   R   R‹   (   R   Rš   R   R›   Rœ   (    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _initrd_dst_imgÿ   s    R%   c         C   s>   | r
 d  S| r: | d  k	 r: |  j j | ƒ d k |  _ n  d  S(   Nt   1(   R   R   t   get_boolR   (   R   Rš   R   R›   Rœ   (    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyR     s    R#   t
   per_devicet   priorityi
   c         C   s_   | r
 d  S| r[ | d  k	 r[ t | ƒ } |  j | ƒ | d k rE t S|  j | ƒ s[ t Sn  d  S(   NR   (   R   R-   RŽ   R   R™   (   R   Rš   R   R›   Rœ   t   src_img(    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _initrd_add_img  s    R$   c   
      C   sv  | r
 d  S| rr| d  k	 rrt | ƒ } |  j | ƒ | d k rE t St j j | ƒ sl t j d | ƒ t St j	 d | ƒ t
 j d d d d ƒ \ } } t j d | ƒ t j | ƒ |  j j d	 | d
 | d t ƒ\ } }	 t j d |	 ƒ | d k r%t j d ƒ |  j j | d t ƒt S|  j | ƒ |  j j | ƒ |  j rrt j	 d | ƒ |  j j | ƒ qrn  d  S(   NR   sF   error: cannot create initrd image, source directory '%s' doesn't exists+   generating initrd image from directory '%s't   prefixs   tuned-bootloader-t   suffixs   .tmps+   writing initrd image to temporary file '%s's   find . | cpio -co > %st   cwdt   shells   cpio log: %si    s   error generating initrd imaget   no_errors   removing directory '%s'(   R   R-   RŽ   R   R   R   R   R0   t   errorRM   t   tempfilet   mkstempRZ   t   closeR   R}   R   RR   R™   R   t   rmtree(
   R   Rš   R   R›   Rœ   t   src_dirt   fdt   tmpfileR   R‚   (    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _initrd_add_dir   s2    (	R&   c   
      C   s  |  j  j |  j j | ƒ ƒ } | rß |  j j d ƒ } t | ƒ d k rL d  St | j ƒ  ƒ } t | j ƒ  ƒ } | j	 | ƒ }	 |	 | k r¯ t
 j t j d t | ƒ f ƒ t St
 j t j d t |	 ƒ t | ƒ f ƒ t Sn  | r| d  k	 rt
 j d ƒ t |  _ | |  _ n  d  S(   Ns   /proc/cmdlinei    R&   s;   installing additional boot command line parameters to grub2(   t
   _variablest   expandR   t   unquoteRj   Rl   R   R{   R6   t   intersectionR0   RM   R   t   STR_VERIFY_PROFILE_VALUE_OKR-   R   Rª   t   STR_VERIFY_PROFILE_VALUE_FAILR   R   R   (
   R   Rš   R   R›   Rœ   t   vR&   t   cmdline_sett	   value_sett   cmdline_intersect(    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _cmdline>  s"     )	c         C   s3   | r/ |  j  r/ |  j ƒ  |  j ƒ  t |  _  n  d  S(   N(   R   Rx   R‰   R   (   R   R   Rš   (    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   _instance_post_staticS  s    

("   R3   t
   __module__t   __doc__R   R   R    t   classmethodR(   RC   R   RK   RS   R   RX   R`   Rg   Rq   Rw   Rx   Rz   RV   Rˆ   R‰   RŽ   R‘   R™   t   command_customR   Rž   R   R¤   R²   R½   R¾   (    (    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyR      s:   				 																	!!!(   R   R    t
   decoratorst
   tuned.logst   tunedR   t   tuned.utils.commandsR   t   tuned.constsR   R   R7   R«   t   logst   getR0   t   PluginR   (    (    (    sC   /usr/lib/python2.7/site-packages/tuned/plugins/plugin_bootloader.pyt   <module>   s   
