
    x[h                     .   S SK r S SKrS SKrS SKrS SKrS SKrS SKrS SKJrJ	r	  S SK
JrJrJrJrJrJrJr  S SKJrJrJrJrJrJrJr  S SKJr  S SKJr  S SKJr  S SKJ r   S S	K!J"r"J#r#  S S
K$J%r%  S SK&J'r'  S SK(J)r)  S SK*J+r+  Sr,Sr-Sr.Sr/\,\-\./r0Sr1Sr2Sr3Sr4Sr5Sr6Sr7Sr8\Rr                  " \:5      r;SS 4SS 4SS 4S .r<\	 " S! S"\5      5       r= " S# S$\5      r> " S% S&\?5      r@ " S' S(\?5      rA " S) S*\?5      rBSGS+ jrC\54S, jrD " S- S.\5      rE " S/ S0\5      rF " S1 S2\5      rG " S3 S\)\ R                  S49rIS5 rJS6\\I\K4   4S7 jrLS8 rM SHS9\KS6\N4S: jjrOS; rPSIS< jrQ " S= S>\R5      rSS? rTS@\ISA\KS6\N4SB jrUSA\KS6\\I   4SC jrVS6\K4SD jrWSE\KS6\K4SF jrXg)J    N)Enumunique)AnyDictList
NamedTupleOptionalTupleUnion)atomic_helperdmiimporter	lifecyclenetperformance
type_utils)	user_data)util)
write_json)Distro)
EventScope	EventType)launch_index)Paths)CloudInitPickleMixin)eventsdisabledlocalr   pass
FILESYSTEMNETWORK
DataSourcez|EXPERIMENTAL: The structure and format of content scoped under the 'ds' key may change in subsequent releases of cloud-init.zredacted for non-root user
cloud-name_unsetunknownz	aws-chinac                     U S:H  $ Naws cs    </usr/lib/python3/dist-packages/cloudinit/sources/__init__.py<lambda>r-   F   s    1:    zaws-govc                     U S:H  $ r'   r)   r*   s    r,   r-   r-   G   s    Q%Zr.   zazure-chinac                     U S:H  $ )Nazurer)   r*   s    r,   r-   r-   H   s    qG|r.   )zcn-zus-gov-chinac                   :    \ rS rSrSrSrSrSrSrSr	S\
4S	 jrS
rg)NetworkConfigSourceL   zV
Represents the canonical list of network config sources that cloud-init
knows about.
cmdlineds
system_cfgfallback	initramfsreturnc                     U R                   $ Nvalueselfs    r,   __str__NetworkConfigSource.__str__Y       zzr.   r)   N)__name__
__module____qualname____firstlineno____doc__CMD_LINEDS
SYSTEM_CFGFALLBACK	INITRAMFSstrrB   __static_attributes__r)   r.   r,   r4   r4   L   s.    
 H	BJHI r.   r4   c                   .    \ rS rSrSrSrSrS\4S jrSr	g)	NicOrder]   zRepresents ways to sort NICsmacnic_namer;   c                     U R                   $ r=   r>   r@   s    r,   rB   NicOrder.__str__c   rD   r.   r)   N)
