f" UdZddlZddlZddlZddlZddlZddlZddlmZddl m Z ddl m Z ddl mZddlmZddlmZmZdd lmZmZdd lmZdd lmZmZdd lmZmZd ddeegdge de de dgdZee d<eeZejBe"Z#dZ$GddejJZ&Gdde&Z'Gdde&Z(de)deded e*d!df d"Z+de,fd#Z-de,d!e,fd$Z.d%e&de,fd&Z/de,de&fd'Z0de,de&fd(Z1y))z9ansible enables running on first boot either ansible-pullN)deepcopy)dedent)Optional)Cloud)Config) MetaSchema get_meta_doc) ALL_DISTROSDistro) PER_INSTANCE)subpwhich)Versionget_cfg_by_path cc_ansibleAnsiblezConfigure ansible for instanceansiblea 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 )idnametitle frequencydistrosactivate_by_schema_keys descriptionexamplesmetaansible_configceZdZdefdZdeefdZdefdZ dZ de fdZ d Z ejd Zejd efd Zy ) AnsiblePulldistrocdg|_ddg|_||_i|_d|_t j jdd|jd<y)Nz ansible-pullz --versionHOMEz/root)cmd_pull cmd_versionr envrun_userosenvironget)selfr s =/usr/lib/python3/dist-packages/cloudinit/config/cc_ansible.py__init__zAnsiblePull.__init__EsM'( *K8 '+ ::>>&':returnc|j|j\}}|jjd}t j d|}|r&|j d}tj|Sy)Nrz ([\d\.]+)) do_asr$ splitlinespopresearchgrouprfrom_str)r*stdout_ first_linematchesversions r+ get_versionzAnsiblePull.get_versionPshJJt//0 &&(,,Q/ ))L*5 mmA&G##G, ,r-cJ|jg|j|\}}|SN)r0r#)r*argsr7r8s r+pullzAnsiblePull.pullYs(JJ6667  r-c:|js tdy)Nz!command: ansible is not installed) is_installed ValueErrorr*s r+ check_depszAnsiblePull.check_deps]s  "@A A#r-commandc |js|j|fi|S|jj||jfi|Sr>)r&r r r0r*rFkwargss r+r0zAnsiblePull.do_asasA}}499W// / t{{  $--B6BBr-c 2t|fd|ji|S)N update_env)r r%rHs r+r zAnsiblePull.subpfsG;;F;;r-cyr>rDs r+rBzAnsiblePull.is_installedi r-pkg_namecyr>rMr*rOs r+installzAnsiblePull.installmrNr-N)__name__ __module__ __qualname__r r,rrr<strr@rElistr0r abcabstractmethodrBrRrMr-r+rrDs ;v ;Xg.SBCTC <       r-rcFeZdZdedeeffd ZdefdZdefdZ xZ S)AnsiblePullPipr userc t||||_|jtj ddg\}}|d}|j jd}|r!dj||g|j d<y||j d<y)Nz-cz('import site; print(site.getuserbase())'z/bin/PATH:) superr,r&r0sys executabler%r)join)r*r r\ user_baser8 ansible_pathold_path __class__s r+r,zAnsiblePullPip.__init__ss   zz ^^T#M N 1$E* 88<<' "xx<(@ADHHV +DHHV r-rOc*|js ddl}t jdddg}tjjtjjtjddr|jd|jr|jd |j!g|d d|j!g||yy#t$r3|jj |jj gYwxYw) zishould cloud-init grow an interface for non-distro package managers? this seems reusable rN-mpiprRstdlibzEXTERNALLY-MANAGEDz--break-system-packagesz--userz --upgrade)rBrj ImportErrorr install_packagespip_package_namerarbr'pathexistsrc sysconfigget_pathappendr&r0)r*rOrjcmds r+rRzAnsiblePullPip.installs  " M C ww~~ &&x02F  45}} 8$ JJ11k151 2 JJ''h' (+# M ,,dkk.J.J-KL MsC9DDr.cV|jtjdddg\}}d|vS)NrirjrWr)r0rarb)r*r7r8s r+rBzAnsiblePullPip.is_installeds,JJeVDE F""r-) rSrTrUr rrVr,rRboolrB __classcell__)rgs@r+r[r[rs2 ,v ,Xc] ,))6#d#r-r[c$eZdZdefdZdefdZy)AnsiblePullDistrorOc^|js|jj|gyyr>)rBr rmrQs r+rRzAnsiblePullDistro.installs'  " KK ( (( 4#r-r.c*ttdS)Nr)rvrrDs r+rBzAnsiblePullDistro.is_installedsE)$%%r-N)rSrTrUrVrRrvrBrMr-r+ryrys55&d&r-ryrcfgcloudr?r.c\|jdi}|jd}|jd}|jd}|jd}|jd} |jdd} |rt||j} |d k(r t| |} n t | } | j | | j |jd d} | r| | jt<|r t|| | rt| t| |r t|| yyy) Nrr&install_methodsetup_controllergalaxyr@ package_namerjr) r)validate_configr r[ryrRrEr% CFG_OVERRIDEansible_galaxyrun_ansible_pullransible_controller)rr|r}r? ansible_cfg ansible_userrr galaxy_cfgpull_cfgrr rrs r+handlers 2.K??:.L __%56N"'9:*Jv&H??>26L $ U "$V\:G'/G %$)92> (6GKK %  :w /  Whx&8 9  / 9 -r-czd}|D]}t||rtd|d||jdr$dD]}t||rtd|d||jd}|r9t|jd|jdgstd ||d }|d vr td y) N)rrzMissing required key 'z' from r@)zpull/urlzpull/playbook_namer repositories run_ansiblezMissing required key from r)rjr z Invalid install method {install})rrCr)any)r| required_keyskeycontroller_cfgrRs r+rrsMIsC(5cU'#GH HI wwv3 MC"3, #9#gcU!KLL MWW/0N"">2""=1  9.9IJK K"#G'';<<(r-c~|jDcic]\}}|dur|jdd|c}}Scc}}w)zremove boolean false valuesFr8-)itemsreplace)r|rvalues r+ filter_argsrsF IIK  S%   Cu$  s!9r@c  |jd}|j}|stjdnT|t dddkrD|j dr3t d|jd|jd|jd |jgt|jDcgc]\}}|d urd |d |nd |c}}|}|r!tjj|yycc}}w) N playbook_namezCannot parse ansible versionrdiffzAnsible version .z%doesn't support --diff flag, exiting.T--=)r2r<LOGwarningrr)rCmajorminorpatchr@rrrar7write)r@r|rvrrr7s r+rrs 1M A  23 WQ1   776?"177)1QWWIQqwwi78 TYY*#.446 U#(t"3bQug 2cU C   F F8%  s7C? c|jdg}|stjd||D]}|j|y)NactionszInvalid config: %s)r)rrr0)r|rrrFs r+rr s?ggi$G  (#. gr-c x|jdgD]}|jdd|d|dg|jdgD]m}|jd}|jd}d |gt|j Dcgc] \}}d |d |c}}}|j|| oycc}}w) Nrgitclonesourceror playbook_dirrzansible-playbookrr)cwd)r)r0r2rr) r|r repositoryr?rrrrrFs r+rrsggnb1  GZ1:f3E F   r*1xx/ 1   4?t3D3J3J3L MZS%3%q M   g< 01 Ns B6 )2__doc__rXloggingr'r3rarqcopyrtextwraprtypingrcloudinit.cloudrcloudinit.configrcloudinit.config.schemarr cloudinit.distrosr r cloudinit.settingsr cloudinit.subpr rcloudinit.utilrrr__annotations__ getLoggerrSrrABCrr[ryrVrWrdictrrrrrrMr-r+rs]?  !#<1+&3   -} ){        ')j)V t g! + #''+ \-#[-#`& &":":6":%":t":":J==8Td&;&T&0{ 1D 1; 1r-