
­­­­­­­­­­­­­­­­­­
<!DOCTYPE html>
<html>
3
\me"              
   @   s  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eZ ej e!Z"dZ#G dd dej$Z%G dd de%Z&G dd de%Z'e(eee)ddddZ*e+dd d!Z,e+e+d"d#d$Z-e%e+d%d&d'Z.e+e%d(d)d*Z/e+e%d(d+d,Z0dS )-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_pathZ
cc_ansibleZ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titleZ	frequencyZdistrosZactivate_by_schema_keysdescriptionZexamplesansible_configc               @   sz   e Zd ZedddZee dddZedddZ	d	d
 Z
edddZdd Zejdd ZejedddZdS )AnsiblePull)distroc             C   s>   dg| _ ddg| _|| _tj| _d | _| jjdd| jd< d S )Nzansible-pullz	--versionHOMEz/root)cmd_pullcmd_versionr   osenvironenvrun_userget)selfr    r!    /usr/lib/python3.6/cc_ansible.py__init__E   s    
zAnsiblePull.__init__)returnc             C   sF   | j | j\}}|j jd}tjd|}|rB|jd}tj|S d S )Nr   z	([\d\.]+))	do_asr   
splitlinespopresearchgroupr   Zfrom_str)r    stdout_Z
first_lineZmatchesversionr!   r!   r"   get_versionP   s    

zAnsiblePull.get_versionc             G   s   | j | j|\}}|S )N)r%   r   )r    argsr+   r,   r!   r!   r"   pullY   s    zAnsiblePull.pullc             C   s   | j  stdd S )Nz!command: ansible is not installed)is_installed
ValueError)r    r!   r!   r"   
check_deps]   s    zAnsiblePull.check_deps)commandc             K   s(   | j s| j|f|S | jj|| j f|S )N)r   r   r   r%   )r    r4   kwargsr!   r!   r"   r%   a   s    zAnsiblePull.do_asc             K   s   t |fd| ji|S )Nr   )r   r   )r    r4   r5   r!   r!   r"   r   f   s    zAnsiblePull.subpc             C   s   d S )Nr!   )r    r!   r!   r"   r1   i   s    zAnsiblePull.is_installed)pkg_namec             C   s   d S )Nr!   )r    r6   r!   r!   r"   installm   s    zAnsiblePull.installN)__name__
__module____qualname__r
   r#   r   r   r.   strr0   r3   listr%   r   abcabstractmethodr1   r7   r!   r!   r!   r"   r   D   s   	r   c                   sD   e Zd Zeee d fddZedddZeddd	Z	  Z
S )
AnsiblePullPip)r   userc                sf   t  j| || _| jtjddg\}}| d}| jjd}|rXdj||g| jd< n
|| jd< d S )Nz-cz('import site; print(site.getuserbase())'z/bin/PATH:)	superr#   r   r%   sys
executabler   r   join)r    r   r@   	user_baser,   Zansible_pathZold_path)	__class__r!   r"   r#   s   s    
zAnsiblePullPip.__init__)r6   c             C   s   | j  syddl}W n& tk
r:   | jj| jjg Y nX tjdddg}tj	j
tj	jtjddrp|jd | jr|jd	 | j|d | j||f dS )zishould cloud-init grow an interface for non-distro package
        managers? this seems reusable
        r   Nz-mpipr7   stdlibzEXTERNALLY-MANAGEDz--break-system-packagesz--user	--upgrade)rK   rI   )r1   rI   ImportErrorr   install_packagesZpip_package_namerD   rE   r   pathexistsrF   	sysconfigget_pathappendr   r%   )r    r6   rI   cmdr!   r!   r"   r7      s"    

zAnsiblePullPip.install)r$   c             C   s    | j tjdddg\}}d|kS )Nz-mrI   r<   r   )r%   rD   rE   )r    r+   r,   r!   r!   r"   r1      s    zAnsiblePullPip.is_installed)r8   r9   r:   r
   r   r;   r#   r7   boolr1   __classcell__r!   r!   )rH   r"   r?   r   s   r?   c               @   s(   e Zd ZedddZedddZdS )AnsiblePullDistro)r6   c             C   s   | j  s| jj|g d S )N)r1   r   rM   )r    r6   r!   r!   r"   r7      s    zAnsiblePullDistro.install)r$   c             C   s   t tdS )Nr   )rT   r   )r    r!   r!   r"   r1      s    zAnsiblePullDistro.is_installedN)r8   r9   r:   r;   r7   rT   r1   r!   r!   r!   r"   rV      s   rV   )r   cfgcloudr/   r$   c             C   s   |j di }|j d}|j d}|j d}|j d}|j d}	|j dd}
