
    f"                        U 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
 ddlmZ ddlmZ ddlmZ ddlmZmZ dd	lmZmZ dd
lmZ ddlmZmZ ddlmZmZ dddeegdg e
d       e
d       e
d      gdZee d<    ee      Z  ejB                  e"      Z#dZ$ G d dejJ                        Z& G d de&      Z' G d de&      Z(de)deded e*d!df
d"Z+de,fd#Z-de,d!e,fd$Z.d%e&de,fd&Z/de,de&fd'Z0de,de&fd(Z1y))z9ansible enables running on first boot either ansible-pull    N)deepcopy)dedent)Optional)Cloud)Config)
MetaSchemaget_meta_doc)ALL_DISTROSDistro)PER_INSTANCE)subpwhich)Versionget_cfg_by_path
cc_ansibleAnsiblezConfigure ansible for instanceansiblea          This module provides ``ansible`` integration for
        augmenting cloud-init's configuration of the local
        node.


        This module installs ansible during boot and
        then uses ``ansible-pull`` to run the playbook
        repository at the remote URL.
        z            ansible:
              package_name: ansible-core
              install_method: distro
              pull:
                url: "https://github.com/holmanb/vmboot.git"
                playbook_name: ubuntu.yml
            z            ansible:
              package_name: ansible-core
              install_method: pip
              pull:
                url: "https://github.com/holmanb/vmboot.git"
                playbook_name: ubuntu.yml
            )idnametitle	frequencydistrosactivate_by_schema_keysdescriptionexamplesmetaansible_configc                       e Zd ZdefdZdee   fdZdefdZ	d Z
defdZd	 Zej                  d
        Zej                  defd       Zy)AnsiblePulldistroc                     dg| _         ddg| _        || _        i | _        d | _        t
        j                  j                  dd      | j                  d<   y )Nzansible-pullz	--versionHOMEz/root)cmd_pullcmd_versionr    envrun_userosenvironget)selfr    s     =/usr/lib/python3/dist-packages/cloudinit/config/cc_ansible.py__init__zAnsiblePull.__init__E   sM    '(*K8'+ ::>>&':    returnc                     | j                  | j                        \  }}|j                         j                  d      }t	        j
                  d|      }|r&|j                  d      }t        j                  |      S y )Nr   z	([\d\.]+))	do_asr$   
splitlinespopresearchgroupr   from_str)r*   stdout_
first_linematchesversions         r+   get_versionzAnsiblePull.get_versionP   sh    JJt//0	&&(,,Q/
))L*5mmA&G##G,,r-   c                 J    | j                  g | j                  |      \  }}|S N)r0   r#   )r*   argsr7   r8   s       r+   pullzAnsiblePull.pullY   s(    JJ6667	r-   c                 :    | j                         st        d      y )Nz!command: ansible is not installed)is_installed
ValueErrorr*   s    r+   
check_depszAnsiblePull.check_deps]   s      "@AA #r-   commandc                     | j                   s | j                  |fi |S  | j                  j                  || j                   fi |S r>   )r&   r   r    r0   r*   rF   kwargss      r+   r0   zAnsiblePull.do_asa   sA    }}499W/// t{{  $--B6BBr-   c                 2    t        |fd| j                  i|S )N
update_env)r   r%   rH   s      r+   r   zAnsiblePull.subpf   s    G;;F;;r-   c                      y r>    rD   s    r+   rB   zAnsiblePull.is_installedi       r-   pkg_namec                      y r>   rM   r*   rO   s     r+   installzAnsiblePull.installm   rN   r-   N)__name__
__module____qualname__r   r,   r   r   r<   strr@   rE   listr0   r   abcabstractmethodrB   rR   rM   r-   r+   r   r   D   s    	;v 	;Xg. S BCT C
< 	  	  r-   r   c                   F     e Zd Zdedee   f fdZdefdZdefdZ	 xZ
S )AnsiblePullPipr    userc                     t         |   |       || _        | j                  t        j
                  ddg      \  }}| d}| j                  j                  d      }|r!dj                  ||g      | j                  d<   y || j                  d<   y )Nz-cz('import site; print(site.getuserbase())'z/bin/PATH:)	superr,   r&   r0   sys
executabler%   r)   join)r*   r    r\   	user_baser8   ansible_pathold_path	__class__s          r+   r,   zAnsiblePullPip.__init__s   s      zz^^T#MN
	1 $E*88<<'"xx<(@ADHHV+DHHVr-   rO   c                 *   | j                         s	 ddl}t        j                  dddg}t        j                  j                  t        j                  j                  t        j                  d      d            r|j                  d       | j                  r|j                  d	       | j!                  g |d
d       | j!                  g ||       yy# t        $ r3 | j                  j	                  | j                  j
                  g       Y w xY w)zishould cloud-init grow an interface for non-distro package
        managers? this seems reusable
        r   N-mpiprR   stdlibzEXTERNALLY-MANAGEDz--break-system-packagesz--userz	--upgrade)rB   rj   ImportErrorr    install_packagespip_package_namera   rb   r'   pathexistsrc   	sysconfigget_pathappendr&   r0   )r*   rO   rj   cmds       r+   rR   zAnsiblePullPip.install   s       "M 	C ww~~&&x02F
 

45}}

