
    i                        d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlmZm	Z	 d dl
mZmZmZmZmZmZmZmZ d dlmZmZmZmZmZmZmZmZmZ d dlmZ d dlm Z  d dl!m"Z"m#Z# d dl$m%Z% d d	l&m'Z' d d
l(m)Z) d dl*m+Z+ dZ,dZ-dZ.dZ/e,e-e.gZ0dZ1dZ2dZ3dZ4dZ5dZ6dZ7dZ8 ejr                  e:      Z;dd fdd fdd fdZ<e	 G d d e             Z= G d! d"e      Z> G d# d$e?      Z@ G d% d&e?      ZA G d' d(e?      ZBdEd)ZCe5fd*ZD G d+ d,e      ZE G d- d.e      ZF G d/ d0e      ZG G d1 de)e j                  2      ZId3 ZJd4eeIeKf   fd5ZLd6 ZM	 dFd7eKd4eNfd8ZOd9 ZPdGd:ZQ G d; d<eR      ZSd= ZTd>eId?eKd4eNfd@ZUd?eKd4eeI   fdAZVd4eKfdBZWdCeKd4eKfdDZXy)H    N)Enumunique)AnyDictList
NamedTupleOptionalTupleUnioncast)	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                     | dk(  S Naws cs    </usr/lib/python3/dist-packages/cloudinit/sources/__init__.py<lambda>r.   F   s
    1:     zaws-govc                     | dk(  S r(   r*   r+   s    r-   r.   r.   G   s
    Q%Z r/   zazure-chinac                     | dk(  S )Nazurer*   r+   s    r-   r.   r.   H   s
    qG| r/   )zcn-zus-gov-chinac                   0    e Zd ZdZdZdZdZdZdZde	fdZ
y	)
NetworkConfigSourcezb
    Represents the canonical list of network config sources that cloud-init
    knows about.
    cmdlineds
system_cfgfallback	initramfsreturnc                     | j                   S Nvalueselfs    r-   __str__zNetworkConfigSource.__str__Y       zzr/   N)__name__
__module____qualname____doc__CMD_LINEDS
SYSTEM_CFGFALLBACK	INITRAMFSstrrB   r*   r/   r-   r5   r5   L   s.    
 H	BJHI r/   r5   c                   $    e Zd ZdZdZdZdefdZy)NicOrderzRepresents ways to sort NICsmacnic_namer;   c                     | j                   S r=   r>   r@   s    r-   rB   zNicOrder.__str__c   rC   r/   N)rD   rE   rF   rG   MACNIC_NAMErM   rB   r*   r/   r-   rO   rO   ]   s    &
CH r/   rO   c                       e Zd ZdZy)DatasourceUnpickleUserDataErrorzERaised when userdata is unable to be unpickled due to python upgradesNrD   rE   rF   rG   r*   r/   r-   rV   rV   g   s    Or/   rV   c                       e Zd Zy)DataSourceNotFoundExceptionNrD   rE   rF   r*   r/   r-   rY   rY   k       r/   rY   c                       e Zd ZdZy)InvalidMetaDataExceptionz8Raised when metadata is broken, unavailable or disabled.NrW   r*   r/   r-   r]   r]   o   s    Br/   r]   c                 x   t        j                  |       }g }g }| j                         D ]  \  }}|r	|dz   |z   }n|}|j                         |v s|j                         |v r|j	                  |       t        |t              r7|j                  d      r&|j	                  |       |j                  dd      ||<   t        |t              st        |||      }	|j                  |	j                  d             |j                  |	j                  d             |	||<    t        |      |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.
    /zci-b64: base64_encoded_keyssensitive_keys)copydeepcopyitemslowerappend