|rt| |j}|d	krpt||}nt|}|j|
 |j  |j d
d}|r||jt< |rt	|| |	rt
|t|	 |rt|| d S )Nr   r   install_methodsetup_controllerZgalaxyr0   package_name rI   r   )r   validate_configr   r?   rV   r7   r3   r   CFG_OVERRIDEansible_galaxyrun_ansible_pullr   ansible_controller)r   rW   rX   r/   Zansible_cfgZansible_userrY   rZ   Z
galaxy_cfgZpull_cfgr[   r   r   r   r!   r!   r"   handle   s0    







rb   )rW   c             C   s   d}x*|D ]"}t | |s
td| d|  q
W | jdrfx*dD ]"}t | |s@td| d|  q@W | jd}|rt|jd	|jd
gstd| | d }|dkrtdd S )NrY   r[   zMissing required key 'z' from r0   pull/urlpull/playbook_namerZ   repositoriesrun_ansiblezMissing required key from rI   r   z Invalid install method {install})rY   r[   )rc   rd   )rI   r   )r   r2   r   any)rW   Zrequired_keyskeyZcontroller_cfgr7   r!   r!   r"   r]      s$     





r]   )rW   r$   c             C   s   dd | j  D S )zremove boolean false valuesc             S   s&   i | ]\}}|d k	r||j ddqS )Fr,   -)replace).0rh   valuer!   r!   r"   
<dictcomp>   s   zfilter_args.<locals>.<dictcomp>)items)rW   r!   r!   r"   filter_args   s    ro   )r0   rW   c             C   s   |j d}| j }|s"tjd n<|tdddk r^|jdr^td|j d|j d|j	 d	| j
d
d t|j D |f }|rtjj|  d S )Nplaybook_namezCannot parse ansible version      r   ZdiffzAnsible version .z%doesn't support --diff flag, exiting.c             S   s2   g | ]*\}}|d k	r$d| d| nd| qS )Tz--=r!   )rk   rh   rl   r!   r!   r"   
<listcomp>  s   z$run_ansible_pull.<locals>.<listcomp>)r'   r.   LOGwarningr   r   r2   majorminorZpatchr0   ro   rn   rD   r+   write)r0   rW   rp   vr+   r!   r!   r"   r`      s    

 
r`   )rW   r   c             C   s8   | j dg }|stjd|  x|D ]}|j| q"W d S )NactionszInvalid config: %s)r   rv   rw   r%   )rW   r   r|   r4   r!   r!   r"   r_     s
    
r_   c             C   s   x.| j dg D ]}|jdd|d |d g qW xT| j dg D ]D}|jd}|jd}d	|fd
d t|j D }|j||d q>W d S )Nre   ZgitZclonesourcerN   rf   playbook_dirrp   zansible-playbookc             S   s    g | ]\}}d | d| qS )z--rt   r!   )rk   rh   rl   r!   r!   r"   ru   !  s    z&ansible_controller.<locals>.<listcomp>)cwd)r   r%   r'   ro   rn   )rW   r   Z
repositoryr/   r~   rp   r4   r!   r!   r"   ra     s    

ra   )1__doc__r=   Zloggingr   r(   rD   rP   copyr   textwrapr   Ztypingr   Zcloudinit.cloudr   Zcloudinit.configr   Zcloudinit.config.schemar   r   Zcloudinit.distrosr	   r
   Zcloudinit.settingsr   Zcloudinit.subpr   r   Zcloudinit.utilr   r   metaZ	getLoggerr8   rv   r^   ABCr   r?   rV   r;   r<   rb   dictr]   ro   r`   r_   ra   r!   r!   r!   r"   <module>   sP   

.0	%		