o x[h@sUddlZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z m Z m Z mZmZddlmZmZeeZdddddd d d d d dddd ZddddZdZdZdZdegZgdZdZdZdZeeeegddd id!Z dd"ddd#idd$dd%gd&Z!d'Z"d(Z#Gd)d*d*e j$Z%Gd+d,d,e&Z'Gd-d.d.e'Z(Gd/d0d0Z)Gd1d2d2e)Z*Gd3d4d4e)Z+Gd5d6d6e+Z,deeedfd7d8Z-d9d:Z. ;dOdd?Z0 dQd@dAZ1e%e j2ffgZ3dBdCZ4edDkrMddl5Z5e-Z6e6dur e7dEe58dFe9e5j:dFkr"e;e<e;e<dGgZe?e@dJ<edKq5e7ejBe>dFdLdMdNdSdS)RN) 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 r ravailability_zone vendor-dataoperator-scriptr dns_domainzsdc:nicsz sdc:resolversz sdc:routes) network-data dns_serversrouteszlx-brandkvmSmartOS datasource)r rr 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/dbc@seZdZdZejZejZej e j e j e j hiZddZddZddZdd Zd d Zd d ZddZddZddZeddZdS)DataSourceSmartOSJoyentcCsjtj||||t|jt|titg|_i|_ d|_ d|_ d|_ t j|jd|_|dS)Nscripts)r DataSource__init__r mergemanydictds_cfgget_cfg_by_path DS_CFG_PATHBUILTIN_DS_CONFIGmetadata network_data_network_config routes_dataospathjoinpaths get_cpath script_base_d_init)selfsys_cfgdistrorArHE/usr/lib/python3/dist-packages/cloudinit/sources/DataSourceSmartOS.pyr4s  zDataSourceSmartOS.__init__cCstj|}d||jfS)Nz%s [client=%s])rr3__str__ md_client)rErootrHrHrIrJs zDataSourceSmartOS.__str__cCs^|jtjkrt|_|jdurd|_|jtjkr-t|j|jd|jd|jdd|_dSdS)Nr!rr ) smartos_typer!rr )rMrUNSETget_smartos_environrKjmc_client_factoryr6rErHrHrIrDs    zDataSourceSmartOS._initcCsLtdd}tjd|dgr$td|dgd|dgdSdS)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>r?existsr@rename)rEsvc_pathrHrHrI_set_provisioneds   z"DataSourceSmartOS._set_provisionedc Cs|i}d}|jstddS|js td|jdS|jtD]\}}|\}}|jj ||d||<q)t D] \}}|j |||<q@|j t j|jd|dd}t j|d }d t} t| d || d d d t j|d} t| d| dd d| d} dt} t| | |ds|dr|d|d<n|d|d<d}|dr|d}|dst|| t j|jddd|d<t||jg|_||_|d|_|d|_|d|_|d S)NzNot running on smartosFz4No metadata device '%r' found for SmartOS datasourcestrip instancesrdatar z%s/user-scriptTi) content_flinkshebangmoder)r`rbrcrz%s/mdata-user-datarr r rr2zper-boot) user_scriptoperator_script per_boot_drr)rDrMrUrVrKrWopen_transportSMARTOS_ATTRIB_MAPitemsgetSMARTOS_ATTRIB_JSONget_jsonclose_transportr>r?r@rArB LEGACY_USER_Dwrite_boot_contentBUILTIN_VENDOR_DATArr5r: userdata_rawvendordata_rawr;r=rZ) rEmdudci_noun attribute smartos_nounr]data_drd u_script_lreu_datau_data_frHrHrI _get_datas~             zDataSourceSmartOS._get_datacCsdtS)Nz serial (%s)) SERIAL_DEVICErQrHrHrI_get_subplatformLz"DataSourceSmartOS._get_subplatformcCs|jd|S)Nr%)r6rj)rEnamerHrHrIdevice_name_to_deviceOz'DataSourceSmartOS.device_name_to_devicecCs|jtkrtSiSN)rMSMARTOS_ENV_KVMBUILTIN_CLOUD_CONFIGrQrHrHrIget_config_objRs z DataSourceSmartOS.get_config_objcCs |jdS)Nr)r:rQrHrHrIget_instance_idWs z!DataSourceSmartOS.get_instance_idcCsN|jtjkr d|_|jdur$|jdur$t|j|jd|jd|jd|_|jS)Nrrr;rrr)r<rrNr;convert_smartos_network_datar:r=rQrHrHrInetwork_configZs   z DataSourceSmartOS.network_configN)__name__ __module__ __qualname__dsnamerrNrMrKrNETWORKrBOOT_NEW_INSTANCEBOOT BOOT_LEGACYdefault_update_eventsr4rJrDrZr|r~rrrpropertyrrHrHrHrIr0s*cr0c@ eZdZdS)JoyentMetadataFetchExceptionNrrrrHrHrHrIrkrc@r)JoyentMetadataTimeoutExceptionNrrHrHrHrIrorrc@seZdZdZedZd#ddZddZdd Z d d Z d d Z ddZ d$ddZ d%ddZd$ddZddZddZddZddZdd Zd!d"ZdS)&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.+))?)NcCs|durt}||_||_dSr)rOrMfp)rErMrrHrHrIr4s zJoyentMetadataClient.__init__cCsdt|dd@S)N{0:08x}zutf-8)formatbinasciicrc32encode)rEbodyrHrHrI _checksumszJoyentMetadataClient._checksumcCs|j|}t|dt|dkr"td|dt|d||d}|d|kr9td||d|d|krItd||d|ddsVt d dSt |d}t d ||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 groupdictintlenrrrrjrUrVrb64d)rEexpected_request_idframe frame_dataexpected_checksumvaluerHrHrI_get_value_from_frames4     z*JoyentMetadataClient._get_value_from_framec sgfdd}d} z|jd}|st|||dkr#|WS|WntyD}z|jtjkr?t|||d}~wwq )z Reads a line a byte at a time until \n 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. csddS)Nascii)r@decoderHresponserHrIas_asciirz0JoyentMetadataClient._readline..as_asciizPartial response: '%s'T N)rreadrappendOSErrorerrnoEAGAIN)rErmsgbyteexcrHrrI _readlines,   zJoyentMetadataClient._readlinecCs |j|d|jdS)Nr)rwriterflush)rErrHrHrI_writeszJoyentMetadataClient._writecCsJtd|d|}td||dkrtd|tddS)NzNegotiating protocol V2z NEGOTIATE V2 z read "%s"V2_OKz'Invalid response "%s" to "NEGOTIATE V2"zNegotiation complete)rUrVrrr)rErrHrHrI _negotiates   zJoyentMetadataClient._negotiatec Csdtdd}d||f}|r|dt|7}dt|| ||}t d|d}|j s<| d}|||}|rK|t d |d |vrWdS|||}|S) Nrrr zV2 {0} {1} {2} z#Writing "%s" to metadata transport.FTz"Read "%s" from metadata transport.SUCCESS)rrandomrandintr@base64 b64encoderrrrrUrVrrgrrrmr) rErtypeparamr message_bodyr need_closerrrHrHrIrequests2    zJoyentMetadataClient.requestFcCs.|jd|d}|dur |S|r|r|}|S)NGETrr)rr])rEkeydefaultr]resultrHrHrIrjs zJoyentMetadataClient.getcCs$|j||d}|dur |St|S)N)r)rjjsonloads)rErrrrHrHrIrls zJoyentMetadataClient.get_jsoncCs|jdd}|s gS|dS)NKEYS)r )rsplit)rErrHrHrIlists  zJoyentMetadataClient.listcCs*ddd||fD}|jd|dS)N cSsg|] }t|qSrH)rrr).0irHrHrI sz,JoyentMetadataClient.put..PUTr)r@rr)rErvalrrHrHrIput s zJoyentMetadataClient.putcCs|jr |jd|_dSdSr)rcloserQrHrHrIrms  z$JoyentMetadataClient.close_transportcCs|jr|S||Sr)rrgrQrHrHrI __enter__szJoyentMetadataClient.__enter__cCs |dSr)rm)rEexc_type exc_value tracebackrHrHrI__exit__szJoyentMetadataClient.__exit__cCstr)NotImplementedErrorrQrHrHrIrgsz#JoyentMetadataClient.open_transportNNrNF)rrr__doc__recompilerr4rrrrrrrjrlrrrmrrrgrHrHrHrIrss(  !  rcs8eZdZeffdd ZddZddZddZZS) JoyentMetadataSocketClientcstt||||_dSr)superrr4 socketpath)rErrM __class__rHrIr4#s z#JoyentMetadataSocketClient.__init__cCs4ttjtj}||j|d|_|dS)Nrwb)socketAF_UNIX SOCK_STREAMconnectrmakefilerr)rEsockrHrHrIrg's   z)JoyentMetadataSocketClient.open_transportcCtj|jSr)r>r?rWrrQrHrHrIrW-z!JoyentMetadataSocketClient.existscCsd|jj|jfS)Nz%s(socketpath=%s))rrrrQrHrHrI__repr__0sz#JoyentMetadataSocketClient.__repr__) rrrSMARTOS_ENV_LX_BRANDr4rgrWr __classcell__rHrHrrIr"s rcsDeZdZdedffdd ZddZddZd d Zd d ZZ S) JoyentMetadataSerialClient Ncs"tt|||||_||_dSr)rrr4r-timeout)rEr-rrMrrrHrIr45s z#JoyentMetadataSerialClient.__init__cCrr)r>r?rWr-rQrHrHrIrW<rz!JoyentMetadataSerialClient.existsc Cs|jdur;zddl}Wnty}ztd|d}~ww|j|j|jd}|s1td|j||_t |t j | | dS)Nrzserial support is not available)rzUnable to open %s)rserial ImportErrorrSerialr-risOpen SystemErrorfcntllockfLOCK_EX_flushr)rEreserrHrHrIrg?s$   z)JoyentMetadataSerialClient.open_transportcCstd|jj}d|j_ z|Wn tyYnwqtd|dkr-d|j_n||j_ td|dz|}|dkrGWn"|d krRtd Wq1td |Wntygtd Ynwq2td ||j_dS)NzFlushing inputg?Tz 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.)rUrVrrrrrwarning)rErrrHrHrIrOsB           z!JoyentMetadataSerialClient._flushcCsd|jj|j|jfS)Nz%s(device=%s, timeout=%s))rrr-rrQrHrHrIrvs z#JoyentMetadataSerialClient.__repr__) rrrrr4rWrgrrrrHrHrrIr4s'rcsNeZdZdZdfdd ZdddZdfd d Zdd d Zdd dZZ 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.rNcs(tt|}||||d|_d|_dSr)rrr4r#r$)rEr-rrMsrrHrIr4s  z)JoyentMetadataLegacySerialClient.__init__FcCs|rd|_d|_d}|jdur$|}d|vr!t|d|_nd|_|jr)dS|jdurm|dur6|}t}d|vrGt|dd}dd|DD]}t||r^||qN||vrg| |qN||_dSdS)Nr$Fr#,cSs"g|] }|dr|ddqS)zb64-N) startswith)rkrHrHrIrs"zFJoyentMetadataLegacySerialClient._init_base64_keys..) r#r$rris_true_getsetraddremove)rEresetkeysb64_keysrrHrHrI_init_base64_keyss2     z2JoyentMetadataLegacySerialClient._init_base64_keyscstt|j|||dS)N)rr])rrrj)rErrr]rrHrIrs z%JoyentMetadataLegacySerialClient._getcCs,|tvrdS|j|d|jrdS||jvS)NF)r T)NO_BASE64_DECODEr#r$r#)rErr rHrHrIis_b64_encodeds   z/JoyentMetadataLegacySerialClient.is_b64_encodedcCsvt}|j|d|d}||ur|S||r3z t|}Wntjy2t d||Ynw|r9| }|S)NF)r]rz#Failed base64 decoding key '%s': %s) objectrr%r b64decoderrrErrorrUrr])rErrr]mdefaultrrHrHrIrjs z$JoyentMetadataLegacySerialClient.get)rN)Fr) rrrrr4r#rr%rjrrHrHrrIr~s "  rcCsR|durt|}|durdS|tkrt|||dS|tkr#t||dStd|)N)r-rrM)rrMz"Unknown value for smartos_type: %s)rOrrrr ValueError)rMr!rr uname_versionrHrHrIrPs rPc Csddd|g}d}zt|\}}td||Wntjy5}zttd||fWYd}~nd}~ww|durr?rWunlinkislinkr write_filerr2r@rUrV ensure_dirdirnamesymlinkIOErrorr.)contentr`rarbrcr0rrHrHrIros6      rocCsRt}|dur |d}|dkrtS|durtd}n|}|r'|dr'tSdS)NrzBrandZ virtual linuxzsystem-product-nameSmartDC)r>unamerr read_dmi_datarr)r+ product_namer= system_typerHrHrIrO1s rOcsLgdgdddgd|rt|ttfs|g}ng}|r(t|ttfs'|g}ng}|s.g}dd}dd }|d d |d d d g}|D]}tfd d|D}|d|ddd|vrk|d|dig} |dgD]} | dkr~ddi} n| dkrddi} n{g} tfdd|D} | d| d|| rdndd|vr|dd rۈd!sۇfd"d#|d$gD} t| r| d%d!<| dd!i|D]$}tfd&d|D}|d|d'i| || d(| iq| | qs|d)| i||qE|r!|d*||d+d,|d-S).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 pointopointrscoperEnetworkgateway)physicalsubnetroutecSd|vS)N.rHaddrrHrHrI is_valid_ipv4rz3convert_smartos_network_data..is_valid_ipv4cSrR)N:rHrTrHrHrI is_valid_ipv6rz3convert_smartos_network_data..is_valid_ipv6N)rgw)ipv4ipv6c3(|]\}}|dvr||fVqdS)rONrHrrv valid_keysrHrI z/convert_smartos_network_data..rO interface)rErmacrAipsdhcprEdhcp4addrconfdhcp6c3r\)rPNrHr]r_rHrIrarbstatic)rErFrZr[primaryFrYcs g|] }d|r|qS)rrH)rrY)pgwsprotorHrIrs z0convert_smartos_network_data..gatewaysrc3r\)rQNrHr]r_rHrIras dstrrD nameserver)rErFsearchr)versionconfig) isinstancertupledictriupdaterjrr)r;rrrrVrXrsniccfgrDiprP routeentsrnrQrcfgrH)rlrmr`rIrGs             rcCs t|tSr)rlist_from_depends datasources)dependsrHrHrIget_datasource_lists r__main__zDo not appear to be on smartos.rrcCs||vr||S|tvrt|}||||<||S|dkr@dD]}t|||q!t|d|d|d|dd||<||S|tvrKt|\}}n|d}}|j||d ||<||S) Nr)rrrrrrrrrFr\)rkrlload_keyrrhrj)clientrr_keynamedepkeyr]rHrHrIrs*   rr_)rrr_T)rz: )indent sort_keys separators)NFr3r)NNNN)Crrrr rloggingr>rrr cloudinitrrrrrcloudinit.eventrr getLoggerrrUrhrkrrDS_NAMEr8r$METADATA_SOCKFILEr}SERIAL_TIMEOUTr9rrprnr3r0 ExceptionrrrrrrrPr2rorOrDEP_FILESYSTEMr~rsysjmcprintexitrargvrr!rr_rv__annotations__rdumpsrHrHrHrIs     H0JY  3  #