isinstancerM   
startswithreplacedictprocess_instance_metadataextendpopsorted)
metadatakey_pathrb   md_copyra   	sens_keyskeyvalsub_key_path
return_vals
             r-   rl   rl   s   s/    mmH%GINN$ &S#c>C/LLIIK>)!!#~5\*c3CNN9$=&&|4;;y"5GCLc4 2\>J  &&z~~6K'LMZ^^,<=>%GCL'&( &,,?%@G!" &y 1GNr/   c                    | j                  dg       s| S t        j                  |       }| j                  d      D ]M  }|j                  d      }|}|D ])  }||v st	        ||   t
              s||d   k7  s%||   }+ |v sI|||<   O |S )zRedact any sensitive keys from to provided metadata dictionary.

    Replace any keys values listed in 'sensitive_keys' with redact_value.
    rb   r_   )getrc   rd   splitrh   rk   )rp   redact_valuerr   rq   
path_partsobjpaths          r-   redact_sensitive_keysr      s     <<("-mmH%GLL!12 %^^C(
 	 Ds4y$/JrN*$i	  3;$CI% Nr/   c                   6    e Zd ZU eed<   eed<   eed<   eed<   y)	URLParamsmax_wait_secondstimeout_secondsnum_retriessec_between_retriesN)rD   rE   rF   int__annotations__r*   r/   r-   r   r      s    r/   r   c                   (    e Zd ZU ee   ed<   eed<   y)DataSourceHostnamehostname
is_defaultN)rD   rE   rF   r	   rM   r   boolr*   r/   r-   r   r      s    smr/   r   c                   0    e Zd ZU dZeed<   eed<   eed<   y)HotplugRetrySettingsz
in secondsforce_retrysleep_periodsleep_totalN)rD   rE   rF   rG   r   r   r   r*   r/   r-   r   r      s    r/   r   c            	          e Zd ZU eZdZdZdZee	   e
d<   dZdZdZeeee	f      e
d<   ej"                  ej$                  ej&                  ej(                  fZeedf   e
d<   dZd	Zd
ZdZej8                  ej<                  ej>                  ej@                  ejB                  hiZ"ej8                  ej<                  hiZ#de$fde$fdi fddddddf	Z%eee	e&f   df   e
d<   dZ'dZ(ee	df   e
d<   dZ) e*ddd      Z+dZ,ee	   e
d<   dZ-dPde.de/fdZ0de1ddfd Z2d! Z3de4fd"Z5de4fd#Z6d$ Z7d% Z8dQd&Z9 e:jv                  d'd()      de4fd*       Z<dRd+Z=de4fd,Z>d- Z?dSd.Z@d/ ZAd0 ZBeCd1        ZDeCd2        ZEd3 ZFeCd4        ZGd5 ZHeCd6        ZId7 ZJd8 ZKd9 ZLd: ZMd; ZNd< ZOd= ZPd> ZQd? ZRd@ ZSeCdA        ZTeCdB        ZUdC ZVdTdDZWdE ZXdFeYe   fdGZZdFeYe   de4fdHZ[dI Z\dJ Z]e^dUdK       Z_eCdL        Z`dM ZadN ZbdO Zcy)Vr#   zen_US.UTF-8_undefN_cloud_name_crawled_metadata.network_config_sourcesry   
         ec2_metadatanetwork_jsonrp   )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                    || _         || _        || _        d | _        i | _        d | _        d | _        d | _        d | _        d | _	        d | _
        t        | _        t        | _        t        j                  | j                   d| j                   fi       | _        | j"                  si | _        |s%t%        j&                  | j                        | _        y || _        y )N
