oB]c@sddlZddlmZddlZddlZddlZddlZddlmZddlmZ ddlm Z ddl m Z ddl m Z ddl mZdd lmZdd lmZdd lmZdd lmZd Ziddgd6ddddgd6dgd6dgd6ddgd6dgd6Ze jeZejdZddddgZejejd efd!YZe ej!d"Z"d#Z#d$Z$e d%d&d'Z%d(Z&dS()iN(tStringIO(timporter(tlog(tnet(teni(t network_state(t renderers(tssh_util(t type_utils(tutil(thoststalltdebiantubuntutamazontcentostfedoratrheltredhattgentootfreebsdtopensusetslestsusetarchs#^[a-z][a-z]-(?:[a-z]+-)+[0-9][a-z]$tchronyssystemd-timesyncdtntptntpdatetDistrocBsKeZdZdZdZdZdZdgZiZd3Z dZ e j dZdZd Zd Zd Zd3d Zd3d ZdZe j d3d3dZe j dZdZd3dZd3d3dZedZedZdZedZ dZ!e j d3dZ"e j dZ#dZ$dZ%e j d3dZ&e j dZ'e j dZ(d Z)d!Z*e+d"Z,d#Z-d$Z.e/d%Z0d&Z1d'Z2d(Z3d)Z4d*Z5d+Z6d,Z7d-Z8ed.Z9d/d0Z:d3d1Z;d3d2Z<RS(4s/usr/libs /etc/hostss"/etc/sudoers.d/90-cloud-init-userss /etc/hostnames/usr/share/zoneinfotservicecCs||_||_||_dS(N(t_pathst_cfgtname(tselfR tcfgtpaths((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt__init__Ds  cCs tdS(N(tNotImplementedError(R!tpkglist((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pytinstall_packagesIscCstd|jdS(NshLegacy function '_write_network' was called in distro '%s'. _write_network_config needs implementation. (t RuntimeErrorR (R!tsettings((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt_write_networkMscCs tdS(N(R%(R!R)((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt_write_network_configRscCsotj|jdd}tjd|\}}tjd|||d|jj |}|j |gS(NtnetworkRtprioritys-Selected renderer '%s' from priority list: %stconfig(R,s renderers( R tget_cfg_by_pathRtNoneRtselecttLOGtdebugtrenderer_configstgettrender_network_config(R!tnetwork_configR-R t render_clstrenderer((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt_supported_write_network_configUs   cCsMtjj|jt|}tjj|sItd||fn|S(Ns(Invalid timezone %s, no file found at %s(tostpathtjoint tz_zone_dirtstrtisfiletIOError(R!ttzttz_file((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt _find_tz_file`s cCs|jj||S(N(RR5(R!topt_nametdefault((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt get_optiongscCs6|j||}|j||j|j|dS(N(t_select_hostnamet_write_hostnamethostname_conf_fnt_apply_hostname(R!thostnametfqdntwriteable_hostname((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt set_hostnamejscCstS(s?Wrapper to report whether this distro uses systemd or sysvinit.(t uses_systemd(R!((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyRPoscCs tdS(N(R%(R!tcmdtargstpkgs((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pytpackage_commandsscCs tdS(N(R%(R!((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pytupdate_package_sourceswscCs$tjd}|dkr dS|S(Niti386ti486ti586ti686(RVRWRXRY(R;tuname(R!R((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pytget_primary_arch{s cCs4|jdg}|s'|j}nt||S(Ntpackage_mirrors(RGR[t_get_arch_package_mirror_info(R!Rt mirror_info((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyR]scCs"|j|}td|d|S(Nt data_sourceR^(R]t_get_package_mirror_info(R!RR_t arch_info((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pytget_package_mirror_infos cCs&|j|}|r"|j|StS(N(R*t_bring_up_interfacestFalse(R!R)tbring_upt dev_names((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt apply_networks cCso|j}tjd|djd|dg}tj|}tj|d|dt}|j |d|S(Nsiapply_network_config is not currently implemented for distribution '%s'. Attempting to use apply_networks s-# Converted from network_config for distro %ss4# Implementation of _write_network_config is needed.theadertrender_hwaddressRe( t __class__R2twarningR=Rtparse_net_config_dataRtnetwork_state_to_enitTrueRg(R!t netconfigRetdistroRhtnstcontents((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt"_apply_network_from_network_configs   cCs tjS(N(Rtgenerate_fallback_config(R!((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyRtscCsNy|j|}Wn!tk r6|j|d|SX|rJ|j|StS(NRe(R+R%RsRcRd(R!RoReRf((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pytapply_network_configs  cCstj|dS(N(Rtapply_network_config_names(R!Ro((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyRvscCs tdS(N(R%(R!tlocaletout_fn((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt apply_localescCs tdS(N(R%(R!RB((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt set_timezonescCsdS(Ns 127.0.0.1((R!((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt_get_localhost_ipscCs tdS(N(R%(R!((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt get_localescCs tdS(N(R%(R!tfilenameRF((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt_read_hostnamescCs tdS(N(R%(R!RLR}((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyRIscCs tdS(N(R%(R!((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt_read_system_hostnamescCsUtjd|ytjd|gWn'tjk rPtjtd|nXdS(Ns2Non-persistently setting the system hostname to %sRLs;Failed to non-persistently adjust the system hostname to %s(R2R3R tsubptProcessExecutionErrortlogexc(R!RL((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyRKs  cCs|s |S|S(N((R!RLRM((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyRHscCsKg}x>|D]6}|tkr2td|n|jt|q W|S(Ns%No distibutions found for osfamily %s(t OSFAMILIESt ValueErrortextend(t family_listtdistrostfamily((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pytexpand_osfamilys   c Cs|}|j||}|rBtjj|rB|j|}nd}|j\}}g}| ss||kr|j|n| s||kr||kr|j|n|r|r||krtj d||dSt g|D]} | r| ^q}tj d|t |xL|D]D} y|j || Wq&tk ritjtd|| q&Xq&W||kr|j|ndS(Ns6%s differs from %s, assuming user maintained hostname.s/Attempting to update hostname to %s in %s filess!Failed to write hostname %s to %s(RHR;R<texistsR~R0RtappendR2tinfotsetR3tlenRIRAR RRK( R!RLRMtprev_hostname_fntapplying_hostnamet prev_hostnametsys_fnt sys_hostnamet update_filestftfn((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pytupdate_hostnames8     %    c Cs"d}tjj|jr9tjtj|j}n!tjd}tjdd}|j }|j |}t }|s|j |||t }n%t }x|D]}d} g} t|dkr|d} nt|dkr|d} n| dk r| |kr|| kr*t }q*qqW|rt|} | j||g|j|x_| D]T}t|dkr|j ||dqgt|dkrg|j ||qgqgWn|rt} |r| jd|n| jd|tj|j| jdd ndS( Nttbasetaddediiis%s tmodei(R;R<Rthosts_fnR t HostsConfR t load_filet make_headerR{t get_entryRdt add_entryRnR0RtlistRt del_entriesRtwritet write_filetgetvalue( R!RLRMRhtehtlocal_ipt prev_infot need_changetentryt entry_fqdnt entry_aliasest new_entriesRr((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pytupdate_etc_hosts2sJ          cCs"|jstt|_n|jS(s7Allow distro to determine the preferred ntp client list(t_preferred_ntp_clientsRtPREFERRED_NTP_CLIENTS(R!((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pytpreferred_ntp_clients]s cCsd|g}tjd||y?tj|\}}t|rYtjd||ntSWn(tjk rtjtd|t SXdS(Ntifups8Attempting to run bring up interface %s using command %ss(Running %s resulted in stderr output: %ss#Running interface command %s failed( R2R3R RRRkRnRRRd(R!t device_nameRQt_outterr((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt_bring_up_interfacees      cCsGd}x*|D]"}|j|s |d7}q q W|dkrCtStS(Nii(RRnRd(R!t device_namest am_failedtd((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyRcss  cCs |jdS(Nt default_user(RG(R!((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pytget_default_user|scKs^tj|r#tjd|dSd|krA|jd}nt}d|g}d|g}tjr|jd|jdni dd6dd 6d d 6d d 6dd6dd6dd6dd6dd6dd6}idd6dd6dd6}dg}|jd} | rt | t j r1| j d } ng| D]} | j ^q8} d j| |d<|jd } | r| j| qn|r| rxC| D]8} tj| s|j| tjd!| |qqWnxt|jD]\} }| |krt|rtt |trt|j|| |g| |krZ|j|| d"gq|j|| |gq| |kr|r|j|| |j|| qqW|jd#s|jdr|jd$|jd$n|jd%|jd%tjd&|ytj|d'|Wn,tk rY}tjtd(||nXdS()sC Add a user to the system using standard GNU tools s!User %s already exists, skipping.Nt create_groupstuseradds --extrauserss --commenttgecoss--homethomedirs--gidt primary_groups--uidtuids--groupstgroupss --passwordtpasswds--shelltshells --expiredatet expiredates --inactivetinactives--selinux-usert selinux_users--no-user-groupt no_user_groups--systemtsystems --no-log-initt no_log_initt,s created group '%s' for user '%s'tREDACTEDtno_create_homes-Ms-msAdding user %st logstringsFailed to create user %s(R tis_userR2RtpopRntsystem_is_snappyRR5t isinstancetsixt string_typestsplittstripR=tis_groupt create_groupR3tsortedtitemsR?RRt ExceptionR(R!R tkwargsRt useradd_cmdtlog_useradd_cmdt useradd_optst useradd_flagst redact_optsRtgRtgrouptkeytvalte((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pytadd_usersz           !    c Ks|jd}|jdt}ddddg}|rI|jdn|j|tjd|yYtj|d |d t\}}tjd ||tj|}|jd d} Wn,t k r} tj td || nX| S(sD Add a snappy user to the system using snappy tools tsnapusertknowntsnaps create-users--sudoers--jsons--knownsAdding snap user %sRtcaptures snap create-user returned: %s:%stusernamesFailed to create snap user %sN( R5RdRR2R3R RRnt load_jsonR0RR( R!R RRRtcreate_user_cmdtoutRtjobjRR((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt add_snap_users"  c KsBd|kr|j||S|j||d|krY|drY|j||dnd|kr|dr|j||ddtn|jdtr|j|nd|kr|dtk r|j||dnd|kr|d}t|t j r|g}n$t|t r9t |j }n|dk rt|tt tfs|tjdt|g}qt|pg}ntjt||nd |kr>|jd g}|stjd ||d q>|d }tj}|jd |}|jd |}tjt||d|ntS(s Creates users for the system using the GNU passwd tools. This will work on an GNU system. This should be overriden on distros where useradd is not desirable or not available. Rtplain_text_passwdt hashed_passwdthashedt lock_passwdtsudotssh_authorized_keyssZInvalid type '%s' detected for 'ssh_authorized_keys', expected list, string, dict, or set.tssh_redirect_usertcloud_public_ssh_keyss^Unable to disable ssh logins for %s given ssh_redirect_user: %s. No cloud public-keys present.s$USERs $DISABLE_USERtoptionsN(RRt set_passwdRnR5RRdtwrite_sudo_rulesRRRtdictRtvaluesR0ttupleRR2RkttypeRtsetup_user_keystDISABLE_USER_OPTStreplace(R!R Rtkeyst cloud_keyst redirect_usertdisable_option((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt create_usersJ           cCsdd|gdd|gf}ytd|D}Wn>tk rxtd|g|D]}|d^qXfnXytj|Wn,tk r}tjtd||nXd S( sL Lock the password of a user, i.e., disable password logins Rs-ltusermods--lockcss(|]}tj|dr|VqdS(iN(R twhich(t.0tl((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pys GssBUnable to lock user account '%s'. No tools available. Tried: %s.is&Failed to disable password for user %sN(tnextt StopIterationR(R RRRR2(R!R t lock_toolsRQtcR((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyR@s +cCsMytjdd|gWn,tk rH}tjtd||nXdS(NRs--expiresFailed to set 'expire' for %s(R RRRR2(R!tuserR((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt expire_passwdRs cCsd||f}dg}|r/|jdnytj||dd|Wn,tk r{}tjtd||nXtS(Ns%s:%stchpasswds-eRschpasswd for %ssFailed to set password for %s(RR RRRR2Rn(R!RRRt pass_stringRQR((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyRYs  s /etc/sudoersc Csd}t}tjj|r6tj|}t}nt}x|jD]y}|j}t j d|}|syqIn|j dj}|sqIntjj |}||krIt}PqIqIW|sy|sddtj ddd|dg} dj| }tj||d nAdtj ddd|dg} dj| }tj||tjd ||Wqtk r} tjtd || qXntj|d dS( NRs^#includedir\s+(.*)$is?# See sudoers(5) for more information on "#include" directives:RRs#includedir %ss i sAdded '#includedir %s' to %ssFailed to write %si(RdR;R<RR RRnt splitlinesRtretsearchRtabspathRR=Rt append_fileR2R3RARt ensure_dir( R!R<t sudo_basetsudoers_contentst base_existst found_includetlinet include_matcht included_dirtlinesR((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pytensure_sudo_dirksH    c Cs|s|j}ndd|g}t|ttfrbxs|D]}|jd||fq>WnKt|tjr|jd||fnd}t|tj |dj |}|d7}|j t j j|t j j|sUtj|g}y tj|dj |dWqtk rQ} tjtd|| qXnCytj||Wn,tk r} tjtd|| nXdS( NRs# User rules for %ss%s %ss1Can not create sudoers rule addition with type %rs i sFailed to write sudoers file %ss Failed to append sudoers file %s(t ci_sudoers_fnRRRRRRt TypeErrorRtobj_nameR=R$R;R<tdirnameRR RRRARR2R( R!Rtrulest sudo_fileR#truletmsgtcontentRrR((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyRs6        cCs"d|g}tjr(|jdn|s7g}ntj|rYtjd|nHy!tj|tjd|Wn$tk rtj td|nXt |dkrxh|D]]}tj |stjd||qntjdd d ||gtjd ||qWndS( Ntgroupadds --extrauserss(Skipping creation of existing group '%s'sCreated new group %ssFailed to create group %sisCUnable to add group member '%s' to group '%s'; user does not exist.R s-as-GsAdded user '%s' to group '%s'( R RRRR2RkRRRRRR(R!R tmemberst group_add_cmdtmember((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyRs(        N(=t__name__t __module__t usr_lib_execRR%RJR>tinit_cmdR4R0RR$tabctabstractmethodR'R*R+R:RDRGRORPRTRUR[R]RbRnRgRsRtRdRuRvRyRzR{R|R~RIRRKRHt staticmethodRRRtpropertyRRRcRRRR RRRR$RR(((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyR8sn                   : +   g  @    ) %c CsU|si}ni}|ra|jra|j|d/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyR`s0  %%   cCsOd}xB|D]:}|jd}||kr2|Sd|kr |}q q W|S(NtarchesRF(R0R5(R\RRFtitemRI((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyR]s    cCsitj|dtgdg\}}|sCtd||fntj|d}t|d}|S(NRRs1No distribution found for distro %s (searched %s)i(Rt find_moduleR2t ImportErrort import_moduletgetattr(R tlocst looked_locstmodtcls((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pytfetch s$s /etc/timezones/etc/localtimecCstj|t|jd|r|rtjj|}|sWtjj| r|rmtj|ntj ||qtj ||ndS(Ns ( R RR?trstripR;R<tislinkRtdel_filetsymlinktcopy(RBRCttz_confttz_localRU((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pytset_etc_timezones  cCs<y#tjd}tj|jSWntk r7tSXdS(Ns/run/systemd/system(R;tlstattstattS_ISDIRtst_modeRRd(tres((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyRP%s  ('RRR6R;RR]t cloudinitRRtloggingRt cloudinit.netRRRRRR tcloudinit.distros.parsersR t ALL_DISTROSRt getLoggerR2R2tcompileR>Rt add_metaclasstABCMetatobjectRR0tsearch_for_mirrorR`R]RSR[RP(((s>/usr/lib/python2.7/site-packages/cloudinit/distros/__init__.pyt sJ          (