fUddlZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl m Z m Z mZmZmZddlmZmZej(eZdddddd d d d d dddd ZddddZdZdZdZdegZgdZdZdZdZ ee eegddd id!Z!dd"ddd#idd$dd%gd&Z"d'Z#d(Z$Gd)d*ejJZ&Gd+d,e'Z(Gd-d.e(Z)Gd/d0Z*Gd1d2e*Z+Gd3d4e*Z,Gd5d6e,Z-deee dfd7Z.d8Z/ dGd9Z0dHd:Z1 dId;Z2e&ejfffgZ4d<Z5ed=k(rddl6Z6e.Z7e7e8d>e6jrd?e:e6jvd?k(r2eiZ?e@eAdB<e=D] ZBe>e7eBe?Ce8eje?d?dDdEFyy)JN) atomic_helperdmisourcessubputil) EventScope EventType)zsdc:uuidT)hostnameT)root_authorized_keysT) user-scriptF) user-dataF)zcloud-init:user-dataF)iptables_disableT) motd_sys_infoT)sdc:datacenter_nameT)zsdc:vendor-dataF)zsdc:operator-scriptF)z sdc:hostnameT)zsdc:dns_domainT) instance-idlocal-hostnamez public-keysr legacy-user-datar rravailability_zone vendor-dataoperator-scriptr dns_domainzsdc:nicsz sdc:resolversz sdc:routes) network-data dns_serversrouteszlx-brandkvmSmartOS datasource)rrr rzsdc:uuiduser-datar z"/native/.zonecontrol/metadata.sockz /dev/ttyS1<F ephemeral0z/dev/vdb) serial_deviceserial_timeoutmetadata_sockfileno_base64_decode base64_keys base64_all disk_aliasesmbr) table_typelayout overwriteext4)label filesystemdevice) disk_setupfs_setupaU#cloud-boothook #!/bin/sh fname="%(per_boot_d)s/01_smartos_vendor_data.sh" mkdir -p "${fname%%/*}" cat > "$fname" <<"END_SCRIPT" #!/bin/sh ## # This file is written as part of the default vendor data for SmartOS. # The SmartOS datasource writes the listed file from the listed metadata key # sdc:operator-script -> %(operator_script)s # user-script -> %(user_script)s # # You can view content with 'mdata-get ' # for script in "%(operator_script)s" "%(user_script)s"; do [ -x "$script" ] || continue echo "executing '$script'" 1>&2 "$script" done END_SCRIPT chmod +x "$fname" z/var/dbceZdZdZej Zej Zeje je je jhiZdZdZdZdZdZdZdZd Zd Zed Zy ) DataSourceSmartOSJoyentctjj||||tj|j tj |titg|_i|_ d|_ d|_ tjj|jj!d|_|j%y)Nscripts)r DataSource__init__r mergemanydictds_cfgget_cfg_by_path DS_CFG_PATHBUILTIN_DS_CONFIGmetadata network_data_network_configospathjoinpaths get_cpath script_base_d_init)selfsys_cfgdistrorCs E/usr/lib/python3/dist-packages/cloudinit/sources/DataSourceSmartOS.pyr7zDataSourceSmartOS.__init__s##D'65A(( $$Wk2>!     #WW\\$***>*>y*IJ cdtjj|}|d|jdS)Nz [client=])rr6__str__ md_client)rGroots rJrNzDataSourceSmartOS.__str__s'!!))$/#'88rKcH|jtjk(r"t|_|jd|_|jtjk(rFt |j|j d|j d|j d|_yy)Nr"r r!) smartos_typer"r r!)rRrUNSETget_smartos_environrOjmc_client_factoryr9rGs rJrFzDataSourceSmartOS._inits    - 3 5D   (!% >>W]] */!.."&++.A"B"kk/:#{{+;< DN +rKctjdd}tjj dj |dgr9tj dj |dgdj |dgyy)aMark the instance provisioning state as successful. When run in a zone, the host OS will look for /var/svc/provisioning to be renamed as /var/svc/provision_success. This should be done after meta-data is successfully retrieved and from this point the host considers the provision of the zone to be a success and keeps the zone running. z-Instance provisioning state set as successfulz/var/svc/ provisioningprovision_successN)LOGdebugr@rAexistsrBrename)rGsvc_paths rJ_set_provisionedz"DataSourceSmartOS._set_provisionedsi AB 77>>#((Hn#=> ? II(N34($789  @rKc|ji}d}|jstjdy|jj s!tjd|jy|jj tjD]*\}}|\}}|jj||||<,tjD]#\}}|jj|||<%|jjtjj|j j#d|dd}tjj|d }d t$z} t'|jd || d d tjj|d} t'|jd| dd |jd} dt$z} t'| | |ds|dr |d|d<n|d|d<d}|dr|d}|dsGt(|| tjj|j j#dddz|d<t+j,||j.g|_||_|d|_|d|_|d|_|j9y )NzNot running on smartosFz4No metadata device '%r' found for SmartOS datasourcestrip instancesrdatar z%s/user-scriptTi) content_flinkshebangmoder)rgrirjrz%s/mdata-user-datarr r rr5zper-boot) user_scriptoperator_script per_boot_drr)rFrRr[r\rOr]open_transportSMARTOS_ATTRIB_MAPitemsgetSMARTOS_ATTRIB_JSONget_jsonclose_transportr@rArBrCrD LEGACY_USER_Dwrite_boot_contentBUILTIN_VENDOR_DATArr8r= userdata_rawvendordata_rawr> routes_datar`) rGmdudci_noun attribute smartos_nounrddata_drk u_script_lrlu_datau_data_fs rJ _get_datazDataSourceSmartOS._get_datas    II. /~~$$& IIF  %%'"4":":"< H GY"+ L%..,,\,GBwK H&9%>%>%@ @ !G\..11,?BwK @ &&( JJ "KM1BF ggll6=9 % 5  FF= !!  '',,v/@A FF$ %%  *+'-768, "#*~')*~#$')-'8#$  k?KB- 3*#2 ggllJJ((3Z7!B} **B +>?  /~.h< rKcdtzS)Nz serial (%s)) SERIAL_DEVICErVs rJ_get_subplatformz"DataSourceSmartOS._get_subplatformMs },,rKc>|jdj|S)Nr&)r9rq)rGnames rJdevice_name_to_devicez'DataSourceSmartOS.device_name_to_devicePs{{>*..t44rKc8|jtk(rtSiSN)rRSMARTOS_ENV_KVMBUILTIN_CLOUD_CONFIGrVs rJget_config_objz DataSourceSmartOS.get_config_objSs    /' ' rKc |jdS)Nr)r=rVs rJget_instance_idz!DataSourceSmartOS.get_instance_idXs}}]++rKc|jtjk(rd|_|jN|jBt |j|j d|j d|j |_|jS)Nrrr>rrr)r?rrSr>convert_smartos_network_datar=rzrVs rJnetwork_configz DataSourceSmartOS.network_config[s{   7== 0#'D    '  ,'C!%!2!2 $ m <#}}\:++ ($ ###rKN)__name__ __module__ __qualname__dsnamerrSrRrOrNETWORKr BOOT_NEW_INSTANCEBOOT BOOT_LEGACYdefault_update_eventsr7rNrFr`rrrrrpropertyrrKrJr2r2s F==L I  ' ' NN  ! ! $9 $aF-5 , $ $rKr2c eZdZy)JoyentMetadataFetchExceptionNrrrrrKrJrrlrKrc eZdZy)JoyentMetadataTimeoutExceptionNrrrKrJrrprrKrceZdZdZej dZddZdZdZ dZ dZ d Z dd Z dd Zdd Zd ZdZdZdZdZdZy)JoyentMetadataClientz A client implementing v2 of the Joyent Metadata Protocol Specification. The full specification can be found at http://eng.joyent.com/mdata/protocol.html z~V2 (?P\d+) (?P[0-9a-f]+) (?P(?P[0-9a-f]+) (?PSUCCESS|NOTFOUND)( (?P.+))?)Nc8| t}||_||_yr)rTrRfp)rGrRrs rJr7zJoyentMetadataClient.__init__s  .0L(rKcndjtj|jddzS)N{0:08x}zutf-8)formatbinasciicrc32encode)rGbodys rJ _checksumzJoyentMetadataClient._checksums/ NN4;;w/ 0: =  rKc R|jj|j}t|dt |dk7r*t dj |dt |d|j|d}|d|k7rt dj ||d|d|k7rt dj ||d|jddstjd ytj|d}tjd ||S) Nlengthrz*Incorrect frame length given ({0} != {1}).checksumz*Invalid checksum (expected: {0}; got {1}). request_idz-Request ID mismatch (expected: {0}; got {1}).payloadzNo value found.zValue "%s" found.) line_regexmatch groupdictintlenrrrrqr[r\rb64d)rGexpected_request_idframe frame_dataexpected_checksumvalues rJ_get_value_from_framez*JoyentMetadataClient._get_value_from_frames1__**51;;= z(# $Jv,>(? ?.<CCx(#j.@*A  !NN:f+=> j !%6 6.<CC%z*'=  l #': :.?FF'L)A  ~~i. II' ("":i#89 %u- rKcTgfd}d} |jjd}t|dk(rt||z|dk(r|Sj |[#t $r7}|j t jk(rt||z|d}~wwxYw)z Reads a line a byte at a time until is encountered. Returns an ascii string with the trailing newline removed. If a timeout (per-byte) is set and it expires, a JoyentMetadataFetchException will be thrown. cDdjjdS)NrKascii)rBdecode)responsesrJas_asciiz0JoyentMetadataClient._readline..as_asciis88H%,,W5 5rKzPartial response: '%s'r N)rreadrrappendOSErrorerrnoEAGAIN)rGrmsgbyteexcrs @rJ _readlinezJoyentMetadataClient._readlines 6' ww||At9>8xz9IJJ5=#:%% 99 ,8hj(  sAA'A'' B'02B""B'c|jj|jd|jjy)Nr)rwriterflush)rGrs rJ_writezJoyentMetadataClient._writes(  cjj)*  rKctjd|jd|j}tjd||dk7rt d|ztjdy)NzNegotiating protocol V2z NEGOTIATE V2 z read "%s"V2_OKz'Invalid response "%s" to "NEGOTIATE V2"zNegotiation complete)r[r\rrr)rGrs rJ _negotiatezJoyentMetadataClient._negotiatesb +, $%>># +x( w .9HD  ()rKcjdjtjdd}dj||f}|r7|dt j |j jzz }djt||j||}tjd|d}|js|jd}|j||j}|r|j!tjd |d |vry|j#||}|S) Nrrr zV2 {0} {1} {2} z#Writing "%s" to metadata transport.FTz"Read "%s" from metadata transport.SUCCESS)rrandomrandintrBbase64 b64encoderrrrr[r\rrnrrrtr) rGrtypeparamr message_bodyr need_closerrs rJrequestzJoyentMetadataClient.requests%%fnnQ &CD xx   C&"2"25<<>"B"I"I"KK KL ''  t~~l;\  7= ww    !J C>>#   " 6A H $**:x@ rKc\|jd|}||S|r|r|j}|S)NGETrr)rrd)rGkeydefaultrdresults rJrqzJoyentMetadataClient.gets3E5 >N e\\^F rKcZ|j||}||Stj|S)N)r)rqjsonloads)rGrrrs rJrszJoyentMetadataClient.get_jsons-#w/ >Nzz&!!rKcP|jd}|sgS|jdS)NKEYS)r )rsplit)rGrs rJlistzJoyentMetadataClient.lists)F+I||D!!rKc dj||fDcgc]%}tj|j'c}j }|j d|Scc}w)N PUTr)rBrrrrr)rGrvalirs rJputzJoyentMetadataClient.put sW 47: >aV  ahhj ) > &( ||%u|55 ?s*A$c`|jr"|jjd|_yyr)rcloserVs rJrtz$JoyentMetadataClient.close_transports" 77 GGMMODG rKcB|jr|S|j|Sr)rrnrVs rJ __enter__zJoyentMetadataClient.__enter__s 77K  rKc$|jyr)rt)rGexc_type exc_value tracebacks rJ__exit__zJoyentMetadataClient.__exit__s rKctr)NotImplementedErrorrVs rJrnz#JoyentMetadataClient.open_transports!!rKNNrNF)rrr__doc__recompilerr7rrrrrrrqrsrrrtrrrnrrKrJrrtsj J   8: *B" " 6   "rKrc4eZdZeffd ZdZdZdZxZS)JoyentMetadataSocketClientc:tt| |||_yr)superrr7 socketpath)rGrrR __class__s rJr7z#JoyentMetadataSocketClient.__init__$s ($8F$rKctjtjtj}|j|j|j d|_|jy)Nrwb)socketAF_UNIX SOCK_STREAMconnectrmakefilerr)rGsocks rJrnz)JoyentMetadataSocketClient.open_transport(sF}}V^^V-?-?@ T__%--& rKcTtjj|jSr)r@rAr]rrVs rJr]z!JoyentMetadataSocketClient.exists.sww~~doo..rKcN|jjd|jdS)Nz (socketpath=))rrrrVs rJ__repr__z#JoyentMetadataSocketClient.__repr__1s&*nn&=&=tOOrK) rrrSMARTOS_ENV_LX_BRANDr7rnr]r __classcell__rs@rJrr#s0D% /PrKrc>eZdZdedffd ZdZdZdZdZxZ S)JoyentMetadataSerialClient NcJtt| ||||_||_yr)rr#r7r.timeout)rGr.r&rRrrs rJr7z#JoyentMetadataSerialClient.__init__6s% ($8rJ  rKcTtjj|jSr)r@rAr]r.rVs rJr]z!JoyentMetadataSerialClient.exists=sww~~dkk**rKcX|j~tj|j|j}|j st d|jz||_tj|tj|j|jy)N)r&zUnable to open %s) rserialSerialr.r&isOpen SystemErrorfcntllockfLOCK_EX_flushr)rGsers rJrnz)JoyentMetadataSerialClient.open_transport@sm 77?-- T\\BC::<!"5 "CDDDG KKU]] +  rKctjd|jj}d|j_ |j #t $rYnwxYwtjd|dkDrd|j_n||j_ tjd|j d |j }|dk(rnW|dk(rtjd Ytjd |n$#t $rtjd YnwxYwtjd ||j_y) NzFlushing inputg?z Input emptyz,Writing newline, expecting "invalid command"rzinvalid commandFAILUREzGot "FAILURE". Retrying.z%Unexpected response "%s" during flushzQTimeout while initializing metadata client. Is the host metadata service running?z'Got "invalid command". Flush complete.)r[r\rr&rrrwarning)rGr&rs rJr0z!JoyentMetadataSerialClient._flushJs "#''//  2   - Q;DGGO%DGGO IID E KK  >>+00y(II9: CXN1  <  ;<!s/A AAD D 5D D-,D-ch|jjd|jd|jdS)Nz(device=z , timeout=r)rrr.r&rVs rJrz#JoyentMetadataSerialClient.__repr__qs' NN # # KK LL  rK) rrrrr7r]rnr0rr r!s@rJr#r#5s$ 4+%"N rKr#cHeZdZdZdfd ZddZd fd ZddZd dZxZ S) JoyentMetadataLegacySerialClientaV1 of the protocol was not safe for all values. Thus, we allowed the user to pass values in as base64 encoded. Users may still reasonably expect to be able to send base64 data and have it transparently decoded. So even though the V2 format is now used, and is safe (using base64 itself), we keep legacy support. The way for a user to do this was: a.) specify 'base64_keys' key whose value is a comma delimited list of keys that were base64 encoded. b.) base64_all: string interpreted as a boolean that indicates if all keys are base64 encoded. c.) set a key named b64- with a boolean indicating that is base64 encoded.chtt|}|j|||d|_d|_yr)rr8r7r$r%)rGr.r&rRsrs rJr7z)JoyentMetadataLegacySerialClient.__init__s/ 2D 9 67L1rKc|rd|_d|_d}|jE|j}d|vr*tj|j d|_nd|_|jry|j||j}t }d|vr)t |j djd}|Dcgc]}|jds|ddc}D]N}tj|j |r|j|9||vs>|j|P||_yycc}w)Nr%Fr$,zb64-) r$r%rris_true_getsetr startswithaddremove)rGresetkeysb64_keyskrs rJ_init_base64_keysz2JoyentMetadataLegacySerialClient._init_base64_keyss #D "DO ?? "99;Dt#"&,,tyy/F"G"' ??     #|yy{uH$tyy7==cBC(,D!q||F/C!"D -<< #/LL%h ,  - (D  $Es E!Ec0tt| |||S)N)rrd)rr8rq)rGrrrdrs rJr?z%JoyentMetadataLegacySerialClient._gets%5t@ A  rKcn|tvry|j||jry||jvS)NF)rDT)NO_BASE64_DECODErHr%r$)rGrrDs rJis_b64_encodedz/JoyentMetadataLegacySerialClient.is_b64_encodeds: " " U+ ??d&&&&rKcXt}|j|d|}||ur|S|j|r2 tj|j j }|r|j}|S#tj$rtjd||Y@wxYw)NF)rdrz#Failed base64 decoding key '%s': %s) objectr?rLr b64decoderrrErrorr[r5rd)rGrrrdmdefaultrs rJrqz$JoyentMetadataLegacySerialClient.gets8ii5(i; (?N   s # M&&szz|4;;= ))+C >> M A3L Ms1A<<*B)(B))r$N)Fr ) rrrr r7rHr?rLrqr r!s@rJr8r8ys" * (D 'rKr8c| t|}|y|tk(rt|||S|tk(r t ||St d|z)N)r.r&rR)rrRz"Unknown value for smartos_type: %s)rTrr8rr ValueError)rRr"r r! uname_versions rJrUrUsk*=9   (/ "%  - -)(|   9LH IIrKcddd|g}d} tj|\}}tjd|||dS|j S#tj$r)}t j td|z|fYd}~Kd}~wwxYw)Nfilez--briefz --mime-typezscript %s mime type is %sz%Failed to identify script type for %s)rr[r\ProcessExecutionErrorrlogexcrd)rgcmdf_type_erres rJ identify_filer]s 9mY 7C F 3 -y&A >45v||~5  % %  9IEqI   s/A B  BB c~|s4tjj|rtj||r4tjj |rtj||syt j ||||r`|jdsOt|}|dk(r?t j |djd|g|tjd||r tjj |rtj||ritjj|rIt jtjj|tj||yyyy#t$r%}t j td|Yd}~yd}~wwxYw) a  Write the content to content_f. Under the following rules: 1. If no content, remove the file 2. Write the content 3. If executable and no file magic, add it 4. If there is a link, create it @param content: what to write @param content_f: the file name @param backup_d: the directory to save the backup at @param link: if defined, location to create a symlink to @param shebang: if no file magic, set shebang @param mode: file mode Because of the way that Cloud-init executes scripts (no shell), a script will fail to execute if does not have a magic bit (shebang) set for the file. If shebang=True, then the script will be checked for a magic bit and to the SmartOS default of assuming that bash. N)rjz#!z text/plainrz #!/bin/bashzadded shebang to file %sz$failed establishing content link: %s)r@rAr]unlinkislinkr write_filerAr]rBr[r\ ensure_dirdirnamesymlinkIOErrorrX)contentrgrhrirjrZr\s rJrvrvs:. rww~~i0 ) t$ $ OOIwT2w))$/y) \ ! OO499mW%=>T  II0) <  Hww~~d# $277>>)4 56 9d+5w   H KKCQ G G Hs-BF F<F77F<ctj}||d}|dk(rtS|tjd}n|}|r|j drt Sy)Nr=zBrandZ virtual linuxzsystem-product-nameSmartDC)r@unamerr read_dmi_datarAr)rT product_nameri system_types rJrTrT,sb HHJEa ..##''(=> " {--i8 rKcgdgdddgd|rt|ttfs|g}ng}|rt|ttfs|g}ng}|sg}d}d}|dd |dd d }g}|D]}tfd |j D} | j d |d dd|vr| j d|dig} |j dgD]@} | dk(rddi} n!g} tfd|j D} | j d| d|| rdnd}d|vrv|j ddrd||ds\|j dgDcgc]}||d|r|}}t|r$|d||d<| j d||di|D]^}tfd |j D}|j d|d!i| j|| j d"| i`| j| C| j d#| i|j| |r|jd$||d%d&|d'Scc}w)(aReturn a dictionary of network_config by parsing provided SMARTOS sdc:nics configuration data sdc:nics data is a dictionary of properties of a nic and the ip configuration desired. Additional nic dictionaries are appended to the list. Converting the format is straightforward though it does include duplicate information as well as data which appears to be relevant to the hostOS rather than the guest. For each entry in the nics list returned from query sdc:nics, we create a type: physical entry, and extract the interface properties: 'mac' -> 'mac_address', 'mtu', 'interface' -> 'name'. The remaining keys are related to ip configuration. For each ip in the 'ips' list we create a subnet entry under 'subnets' pairing the ip to a one in the 'gateways' list. Each route in sdc:routes is mapped to a route on each interface. The sdc:routes properties 'dst' and 'gateway' map to 'network' and 'gateway'. The 'linklocal' sdc:routes property is ignored. ) mac_addressmturparamssubnetstype) address broadcastdns_nameservers dns_searchmetric pointopointrscoperrnetworkgateway)physicalsubnetroutec d|vS)N.raddrs rJ is_valid_ipv4z3convert_smartos_network_data..is_valid_ipv4 d{rKc d|vS)N:rrs rJ is_valid_ipv6z3convert_smartos_network_data..is_valid_ipv6rrKN)rgw)ipv4ipv6c3<K|]\}}|dvs||fyw)r|Nr.0rGv valid_keyss rJ z/convert_smartos_network_data..s* q!a:j3I.IQF  r| interface)rrrmacrnipsdhcprrdhcp4c3<K|]\}}|dvs||fyw)r}Nrrs rJrz/convert_smartos_network_data..s*#q!a:h;O6OQFrstatic)rrrsrrprimaryFrgatewaysrrc3:K|]\}}|dvr||fyw)r~Nrrs rJrz/convert_smartos_network_data..s.  Aq 7 33A sdstrrq nameserver)rrrssearchr)versionconfig) isinstancertupledictrpupdaterqrr)r>rrrrrpgwsrniccfgrqipr} routeentsprotorrr~rcfgrs @rJrrBs6      )J4+e}5&-K *tUm4$J (t4't4 D FA "yy{   JK0@AB C< JJ s5z2 3''%$6 #BV| '* '*yy{ (#%#0"3# 5(A  ;t,'*ggj"&=$ "3tE{73B7$$ x=08 DK-"MM9d5k$6G*HI#9E $)KKM D"KKE%L 9:$$T*MM8Y"78)9, NN6 "m6 #n Iw'( cCAF $&$  F ++Y$sIc6tj|tSr)rlist_from_depends datasources)dependss rJget_datasource_listrs  $ $Wk ::rK__main__zDo not appear to be on smartos.rrcH||vr||S|tvr"t|}|j|||<||S|dk(r7dD]}t|||t|d|d|d|d||<||S|tvr t|\}}n|d}}|j || ||<||S) Nr)rrrrrrrrrFrc)rrrsload_keyrrorq)clientrrfkeynamedepkeyrds rJrrs $;9  % %)#.G0DI,Cy+$ $ / .  /5!.1 / -H~ DICy ((!3C!8"%u 7% 8DICyrKrf)rrrfT)r<z: )indent sort_keys separators)NFr)NNNN)Drrrr-rloggingr@rr rr) cloudinitrrrrrcloudinit.eventrr getLoggerrr[rorrrrDS_NAMEr;rKMETADATA_SOCKFILErSERIAL_TIMEOUTr<rrwrur6r2 Exceptionrrrrr#r8rUr]rvrTrDEP_FILESYSTEMrrsysjmcprintexitrargvrrErrfr__annotations__rdumpsrrKrJrs.  ==1g!&(1),02,6-5&*&" " W% 9 "#$*(!:.  f M 88 C$**C$L 9  %A l"l"^P!5P$A !5A HU'AUr'! J6 68=0Hf.BF[,@//12 ; z  C { /0  388} $))+ ,%**,- .  ! xx|<D$O1401 *$**T!t LMerK