o
    f                  
   @   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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 ddlmZ deegdgdZeed< eeZdZ G dd dej!Z"G dd de"Z#G dd de"Z$de%dedede&ddf
ddZ'de(fddZ)de(de(fd d!Z*d"e"de(fd#d$Z+de(de"fd%d&Z,de(de"fd'd(Z-dS ))z9ansible enables running on first boot either ansible-pull    N)deepcopy)Optional)	lifecyclesubp)Cloud)Config)
MetaSchema)ALL_DISTROSDistro)PER_INSTANCE)get_cfg_by_path
cc_ansibleansible)id	frequencydistrosactivate_by_schema_keysmetaansible_configc                   @   s|   e Zd ZdefddZdeej fddZde	fddZ
d	d
 ZdefddZdd Zejdd Zejde	fddZdS )AnsiblePulldistroc                 C   s<   dg| _ ddg| _|| _i | _d | _tjdd| jd< d S )Nzansible-pullz	--versionHOMEz/root)cmd_pullcmd_versionr   envrun_userosenvironget)selfr    r    =/usr/lib/python3/dist-packages/cloudinit/config/cc_ansible.py__init__    s   
zAnsiblePull.__init__returnc                 C   sH   |  | j\}}| d}td|}|r"|d}tj	|S d S )Nr   z	([\d\.]+))
do_asr   
splitlinespopresearchgroupr   Versionfrom_str)r   stdout_
first_linematchesversionr    r    r!   get_version+   s   
zAnsiblePull.get_versionc                 G   s   |  g | j|\}}|S N)r$   r   )r   argsr,   r-   r    r    r!   pull4   s   zAnsiblePull.pullc                 C   s   |   stdd S )Nz!command: ansible is not installed)is_installed
ValueErrorr   r    r    r!   
check_deps8   s   zAnsiblePull.check_depscommandc                 K   s0   | j s| j|fi |S | jj|| j fi |S r2   )r   r   r   r$   r   r9   kwargsr    r    r!   r$   <   s   zAnsiblePull.do_asc                 K   s   t j |fd| ji|S )N
update_env)r   r   r:   r    r    r!   r   A   s   zAnsiblePull.subpc                 C      d S r2   r    r7   r    r    r!   r5   D      zAnsiblePull.is_installedpkg_namec                 C   r=   r2   r    r   r?   r    r    r!   installH   r>   zAnsiblePull.installN)__name__
__module____qualname__r
   r"   r   r   r*   r1   strr4   r8   listr$   r   abcabstractmethodr5   rA   r    r    r    r!   r      s    	
r   c                       sF   e Zd Zdedee f fddZdefddZdefd	d
Z	  Z
S )AnsiblePullPipr   userc                    sh   t  | || _| tjddg\}}| d}| jd}|r-d||g| jd< d S || jd< d S )Nz-cz('import site; print(site.getuserbase())'z/bin/PATH:)	superr"   r   r$   sys
executabler   r   join)r   r   rJ   	user_baser-   ansible_pathold_path	__class__r    r!   r"   N   s   

zAnsiblePullPip.__init__r?   c                 C   s   |   sUzddl}W n ty   | j| jjg Y nw tjdddg}tj	
tj	tddr7|d | jr?|d	 | g |d
d | g || dS dS )zishould cloud-init grow an interface for non-distro package
        managers? this seems reusable
        r   N-mpiprA   stdlibzEXTERNALLY-MANAGEDz--break-system-packagesz--userz	--upgrade)r5   rW   ImportErrorr   install_packagespip_package_namerN   rO   r   pathexistsrP   	sysconfigget_pathappendr   r$   )r   r?   rW   cmdr    r    r!   rA   ]   s,   


