a 'Dg@sddlZddlZddlZddlZddlZddlZddlZddlmZddl m Z m Z ddl m Z mZmZmZmZmZddlmZmZmZmZmZmZmZddlmZddlmZddlmZdd l m!Z!dd l"m#Z#m$Z$dd l%m&Z&dd l'm(Z(dd l)m*Z*ddl+m,Z,dZ-dZ.dZ/dZ0e-e.e/gZ1dZ2dZ3dZ4dZ5dZ6dZ7dZ8dZ9e:e;ZGd%d&d&e Z?Gd'd(d(e@ZAGd)d*d*e@ZBGd+d,d,e@ZCdYd/d0ZDe6fd1d2ZEed3gd4ZFed5d6d7gZGGd8dde*ejHd9ZId:d;ZJeeIeKfd<d=d>ZLd?d@ZMdZeKeNdBdCdDZOdEdFZPd[dHdIZQGdJdKdKeRZSdLdMZTeIeKeNdNdOdPZUeKeeIdQdRdSZVeKd<dTdUZWeKeKdVdWdXZXdS)\N) namedtuple)Enumunique)AnyDictListOptionalTupleUnion) atomic_helperdmiimporter lifecyclenet performance type_utils) user_data)util) write_json)Distro) EventScope EventType) launch_index)Paths)CloudInitPickleMixin)eventsZdisabledlocalrpassZ FILESYSTEMNETWORK DataSourcez|EXPERIMENTAL: The structure and format of content scoped under the 'ds' key may change in subsequent releases of cloud-init.zredacted for non-root user cloud-nameZ_unsetunknownz aws-chinacCs|dkSNZawscr#r#>/usr/lib/python3.9/site-packages/cloudinit/sources/__init__.pyGr'zaws-govcCs|dkSr"r#r$r#r#r&r'Hr(z azure-chinacCs|dkS)NZazurer#r$r#r#r&r'Ir()zcn-zus-gov-Zchinac@s2eZdZdZdZdZdZdZdZe ddd Z d S) NetworkConfigSourcezb Represents the canonical list of network config sources that cloud-init knows about. ZcmdlinedsZ system_cfgfallbackZ initramfsreturncCs|jSNvalueselfr#r#r&__str__ZszNetworkConfigSource.__str__N) __name__ __module__ __qualname____doc__CMD_LINEDS SYSTEM_CFGZFALLBACK INITRAMFSstrr3r#r#r#r&r)Msr)c@s&eZdZdZdZdZedddZdS)NicOrderzRepresents ways to sort NICsZmacZnic_namer,cCs|jSr.r/r1r#r#r&r3dszNicOrder.__str__N)r4r5r6r7ZMACZNIC_NAMEr<r3r#r#r#r&r=^sr=c@seZdZdZdS)DatasourceUnpickleUserDataErrorzERaised when userdata is unable to be unpickled due to python upgradesNr4r5r6r7r#r#r#r&r>hsr>c@s eZdZdS)DataSourceNotFoundExceptionNr4r5r6r#r#r#r&r@lsr@c@seZdZdZdS)InvalidMetaDataExceptionz8Raised when metadata is broken, unavailable or disabled.Nr?r#r#r#r&rBpsrBr#c Cst|}g}g}|D]\}}|r4|d|}n|}||vsP||vrZ||t|tr|dr|||dd||<t|t rt |||} | | d| | d| ||<qt ||d<t ||d<|S)zProcess all instance metadata cleaning it up for persisting as json. Strip ci-b64 prefix and catalog any 'base64_encoded_keys' as a list @return Dict copy of processed metadata. /zci-b64:rCbase64_encoded_keyssensitive_keys)copydeepcopyitemslowerappend isinstancer< startswithreplacedictprocess_instance_metadataextendpopsorted) metadatakey_pathrFmd_copyrEZ sens_keyskeyvalZ sub_key_pathZ return_valr#r#r&rPts2         rPcCs|dgs|St|}|dD]V}|d}|}|D].}||vr:t||tr:||dkr:||}q:||vr$|||<q$|S)zRedact any sensitive keys from to provided metadata dictionary. Replace any keys values listed in 'sensitive_keys' with redact_value. rFrD)getrGrHsplitrLrO)rTZ redact_valuerVrU path_partsobjpathr#r#r&redact_sensitive_keyss"       r_ URLParams)Zmax_wait_secondsZtimeout_secondsZ num_retriessec_between_retriesDataSourceHostnamehostname is_defaultc @seZdZUeZdZdZdZee e d<dZ dZ dZ eeee fe d<ejejejejfZeedfe d<dZd Zd Zd Zejejejej ej!hiZ"ejejhiZ#d e$fd e$fdifddddddf Z%eee e&fdfe d<dZ'dZ(ee dfe d<dZ)dZ*ee e d<d Z+d|e,e-dddZ.e/ddddZ0d d!Z1e2d"d#d$Z3e2d"d%d&Z4d'd(Z5d)d*Z6d}d,d-Z7e8j9d.d/d0e2d"d1d2Z:d~d4d5Z;e2d"d6d7Zdd?Z@eAd@dAZBeAdBdCZCdDdEZDeAdFdGZEdHdIZFeAdJdKZGdLdMZHdNdOZIdPdQZJdRdSZKdTdUZLdVdWZMdXdYZNdZd[ZOd\d]ZPd^d_ZQeAd`daZReAdbdcZSdddeZTddfdgZUdhdiZVeWedjdkdlZXeWee2dmdndoZYdpdqZZdrdsZ[e\ddtduZ]eAdvdwZ^dxdyZ_dzd{Z`dS)rz en_US.UTF-8Z_undefN _cloud_name_crawled_metadata.network_config_sourcesrY  ec2_metadata network_jsonrT)userdataN) userdata_rawN) vendordataN)vendordata_rawN) vendordata2N)vendordata2_rawNcached_attr_defaultsF) Zcombined_cloud_config merged_cfgmerged_system_cfgzsecurity-credentialsrm user-datarro vendor-datazds/vendor_datasensitive_metadata_keysextra_hotplug_udev_rules)distropathscCs||_||_||_d|_i|_d|_d|_d|_d|_d|_ d|_ t |_ t |_ t|jd|jfi|_|jsri|_|st|j|_n||_dS)NZ datasource)sys_cfgrzr{rmrTrnrorqrprrmetadata_addressUNSETrlrkrZget_cfg_by_pathdsnameds_cfgudZUserDataProcessorud_proc)r2r|rzr{rr#r#r&__init__Ds*zDataSource.__init__)ci_pkl_versionr-c Csdddtddtdddd }|D]\}}t||s"t|||q"t|ds\t|dddt|dr|jdurzt|jWn8ty}z td|t |WYd}~n d}~00dS) z(Perform deserialization fixes for Paths.NF) rf_platform_type _subplatformrkryr}rlskip_hotplug_detectrqrrcheck_if_fallback_is_allowedcSsdSNFr#r#r#r#r&r'qr(z&DataSource._unpickle..rmz:Unable to unpickle datasource: %s. Ignoring current cache.) r~rIhasattrsetattrrmr<AttributeErrorLOGdebugr>)r2rZexpected_attrsrWr0er#r#r& _unpickle^s2   zDataSource._unpicklecCs t|Sr.robj_namer1r#r#r&r3szDataSource.__str__r,cCsdS)z#Check if running on this datasourceTr#r1r#r#r& ds_detectszDataSource.ds_detectcCsN|jtkr$td|dS|jdg|jgkrJtd|dSdS)aJOverride if either: - only a single datasource defined (nothing to fall back to) - command line argument is used (ci.ds=OpenStack) Note: get_cmdline() is required for the general case - when ds-identify does not run, _something_ needs to detect the kernel command line definition. z6Kernel command line set to use a single datasource %s.TZdatasource_listz2Datasource list set to use a single datasource %s.F)rrJ parse_cmdlinerrr|rZr1r#r#r&override_ds_detects zDataSource.override_ds_detectcCs@|r|S|r,td||Std|dSdS)z&Overrides runtime datasource detectionz Detected %szDid not detect %sFN)r _get_datarrrr1r#r#r&_check_and_get_datas zDataSource._check_and_get_datacCs|j}|}|j}|d}ddg||t|j|j|j|j|j|dd|dd|dd|j||d|||d d|||d d |j|j |d |d d iS)z2Return a dictionary of standardized metadata keys.sys_infov1 subplatformZdistrrjZpythonunameplatformvariant)Z _beta_keysavailability-zoneavailability_zonecloud_idr cloud_namerzZdistro_versionZdistro_releaserZpublic_ssh_keysZpython_version instance-id instance_idZkernel_releaselocal-hostnamelocal_hostnamemachineregionrZsystem_platformr) get_hostnamercget_instance_idrcanonical_cloud_idrr platform_typeget_public_ssh_keysr)r2 instance_datarrrZsysinfor#r#r&_get_standardized_metadatas>       z%DataSource._get_standardized_metadatar#cCsL|js dS|r|}n|j}|D]\}}t||rt|||q|sHd|_dS)zReset any cached metadata attributes to datasource defaults. @param attr_defaults: Optional tuple of (attr, value) pairs to set instead of cached_attr_defaults. NF) _dirty_cachersrr)r2Z attr_defaultsZ attr_valuesZ attributer0r#r#r&clear_cached_attrss  zDataSource.clear_cached_attrszGetting metadataalways)Zlog_modecCs"d|_|}|s|S||S)zDatasources implement _get_data to setup metadata and userdata_raw. Minimally, the datasource should return a boolean True on success. T)rrpersist_instance_data)r2Z return_valuer#r#r&get_datas zDataSource.get_dataTc Cs\|r&tj|jjr&t||jd|jdur^t |j}| dd| ddd|i}n>dd|j ii}|j t kr|j |dd<|jt kr|j|dd<t|dd <t |j|d <d |d d <t |d |d <d |d d <t|d<|||z"t|}tt||jd}WnntyX}ztdt|WYd}~dSd}~0ty}ztdt|WYd}~dSd}~00|j d}|d!dd}tj"|jj#d} t$| d||dd} | d|} tj%| rtj&| } tj'| | dd| r0| | kr0t(| t)||dd|j d} t)| t*|dS)aPProcess and write INSTANCE_JSON_FILE with all instance metadata. Replace any hyphens with underscores in key names for use in template processing. :param write_cache: boolean set True to persist obj.pkl when instance_link exists. @return True on successful write, False otherwise. Zobj_pklNrvrwr*Z meta_datarlrkZ_docrtz, (str, bool). 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. Optionally return (None, False) when metadata_only is True and local-hostname data is not available. Z localdomainZ localhostFrNT.rzip-%srrjz%s.%s)rTrZrbrrZget_fqdn_from_hostsfindr<r[rZis_ipv4_addressZ gethostbyaddrrNrr) r2ZfqdnZ resolve_ipZ metadata_onlyZ defdomainZdefhostdomainrdZtoksrcZ hosts_fqdnZlhostr#r#r&r5sF         zDataSource.get_hostnamecCs|jj|dS)N)Z data_source)rzget_package_mirror_infor1r#r#r&r}sz"DataSource.get_package_mirror_info)source_event_typescCsPi}|D]B}|jD]2\}}||vr||s:t||<|||qq|Sr.)supported_update_eventsrIrZsetadd)r2rsupported_eventseventZ update_scopeZ update_eventsr#r#r&get_supported_eventss  zDataSource.get_supported_events)rr-c Cs||}|D]<\}}td|jddd|D|d|tffq|rl||}|rldStd|ddd|Dd S) aRefresh cached metadata if the datasource supports this event. The datasource has a list of supported_update_events which trigger refreshing all cached metadata as well as refreshing the network configuration. @param source_event_types: List of EventTypes which may trigger a metadata update. @return True if the datasource did successfully update cached metadata due to source_event_type. z:Update datasource metadata and %s config due to events: %s, cSsg|] }|jqSr#r/.0rr#r#r& r(z;DataSource.update_metadata_if_supported..z _%s_configTz(Datasource %s not updated for events: %scSsg|] }|jqSr#r/rr#r#r&rr(F) rrIrrr0rrr~r)r2rrZscopeZmatched_eventsresultr#r#r&update_metadata_if_supporteds& z'DataSource.update_metadata_if_supportedcCsdSrr#)r2r|r#r#r&check_instance_idszDataSource.check_instance_idcCsdS)acheck_if_fallback_is_allowed() Checks if a cached ds is allowed to be restored when no valid ds is found in local mode by checking instance-id and searching valid data through ds list. @return True if a ds allows fallback, False otherwise. Fr#r1r#r#r&rsz'DataSource.check_if_fallback_is_allowedcCsV|dur t}|durt}|D]4}|dur*q||vr:|Std|||Sq|S)Nz%invalid dsmode '%s', using default=%s)DSMODE_NETWORK VALID_DSMODESrr)Z candidatesdefaultZvalid candidater#r#r&_determine_dsmodes zDataSource._determine_dsmodecCsdSr.r#r1r#r#r&network_configszDataSource.network_configcCsdS)a(setup(is_new_instance) This is called before user-data and vendor-data have been processed. Unless the datasource has set mode to 'local', then networking per 'fallback' or per 'network_config' will have been written and brought up the OS at this point. Nr#)r2is_new_instancer#r#r&setups zDataSource.setupcCsdS)aactivate(cfg, is_new_instance) This is called before the init_modules will be called but after the user-data and vendor-data have been fully processed. The cfg is fully up to date config, it contains a merged view of system config, datasource config, user config, vendor config. It should be used rather than the sys_cfg passed to __init__. is_new_instance is a boolean indicating if this is a new instance. Nr#)r2Zcfgr r#r#r&activates zDataSource.activate)N)r#)T)F)FFF)NN)ar4r5r6rZdsmoderrrerr<__annotations__rrrfr rr)r8r;r:r9rgr rrrrrrrBOOT_NEW_INSTANCEZBOOTZ BOOT_LEGACYZHOTPLUGrZdefault_update_eventsr~rsrrrxrryZ_ci_pkl_versionrrrrrr3boolrrrrrrZtimedrrrrrrrpropertyrrrrrrrrrrrrrrrrrrrrrrrrrr staticmethodrr r r r#r#r#r&rs     $&   L<           H &    ) metaclasscCsg}|s |St|tr|St|ttfr4t|St|tr|D]>\}}t|tr^|g}t|ttfrF|D]}|rp||qpqF|Sr.)rLr< splitlineslistrrOrIrK)Z pubkey_datakeysZ_keynameZklistZpkeyr#r#r&rs    rr,c Cs6t|||}dd|D}t|vr&dnd} td| |t||D]\} } tjd| ddd | | fd | | f|d } z~| ftd | | |||} | t j grd | | f| _ | t | fWdWSWdn1s0YWqBtyttd| YqB0qBdd|}t|dS)NcSsg|]}t|qSr#r)rrr#r#r&rr(zfind_source..networkrz#Searching for %s data source in: %sz search-%srrCzsearching for %s data from %szno %s data found from %s)name descriptionmessageparentz%Seeing if we can get any data from %szfound %s data from %szGetting data from %s failedz4Did not find any data source, searched classes: (%s)r) list_sources DEP_NETWORKrrziprZReportEventStackrNrrrrrrrrrrr@)r|rzr{Zds_depscfg_listpkg_listZreporterds_listZds_namesrrclsZmyrepsmsgr#r#r& find_sources4     Dr$c Csg}td||||D]j}t|}t||dg\}}|sJtd||D]2}t|} t| d} | |} | rN|| qqNq|S)zReturn a list of classes that have the same depends as 'depends' iterate through cfg_list, loading "DataSource*" modules and calling their "get_datasource_list". Return an ordered list of classes that match (if any) zLLooking for data source in: %s, via packages %s that matches dependencies %sZget_datasource_listzDCould not import %s. Does the DataSource exist and is it importable?) rrr Z"match_case_insensitive_module_name find_moduleerror import_modulegetattrrQ) rdependsrZsrc_listr*Zds_nameZm_locsZ _looked_locsZm_locmodZlistermatchesr#r#r&r3s2    r system-uuid)fieldr-cCs*|sdSt|}|sdS||kSr)r Z read_dmi_datarJ)rr-Z dmi_valuer#r#r&instance_id_matches_system_uuidWs  r.cCsl|st}|st}|tkr(|tkr$|S|StD]*\}}|\}}||r0||r0|Sq0|tkrh|S|S)z@Lookup the canonical cloud-id for a given cloud_name and region.)rCLOUD_ID_REGION_PREFIX_MAPrIrM)rrrprefixZ cloud_id_testrZ valid_cloudr#r#r&res rTcCsj|sdSt|tr|St|tr*t|St|trV|durNt|dddStdtdt |dS)aLdata: a loaded object (strings, arrays, dicts). return something suitable for cloudinit vendordata_raw. if data is: None: return None string: return string list: return data the list is then processed in UserDataProcessor dict: return convert_vendordata(data.get('cloud-init')) NTz cloud-initF)recursez'vendordata['cloud-init'] cannot be dictz$Unknown data type for vendordata: %s) rLr<rrGrHrOconvert_vendordatarZrr)datar1r#r#r&r2xs     r2c@s eZdZdS)BrokenMetadataNrAr#r#r#r&r4sr4cCs4g}t|}|D]\}}|t|kr||q|Sr.)rrK)r)r Zret_listZdepsetr!Zdepsr#r#r&list_from_dependss    r5)r]fnamer-cCspzt|}Wn"ty0ttd|YdS0ztj||dddWn"tyjttd|YdS0dS)z[Use pickle to serialize Datasource to a file as a cache. :return: True on success zFailed pickling datasource %sFwb)Zomoderz Failed pickling datasource to %sT)pickledumpsrrrrr)r]r6Z pk_contentsr#r#r&rs  r)r6r-c Csd}zt|}Wn>tyP}z&tj|rr)r6Zpickle_contentsrr#r#r&pkl_loads $   r<cCs ttS)zCheck if command line argument for this datasource was passed Passing by command line overrides runtime datasource detection )parse_cmdline_or_dmirZ get_cmdliner#r#r#r&rsr)inputr-cCstd|}td|}td|}|p.|p.|}|p6|}|rn|d}tjd|d|dd|d d |r|dr|dSd S) Nz(?:^|\s)ds=([^\s;]+)z(?:^|\s)ci\.ds=([^\s;]+)z (?:^|\s)ci\.datasource=([^\s;]+)rjz8Defining the datasource on the command line using ci.ds=z or ci.datasource=z23.2zUse ds=z instead) deprecatedZdeprecated_versionZ extra_messagerC)researchgroupstriprZ deprecate)r>Z ds_parse_0Z ds_parse_1Z ds_parse_2r*r?rr#r#r&r=s&       r=)rCr#)r,)T)YabcrGrZloggingrr9r@ collectionsrenumrrtypingrrrrr r Z cloudinitr r r rrrrrrrZcloudinit.atomic_helperrZcloudinit.distrosrZcloudinit.eventrrZcloudinit.filtersrZcloudinit.helpersrZcloudinit.persistencerZcloudinit.reportingrZDSMODE_DISABLEDZ DSMODE_LOCALrZ DSMODE_PASSrZDEP_FILESYSTEMrZ DS_PREFIXrZREDACT_SENSITIVE_VALUErr~rZ getLoggerr4rr/r)r=rr>r@rBrPr_r`rbABCMetarrr<r$rrr.rr2IOErrorr4r5rr<rr=r#r#r#r& s  $               #  7 !%