rE   rF   rG   rH   rI   MACNIC_NAMErO   rB   rP   r)   r.   r,   rR   rR   ]   s    &
CH r.   rR   c                       \ rS rSrSrSrg)DatasourceUnpickleUserDataErrorg   zERaised when userdata is unable to be unpickled due to python upgradesr)   NrE   rF   rG   rH   rI   rP   r)   r.   r,   r[   r[   g   s    Or.   r[   c                       \ rS rSrSrg)DataSourceNotFoundExceptionk   r)   NrE   rF   rG   rH   rP   r)   r.   r,   r_   r_   k       r.   r_   c                       \ rS rSrSrSrg)InvalidMetaDataExceptiono   z8Raised when metadata is broken, unavailable or disabled.r)   Nr]   r)   r.   r,   rd   rd   o   s    Br.   rd   c                    [         R                  " U 5      n/ n/ nU R                  5        GH  u  pgU(       a	  US-   U-   nOUnUR                  5       U;   d  UR                  5       U;   a  UR	                  U5        [        U[        5      (       a;  UR                  S5      (       a%  UR	                  U5        UR                  SS5      X6'   [        U[        5      (       d  M  [        XxU5      n	UR                  U	R                  S5      5        UR                  U	R                  S5      5        XU'   GM     [        U5      US'   [        U5      US'   U$ )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.
/zci-b64: base64_encoded_keyssensitive_keys)copydeepcopyitemslowerappend
isinstancerO   
startswithreplacedictprocess_instance_metadataextendpopsorted)
metadatakey_pathrj   md_copyri   	sens_keyskeyvalsub_key_path
return_vals
             r,   rt   rt   s   s+    mmH%GINN$#c>C/LLIIK>)!!#~5\*c3CNN9$=$=&&|4;;y"5GLc4  2>J  &&z~~6K'LMZ^^,<=>%CL' %( &,,?%@G!" &y 1GNr.   c                 @   U R                  S/ 5      (       d  U $ [        R                  " U 5      nU R                  S5       HY  nUR                  S5      nUnU H1  nXe;   d  M
  [	        XV   [
        5      (       d  M#  XdS   :w  d  M-  XV   nM3     WU;   d  MU  XU'   M[     U$ )zRedact any sensitive keys from to provided metadata dictionary.

Replace any keys values listed in 'sensitive_keys' with redact_value.
rj   rg   )getrk   rl   splitrp   rs   )rx   redact_valuerz   ry   
path_partsobjpaths          r,   redact_sensitive_keysr      s     <<("--mmH%GLL!12^^C(
Dsy$//rN*i  3;$I 3 Nr.   c                   >    \ rS rSr% \\S'   \\S'   \\S'   \\S'   Srg)	URLParams   max_wait_secondstimeout_secondsnum_retriessec_between_retriesr)   N)rE   rF   rG   rH   int__annotations__rP   r)   r.   r,   r   r      s    r.   r   c                   0    \ rS rSr% \\   \S'   \\S'   Srg)DataSourceHostname   hostname
is_defaultr)   N)	rE   rF   rG   rH   r	   rO   r   boolrP   r)   r.   r,   r   r      s    smr.   r   c                   8    \ rS rSr% Sr\\S'   \\S'   \\S'   Srg)HotplugRetrySettings   z
in secondsforce_retrysleep_periodsleep_totalr)   N)	rE   rF   rG   rH   rI   r   r   r   rP   r)   r.   r,   r   r      s    r.   r   c            	          \ rS rSr% \rSrSrSr\	\
   \S'   SrSrSr\	\\\
4      \S'   \R$                  \R&                  \R(                  \R*                  4r\\S4   \S'   S	rS
rSrSr\R:                  \R>                  \R@                  \RB                  \RD                  10r#\R:                  \R>                  10r$S\%4S\%4S0 4SSSSSS4	r&\\\
\'4   S4   \S'   Sr(Sr)\\
S4   \S'   Sr*\+" SSS5      r,Sr-\	\
   \S'   Sr.SQS\/S\04S jjr1S\2S S4S! jr3S" r4S \54S# jr6S \54S$ jr7S% r8S& r9SRS' jr:\;Rx                  " S(S)S*9S \54S+ j5       r=SSS, jr>S \54S- jr?S. r@STS/ jrAS0 rBS1 rC\DS2 5       rE\DS3 5       rFS4 rG\DS5 5       rHS6 rI\DS7 5       rJS8 rKS9 rLS: rMS; rNS< rOS= rPS> rQS? rRS@ rSSA rT\DSB 5       rU\DSC 5       rVSD rWSUSE jrXSF rYSG\Z\   4SH jr[SG\Z\   S \54SI jr\SJ r]SK r^\_SVSL j5       r`\DSM 5       raSN rbSO rcSPrdg)Wr"      zen_US.UTF-8_undefN_cloud_name_crawled_metadata.network_config_sourcesr   
         ec2_metadatanetwork_jsonrx   )userdataN)userdata_rawN)
vendordataN)vendordata_rawN)vendordata2N)vendordata2_rawNcached_attr_defaultsF)
combined_cloud_config
merged_cfgmerged_system_cfgzsecurity-credentialsr   	user-datar   r   vendor-datazds/vendor_datasensitive_metadata_keysr   extra_hotplug_udev_rulesdistropathsc                    Xl         X l        X0l        S U l        0 U l        S U l        S U l        S U l        S U l        S U l	        S U l
        [        U l        [        U l        [        R                  " U R                   SU R                   40 5      U l        U R"                  (       d  0 U l        U(       d&  [$        R&                  " U R                  5      U l        g X@l        g )N
datasource)sys_cfgr   r   r   rx   r   r   r   r   r   metadata_addressUNSETr   r   r   get_cfg_by_pathdsnameds_cfgudUserDataProcessorud_proc)rA   r   r   r   r   s        r,   __init__DataSource.__init__O  s    
'+ 9="#/3+0!**LL<5r
 {{DK//

;DL"Lr.   ci_pkl_versionr;   c                    SSS[         SS[         SSS[        SSS5      S.nUR                  5        H#  u  p4[        X5      (       a  M  [	        XU5        M%     [        U S5      (       d  [	        U SS 5        [        U S5      (       a%  U R
                  b   [        U R
                  5        ggg! [         a&  n[        R                  SU5        [        5       UeSnAff = f)	z(Perform deserialization fixes for Paths.NFr   )r   _platform_type_subplatformr   r   r   r   skip_hotplug_detectr   r   hotplug_retry_settingscheck_if_fallback_is_allowedc                      gNFr)   r)   r.   r,   r-   &DataSource._unpickle.<locals>.<lambda>}  s    %r.   r   z:Unable to unpickle datasource: %s. Ignoring current cache.)r   r   rm   hasattrsetattrr   rO   AttributeErrorLOGdebugr[   )rA   r   expected_attrsr|   r?   es         r,   	_unpickleDataSource._unpicklei  s     "&" !(, $!#(#&:5!Q&G
 )..0JC4%%5) 1 t;<<D8-H4$$)B?DMM" *C$ " ?		/
 67Q>?s   B/ /
C9!CCc                 .    [         R                  " U 5      $ r=   )r   obj_namer@   s    r,   rB   DataSource.__str__  s    ""4((r.   c                     g)z#Check if running on this datasourceTr)   r@   s    r,   	ds_detectDataSource.ds_detect      r.   c                    U R                   R                  5       [        5       R                  5       :X  a  [        R	                  SU 5        gU R
                  R                  S/ 5      U R                   /:X  a  [        R	                  SU 5        gg)a  Override 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.Tdatasource_listz2Datasource list set to use a single datasource %s.F)r   rn   parse_cmdliner   r   r   r   r@   s    r,   override_ds_detectDataSource.override_ds_detect  st     ;;-/"7"7"99IIH \\/4EIIDd r.   c                     U R                  5       (       a  U R                  5       $ U R                  5       (       a&  [        R	                  SU 5        U R                  5       $ [        R	                  SU 5        g)z&Overrides runtime datasource detectionzDetected %szDid not detect %sF)r   	_get_datar   r   r   r@   s    r,   _check_and_get_dataDataSource._check_and_get_data  s^    ""$$>>##^^II >>##II)40r.   c                    U R                  5       R                  nU R                  5       nU R                  nUS   nS0 SS/_SU_SU_S[	        U R
                  U R                  U R                  5      _SU R
                  _S	U R
                  _S
US   S   _SUS   S   _SUS   S   _SU R                  _SU R                  5       _SUS   _SU_SU_SUS   S   _SU_SU_US   S   U R                  U R                  US   US   S.E0$ )z2Return a dictionary of standardized metadata keys.sys_infov1
_beta_keyssubplatformavailability-zoneavailability_zonecloud_idr#   
cloud_namer   distr   distro_versionr   distro_release   platformpublic_ssh_keyspython_versionpythoninstance-idinstance_idkernel_releaseunamelocal-hostnamelocal_hostname   variant)machineregionr   system_platformr  )
get_hostnamer   get_instance_idr   canonical_cloud_idr   r  platform_typeget_public_ssh_keysr   )rA   instance_datar   r   r   sysinfos         r,   _get_standardized_metadata%DataSource._get_standardized_metadata  s   **,55**, 22  
+ }o#%6 $%6 .OOT[[$2D2D	 doo doo '&/!, !'&/!"4 !'&/!"4 D.. "4#;#;#= !'("3 {  {!" !''"21"5#$ !.%& !.'( #7+A.++#//#*:#6"9-1
 	
r.   c                     U R                   (       d  gU(       a  UnOU R                  nU H#  u  p4[        X5      (       d  M  [        XU5        M%     U(       d  SU l         gg)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_cacher   r   r   )rA   attr_defaultsattr_values	attributer?   s        r,   clear_cached_attrsDataSource.clear_cached_attrs  sW       'K33K +It''/ !,  %D r.   zGetting metadataalways)log_modec                 f    SU l         U R                  5       nU(       d  U$ U R                  5         U$ )zDatasources implement _get_data to setup metadata and userdata_raw.

Minimally, the datasource should return a boolean True on success.
T)r  r   persist_instance_data)rA   return_values     r,   get_dataDataSource.get_data  s7     !//1 ""$r.   c                     U(       a\  [         R                  R                  U R                  R                  5      (       a$  [        X R                  R                  S5      5        U R                  bI  [        R                  " U R                  5      nUR                  SS5        UR                  SS5        SU0nO\SSU R                  00nU R                  [        :w  a  U R                  US   S'   U R                  [        :w  a  U R                  US   S'   [        US   S	'   [        R                  " U R                   5      US
'   SUS
   S	'   [        R                  " US
   5      US'   SUS   S	'   ["        R$                  " 5       US'   UR'                  U R)                  U5      5         [*        R,                  " U5      n[/        [0        R2                  " U5      U R4                  S9nU R                  RA                  S5      nUS   RC                  SS5      n[         R                  RE                  U R                  RF                  S5      n	["        RH                  " U	 SU 3U S35        Sn
U	 SU 3n[         R                  RK                  U	5      (       a  [         R                  RM                  U	5      n
["        RN                  " XSS9  U
(       a  X:w  a  ["        RP                  " U
5        [S        XuSS9  U R                  RA                  S5      n[S        U[U        U5      5        g! [6         a)  n[8        R;                  S[=        U5      5         SnAgSnAf[>         a)  n[8        R;                  S[=        U5      5         SnAgSnAff = f)a   Process 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.
obj_pklNr   r   r7   	meta_datar   r   _docr   z<DEPRECATED: Use merged_system_cfg. Will be dropped from 24.1r   zUMerged cloud-init system config from /etc/cloud/cloud.cfg and /etc/cloud/cloud.cfg.d/r   )rj   z'Error persisting instance-data.json: %sFinstance_data_sensitiver   r   nonezcloud-id-
T)forcei  )moder
  )+osr   lexistsr   instance_link	pkl_storeget_ipath_curr   rk   rl   rv   rx   r   r   r   EXPERIMENTAL_TEXTr   r   system_infoupdater  r   
json_dumpsrt   jsonloadsr   	TypeErrorr   warningrO   UnicodeDecodeErrorget_runpathr   joinrun_dir
write_fileexistsrealpathsym_linkdel_filer   r   )rA   write_cachecrawled_metadatar
  contentprocessed_datar   json_sensitive_filer   cloud_id_fileprev_cloud_id_filenew_cloud_id_file	json_files                r,   r   DataSource.persist_instance_data  s    277??4::+C+CDDdJJ44Y?@!!-  $}}T-C-CD  d3  5!#34M!K#?@M  E)6:6G6Gd#N3  E)6:6G6Gd#N3&7dF#&*mmDLL&Al# K 	l#	
 .2]],'.
)*' 	)*62 %)$4$4$6j!T<<]KL	#..}=G6

7##;;N #jj445NO &**:v>TZZ%7%7D=/8*5(2G!,oQxj977>>-((!#!1!1-!@'dC"4"IMM,-&UCJJ**?;	93NCD1  	KKA3q6J! 	KKA3q6J	s$   *>L) )
N3MN$NNc                     [        S5      e)z@Walk metadata sources, process crawled data and save attributes.zlSubclasses of DataSource must implement _get_data which sets self.metadata, vendordata_raw and userdata_raw.)NotImplementedErrorr@   s    r,   r   DataSource._get_dataQ  s    !D
 	
r.   c           	      ^   U R                   n [        U R                  R                  SU R                   5      5      nU R                  n [        S[        U R                  R                  SU R                  5      5      5      nU R                  n [        U R                  R                  SU R                  5      5      nU R                  n [        U R                  R                  SU R                  5      5      n[        XX45      $ ! [         a:    [
        R                  " [        SU R                  R                  S5      U5         GNf = f! [         aF    U R                  n[
        R                  " [        SU R                  R                  S5      U5         GNf = f! [         a:    [
        R                  " [        SU R                  R                  S5      U5         GN%f = f! [         a:    [
        R                  " [        S	U R                  R                  S5      U5         GN0f = f)
zReturn the Datasource's preferred url_read parameters.

Subclasses may override url_max_wait, url_timeout, url_retries.

@return: A URLParams object with max_wait_seconds, timeout_seconds,
    num_retries.
max_waitz6Config max_wait '%s' is not an int, using default '%s'r   timeoutz5Config timeout '%s' is not an int, using default '%s'retriesz5Config retries '%s' is not an int, using default '%s'r   zAConfig sec_between_retries '%s' is not an int, using default '%s')url_max_waitr   r   r   
ValueErrorr   logexcr   url_timeoutmaxurl_retries	Exceptionurl_sec_between_retriesr   )rA   rJ  rK  rL  r   s        r,   get_url_paramsDataSource.get_url_paramsX  s    $$	4;;??:t7H7HIJH ""		!SD<L<L!MNOG ""	$++//)T5E5EFGG #::	"%)4+G+G# GII_  	KKH
+		  	&&GKKG	*		  	KKG	*		  	KK& 56#	sK   /D 
9E /F! /G( A E
EAFF!A G%$G%(A H,+H,c                     U R                   c.  U R                  R                  U R                  5       5      U l         U(       a  U R	                  U R                   5      $ U R                   $ r=   )r   r   processget_userdata_raw_filter_xdata)rA   apply_filters     r,   get_userdataDataSource.get_userdata  sM    ==  LL001F1F1HIDM%%dmm44}}r.   c                     U R                   c.  U R                  R                  U R                  5       5      U l         U R                   $ r=   )r   r   rX  get_vendordata_rawr@   s    r,   get_vendordataDataSource.get_vendordata  s5    ??""ll2243J3J3LMDOr.   c                     U R                   c.  U R                  R                  U R                  5       5      U l         U R                   $ r=   )r   r   rX  get_vendordata2_rawr@   s    r,   get_vendordata2DataSource.get_vendordata2  s:    ##||33D4L4L4NODr.   c                 z    U R                   (       d  U R                  R                  5       U l         U R                   $ r=   )r   r   rn   r@   s    r,   r  DataSource.platform_type  s,    """&++"3"3"5D"""r.   c                 f    U R                   (       d  U R                  5       U l         U R                   $ )a}  Return a string representing subplatform details for the datasource.

This should be guidance for where the metadata is sourced.
Examples of this on different clouds:
    ec2:       metadata (http://169.254.169.254)
    openstack: configdrive (/dev/path)
    openstack: metadata (http://169.254.169.254)
    nocloud:   seed-dir (/seed/dir/path)
    lxd:   nocloud (/seed/dir/path)
)r   _get_subplatformr@   s    r,   r   DataSource.subplatform  s*        $ 5 5 7D   r.   c                 P    U R                   (       a  SU R                    S3$ [        $ )z?Subclasses should implement to return a "slug (detail)" string.z
metadata ())r   METADATA_UNKNOWNr@   s    r,   ri  DataSource._get_subplatform  s'       5 56a88r.   c                 V   U R                   (       a  U R                   $ U R                  (       a  U R                  R                  [        5      (       a  U R                  R                  [        5      n[	        U[
        5      (       a!  UR                  5       U l         U R                   $ U R                  5       R                  5       U l         [        R                  S[        [        U5      5         U R                   $ U R                  5       R                  5       U l         U R                   $ )zReturn lowercase cloud name as determined by the datasource.

Datasource can determine or define its own cloud product name in
metadata.
z5Ignoring metadata provided key %s: non-string type %s)r   rx   r   METADATA_CLOUD_NAME_KEYrp   rO   rn   _get_cloud_namer   r   type)rA   r   s     r,   r   DataSource.cloud_name  s     ###==T]]../FGG**+BCJ*c**#-#3#3#5   $(#7#7#9#?#?#A 		K+$   $335;;=Dr.   c                     U R                   $ )zReturn the datasource name as it frequently matches cloud name.

Should be overridden in subclasses which can run on multiple
cloud names, such as DatasourceEc2.
)r   r@   s    r,   rq  DataSource._get_cloud_name  s     {{r.   c                 f    U R                   (       d  g SU R                   ;   a  U R                   S   $ g )Nzlaunch-index)rx   r@   s    r,   r   DataSource.launch_index  s*    }}T]]*==00r.   c                     [         R                  " [        R                  " U R                   5      5      /nUnU H  nUR	                  U5      nM     U$ r=   )r   Filterr   safe_intapply)rA   processed_udfiltersnew_udfs        r,   rZ  DataSource._filter_xdata  sI    d.?.? @A
 AWWV_F r.   c                     U R                   $ r=   )r   r@   s    r,   rY  DataSource.get_userdata_raw  s       r.   c                     U R                   $ r=   )r   r@   s    r,   r_  DataSource.get_vendordata_raw  s    """r.   c                     U R                   $ r=   )r   r@   s    r,   rc  DataSource.get_vendordata2_raw  s    ###r.   c                     0 $ r=   r)   r@   s    r,   get_config_objDataSource.get_config_obj  s    	r.   c                 J    [        U R                  R                  S5      5      $ )Nzpublic-keys)normalize_pubkey_datarx   r   r@   s    r,   r	  DataSource.get_public_ssh_keys  s    $T]]%6%6}%EFFr.   c                     g)a  Publish the public SSH host keys (found in /etc/ssh/*.pub).

@param hostkeys: List of host key tuples (key_type, key_value),
    where key_type is the first field in the public key file
    (e.g. 'ssh-rsa') and key_value is the key itself
    (e.g. 'AAAAB3NzaC1y...').
Nr)   )rA   hostkeyss     r,   publish_host_keysDataSource.publish_host_keys  s    r.   c                     SS0nUR                  5        He  u  p4UR                  U5      (       d  M  U HB  nSU< U[        U5      S  < 3n[        R                  R                  U5      (       d  M>  Us  s  $    Mg     g )Nsd)vdxvdvtbz/dev/)rm   rq   lenr&  r   r8  )rA   
short_namemappingsnfromtlistntocands          r,   _remap_deviceDataSource._remap_device  sr     ./$NN,LE((//&):c%jl+CD77>>$''K  - r.   c                     g r=   r)   )rA   _names     r,   device_name_to_device DataSource.device_name_to_device  s     r.   c                 v    U R                   n U R                  R                  5       nU$ ! [         a     U$ f = f)z<Default locale is en_US.UTF-8, but allow distros to override)default_localer   
get_localerG  )rA   locales     r,   r  DataSource.get_locale%  sD    $$	[[++-F  # 		s   * 
88c                     U R                   R                  SU R                   R                  S5      5      nU(       a  U$ U R                   R                  S0 5      R                  S5      $ )Nr   r   	placementrx   r   )rA   top_level_azs     r,   r   DataSource.availability_zone.  sY    }}((!2!23F!G
 }}  b1556IJJr.   c                 8    U R                   R                  S5      $ )Nr  r  r@   s    r,   r  DataSource.region7  s    }}  **r.   c                 v    U R                   (       a  SU R                   ;  a  g[        U R                   S   5      $ )Nr   ziid-datasource)rx   rO   r@   s    r,   r  DataSource.get_instance_id;  s+    }}T]] B#4==/00r.   c                    SnSnUnSnU R                   (       a   U R                   R                  S5      (       d  U(       a  [        SU5      $ / n[        R                  " 5       n	U	S:X  a  Sn[        R
                  " U	5      n
U
(       a0  U
R                  S5      S:  a  [        U
5      R                  S5      nOU	(       a0  U	R                  S5      S:  a  [        U	5      R                  S5      nOU	(       a  X/nOXT/nOU R                   S   n[        R                  " U5      (       aX  / nU(       a  [        R                  " U5      nU(       a  [        U5      R                  S5      nO(S	UR                  SS
5      -  /nOUR                  S5      n[        U5      S:  a  US   n	SR                  USS 5      nOUS   n	U(       a  Xd:w  a	  U	< SU< 3n	[        X5      $ )a  Get hostname or fqdn from the datasource. Look it up if desired.

@param fqdn: Boolean, set True to return hostname with domain.
@param resolve_ip: Boolean, set True to attempt to resolve an ipv4
    address provided in local-hostname meta-data.
@param metadata_only: Boolean, set True to avoid looking up hostname
    if meta-data doesn't have local-hostname present.

@return: a DataSourceHostname NamedTuple
    <hostname or qualified hostname>, <is_default> (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.
localdomain	localhostFr   NT.r   zip-%sr"  r   )rx   r   r   r   r  get_fqdn_from_hostsfindrO   r   r   is_ipv4_addressgethostbyaddrrr   r  r5  )rA   fqdn
resolve_ipmetadata_only	defdomaindefhostdomainr   toksr   
hosts_fqdnlhosts               r,   r  DataSource.get_hostnameA  s   & "	
}}DMM$5$56F$G$G)$
;;
 D((*H;&!
11(;Jjooc2Q6:,,S1hmmC0148}**3/ ,+ MM"23E""5))--e4Dt9??3/D#emmC&==>D{{3't9q=AwHXXd12h'FAwHF'"*F3H!(77r.   c                 4    U R                   R                  U S9$ )N)data_source)r   get_package_mirror_infor@   s    r,   r  "DataSource.get_package_mirror_info  s    {{22t2DDr.   source_event_typesc                     0 nU Hc  nU R                   R                  5        HB  u  nnX5;   d  M  UR                  U5      (       d  [        5       X$'   X$   R	                  U5        MD     Me     U$ r=   )supported_update_eventsrm   r   setadd)rA   r  supported_eventseventupdate_scopeupdate_eventss         r,   get_supported_eventsDataSource.get_supported_events  sq    24'E --335)+//==9<(6$266u=	 6	 (  r.   c                    U R                  U5      nUR                  5        Hj  u  p4[        R                  SUR                  SR                  U Vs/ s H  oUR                  PM     sn5      5        U R                  SU-  [        445        Ml     U(       a(  U R                  5         U R                  5       nU(       a  g[        R                  SU SR                  U Vs/ s H  oUR                  PM     sn5      5        gs  snf s  snf )a  Refresh 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, z
_%s_configTz(Datasource %s not updated for events: %sF)	r  rm   r   r   r?   r5  r  r   r  )rA   r  r  scopematched_eventsr  results          r,   update_metadata_if_supported'DataSource.update_metadata_if_supported  s      445GH%5%;%;%=!EIIL		NCN5;;NCD ##lU&:E%B$DE &> ##%]]_F		6II0BC0Bu{{0BCD	

 ! D Ds   D Dc                     gr   r)   )rA   r   s     r,   check_instance_idDataSource.check_instance_id  s    r.   c                     g)zcheck_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)   r@   s    r,   r   'DataSource.check_if_fallback_is_allowed  s     r.   c                     Uc  [         nUc  [        nU  H)  nUc  M  X2;   a  Us  $ [        R                  SX15        Us  $    U$ )Nz%invalid dsmode '%s', using default=%s)DSMODE_NETWORKVALID_DSMODESr   r2  )
candidatesdefaultvalid	candidates       r,   _determine_dsmodeDataSource._determine_dsmode  sV     ?$G=!E#I !  ;Y  $ r.   c                     g r=   r)   r@   s    r,   network_configDataSource.network_config  r   r.   c                     g)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)   )rA   is_new_instances     r,   setupDataSource.setup  s     	r.   c                     g)a  activate(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)   )rA   cfgr  s      r,   activateDataSource.activate  s     	r.   )r   r  r   r   r   r   r   rx   r   r   r   r   r   r   r   r   r   r   r   r=   )r)   T)F)FFF)NN)erE   rF   rG   rH   r  dsmoder  r   r   r	   rO   r   r   r   r   r   r   r4   rJ   rN   rL   rK   r   r
   rM  rP  rR  rT  r   r!   r   BOOT_NEW_INSTANCEBOOTBOOT_LEGACYHOTPLUGr  default_update_eventsr   r   r   r  r   r   r   r   r   _ci_pkl_versionr   r   r   r   r   rB   r   r   r   r   r  r  r   timedr  r  r   rU  r\  r`  rd  propertyr  r   ri  r   rq  r   rZ  rY  r_  rc  r  r	  r  r  r  r  r   r  r  r  r  r   r  r  r  r   staticmethodr  r  r  r  rP   r)   r.   r,   r"   r"      sl   F"N F "&K#% N
 L48xdCi 018 	$$%%&&	?E"5s":;  LKK@ 	''NN!!	
 	''
 
		R !