datasource)sys_cfgr   r   r   rp   r   r   r   r   r   metadata_addressUNSETr   r   r   get_cfg_by_pathdsnameds_cfgr   UserDataProcessorud_proc)rA   r   r   r   r   s        r-   __init__zDataSource.__init__O  s    
'+ 9="#/3+0!**LL<5r
 {{DK$66tzzBDL"DLr/   ci_pkl_versionr;   c                    dddt         ddt         dddt        ddd      d}|j                         D ]  \  }}t        | |      rt	        | ||       ! t        | d      st	        | dd        t        | d      r$| j
                  	 t        | j
                         yyy# t        $ r&}t        j                  d|       t               |d}~ww xY w)	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                       yNFr*   r*   r/   r-   r.   z&DataSource._unpickle.<locals>.<lambda>}      r/   r   z:Unable to unpickle datasource: %s. Ignoring current cache.)r   r   re   hasattrsetattrr   rM   AttributeErrorLOGdebugrV   )rA   r   expected_attrsrt   r?   es         r-   	_unpicklezDataSource._unpicklei  s     "&" !(, $!#(#&:5!Q&G
 )..0 	*JC4%c5)	* t;<D8-H4$)B?DMM" *C$ " ?		/
 67Q>?s   B 	C(!C		Cc                 ,    t        j                  |       S r=   )r   obj_namer@   s    r-   rB   zDataSource.__str__  s    ""4((r/   c                      y)z#Check if running on this datasourceTr*   r@   s    r-   	ds_detectzDataSource.ds_detect      r/   c                    | j                   j                         t               j                         k(  rt        j	                  d|        y| j
                  j                  dg       | j                   gk(  rt        j	                  d|        yy)aJ  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   rf   parse_cmdliner   r   r   rz   r@   s    r-   override_ds_detectzDataSource.override_ds_detect  st     ;;-/"7"7"99IIH \\/4EIIDd r/   c                     | j                         r| j                         S | j                         r&t        j	                  d|        | j                         S t        j	                  d|        y)z&Overrides runtime datasource detectionzDetected %szDid not detect %sF)r   	_get_datar   r   r   r@   s    r-   _check_and_get_datazDataSource._check_and_get_data  sX    ""$>>##^^II >>##II)40r/   c                    | j                         j                  }| j                         }| j                  }|d   }di ddgd|d|dt	        | j
                  | j                  | j                        d| j
                  d	| j
                  d
|d   d   d|d   d   d|d   d   d| j                  d| j                         d|d   d|d|d|d   d   d|d||d   d   | j                  | j                  |d   |d   diS )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_metadataz%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                     | j                   sy|r|}n| j                  }|D ]  \  }}t        | |      st        | ||       ! |sd| _         yy)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_attrszDataSource.clear_cached_attrs  s_       'K33K + 	0IutY'i/	0  %D r/   zGetting metadataalways)log_modec                 \    d| _         | j                         }|s|S | j                          |S )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_datazDataSource.get_data  s7     !//1 ""$r/   c                    |rXt         j                  j                  | j                  j                        r%t        | | j                  j                  d             | j                  Vt        t        t        j                  | j                              }|j                  dd       |j                  dd       d|i}nZdd| j                  ii}| j                  t        k7  r| j                  |d   d<   | j                   t        k7  r| j                   |d   d<   t"        |d   d	<   t        j                  | j$                        |d
<   d|d
   d	<   t        j                  |d
         |d<   d|d   d	<   t'        j(                         |d<   |j+                  | j-                  |             	 t/        j0                  |      }t3        t5        j6                  |      | j8                        }| j                  jE                  d      }|d   jG                  dd      }t         j                  jI                  | j                  jJ                  d      }	t'        jL                  |	 d| | d       d}
|	 d| }t         j                  jO                  |	      rt         j                  jQ                  |	      }
t'        jR                  ||	d       |
r|
|k7  rt'        jT                  |
       tW        ||d       | j                  jE                  d      }tW        |tY        |             y# t:        $ r)}t<        j?                  dtA        |             Y d}~yd}~wtB        $ r)}t<        j?                  dtA        |             Y d}~yd}~ww xY w)aP  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   )rb   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   r   rk   rc   rd   rn   rp   r   r   r   EXPERIMENTAL_TEXTr   r   system_infoupdater   r   
