[hj ddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlmZddlmZddlmZmZddl m!Z!ddl"m#Z#ddl$m%Z%ddl&m'Z'dd l(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6dd l7m8Z8ddl9Z9dd l:m;Z;mZ>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZEdd lFmGZGdd lHmIZImJZJe*rddlKmLZLdaMe jeOZPe jdiZRdejzejzZUdZVdZWdZXe#dZYe#dZZdde5e[e\fde[fdZ]dde5e[e\fde\fdZ^e?jdde\de\fdZ`dZaGdd ZbGd!d"ecZdGd#d$ecZed%Zfdd&Zgdd'Zhdd(Zidd)Zjdd*Zkdd+de.fd,Zld-Zmd.Znd/Zodd1Zpd2Zqd3e[derfd4Zse#d5Zte#d6Zue#d7Zve#d8Zwe#d9Zxe#d:Zydd<Zzdd=Z{dd>Z|dd?Z}e#d@Z~dAZe#dBZddCZddDZdEZddFZddGe4e1derfdHZej<dIZej<dJZdKZdLZddMZddNZderffdOZddPZdd+derfdQZdd+derfdRZddSZddTZdUZGdVdWe2ZddXZddYZe?jdZdefd[Zd\Zd]Zd^Zd_Z dd`Z ddaZ ddbZ ddcZ dddZddeZdfZdd;dgdhe5e[e jFfdie3e,egdfdjede\fdkZdd;dgdhe5e[e jFfdie3e,egdfdjede[fdlZe#dmZdnZdefdoZddpZddqZddrZdse.e[e+fdte3e[de0e3e[fduZdse.e[e+ffdvZddwe[de[fdxZdyZdzZd{Zdd|Ze?jd}erffd~ZdZddZej<dZdZ ddZdZdZddZdZdZdZe#dZdZdZ dd;ddtededdfdZdZdZde[defdZde[defdZde[de[fdZde[de[fdZde[de0e[fdZe?jd dd0ddddedefdZdZddZddZddZdZdZdZdZe#dZdZ dde[de[de.e[e[ffdZdZdZdZePd;fdZdZdZdZdZddZePd;fdZde[defdZdZdde jjfdZddZdZddZdZdZdZdZddZddZd„ZdÄZddĄZddderfdDŽZede/de+dffdȄZy)N) b64decode)deque)contextmanagersuppress)ENOENT) lru_cache)Path) ModuleType)IO TYPE_CHECKINGAnyCallableDequeDict GeneratorListMapping NamedTupleOptionalSequenceUnioncast)parse) featuresimportermergersnet performancesettingssubp temp_utils type_utils url_helperversion)logexc) CFG_BUILTINPER_ONCE)Paths_z_-.())true1onyes)off0nofalsecttttjj j dddS)N.)tuplemapintosunamereleasesplit0/usr/lib/python3/dist-packages/cloudinit/util.pykernel_versionr?`s2 S"((*,,2237;< ==r=chtjddgd}|jjS)zReturn the sanitized string output by `dpkg --print-architecture`. N.B. This function is wrapped in functools.lru_cache, so repeated calls won't shell out every time. dpkgz--print-architectureTcapture)r stdoutstrip)outs r>get_dpkg_architecturerGds- ))V34d CC ::   r=c4ddddd}i} tjddgd }|jjD]2}|jd \}}}||vs|j |||<4|j Dcgc] }||vs| }}|r%t jd d j||Scc}w#tj$rA} t jd | td|j D}Yd} ~ |Sd} ~ wwxYw)Ncodename descriptionidr:)Codename DescriptionzDistributor IDRelease lsb_releasez--allTrB:z.Missing fields in lsb_release --all output: %s,z#Unable to get lsb_release --all: %sc3$K|]}|df yw) UNAVAILABLENr<).0vs r> zlsb_release..s>1Q &>s) r rD splitlines partitionrEvaluesLOGwarningjoinProcessExecutionErrordict) fmapdatarFlinefnamer)valkmissingerrs r>rOrOos$  D D?ii0$?JJ))+ 0D NN3/ME1c}$'IIKT%[! 0#kkm=q}1==  KK@!  K>  % %? 93?> >> K ?s6AC*C B>B>)C>CD6DDblobreturncJt|tr|S|j|SN)encoding) isinstancestrdecode)rgrks r> decode_binaryros!dC(4Ldkk8k.LLr=textcJt|tr|S|j|Srj)rlbytesencode)rprks r> encode_textrts!dE*4N X 0NNr=zBase64 decodingr`ct|tstdt|z t |dS#t j $r|cYSwxYw)zbase64 decode data If data is base64 encoded bytes, return b64decode(data). If not, return data unmodified. @param data: data as bytes. TypeError is raised if not bytes. zdata is '%s', expected bytesT)validate)rlrr TypeErrortyperbinasciiError)r`s r>maybe_b64decoder{sM dE "6dCDD-- >> s 6A Ac|jd}|jdk(rOt|tr?|j }|r|j r |j }nd}|j |dS|S)NT)rnrputf-8surrogateescape) get_payloadget_content_maintyperlrr get_charset input_codecrn)part cte_payloadcharsetrks r>fully_decoded_payloadrsy ""$"/K   "f,U2""$ w****HH!!(,=>> r=c eZdZddZdZdZy) SeLinuxGuardc| tjd|_||_||_y#t$r d|_Y!wxYw)Nselinux)r import_moduler ImportErrorpath recursive)selfrrs r>__init__zSeLinuxGuard.__init__sF  #11) __enter__zSeLinuxGuard.__enter__s <__exit__zSeLinuxGuard.__exit__s||4<<#B#B#D wwtyy) ww * HHTNE LL % %dE$,,,? @ :  NN   LL # #DDNN # C     KK>    s+rrs # r=rc eZdZy)MountFailedErrorNrrrr<r=r>rrr=rc eZdZy)DecompressionErrorNrr<r=r>rrrr=rcXtj}|dk(r ||i|tjdyt jd|t j|y#t$r<t t dt j|tjdYywxYw)Nrz&Failed forking and calling callback %sz(Forked child %s who will run callback %s) r8fork_exit Exceptionr%rZr"obj_namer)child_cbargskwargsfids r>fork_cbrs '')C ax  d %f % HHQK 6     )   8##H-  HHQK  sA$$AB)(B)ct|tr|duSt}|rt||z}t |j j |vryyr)rlbool TRUE_STRINGSlistrmlowerrErcaddons check_sets r>is_truersN#d{I Of,  3x~~9, r=ct|tr|duSt}|rt||z}t |j j |vryy)NFT)rlr FALSE_STRINGSrrmrrErs r>is_falsersN#e|I Of,  3x~~9, r=cD|syt|tr|St||SNF)rlrr)rcrs r>translate_boolrs& # 3 r=ctj}|s!tjtjz}dj t |Dcgc]}|j|c}Scc}wN)random SystemRandomstring ascii_lettersdigitsr\rangechoice)strlen select_fromr_xs r>rand_strr(sQA **V]]: 77E&MBbAHH[)B CCBsA/c@|sd} tddz|z}||vr |S)Nr)rr))r) dictionarypostfixnewkeys r> rand_dict_keyr/s6  #c)G3  #  M r=instance_data_filec ddlm}m}m}m} t |}|rAtjj|r" ||||}tjd||t|iS#t $ricYSwxYw#|$r!}tjd||Yd}~?d}~w|$rYI|$r+}tjd||t|Yd}~sd}~wwxYw)z>Read a yaml config with optional template, and convert to dictr)JinjaLoadErrorJinjaSyntaxParsingException NotJinjaErrorrender_jinja_payload_from_filez?Applied instance data in '%s' to configuration loaded from '%s'z4Failed to render templated yaml config file '%s'. %sNz:Could not apply Jinja template '%s' to '%s'. Exception: %sdefault)!cloudinit.handlers.jinja_templaterrrrload_text_fileFileNotFoundErrorr8rexistsrZrr[repr load_yaml)rbrrrrr config_filers r> read_confr9s$U+ bggnn-?@ 8"K II1"  0 [" --E   +  KKF       KK "Q    s: A)!A:) A76A7:C?BC%C)!CCc$tt|SN)sorted uniq_merge)listss r>uniq_merge_sortedrms *e$ %%r=cg}|D]T}t|tr1|jjd}|Dcgc]}|s| }}|j |Vt |Scc}w)NrQ)rlrmrEr;extend uniq_list)r combined_lista_listas r>rryskM% fc "\\^))#.F!'-A1a-F-V$ % ] ##.s A'A'ctjD]\}}|j||}g}|D]}|tvs |j ||D]}|j|d}|j }|Sr)FN_REPLACEMENTSitemsreplace FN_ALLOWEDappendrE)fnrdrUremovalss r>clean_filenamers%%'1 ZZ1 H  J  OOA  ZZ2  B Ir=Tc tjt|5}tjddd|5}|r+t |j cdddcdddS|j cdddcdddS#1swYnxYwdddy#1swYyxYw#t$r#}|r|cYd}~Stt||d}~wwxYw)Nrbr) ioBytesIOrtgzipGzipFileroreadrrrm)r`quietrnbufghrs r> decomp_gziprs 4 ZZ D) * !c4== $34  ! $RWWY/  ! ! ! wwy  ! ! ! ! ! ! ! 4 K$SV,! 3 4soB*BB  B B*'B 6 B? B* B BB*B'#B*'B** C3C6C<CCc|sy|jdd}|dj}t|dk(r|dj}nd}|r|dk(s|jdk(rd}|r|dk(s|jdk(rd}||fS)NNNrPrrr4z-1none)r;rElenr)ug_pair ug_partedugs r>extract_usergrouprs  c1%I! A 9~ aL     T QWWY&0  T QWWY&0  q6Mr=root_dircht}tjtjj |dD]q}tjj |s#tjj |dd}|j}|sX|jddk(sm|||<s|S)Nz*.pyrr3) r^globr8rr\isfilebasenamerEfind)rentriesrbmodnames r>get_modules_from_dirr#sfG277<<&9:%ww~~e$ ''""5)!B/--/ w||C(B.$GEN % Nr=c.dtjvS)adeprecated: prefer Distro object's `is_linux` property Multiple sources of truth is bad, and already know whether we are working with Linux from the Distro class. Using Distro offers greater code reusablity, cleaner code, and easier maintenance. Linuxplatformsystemr<r=r>is_Linuxr)s hoo' ''r=cbdtjvrytjdk(ryy)NBSDT DragonFlyFr&r<r=r>is_BSDr-s) !!K' r=c"tddk(S)Nvariantfreebsd system_infor<r=r> is_FreeBSDr3 = #y 00r=c"tddk(S)Nr/ dragonflyr1r<r=r>is_DragonFlyBSDr7s = #{ 22r=c"tddk(S)Nr/netbsdr1r<r=r> is_NetBSDr:s = #x //r=c"tddk(S)Nr/openbsdr1r<r=r> is_OpenBSDr=r4r=Fc*||vr|St||Sr)ryobjkeyrs r>get_cfg_option_boolrBs $ $s) $$r=cR||vr|S||}t|ts t|}|Sr)rlrm)r@rArrcs r>get_cfg_option_strrDs/ $ s)C c3 #h Jr=c0tt|||S)Nr)r7rDr?s r>get_cfg_option_intrFs !$W= >>r=cl|sd}tjj|siSt|}d}d|vrd}t j ||}|rc|j }d|dvr|d|d<|djjdd|d<|dd k(rd |d<|d|d |dd SiS) zReturn a dictionary of distro info fields from /etc/redhat-release. Dict keys will align with /etc/os-release keys: ID, VERSION_ID, VERSION_CODENAME z/etc/redhat-releasezA(?P.+) release (?P[\d\.]+) \((?P[^)]+)\) Virtuozzoz)(?P.+) release (?P[\d\.]+)namerIz linuxrzred hat enterpriseredhatr$)ID VERSION_IDVERSION_CODENAME) r8rrrrematch groupdictrrX) release_fileredhat_release redhat_regexrOgroups r>_parse_redhat_releaserUs , 77>>, ' #L1N # n$C HH\> 2E ! %- ' %f E* f ++-77A!Df =0 0$E&M- * %j 1  Ir=cd}d}d}i}d}tjjdrtt d}|s d}t }|r|j dd}|j dd}d|vsd|vrtj}n|d k(s|d k(r|j d d}ni|d k(r|s|j d d}nO|j d d}|s;tjd|j dd}|r|jd}|dk(rd}ntr7tjj}tj}n>d} tj }d}|D]}|sd} |st$j'd|S|||fS#t"$rY7wxYw#d}|D]}|sd} |st$j'dwwxYw)NrF/etc/os-releaseTrKrLslessusealpinephoton PRETTY_NAME virtuozzorMz[^ ]+ \((?P[^)]+)\)VERSIONrIrhelrJ)rrrrzPUnable to determine distribution, template expansion may have unexpected results)r8rrload_shell_contentrrUgetr'machinerNrOrPr-r(rr:distrrZr[) distro_namedistro_versionflavor os_releaseos_release_rhelrOrcfoundentrys r>get_linux_distrork sKN FJO ww~~'('7H(IJ *,  nnT2. # b9 [ Fk$9 %%'F H $ x(?^^M26F K '^^M26F^^$6;F4NN9b1"__.z:F & "K oo'--/ !))+ ==?DE E  <  00   E E  <s*!F!! F-*F0,F--F00 G;Gc|dj}d}|dk(r;|ddj}|dvr|}|S|dvrd}|S|d k(rd }|S|d vrd }|Sd}|S|d vr|}|S)Nr(unknownlinuxrcr) almalinuxrZaoscarch azurelinuxcentos cloudlinuxdebian eurolinuxfedoramariner miraclelinux openeuler opencloudos openmandrivar[r_rockyrY tencentosr])ubuntu linuxmintmintrrJr_)opensusez opensuse-leapzopensuse-microoszopensuse-tumbleweedsle_hpcz sle-microrXrY)windowsdarwinr0r9r<r6)r)infor(r/ linux_dists r> _get_variantr^s (^ ! ! #FG &\!_**,   .!G6 N5: :G2 N18 #G. N-  G NG N   Nr=c tjtjtjtjt tj t d}t||d<|S)N)r'r(r:pythonr9rcr/)r'r(r:python_versionrr9rkr)rs r>r2r2sc%%'//###%))+hnn&' "  D#4(DO Kr=c||vr|S||gS||}t|tr|Dcgc]}|}}|St|ts t|}|gScc}w)a Gets the C{key} config option from C{yobj} as a list of strings. If the key is present as a single string it will be returned as a list with one string arg. @param yobj: The configuration object. @param key: The configuration key to get. @param default: The default to return if key is not found. @return: The configuration option as a list of strings or default if key is not found. )rlrrm)r@rArrcrUcvals r>get_cfg_option_listrsi $ Cy s)C#a c3 #h 5L  s Actt|tr|jd}|}|D]}||vr|cS||}|S)aReturn the value of the item at path C{keyp} in C{yobj}. example: get_cfg_by_path({'a': {'b': {'num': 4}}}, 'a/b/num') == 4 get_cfg_by_path({'a': {'b': {'num': 4}}}, 'c/d') == None @param yobj: A dictionary. @param keyp: A path inside yobj. it can be a '/' delimited string, or an iterable. @param default: The default to return if the path does not exist. @return: The value of the item at keyp." is not found./)rlrmr;)r@keyprcurtoks r>get_cfg_by_pathrsK$zz# C c>N#h Jr=c@t||\}}t||||fSr)get_output_cfgredirect_output)cfgmodeoutfmterrfmts r> fixup_outputrs(%c40VVFF# F r=cttjjdrtj dy|st j}|st j}d}|r+tj d|||jdd\}}|dk(s|dk(rd }|dk(rd }t||}n\|d k(rItj|d tj| } ttt | j"}nt%d|z|r2tj&|j)|j)||k(rJtj d||tj&|j)|j)y|rtj d|||jdd\}}|dk(s|dk(rd }|dk(rd }t||}n\|d k(rItj|d tj| } ttt | j"}nt%d|z|r3tj&|j)|j)yyy)N_CLOUD_INIT_SAVE_STDOUTz5Not redirecting output due to _CLOUD_INIT_SAVE_STDOUTctjd tjdj}tj |y#t $rYywxYw)aReconfigure umask and group ID to create output files securely. This is passed to subprocess.Popen as preexec_fn, so it is executed in the context of the newly-created process. It: * sets the umask of the process so created files aren't world-readable * if an adm group exists in the system, sets that as the process' GID (so that the created file(s) are owned by root:adm) admN)r8umaskgrpgetgrnamgr_gidsetgidKeyError)group_ids r>set_subprocess_umask_and_gidz5redirect_output..set_subprocess_umask_and_gidsJ  ||E*11H IIh     sA AAzRedirecting %s to %s r>>>abwb|T)shellstdin preexec_fnz"Invalid type for output format: %sz!Invalid type for error format: %s)rr8environrarZrsysrDstderrr;open subprocessPopenPIPErr r rrwdup2fileno) rro_outo_errrrargowithnew_fpprocs r>rrsrzz~~789 IJ     & (%8ll3* s 3;$$,Es{#u%F S[## oo7 D"S'4::.F@6IJ J  GGFMMOU\\^ 4 V  II,eV < GGFMMOU\\^ 4   (%8ll3* s 3;$$,Es{#u%F S[## oo7 D"S'4::.F?&HI I  GGFMMOU\\^ 4 +r=sourcesc|rtt|}i}|D]W}|stj|}|stj}tj |}|j ||}Y|S)aFMerge multiple dicts according to the dict merger rules. Dict merger rules can be found in cloud-init documentation. If no mergers have been specified, entries will be recursively added, but no values get replaced if they already exist. Functionally, this means that the highest priority keys must be specified first. Example: a = { "a": 1, "b": 2, "c": [1, 2, 3], "d": { "a": 1, "b": 2, }, } b = { "a": 10, "c": [4], "d": { "a": 3, "f": 10, }, "e": 20, } mergemanydict([a, b]) results in: { 'a': 1, 'b': 2, 'c': [1, 2, 3], 'd': { 'a': 1, 'b': 2, 'f': 10, }, 'e': 20, } )rreversedrdict_extract_mergersdefault_mergers constructmerge)rreverse merged_cfgrmergers_to_applymergers r> mergemanydictr@szTx()J7 &;;C@ ##*#:#:#< &&'78Fj#6J7 r=c#Ktj} tj||tj|y#tj|wxYwwr)r8getcwdchdir)ndircurrs r>rrxs< 99;D   sA!AA!AA!c#Ktj|} |tj|y#tj|wxYwwr)r8r)n_mskolds r>rrs3 ((5/C    sA 3A A  A c,dj||d|S)Nz{0:{fill}{align}{size}}^)fillalignsize)format)rprmax_lens r>centerrs# $ + + 4s , r=cZtjd|tj|y)NzRecursively deleting %s)rZrshutilrmtreers r>del_dirrsII'. MM$r=c t|||\}}}}||d<||d<||d<||d<y#tj$r(}|jtjk(rYd}~yd}~wwxYw) z returns boolean indicating success or failure (presense of files) if files are present, populates 'fill' dictionary with 'user-data' and 'meta-data' entries )baseexttimeout user-data vendor-data meta-dataznetwork-configTNF) read_seededr#UrlErrorcode NOT_FOUND) rrrrmdudvdnetworkrs r>read_optional_seedrsx )tgNBG[ ][!(     66Z)) ) s'*A%A A  A%c&i}|sddg}n^tjj|jddtjj|j ddg}t |}|Dcgc]'}|stjj |s&|)}}d}|D]a}tjjtjj|dsAtjj|d}nd}|D]a}tjjtjj|dsAtjj|d}n|r|r ||d<||d<|S|r||d<|Scc}w) Nz/var/lib/cloud/data/sslz /var/lib/cloud/instance/data/sslr`sslzcert.pemzkey.pem cert_filekey_file)r8rr\ get_ipath_cur get_cpathrisdirr)paths ssl_detailsssl_cert_pathsdrrs r>fetch_ssl_detailsrs\K  % .  GGLL,,V4e < GGLL0% 8  /N!/JA1q9IaJNJI  77>>"'',,q*5 6 Q 3I H  77>>"'',,q)4 5ww||Ay1H X#, K "* J  #, K !Ks7F?FFc|}t|} tjdt||t j |}|tjd|}n1t ||s%td|dtj|d|}|S#tjttf$r}d}d}t|drt|dr t|d}n$t|drt|dr t|d}|r2|d j|jd z|j d z| z }n|d j| z }tj#|Yd}~|Sd}~wwxYw)NzKAttempting to load yaml from string of length %s with allowed root types %sz-loaded blob returned None, returning default.zYaml load allows z root types, but got  insteadzFailed loading yaml blob context_mark problem_markz5. Invalid format at line {line} column {col}: "{err}"r)racolrfz. {err})rf)rorZrryaml safe_loadrlrwr"r YAMLError ValueErrorhasattrgetattrrracolumnr[)rgrallowedloaded convertedrmsgmarks r>rrs^ F  D!  6 I   NN4(   IIE FIIw/J// :< " M! NNIz 2( 1n %'!^*D1n-D Q 'GA~,F1n-D  GNNQDKK!OO C 9###* *C C M!sBBE'1B+E""E'c^|jddk\r@|jdd|z}|jdd|z}|jdd|z}nWtjr/|ddk7r't j |j dk(r|dz }|d|}|d|}|d|}d}tj||| }d} |jrt|ji } tj||| } d} | jr | j} d} tj||| } | jr | j} ntjd  | | | |fS#tj$r }tjd |Yd}~4d}~wwxYw) Nz%srrrrrrr)rretriesrzError in vendor-data responsez!Error in vendor-data response: %s)r rr%NOCLOUD_SEED_URL_APPEND_FORWARD_SLASHrurlparsequeryr#read_file_or_urlokrcontentsrZrr)rrrrud_urlvd_urlmd_urlrmd_resprud_resprrvd_resprs r>rrs yy!dK#$56dMC$78dK#$56  9 9Bx35>>$#7#=#=#C !;4!=#6!;4G))G Bzz| w'' 4))G Bzz|    B 7-- GW  ::<!!B II5 6 r2w    : 5q99:s(E99F, F''F,c nttj|d}|Dcgc]}|jds|}}|Dcgc]B}tjj tjj ||sA|D}}g}|D]?}tjj ||} |jt||At|Scc}wcc}w#t$rtjd|Yxt$r!}tjd||Yd}~d}~wwxYw)zRead configuration directory.Trz.cfgr1REDACTED config part %s, insufficient permissionsError accessing file %s: [%s]N)rr8listdirendswithrrr\rrPermissionErrorrZr[rr)confdrconfsfcfgsrrrs r> read_conf_dr)s 2::e$d 3E 41F!3Q 4E 4 H1 UA0F!GQ HE H DBww||E2& B KK'9 B  / 5 I  KKCT  B KK7q A A Bs5C C AC% C%7C**D4 D4D//D4ct}i} t||}|j|d}d|vrU|d}|rut|ts$td|dtj|t|j}n'tjj|d r|d }|r=tjj|rt!||}|j#|t%|S#t$rtj d|Yt $r"}tj d||Yd}~d}~wwxYw) aRead yaml file along with optional ".d" directory, return merged config Given a yaml file, load the file as a dictionary. Additionally, if there exists a same-named directory with .d extension, read all files from that directory in order and return the merged config. The template file is optional and will be applied to any applicable jinja file in the configs. For example, this function can read both /etc/cloud/cloud.cfg and all files in /etc/cloud/cloud.cfg.d and merge all configs into a single dict. rr r!Nrconf_dz Config file z( contains 'conf_d' with non-string type z.d)rrrr$rZr[rrlrmrwr"rrEr8rrr) appendleftr)cfgfilerr(rrr% confd_cfgs r>read_conf_with_confdr/>s"DC 4FG C E3H  eS) 3 3E :< E ((* '"~ &)2 u%:LM   "  9   ?  A 3Wa@@As C88EE!D>>Ec,tt|S)Ncmdline)rread_cc_from_cmdliner1s r>read_conf_from_cmdliner4ms )': ;;r=c| t}d|}d}d}t|}t|}t|}g}|j|}|dk\r|j|||z}|dkr|}|jt j |||z|j jdd|j|||z}|dk\rdj|S)Nrz cc:end_ccrz\n ) get_cmdlinerr rrunquotelstriprr\) r2 tag_begintag_endbegin_lend_lclentokensbeginends r>r3r3rs-'mGIG)nG LE wdos2unixrFs? -- C ax8C!G$,   FD ))r=c,eZdZUeed<eed<eed<y)HostnameFqdnInfohostnamefqdn is_defaultN)rrrrm__annotations__rr<r=r>rHrHsM Ir=rHcld}d|vr.t|d}t|d|jdd}ntd|vr4|djddkDr|d}|dd|jd}n<|j d|j }d|vr|d}n|j | \}}t |||S) aGet hostname and fqdn from config if present and fallback to cloud. @param cfg: Dictionary of merged user-data configuration (from init.cfg). @param cloud: Cloud instance from init.cloudify(). @param metadata_only: Boolean, set True to only query meta-data, returning None if not present in meta-data. @return: a namedtuple of , , (str, str, bool). Values can be none when metadata_only is True and no cfg or metadata provides hostname info. is_default is a bool and it's true only if hostname is localhost and was returned by util.get_hostname() as a default. This is used to differentiate with a user-defined localhost hostname. FrJrIr3rNT)rJ metadata_only)rN)rmrDr;r  get_hostnamerIrH)rcloudrNrKrJrIs r>get_hostname_fqdnrQs"J }3v;%c:tzz#q7IJ  Z!5!5c!:Q!>z?D:'738H%%&h S z?','9'9"/(:($* HdJ 77r=c"d} t|jD]^}|jd}|dk\r|d|}|j}|s1|j }t |dkrP||ddvsX|d}|S |S#t $rY|SwxYw)a For each host a single line should be present with the following information: IP_address canonical_hostname [aliases...] Fields of the entry are separated by any number of blanks and/or tab characters. Text from a "#" character until the end of the line is a comment, and is ignored. Host names may contain only alphanumeric characters, minus signs ("-"), and periods ("."). They must begin with an alphabetic character and end with an alphanumeric character. Optional aliases provide for name changes, alternate spellings, shorter hostnames, or generic hostnames (for example, localhost). N#rr4r)rrWr rEr;rIOError)rIfilenamerJrahashpostokss r>get_fqdn_from_hostsrYs D "8,779 DiinG!|Ag:: is_resolvablerus$J   D    E ++4Av'9'96;N;N%' 5!=C,9D&&%u%,, -LMJJx{+, "  II4j A  j !   !2!2!8!8!>?  ? ##D$/ay|A+++OOV\\2     OOV\\ *sBA8E F 0E5F0F #E21E25E>:F#F'&F'c.tj}|Sr)r_ gethostname)rIs r>rOrO*s!!#H Or=cf tj|dS#tj$rYywxYwNr)r_ gethostbyaddrherror)ips r>rzrz/s3##B'** ==s 00ct|S)z5determine if this url is resolvable (existing or ip).)ru)rhs r>is_resolvable_urlr~6s  r=c|ytjd||D](} t|rtjd||cS*y#t$rY7wxYw)zc Search through a list of mirror urls for one that works This needs to return quickly. Nz%search for mirror in candidates: '%s'zfound working mirror: '%s')rZrr~r) candidatescands r>search_for_mirrorr;sj II5zB  & 6= '    s"A AAcg}|s+tjdtjdzS|jdrI|jd}d|zd|zfDcgc]#}tjj |r|%}}|S|dk(rtjd}|S|dk(rtjd}|Scc}w)Nz/dev/msdosfs/*z/dev/iso9660/*LABEL=z /dev/msdosfs/z /dev/iso9660/ TYPE=vfat TYPE=iso9660)r startswithr:r8rr)criteriaoformattagno_cacherdevlistlabelps r>find_devs_with_freebsdrNsG yy)*TYY7G-HHH8$)&-/FG ww~~a     N [ )),- N ^ #)),- N s(Ccg}d}d}d}|rD|jdr|jd}|jdr|jd}tjgddg} | jj D]V} |s|rtjd| gddg\}} |rd |z|vr/|d k(rd |vr9|d k(rd |vrC|j d | zX|S)NrrzTYPE=sysctl-nz hw.disknamesrrcs mscdlabelrz label "%s"iso9660zISO filesystemvfat/dev/)rr:r rDr;r) rrrrrrr_type mscdlabel_outrFdevr)s r>find_devs_with_netbsdrbsG E EM   x (OOH-E   w 'OOG,E ))41# >Czz! & E#yy+s);!QH M1 lU*=@  I "2-"G  F?/=@ w}% & Nr=cvtjgddg}g}|jjjdD]Z}|j ds|dk(r|j |dddz|j d rD|j |ddd z\|Dcgc]}d |z c}Scc}w) NrrrrQrPzfd0:rrcdir)r rDrstripr;r#rr) rrrrrrFrrjrs r>find_devs_with_openbsdr|s ))41# >CG""$**3/-~~c"  F? uSbzC'(% NN5":+ ,-") )AGaK )) )s' B6ctjgddg}t|jjdDcgc]&}|j ds|j ds|(}}|dk(r"|Dcgc]}|j d s|}}n>|d vr"|Dcgc]}|j d r|}}n|rt j d ||Dcgc]}d |z c}Scc}wcc}wcc}wcc}w) N)rrz kern.disksrrTrrvnr)racd)zLABEL=CONFIG-2rzUnexpected criteria: %sr)r rrDr;rrZr)rrrrrrFrrs r>find_devs_with_dragonflybsdrs ))2 !%Em)D1EE 4 4%Kall=.I1KK  +X6!( )AGaK ))FK *s$+C'8C,C,C15C1 C6ctrt|||||Strt|||||St rt |||||St rt|||||Sdg}g}|r|jd|z|r|jd|z|r|jddg|r|jd|z|r|j|||z} tj|ddg \}} g} |jD]&} | j} | s| j| (| S#tj$r!} | jtk(rd }nYd } ~ ld } ~ wwxYw) z find devices matching given criteria (via blkid) criteria can be *one* of: TYPE= LABEL=