8$JJ11k1512JJ''h'(+ #  M,,dkk.J.J-KLMs   C 9DDr.   c                 V    | j                  t        j                  dddg      \  }}d|v S )Nri   rj   rW   r   )r0   ra   rb   )r*   r7   r8   s      r+   rB   zAnsiblePullPip.is_installed   s,    JJeVDE	F""r-   )rS   rT   rU   r   r   rV   r,   rR   boolrB   __classcell__)rg   s   @r+   r[   r[   r   s2    ,v ,Xc] ,) )6#d #r-   r[   c                   $    e Zd ZdefdZdefdZy)AnsiblePullDistrorO   c                 ^    | j                         s| j                  j                  |g       y y r>   )rB   r    rm   rQ   s     r+   rR   zAnsiblePullDistro.install   s'      "KK(((4 #r-   r.   c                 *    t        t        d            S )Nr   )rv   r   rD   s    r+   rB   zAnsiblePullDistro.is_installed   s    E)$%%r-   N)rS   rT   rU   rV   rR   rv   rB   rM   r-   r+   ry   ry      s    5 5&d &r-   ry   r   cfgcloudr?   r.   c                 \   |j                  di       }|j                  d      }|j                  d      }|j                  d      }|j                  d      }|j                  d      }	|j                  dd      }
|rt        |       |j                  }|d	k(  rt        ||      }nt	        |      }|j                  |
       |j                          |j                  d
d      }|r||j                  t        <   |rt        ||       |	rt        |t        |	             |rt        ||       y y y )Nr   r&   install_methodsetup_controllergalaxyr@   package_name rj   r   )r)   validate_configr    r[   ry   rR   rE   r%   CFG_OVERRIDEansible_galaxyrun_ansible_pullr   ansible_controller)r   r|   r}   r?   ansible_cfgansible_userr   r   
galaxy_cfgpull_cfgr   r    r   r   s                 r+   handler      s   	2.K??:.L __%56N"'9:*Jv&H??>26L$U"$V\:G'/G%$)92>(6GKK%:w/Whx&89/9 - r-   c                 z   d}|D ]  }t        | |      rt        d| d|         | j                  d      r$dD ]  }t        | |      rt        d| d|         | j                  d      }|r9t        |j                  d      |j                  d      g      st        d	|       | d
   }|dvrt        d      y )N)r   r   zMissing required key 'z' from r@   )zpull/urlzpull/playbook_namer   repositoriesrun_ansiblezMissing required key from r   )rj   r    z Invalid install method {install})r   rC   r)   any)r|   required_keyskeycontroller_cfgrR   s        r+   r   r      s    M  IsC(5cU'#GHHI wwv3 	MC"3, #9#gcU!KLL	M WW/0N"">2""=1
 9.9IJKK"#G'';<< (r-   c                 ~    | j                         D ci c]  \  }}|dur|j                  dd      | c}}S c c}}w )zremove boolean false valuesFr8   -)itemsreplace)r|   r   values      r+   filter_argsr      sF      IIKS% 	Cu$  s   !9r@   c                 
   |j                  d      }| j                         }|st        j                  d       nT|t	        ddd      k  rD|j                  d      r3t        d|j                   d|j                   d|j                   d	       | j                  g t        |      j                         D cg c]  \  }}|d
urd| d| nd|  c}}| }|r!t        j                  j                  |        y y c c}}w )Nplaybook_namezCannot parse ansible version      r   diffzAnsible version .z%doesn't support --diff flag, exiting.T--=)r2   r<   LOGwarningr   r)   rC   majorminorpatchr@   r   r   ra   r7   write)r@   r|   r   vr   r   r7   s          r+   r   r      s   1MA23	
WQ1	776?"177)1QWWIQqwwi78  TYY  *#.446

U #(t"3bQug2cUC


 	F 

F8% 

s   7C?c                     | j                  dg       }|st        j                  d|        |D ]  }|j                  |        y )NactionszInvalid config: %s)r)   r   r   r0   )r|   r   r   rF   s       r+   r   r     s?    ggi$G(#. gr-   c           
      x   | j                  dg       D ]  }|j                  dd|d   |d   g        | j                  dg       D ]m  }|j                  d      }|j                  d      }d	|gt        |      j	                         D cg c]  \  }}d
| d|  c}}}|j                  ||       o y c c}}w )Nr   gitclonesourcero   r   playbook_dirr   zansible-playbookr   r   )cwd)r)   r0   r2   r   r   )	r|   r   
repositoryr?   r   r   r   r   rF   s	            r+   r   r     s    ggnb1 

GZ1:f3EF	

 r* 1xx/1
 4?t3D3J3J3LMZS%3%q M

 	g<01 Ns   	B6
)2__doc__rX   loggingr'   r3   ra   rq   copyr   textwrapr   typingr   cloudinit.cloudr   cloudinit.configr   cloudinit.config.schemar   r	   cloudinit.distrosr
   r   cloudinit.settingsr   cloudinit.subpr   r   cloudinit.utilr   r   r   __annotations__	getLoggerrS   r   r   ABCr   r[   ry   rV   rW   r   dictr   r   r   r   r   rM   r-   r+   <module>r      s]   ? 
  	 	 
     ! # < 1 + & 3 -} ){		 			
 			
')j )V t
g!+#'' +\-#[ -#`& &": ":6 ":% ":t ": ":J= =8T d &; &T &0 { 1D 1; 1r-   