� oB�]c @sqddlZddlZddlZddlZddlZddlZddlZddlZddlZddl m Z ddl m Z ddl m Z ddl mZddlmZe je�Zi defd6d efd 6d efd 6d efd 6defd6defd6defd6defd6defd6defd6defd6defd 6defd6Zidd6dd6d d!6Zd"Zd#Zd$Zd%egZddd dd&d gZd'Zd(Zd)Zied*6ed+6ed,6ed-6gd.6ed/6id0d16d26Z iiid3d46ed56ed66d16d76id1d86d9d:6d1d;6gd<�6Z!d=Z"d>Z#d?e j$fd@��YZ%dAe&fdB��YZ'dCe'fdD��YZ(dEe)fdF��YZ*dGe*fdH��YZ+dIe*fdJ��YZ,dKe,fdL��YZ-deeeddM�Z/dN�Z0dedOdP�Z1dddQ�Z2dddddR�Z3e%e j4ffgZ5dS�Z6edTkrmddl7Z7e/�Z8e8dkr�dUGHe7j9dV�ne:e7j;�dVkre<�ej=��e<�ej=��dWgZ=n e7j;dVZ=dX�Z>iZ?x'e=D]Z@e>dYe8dZe@d[e?�q'WejAe?d\dVd]ed^da�GHndS(bi����N(tlog(tserial(tsources(tutil(t EventTypessdc:uuids instance-idthostnameslocal-hostnametroot_authorized_keyss public-keyss user-scripts user-dataslegacy-user-datascloud-init:user-datatiptables_disablet motd_sys_infossdc:datacenter_nametavailability_zonessdc:vendor-datas vendor-datassdc:operator-scriptsoperator-scripts sdc:hostnamessdc:dns_domaint dns_domainssdc:nicss network-datas sdc:resolverst dns_serverss sdc:routestroutesslx-brandtkvmtSmartOSt datasourcessdc:uuiduser-datas"/native/.zonecontrol/metadata.socks /dev/ttyS1i<�t serial_devicetserial_timeouttmetadata_sockfiletno_base64_decodet base64_keyst base64_alls/dev/vdbt ephemeral0t disk_aliasestmbrt table_typetlayoutt overwritet disk_setuptlabeltext4t filesystemtdevicetfs_setupsU#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" s/var/dbtDataSourceSmartOScBs�eZdZejZejZd�Zd�Zd�Z d�Z d�Z d�Z d�Z d�Zd �Zed ��ZRS( tJoyentcCs�tjj||||�tj|jtj|ti�tg�|_i|_ d|_ d|_ |j djtj�tjj|jjd��|_|j�dS(Ntnetworktscripts(Rt DataSourcet__init__Rt mergemanydicttds_cfgtget_cfg_by_patht DS_CFG_PATHtBUILTIN_DS_CONFIGtmetadatatNonet network_datat_network_configt update_eventstaddRtBOOTtostpathtjointpathst get_cpatht script_base_dt_init(tselftsys_cfgtdistroR7((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR'�s   !cCs#tjj|�}d||jfS(Ns%s [client=%s](RR&t__str__t md_client(R;troot((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR>�sc Cs�|jtjkr<�t�|_|jdkr<�d|_q<�n|jtjkr�td|jd|jdd|jdd|jd�|_ndS(Nt smartos_typeRRR(RARtUNSETtget_smartos_environR.R?tjmc_client_factoryR)(R;((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR:�s    cCsitjd�d}tjjdj|dg��retjdj|dg�dj|dg��ndS(s�Mark 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. s-Instance provisioning state set as successfuls/var/svct/t provisioningtprovision_successN(tLOGtdebugR4R5texistsR6trename(R;tsvc_path((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyt_set_provisioned�s !c Cs�|j�i}d}|js0tjd�tS|jj�sVtjd|j�tS|jj�xBtj �D]4\}}|\}}|jj |d|�||R:RMRqRsRuRxRytpropertyR{(((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR"�s      W    tJoyentMetadataFetchExceptioncBseZRS((R|R}(((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR�SstJoyentMetadataTimeoutExceptioncBseZRS((R|R}(((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR�WstJoyentMetadataClientcBs�eZdZejd�Zddd�Zd�Zd�Z d�Z d�Z d�Z dd�Z ded �Zdd �Zd �Zd �Zd �Zd�Zd�Zd�Zd�ZRS(s� A client implementing v2 of the Joyent Metadata Protocol Specification. The full specification can be found at http://eng.joyent.com/mdata/protocol.html s~V2 (?P\d+) (?P[0-9a-f]+) (?P(?P[0-9a-f]+) (?PSUCCESS|NOTFOUND)( (?P.+))?)cCs.|dkrt�}n||_||_dS(N(R.RCRAtfp(R;RAR�((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR'gs   cCs#djtj|jd��d@�S(Ns{0:08x}sutf-8I����(tformattbinasciitcrc32tencode(R;tbody((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyt _checksummscCs|jj|�j�}t|d�t|d�kratdj|dt|d����n|j|d�}|d|kr�tdj||d���n|d|kr�tdj||d���n|jdd�s�t j d �dSt j |d�}t j d |�|S( NtlengthR�s*Incorrect frame length given ({0} != {1}).tchecksums*Invalid checksum (expected: {0}; got {1}).t request_ids-Request ID mismatch (expected: {0}; got {1}).tpayloadsNo value found.sValue "%s" found.(t line_regextmatcht groupdicttinttlenR�R�R�R]R.RHRIRtb64d(R;texpected_request_idtframet frame_datatexpected_checksumtvalue((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyt_get_value_from_frameqs(   cs�g��fd�}d}x�tr�y^|jjd�}t|�dkrat||���n|dkrt|�S�j|�Wqtk r�}|jtjkr�t||���n�qXqWdS(s 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. csdj��jd�S(NRNtascii(R6tdecode((tresponse(sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pytas_ascii�ssPartial response: '%s'iis N( RcR�treadR�R�tappendtOSErrorterrnotEAGAIN(R;R�tmsgtbytetexc((R�sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyt _readline�s  cCs*|jj|jd��|jj�dS(NR�(R�twriteR�tflush(R;R�((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyt_write�scCsftjd�|jd�|j�}tjd|�|dkrUtd|��ntjd�dS(NsNegotiating protocol V2s NEGOTIATE V2 s read "%s"tV2_OKs'Invalid response "%s" to "NEGOTIATE V2"sNegotiation complete(RHRIR�R�R�(R;R�((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyt _negotiate�s    c Csdjtjdd��}dj||f�}|r\|dtj|j��j�7}ndjt|�|j |�|�}t j d|�t }|j s�|j�t}n|j|�|j�}|r�|j�nt j d|�d|kr�dS|j||�}|S( Ns{0:08x}iI����t sV2 {0} {1} {2} s#Writing "%s" to metadata transport.s"Read "%s" from metadata transport.tSUCCESS(R�trandomtrandintR6tbase64t b64encodeR�R�R�R�RHRIRYR�RZRcR�R�R`R.R�( R;trtypetparamR�t message_bodyR�t need_closeR�R�((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pytrequest�s(&       cCsG|jddd|�}|dkr(|S|rC|rC|j�}n|S(NR�tGETR�(R�R.RO(R;tkeytdefaultROtresult((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR]�s   cCs2|j|d|�}|dkr%|Stj|�S(NR�(R]R.tjsontloads(R;R�R�R�((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR_�s cCs)|jdd�}|sgS|jd�S(NR�tKEYSs (R�tsplit(R;R�((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pytlist�scCsSdjg||fD]}tj|j��^q�j�}|jddd|�S(NR�R�tPUTR�(R6R�R�R�R�R�(R;R�tvaltiR�((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pytput�s 4cCs|jddd|�S(NR�tDELETER�(R�(R;R�((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pytdelete�scCs&|jr"|jj�d|_ndS(N(R�tcloseR.(R;((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR`�s  cCs|jr |S|j�|S(N(R�RZ(R;((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyt __enter__�s  cCs|j�dS(N(R`(R;texc_typet exc_valuet traceback((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyt__exit__�s cCs t�dS(N(tNotImplementedError(R;((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyRZ�sN(R|R}t__doc__tretcompileR�R.R'R�R�R�R�R�R�RYR]R_R�R�R�R`R�R�RZ(((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR�[s&             tJoyentMetadataSocketClientcBs/eZed�Zd�Zd�Zd�ZRS(cCs#tt|�j|�||_dS(N(tsuperR�R't socketpath(R;R�RA((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR'�scCsHtjtjtj�}|j|j�|jd�|_|j�dS(Ntrwb(tsockettAF_UNIXt SOCK_STREAMtconnectR�tmakefileR�R�(R;tsock((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyRZ�scCstjj|j�S(N(R4R5RJR�(R;((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyRJscCsd|jj|jfS(Ns%s(socketpath=%s)(t __class__R|R�(R;((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyt__repr__s(R|R}tSMARTOS_ENV_LX_BRANDR'RZRJR�(((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR��s   tJoyentMetadataSerialClientcBs>eZdedd�Zd�Zd�Zd�Zd�ZRS(i cCs/tt|�j||�||_||_dS(N(R�R�R'R ttimeout(R;R R�RAR�((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR' s cCstjj|j�S(N(R4R5RJR (R;((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyRJscCs�|jdkrktj|jd|j�}|j�sLtd|j��n||_tj |tj �n|j �|j �dS(NR�sUnable to open %s( R�R.RtSerialR R�tisOpent SystemErrortfcntltlockftLOCK_EXt_flushR�(R;tser((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyRZs   cCs=tjd�|jj}d|j_x-trTy|j�Wq(tk rPPq(Xq(Wtjd�|dkr}d|j_n ||j_x�trtjd�|jd�yO|j�}|dkr�Pn|dkr�tjd �w�ntjd |�Wq�tk rtjd �q�Xq�Wtjd �||j_dS( NsFlushing inputg�������?s Input emptyis,Writing newline, expecting "invalid command"s sinvalid commandtFAILUREsGot "FAILURE". Retrying.s%Unexpected response "%s" during flushsQTimeout while initializing metadata client. Is the host metadata service running?s'Got "invalid command". Flush complete.( RHRIR�R�RcR�R�R�twarning(R;R�R�((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR� s6                  cCsd|jj|j|jfS(Ns%s(device=%s, timeout=%s)(R�R|R R�(R;((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR�EsN( R|R}RvR.R'RJRZR�R�(((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR� s    %t JoyentMetadataLegacySerialClientcBsSeZdZddd�Zed�Zded�Zed�Zded�Z RS(s�V1 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.i cCs8tt|�}|j|||�d|_d|_dS(N(R�R�R'R.RR(R;R R�RAts((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR'Ys cCsj|rd|_d|_nd}|jdkrr|j�}d|krftj|jd��|_qrt|_n|jrdS|jdkrf|dkr�|j�}nt�}d|kr�t|jd�j d��}nxxg|D]}|j d�r�|d^q�D]J}tj|j|��r:|j |�q ||kr |j |�q q W||_ndS(NRRt,sb64-i( R.RRR�Rtis_truet_getRYtsetR�t startswithR2tremove(R;tresettkeystb64_keystkR�((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyt_init_base64_keys_s.         !3 cCs"tt|�j|d|d|�S(NR�RO(R�R�R](R;R�R�RO((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR��scCs:|tkrtS|jd|�|jr-tS||jkS(NR�(tNO_BASE64_DECODERYR�RRcR(R;R�R�((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pytis_b64_encoded�s   cCs�t�}|j|dtd|�}||kr4|S|j|�r�ytj|j��j�}Wq�tt j fk r�t j d||�q�Xn|r�|j �}n|S(NROR�s#Failed base64 decoding key '%s': %s(tobjectR�RYR�R�t b64decodeR�R�t TypeErrorR�tErrorRHR�RO(R;R�R�ROtmdefaultR�((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR]�s  N( R|R}R�R.R'RYR�R�R�R](((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyR�Js   " cCs�|dkrt|�}n|dkr+dS|tkrPtd|d|d|�S|tkrotd|d|�Std|��dS(NR R�RAR�s"Unknown value for smartos_type: %s(R.RCRvR�R�R�t ValueError(RARRRt uname_version((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyRD�s      cCs�ddd|g}d}y,tj|�\}}tjd||�Wn0tjk rv}tjtd||f�nX|dkr�dS|j�S(Ntfiles--briefs --mime-typesscript %s mime type is %ss%Failed to identify script type for %s(R.RtsubpRHRItProcessExecutionErrortlogexcRO(RRtcmdtf_typet_errte((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyt identify_file�sicCsz| r)tjj|�r)tj|�n|rQtjj|�rQtj|�n|s[dStj||d|�|r�|jd� r�t|�}|dkr�tj|dj d|g�d|�t j d|�q�n|rvyjtjj|�rtj|�n|rItjj|�rItj tjj |��tj||�nWqvtk rr}tjt d|�qvXndS( s  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 Becuase 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. NRUs#!s text/plains s #!/bin/bashsadded shebang to file %ss$failed establishing content link: %s(R4R5RJtunlinktislinkRt write_fileR�RR6RHRIt ensure_dirtdirnametsymlinktIOErrorR(tcontentRRRSRTRURR((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyRb�s,  cCsvtj�}|dkr%|d}n|dkr5tS|dkrStjd�}n|}|rr|jd�rrtSdS(NisBrandZ virtual linuxssystem-product-nametSmartDC(R4tunameR.R�Rt read_dmi_dataR�Rv(R�t product_nameRt system_type((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyRC�s     c s�iddddddgd6dd d d d d dddg d6ddgd6�|rxt|ttf�s~|g}q~ng}|r�t|ttf�s�|g}q�ng}|s�g}nd�}d�}ii|d6d,d6d6i|d6d,d6d6}g}xR|D]J}t�fd�|j�D��} | jidd6|dd6�d|krz| ji|dd6�ng} x�|jdg�D]�} | dkr�idd6} nog} t�fd �|j�D��} | jid!d6| d6�|| �r dnd}d"|kr�|jd"t�r�||ds�g|jd#g�D] }||d|�rO|^qO}t |�r�|d$||d<| ji||dd6�q�q�nxi|D]a}t�fd%�|j�D��}|ji|d&d6�| j |�| ji| d6�q�W| j | �q�W| ji| d6�|j | �q W|r�|j id'd6|d6|d(6�nid)d*6|d+6S(-sReturn 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. t mac_addresstmtuRttparamstsubnetsttypetphysicaltaddresst broadcasttdns_nameserverst dns_searchtmetrict pointopointR tscopetsubnetR$tgatewaytroutecSs d|kS(Nt.((taddr((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyt is_valid_ipv4MscSs d|kS(Nt:((R&((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyt is_valid_ipv6PsR�tgwtipv4tipv6c3s1|]'\}}|�dkr||fVqdS(RN((t.0R�tv(t valid_keys(sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pys Zs t interfacetmactipstdhcptdhcp4c3s1|]'\}}|�dkr||fVqdS(R"N((R-R�R.(R/(sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pys hs tstatictprimarytgatewaysic3s1|]'\}}|�dkr||fVqdS(R$N((R-R�R.(R/(sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pys ~s tdstt nameservertsearchitversiontconfigN( t isinstanceR�ttupleR.tdictR\tupdateR]RYR�R�(R/R R R R'R)tpgwsR<tnictcfgRtipR"t routeentstprotoR*R7R$trcfg((R/sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pyRz s�       "   "    % " cCstj|t�S(N(Rtlist_from_dependst datasources(tdepends((sG/usr/lib/python2.7/site-packages/cloudinit/sources/DataSourceSmartOS.pytget_datasource_list�st__main__sDo not appear to be on smartos.iR{c Cs�||kr||S|tkr@t|}|j|�||s�                          (��>Y   0 �     ,