json_dumpsrl   jsonloadsr   	TypeErrorr   warningrM   UnicodeDecodeErrorget_runpathrz   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  z DataSource.persist_instance_data  s    277??4::+C+CDdDJJ44Y?@!!-  $dmmD$:$:;    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"48I"IMM,-&UCJJ**?;	93NCD1  	KKA3q6J! 	KKA3q6J	s$   (?L# #	N,MNN  Nc                     t        d      )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   zDataSource._get_data[  s    !D
 	
r/   c           	      R   | j                   }	 t        | j                  j                  d| j                               }| j                  }	 t        dt        | j                  j                  d| j                                    }| j                  }	 t        | j                  j                  d| j                              }| j                  }	 t        | j                  j                  d| j                              }t        ||||      S # t        $ r9 t        j                  t        d| j                  j                  d      |       Y w xY w# t        $ rE | j                  }t        j                  t        d| j                  j                  d      |       Y w xY w# t        $ r9 t        j                  t        d| j                  j                  d      |       Y !w xY w# t        $ r9 t        j                  t        d	| j                  j                  d      |       Y *w xY w)
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   rz   
ValueErrorr   logexcr   url_timeoutmaxurl_retries	Exceptionurl_sec_between_retriesr   )rA   r2  r3  r4  r   s        r-   get_url_paramszDataSource.get_url_paramsb  s    $$	4;;??:t7H7HIJH ""		!SD<L<L!MNOG ""	$++//)T5E5EFGG #::	"%)4+G+G# 7G5HII_  	KKH
+		  	&&GKKG	*		  	KKG	*		  	KK& 56#	sH   /D	 
9E /F /G$ 	>E
EA
FF>G! G!$>H&%H&c                     | j                   .| j                  j                  | j                               | _         |r| j	                  | j                         S | j                   S r=   )r   r   processget_userdata_raw_filter_xdata)rA   apply_filters     r-   get_userdatazDataSource.get_userdata  sM    ==  LL001F1F1HIDM%%dmm44}}r/   c                     | j                   .| j                  j                  | j                               | _         | j                   S r=   )r   r   r?  get_vendordata_rawr@   s    r-   get_vendordatazDataSource.get_vendordata  s5    ??""ll2243J3J3LMDOr/   c                     | j                   .| j                  j                  | j                               | _         | j                   S r=   )r   r   r?  get_vendordata2_rawr@   s    r-   get_vendordata2zDataSource.get_vendordata2  s:    ##||33D4L4L4NODr/   c                 p    | j                   s| j                  j                         | _         | j                   S r=   )r   r   rf   r@   s    r-   r   zDataSource.platform_type  s,    """&++"3"3"5D"""r/   c                 \    | j                   s| j                         | _         | j                   S )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   zDataSource.subplatform  s*        $ 5 5 7D   r/   c                 F    | j                   rd| j                    dS t        S )z?Subclasses should implement to return a "slug (detail)" string.z
metadata ())r   METADATA_UNKNOWNr@   s    r-   rL  zDataSource._get_subplatform  s'       5 56a88r/   c                 ,   | j                   r| j                   S | j                  r| j                  j                  t              r| j                  j                  t              }t	        |t
              r!|j                         | _         | j                   S | j                         j                         | _         t        j                  dt        t        |             | j                   S | j                         j                         | _         | j                   S )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   rp   rz   METADATA_CLOUD_NAME_KEYrh   rM   rf   _get_cloud_namer   r   type)rA   r   s     r-   r   zDataSource.cloud_name  s     ###==T]]../FG**+BCJ*c*#-#3#3#5   $(#7#7#9#?#?#A 		K+$   $335;;=Dr/   c                     | j                   S )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-   rR  zDataSource._get_cloud_name  s     {{r/   c                 X    | j                   sy d| j                   v r| j                   d   S y )Nzlaunch-index)rp   r@   s    r-   r   zDataSource.launch_index  s*    }}T]]*==00r/   c                     t        j                  t        j                  | j                               g}|}|D ]  }|j	                  |      } |S r=   )r   Filterr   safe_intapply)rA   processed_udfiltersnew_udfs        r-   rA  zDataSource._filter_xdata  sN    d.?.? @A
  	%AWWV_F	%r/   c                     | j                   S r=   )r   r@   s    r-   r@  zDataSource.get_userdata_raw  s       r/   c                     | j                   S r=   )r   r@   s    r-   rE  zDataSource.get_vendordata_raw  s    """r/   c                     | j                   S r=   )r   r@   s    r-   rH  zDataSource.get_vendordata2_raw  s    ###r/   c                     i S r=   r*   r@   s    r-   get_config_objzDataSource.get_config_obj  s    	r/   c                 J    t        | j                  j                  d            S )Nzpublic-keys)normalize_pubkey_datarp   rz   r@   s    r-   r   zDataSource.get_public_ssh_keys  s    $T]]%6%6}%EFFr/   c                      y)a5  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_keyszDataSource.publish_host_keys  r   r/   c                     ddi}|j                         D ]V  \  }}|j                  |      s|D ]:  }d||t        |      d  }t        j                  j                  |      s6|c c S  X y )Nsd)vdxvdvtbz/dev/)re   ri   lenr  r   r"  )rA   
short_namemappingsnfromtlistntocands          r-   _remap_devicezDataSource._remap_device  sx     ./$NN, 	 LE5((/  &):c%jl+CD77>>$'K 	  r/   c                      y r=   r*   )rA   _names     r-   device_name_to_devicez DataSource.device_name_to_device'  s     r/   c                 t    | j                   }	 | j                  j                         }|S # t        $ r Y |S w xY w)z<Default locale is en_US.UTF-8, but allow distros to override)default_localer   
get_localer0  )rA   locales     r-   rz  zDataSource.get_locale/  sD    $$	[[++-F  # 		s   * 	77c                     | j                   j                  d| j                   j                  d            }|r|S | j                   j                  di       j                  d      S )Nr   r   	placementrp   rz   )rA   top_level_azs     r-   r   zDataSource.availability_zone8  sY    }}((!2!23F!G
 }}  b1556IJJr/   c                 8    | j                   j                  d      S )Nr   r~  r@   s    r-   r   zDataSource.regionA  s    }}  **r/   c                 h    | j                   rd| j                   vryt        | j                   d         S )Nr   ziid-datasource)rp   rM   r@   s    r-   r   zDataSource.get_instance_idE  s+    }}T]] B#4==/00r/   c                 N   d}d}|}d}| j                   r| j                   j                  d      s|rt        d|      S g }t        j                         }	|	dk(  rd}t        j
                  |	      }
|
r/|
j                  d      dkD  rt        |
      j                  d      }n|	r/|	j                  d      dkD  rt        |	      j                  d      }n|	r|	|g}n||g}n| j                   d   }t        j                  |      rMg }|rt        j                  |      }|rt        |      j                  d      }n(d	|j                  dd
      z  g}n|j                  d      }t        |      dkD  r|d   }	dj                  |dd       }n|d   }	|r||k7  r|	d|}	t        |	|      S )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   )rp   rz   r   r   r   get_fqdn_from_hostsfindrM   r{   r   is_ipv4_addressgethostbyaddrrj   rm  r  )rA   fqdn
resolve_ipmetadata_only	defdomaindefhostdomainr   toksr   
hosts_fqdnlhosts               r-   r   zDataSource.get_hostnameK  s   & "	
}}DMM$5$56F$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Fi'"*F3H!(J77r/   c                 :    | j                   j                  |       S )N)data_source)r   get_package_mirror_infor@   s    r-   r  z"DataSource.get_package_mirror_info  s    {{22t2DDr/   source_event_typesc                     i }|D ][  }| j                   j                         D ]<  \  }}||v s|j                  |      st               ||<   ||   j	                  |       > ] |S r=   )supported_update_eventsre   rz   setadd)rA   r  supported_eventseventupdate_scopeupdate_eventss         r-   get_supported_eventszDataSource.get_supported_events  s~    24' 	>E --335> M)+//=9<(6$\266u=>	>  r/   c                    | j                  |      }|j                         D ]h  \  }}t        j                  d|j                  dj                  |D cg c]  }|j                   c}             | j                  d|z  t        ff       j |r#| j                          | j                         }|ryt        j                  d| dj                  |D cg c]  }|j                   c}             yc c}w c c}w )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  re   r   r   r?   r  r   r   r  )rA   r  r  scopematched_eventsr  results          r-   update_metadata_if_supportedz'DataSource.update_metadata_if_supported  s      445GH%5%;%;%= 		F!E>IIL		NC55;;CD ##lU&:E%B$DE		F ##%]]_F		6II0BCuu{{CD	

 ! D Ds   C1C6c                      yr   r*   )rA   r   s     r-   check_instance_idzDataSource.check_instance_id  s    r/   c                      y)a  check_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   z'DataSource.check_if_fallback_is_allowed  s     r/   c                 ~    |t         }|t        }| D ]'  }|||v r|c S t        j                  d||       |c S  |S )Nz%invalid dsmode '%s', using default=%s)DSMODE_NETWORKVALID_DSMODESr   r  )
candidatesdefaultvalid	candidates       r-   _determine_dsmodezDataSource._determine_dsmode  s_     ?$G=!E# 		I E!  ;Y 		 r/   c                      y r=   r*   r@   s    r-   network_configzDataSource.network_config  r   r/   c                      y)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-   setupzDataSource.setup  s     	r/   c                      y)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-   activatezDataSource.activate  s     	r/   c                      y)z
        Called when the user issues 'cloud-init clean -c datasource'
        command.
        Individual data sources should implement their own cleanup handler.
        Nr*   r@   s    r-   cleanzDataSource.clean
  s     	r/   r=   )r*   T)F)FFF)NN)drD   rE   rF   r  dsmodery  r   r   r	   rM   r   r   r   r   r   r   r5   rH   rL   rJ   rI   r   r
   r5  r8  r:  r<  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   r=  rC  rF  rI  propertyr   r   rL  r   rR  r   rA  r@  rE  rH  rb  r   rg  rt  rw  rz  r   r   r   r   r  r   r  r  r  r   staticmethodr  r  r  r  r  r*   r/   r-   r#   r#      ss   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=$  >$Tl
4 
:Jx
 
 # #
 ! !     .  !#$G  K K + +1F8PE tI  $"&y/$	$L  *  	r/   )	metaclassc                 r   | sg S t        | t              r| j                         S t        | t        t        f      rt        |       S t        | t
              rag }| j                         D ]J  \  }}t        |t              r|g}t        |t        t        f      s0|D ]  }|s|j                  |        L |S g S r=   )rh   rM   
splitlineslistr  rk   re   rg   )pubkey_datakeys_keynameklistpkeys        r-   rd  rd    s    	+s#%%''+c{+K  +&*002 	*OHe %%%$-! *D D)	*	* Ir/   r;   c           	         t        |||      }|D cg c]  }t        j                  |       }	}t        |v rdnd}
t        j                  d|
|	       t        |	|      D ]  \  }}t        j                  d|j                  dd      z  d|
d|d	|
d
||      }	 |5  t        j                  d|        || ||      }|j                  t        j                  g      r/d|
d||_        |t        j                  |      fcd d d        c S 	 d d d         ddj#                  |	      z  }t%        |      c c}w # 1 sw Y   /xY w# t        $ r t        j                   t        d|       Y w xY w)Nnetworkr   z#Searching for %s data source in: %sz	search-%sr#   r`   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   ReportEventStackrj   r  r   r  r  r;  r   r7  r  rY   )r   r   r   ds_depscfg_listpkg_listreporterds_listr]  ds_namesr  r  clsmyrepsmsgs                   r-   find_sourcer  0  sz    8Wh7G0781
##A&8H8#w.9GDII3T8D7+ A	c''t||L"==;?F26=	

	A 9		A3G/11001 @DT$JEMz223789 99A& A499D C &c
**5 99 9  	AKK:C@	As6   D:E A$D?	EE?E	E$E32E3c                 b   g }t         j                  d| ||       | D ]  }t        j                  |      }t        j                  ||dg      \  }}|st         j                  d|       |D ]@  }t        j                  |      }	t        |	d      }
 |
|      }|s/|j                  |          |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 %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getattrrm   )r  dependsr  src_listr7   ds_namem_locs_looked_locsm_locmodlistermatchess               r-   r  r  Q  s     HII	8  ==bA'33X 56 
 II$
  	E((/CS"78FWoG(	$ Or/   fieldc                 z    | syt        j                  |      }|sy| j                         |j                         k(  S r   )r   read_dmi_datarf   )r   r  	dmi_values      r-   instance_id_matches_system_uuidr  u  s;    
 !!%(I)//"333r/   c                     | st         } |st         }|t         k(  r| t         k7  r| S |S t        j                         D ](  \  }}|\  }}|j                  |      s ||       s&|c S  | t         k7  r| S |S )z@Lookup the canonical cloud-id for a given cloud_name and region.)rO  CLOUD_ID_REGION_PREFIX_MAPre   ri   )r   r   r   prefixcloud_id_testr   valid_clouds          r-   r   r     s    %
!!!))!;!A!A!C "/;V$Z)@O %%Or/   c                    | syt        | t              r| S t        | t              rt        j                  |       S t        | t
              r+|du rt        | j                  d      d      S t        d      t        dt        |       z        )aL  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)
rh   rM   r  rc   rd   rk   convert_vendordatarz   r6  rS  )datar  s     r-   r   r     sz     $$}}T""$d?%dhh|&<eLLBCC
;d4jH
IIr/   c                       e Zd Zy)BrokenMetadataNrZ   r*   r/   r-   r  r    r[   r/   r  c                 t    g }t        |       }|D ]%  \  }}|t        |      k(  s|j                  |       ' |S r=   )r  rg   )r  r  ret_listdepsetr  depss         r-   list_from_dependsr    sB    H\F !	TSYOOC ! Or/   r~   fnamec                    	 t        j                  |       }	 t        j                  ||dd       y# t        $ r t        j                  t
        d|        Y yw xY w# t        $ r t        j                  t
        d|       Y yw xY w)z[Use 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dumpsr;  r   r7  r   r!  )r~   r	  pk_contentss      r-   r  r    sz    
ll3'{$UC   C8#>
  C;UCs    2 A $AA$BBc                 d   d}	 t        j                  |       }|sy	 t        j                  |      S # t        $ r@}t        j                  j                  |       rt        j                  d| |       Y d}~]d}~ww xY w# t        $ r Y yt        $ r t        j                  t        d|        Y yw xY w)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_filer;  r  r   isfiler   r  r  r  rV   r7  )r	  pickle_contentsr   s      r-   pkl_loadr    s    OE//6 ||O,,  E77>>% KK95!DE +  C>Fs+   2 A> 	A;6A66A;>	B/	#B/.B/c                  <    t        t        j                               S )zCheck 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                 v   t        j                  d|       }t        j                  d|       }t        j                  d|       }|xs |xs |}|xs |}|rA|j                  d      j                         }t	        j
                  d| d| dd| d	
       |r"|j                  d      r|j                  d      S y)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_messager`   )researchgroupstripr   	deprecate)r  
ds_parse_0
ds_parse_1
ds_parse_2r7   r  r   s          r-   r  r    s    2E:J6>J>FJ		/z	/ZB)zJ!!!$**, !!!'*  &#F884	
 
bhhqkxx{r/   )r`   r*   )zsystem-uuidr  )Yabcrc   r  loggingr  r  r  enumr   r   typingr   r   r   r   r	   r
   r   r   	cloudinitr   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_VALUErQ  r   rO  	getLoggerrD   r   r  r5   rO   r;  rV   rY   r]   rl   r   r   r   r   ABCMetar#   rd  rM   r  r  r   r  r   r   IOErrorr  r  r  r  r   r  r*   r/   r-   <module>r;     s       	  	  L L L
 
 
 / $ 1 * # 6 & ,?	<  6  '  g!
 -./034  $   t Pi P	) 	Cy C F 2H :
  
: I% IX:+
:s?+B!J ,44	4&J0	W 	: c d $C HZ0 *4s 4  r/   