zAnsiblePullPip.installr#   c                 C   s    |  tjdddg\}}d|v S )NrV   rW   rF   r   )r$   rN   rO   )r   r,   r-   r    r    r!   r5   x   s   zAnsiblePullPip.is_installed)rB   rC   rD   r
   r   rE   r"   rA   boolr5   __classcell__r    r    rT   r!   rI   M   s    rI   c                   @   s(   e Zd ZdefddZdefddZdS )AnsiblePullDistror?   c                 C   s   |   s| j|g d S d S r2   )r5   r   rZ   r@   r    r    r!   rA   ~   s   zAnsiblePullDistro.installr#   c                 C   s   t tdS )Nr   )rb   r   whichr7   r    r    r!   r5      s   zAnsiblePullDistro.is_installedN)rB   rC   rD   rE   rA   rb   r5   r    r    r    r!   rd   }   s    rd   namecfgcloudr3   r#   c                 C   s   | di }| d}| d}| d}| d}| d}	| dd}
|rkt| |j}|d	kr8t||}nt|}||
 |  | d
d}|rR||jt< |rYt	|| |	rbt
|t|	 |rmt|| d S d S d S )Nr   r   install_methodsetup_controllergalaxyr4   package_name rW   r   )r   validate_configr   rI   rd   rA   r8   r   CFG_OVERRIDEansible_galaxyrun_ansible_pullr   ansible_controller)rf   rg   rh   r3   ansible_cfgansible_userri   rj   
galaxy_cfgpull_cfgrl   r   r   r   r    r    r!   handle   s4   







rw   c                 C   s   d}|D ]}t | |std| d|  q| dr/dD ]}t | |s.td| d|  q| d}|rIt|d|dgsItd	| | d
 }|dvrUtdd S )N)ri   rl   zMissing required key 'z' from r4   )zpull/urlzpull/playbook_namerj   repositoriesrun_ansiblezMissing required key from ri   )rW   r   z Invalid install method {install})r   r6   r   any)rg   required_keyskeycontroller_cfgrA   r    r    r!   rn      s,   



rn   c                 C   s   dd |   D S )zremove boolean false valuesc                 S   s&   i | ]\}}|d ur| dd|qS )Fr-   -)replace.0r|   valuer    r    r!   
<dictcomp>   s
    zfilter_args.<locals>.<dictcomp>)items)rg   r    r    r!   filter_args   s   r   r4   c                 C   s   | d}|  }|std n|tdddk r0|dr0td|j d|j	 d|j
 d	| jg d
d t| D |R  }|rNtj|  d S d S )Nplaybook_namezCannot parse ansible version      r   diffzAnsible version .z%doesn't support --diff flag, exiting.c                 S   s2   g | ]\}}|d urd| d| nd| qS )T--=r    r   r    r    r!   
<listcomp>   s     z$run_ansible_pull.<locals>.<listcomp>)r&   r1   LOGwarningr   r*   r   r6   majorminorpatchr4   r   r   rN   r,   write)r4   rg   r   vr,   r    r    r!   rq      s&   


rq   c                 C   s4   |  dg }|std|  |D ]}|| qd S )NactionszInvalid config: %s)r   r   r   r$   )rg   r   r   r9   r    r    r!   rp      s   rp   c                 C   s   |  dg D ]}|dd|d |d g q|  dg D ]"}|d}|d}d	|gd
d t| D }|j||d qd S )Nrx   gitclonesourcer\   ry   playbook_dirr   zansible-playbookc                 S   s    g | ]\}}d | d| qS )r   r   r    r   r    r    r!   r      s     z&ansible_controller.<locals>.<listcomp>)cwd)r   r$   r&   r   r   )rg   r   
repositoryr3   r   r   r9   r    r    r!   rr      s   

rr   ).__doc__rG   loggingr   r'   rN   r^   copyr   typingr   	cloudinitr   r   cloudinit.cloudr   cloudinit.configr   cloudinit.config.schemar   cloudinit.distrosr	   r
   cloudinit.settingsr   cloudinit.utilr   r   __annotations__	getLoggerrB   r   ro   ABCr   rI   rd   rE   rF   rw   dictrn   r   rq   rp   rr   r    r    r    r!   <module>   s@    
.0	%		