9%c3h 45 
 L0U38_ "   2%A> /3hsm2O# #u #4#? #? #?J)4 D ,$
L&& )H=$  >$JX
4 
:Jx
 
 # #
 ! !     .  !#$G  K K + +1F8PE tI  $"&y/$	$L  *  	r.   )	metaclassc                    / nU (       d  U$ [        U [        5      (       a  U R                  5       $ [        U [        [        45      (       a  [        U 5      $ [        U [
        5      (       aq  U R                  5        H]  u  p#[        U[        5      (       a  U/n[        U[        [        45      (       d  M:  U H  nU(       d  M  UR                  U5        M     M_     U$ r=   )rp   rO   
splitlineslistr  rs   rm   ro   )pubkey_datakeys_keynameklistpkeys        r,   r  r    s    D+s##%%''+c{++K  +&&*002OH %%%%$--!D tD)	 "  3 Kr.   r;   c           	         [        XCU5      nU Vs/ s H  n[        R                  " U5      PM     n	n[        U;   a  SOSn
[        R                  SX5        [        X5       H  u  p[        R                  " SUR                  SS5      -  SU
< SU< 3S	U
< S
U< 3US9n U   [        R                  SU5        U" XU5      nUR                  [        R                  /5      (       a2  SU
< SU< 3Ul        U[        R                  " U5      4sS S S 5        s  $  S S S 5        M     SSR#                  U	5      -  n[%        U5      es  snf ! , (       d  f       M  = f! [         a!    [        R                   " [        SU5         GM&  f = f)Nnetworkr   z#Searching for %s data source in: %sz	search-%sr"   rh   zsearching for z data from zno z data found from )namedescriptionmessageparentz%Seeing if we can get any data from %szfound zGetting data from %s failedz4Did not find any data source, searched classes: (%s)r  )list_sourcesr   r   DEP_NETWORKr   r   zipr   ReportEventStackrr   r  r   r  r
  rS  r   rO  r5  r_   )r   r   r   ds_depscfg_listpkg_listreporterds_listr  ds_namesr%  r  clsmyrepsmsgs                   r,   find_sourcer    sh    8h7G0781
##A&H8#w.9GDII3TD+	''t||L"==;?F26=	

	A		A3G/11001  @DT$JEMz22378   ,& A499D C &c
**5 9   	AKK:C@@	As<    E"E$A+E	EE
E	EE&F	F	c                    / n[         R                  SU UU5        U  H  n[        R                  " U5      n[        R                  " XRS/5      u  pgU(       d  [         R                  SU5        U HH  n[        R                  " U5      n	[        U	S5      n
U
" U5      nU(       d  M6  UR                  U5          M     M     U$ )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 %sget_datasource_listzDCould not import %s. Does the DataSource exist and is it importable?)	r   r   r   "match_case_insensitive_module_namefind_moduleerrorimport_modulegetattrru   )r  dependsr  src_listr7   ds_namem_locs_looked_locsm_locmodlistermatchess               r,   r  r  ?  s     HII	8 ==bA'33 56 
 II$
 E((/CS"78FWoGw(  $ Or.   fieldc                     U (       d  g[         R                  " U5      nU(       d  gU R                  5       UR                  5       :H  $ r   )r   read_dmi_datarn   )r   r+  	dmi_values      r,   instance_id_matches_system_uuidr/  c  s;    
 !!%(I)//"333r.   c                    U (       d  [         n U(       d  [         nU[         :X  a  U [         :w  a  U $ U$ [        R                  5        H2  u  p4Uu  pVUR                  U5      (       d  M!  U" U 5      (       d  M0  Us  $    U [         :w  a  U $ U$ )z@Lookup the canonical cloud-id for a given cloud_name and region.)rm  CLOUD_ID_REGION_PREFIX_MAPrm   rq   )r   r  r   prefixcloud_id_testr   valid_clouds          r,   r  r  q  s    %
!!!))!;!A!A!C"/V$$Z)@)@O "D %%Or.   c                 @   U (       d  g[        U [        5      (       a  U $ [        U [        5      (       a  [        R                  " U 5      $ [        U [
        5      (       a)  USL a  [        U R                  S5      SS9$ [        S5      e[        S[        U 5      -  5      e)a,  data: 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)
rp   rO   r   rk   rl   rs   convert_vendordatar   rN  rr  )datar6  s     r,   r7  r7    s     $$}}T""$d?%dhh|&<eLLBCC
;d4jH
IIr.   c                       \ rS rSrSrg)BrokenMetadatai  r)   Nra   r)   r.   r,   r:  r:    rb   r.   r:  c                 z    / n[        U 5      nU H'  u  pEU[        U5      :X  d  M  UR                  U5        M)     U$ r=   )r  ro   )r"  r  ret_listdepsetr  depss         r,   list_from_dependsr?    s;    H\F	SYOOC   Or.   r   fnamec                     [         R                  " U 5      n [        R                  " XSSS9  g! [         a    [        R                  " [
        SU 5         gf = f! [         a    [        R                  " [
        SU5         gf = f)zSUse pickle to serialize Datasource to a file as a cache.

:return: True on success
zFailed pickling datasource %sFwb   )omoder%  z Failed pickling datasource to %sT)pickledumpsrS  r   rO  r   r7  )r   r@  pk_contentss      r,   r)  r)    sx    
ll3'$UC   C8#>
  C;UCs    0 A &AA&BBc                    Sn [         R                  " U 5      nU(       d  g [        R                  " U5      $ ! [         aD  n[        R                  R                  U 5      (       a  [        R                  SX5         SnANhSnAff = f! [         a     g[         a    [         R                  " [        SU 5         gf = f)zBUse pickle to deserialize a instance Datasource from a cache file.Nzfailed loading pickle in %s: %sz#Failed loading pickled blob from %s)r   load_binary_filerS  r&  r   isfiler   r2  rE  r0  r[   rO  )r@  pickle_contentsr   s      r,   pkl_loadrL    s    OE//6 ||O,,  E77>>%  KK95DE +  C>Fs,   9 B
 
B:BB

B>%B>=B>c                  >    [        [        R                  " 5       5      $ )z}Check if command line argument for this datasource was passed
Passing by command line overrides runtime datasource detection
)parse_cmdline_or_dmir   get_cmdliner)   r.   r,   r   r     s       0 0 233r.   inputc                    [         R                  " SU 5      n[         R                  " SU 5      n[         R                  " SU 5      nU=(       d    U=(       d    UnU=(       d    UnU(       a?  UR                  S5      R                  5       n[        R
                  " SU SU 3SSU S	3S
9  U(       a'  UR                  S5      (       a  UR                  S5      $ g)Nz(?:^|\s)ds=([^\s;]+)z(?:^|\s)ci\.ds=([^\s;]+)z (?:^|\s)ci\.datasource=([^\s;]+)r   z8Defining the datasource on the command line using ci.ds=z or ci.datasource=z23.2zUse ds=z instead)
deprecateddeprecated_versionextra_messagerh   )researchgroupstripr   	deprecate)rP  
ds_parse_0
ds_parse_1
ds_parse_2r7   rR  r   s          r,   rN  rN    s    2E:J6>J>FJ		/z	/ZB)zJ!!!$**, !!!'*  &#F884	
 
bhhqkkxx{r.   )rh   r)   )zsystem-uuidr  )Yabcrk   r/  loggingr&  rE  rU  enumr   r   typingr   r   r   r   r	   r
   r   	cloudinitr   r   r   r   r   r   r   r   r   r   cloudinit.atomic_helperr   cloudinit.distrosr   cloudinit.eventr   r   cloudinit.filtersr   cloudinit.helpersr   cloudinit.persistencer   cloudinit.reportingr   DSMODE_DISABLEDDSMODE_LOCALr  DSMODE_PASSr  DEP_FILESYSTEMr  	DS_PREFIXr+  REDACT_SENSITIVE_VALUErp  r   rm  	getLoggerrE   r   r1  r4   rR   rS  r[   r_   rd   rt   r   r   r   r   ABCMetar"   r  rO   r  r  r   r/  r  r7  IOErrorr:  r?  r)  rL  r   rN  r)   r.   r,   <module>rr     s        	  	  F F F   &  . $ 1 * # 6 & ,?	<  6  '  !
 -./034  $   t Pi P	) 	Cy C F 2H :
  
: w% wt:+
:s?+B!J ,44	4&J0	W 	: c d $C HZ0 *4s 4  r.   