+
    iD                        R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHtHt ^ RI	H
t
 ^ RIHtHtHtHtHtHtHt ^ RIt^ RIHt ^ RIHt ^ RIHt ^ RIHtHtHtHtHt ^ R	I H!t! ]PD                  ! ]#4      t$R
t%Rt&Rt'RRRRRRRRRRRR/t(R R lt)R3R R llt* ! R R]4      t+ ! R R]4      t, ! R R]4      t-R  R! lt. ! R" R#]P^                  4      t0R4R$ R% llt1R4R& R' llt2 ! R( R)]4      t3 ! R* R+4      t4]&]3Pj                  3R, R- llt6]0]Pn                  33.t8R. t9]#R/8X  dU   ^ RI:t:R0t;]:Px                  ! ];R17      t=]=P}                  4        ]?! ]P                  ! ]6! ]3Pj                  R27      4      4       R# R# )5a  Datasource for LXD, reads /dev/lxd/sock representation of instance data.

Notes:
 * This datasource replaces previous NoCloud datasource for LXD.
 * Older LXD images may not have updates for cloud-init so NoCloud may
   still be detected on those images.
 * Detect LXD datasource when /dev/lxd/sock is an active socket file.
 * Info on dev-lxd API: https://documentation.ubuntu.com/lxd/en/latest/dev-lxd/
N)Flagauto)JSONDecodeError)AnyDictListOptionalTupleUnioncast)HTTPAdapter)HTTPConnection)HTTPConnectionPool)atomic_helpersourcessubp
url_helperutil)find_fallback_nicz/dev/lxd/sockz1.0z
http://lxdcloud-init.user-data	user-datazcloud-init.network-confignetwork-configcloud-init.vendor-datavendor-datauser.user-datazuser.network-configuser.vendor-datac                $    V ^8  d   QhR\         /#    returnstr)formats   "A/usr/lib/python3/dist-packages/cloudinit/sources/DataSourceLXD.py__annotate__r$   /   s      c     c                     R p \         P                  ! R4      '       dg    \         P                   ! R.4      w  rTP                  4       R
9   d8   \        P                  ! 4       R,          ^,          pTR8X  d   R# TR8X  d   R# R	# V #   \         P                   d#   p\        P	                  RT4       T u Rp?# Rp?ii ; i)eth0zsystemd-detect-virtzHUnable to run systemd-detect-virt: %s. Rendering default network config.Nunameppc64leenp0s5s390xenc9enp5s0)kvmqemu)r   whichProcessExecutionErrorLOGwarningstripr   system_info)default_name	virt_type_errarchs        r#   _get_fallback_interface_namer;   /   s    Lzz'((	 99&;%<=LI ?? !
 
 ##%g.q1Dy % )) 	 KK5
  	 s   B B>B93B>9B>c                ~    V ^8  d   QhR\         \        \        ,          ,          R\        \        \        3,          /# )r   nicsr   )r   r   r!   r   r   )r"   s   "r#   r$   r$   I   s-     # #
49
#	#s(^#r%   c                    \        4       pV'       d   \        P                  RV4       M \        4       p\        P                  RV4       R^RRRRVRRR	R
R/././# )zCReturn network config V1 dict representing instance network config.zCLXD datasource generating network from discovered active device: %szVLXD datasource generating network from systemd-detect-virt platform default device: %sversionconfigtypephysicalnamesubnetsdhcpcontrolr   )r   r2   debugr;   )r=   primary_nics   & r#   generate_network_configrI   I   sz     $%K			
 34		+	
 	1
VVY?@
	 	r%   c                   8   a a ] tR t^ot oV 3R ltR tRtVtV ;t# )SocketHTTPConnectionc                @   < \         SV `  R 4       Wn        RV n        R# 	localhostN)super__init__socket_pathsockselfrQ   	__class__s   &&r#   rP   SocketHTTPConnection.__init__p   s    %&	r%   c                    \         P                   ! \         P                  \         P                  4      V n        V P                  P	                  V P
                  4       R # N)socketAF_UNIXSOCK_STREAMrR   connectrQ   rT   s   &r#   r\   SocketHTTPConnection.connectu   s6    MM&..&2D2DE			$**+r%   )rR   rQ   )	__name__
__module____qualname____firstlineno__rP   r\   __static_attributes____classdictcell____classcell__rU   __classdict__s   @@r#   rK   rK   o   s     
, ,r%   rK   c                   8   a a ] tR t^zt oV 3R ltR tRtVtV ;t# )SocketConnectionPoolc                2   < Wn         \        SV `	  R 4       R# rM   )rQ   rO   rP   rS   s   &&r#   rP   SocketConnectionPool.__init__{   s    &%r%   c                ,    \        V P                  4      # rX   )rK   rQ   r]   s   &r#   	_new_connSocketConnectionPool._new_conn   s    #D$4$455r%   )rQ   )	r_   r`   ra   rb   rP   rm   rc   rd   re   rf   s   @@r#   ri   ri   z   s     &6 6r%   ri   c                   4   a  ] tR t^t o RR ltRR ltRtV tR# )LXDSocketAdapterNc                     \        \        4      # rX   )ri   LXD_SOCKET_PATH)rT   urlproxiess   &&&r#   get_connectionLXDSocketAdapter.get_connection   s    #O44r%   c                :    V P                  VP                  V4      # rX   )ru   rs   )rT   requestverifyrt   certs   &&&&&r#   get_connection_with_tls_context0LXDSocketAdapter.get_connection_with_tls_context   s     ""7;;88r%    rX   )NN)r_   r`   ra   rb   ru   r{   rc   rd   rg   s   @r#   rp   rp      s     5
9 9r%   rp   c                0    V ^8  d   QhR\         R\        /# )r   metadata_typer   )r!   dict)r"   s   "r#   r$   r$      s      c d r%   c                8   \        V\        4      '       d   V# Vf   / #  \        P                  ! V4      pTf'   \
        P                  ! RP                  YR7      4      hT#   \         d-   p\
        P                  ! RP                  YR7      4      ThRp?ii ; i)a"  Convert raw instance data from str, bytes, YAML to dict

:param metadata_type: string, one of as: meta-data, vendor-data, user-data
    network-config

:param metadata_value: str, bytes or dict representing or instance-data.

:raises: InvalidMetaDataError on invalid instance-data content.
NzAInvalid {md_type}. Expected str, bytes or dict but found: {value})md_typevaluez:Invalid {md_type} format. Expected YAML but found: {value})
isinstancer   r   	load_yamlAttributeErrorr   InvalidMetaDataExceptionr"   )r   metadata_valueparsed_metadataexcs   &&  r#   _raw_instance_data_to_dictr      s     .$''	..8 ..vmvJ
 	
   ..vmvJ
 	s   A" "B-'BBc                   *  a a ] tR t^t oRt]P                  t]P                  t]P                  P                  R,           t
RtV3R lV 3R llt]V3R lR l4       tV3R lR ltV3R	 lR
 ltV3R lR lt]V3R lR l4       tV3R ltRtVtV ;t# )DataSourceLXDLXDTc                $   < V ^8  d   QhRS[ RR/# )r   ci_pkl_versionr   N)int)r"   rg   s   "r#   r$   DataSourceLXD.__annotate__   s     ( ( ( (r%   c                4   < \         SV `  V4       R V n        R# )TN)rO   	_unpickleskip_hotplug_detect)rT   r   rU   s   &&r#   r   DataSourceLXD._unpickle   s    .)#' r%   c                    < V ^8  d   QhRS[ /# r   bool)r"   rg   s   "r#   r$   r      s      t r%   c                 D   \         P                  P                  \        4      '       g   \        P                  R\        4       R# \        P                  ! \         P                  ! \        4      P                  4      '       g   \        P                  R\        4       R# R# )z@Check platform environment to report if this datasource may run.z%s does not exist.Fz%s is not a socketT)
ospathexistsrr   r2   r3   statS_ISSOCKlstatst_moder}   r%   r#   	ds_detectDataSourceLXD.ds_detect   s\     ww~~o..KK,o>rxx8@@AAKK,o>r%   c                    < V ^8  d   QhRS[ /# r   r   )r"   rg   s   "r#   r$   r      s      4 r%   c                8   \        4       V n        \        RV P                  P                  R4      4      V n        V P                  P                  R/ 4      pVP                  R/ 4      pV'       d&   V P                  P                  \        RV4      4       RV P                  9   d   V P                  R,          V n        RV P                  9   d#   \        RV P                  R,          4      V n        RV P                  9   d   V P                  R,          V n        R# )z=Crawl LXD socket API instance data and return True on success	meta-datar@   user.meta-datar   r   r   T)	read_metadata_crawled_metadatar   getmetadataupdateuserdata_raw_network_configvendordata_raw)rT   r@   user_metadatas   &  r#   	_get_dataDataSourceLXD._get_data   s    !.2//33K@
 ''++Hb9

#3R8MM  *+;]K $000 $ 6 6{ CDt555#= $"8"89I"J$D  D222"&"8"8"GDr%   c                    < V ^8  d   QhRS[ /# r   r    )r"   rg   s   "r#   r$   r      s     
 
# 
r%   c                8    RP                  \        \        R7      # )z.Return subplatform details for this datasourcez"LXD socket API v. {ver} ({socket}))verrY   )r"   LXD_SOCKET_API_VERSIONrr   r]   s   &r#   _get_subplatformDataSourceLXD._get_subplatform   s    3::& ; 
 	
r%   c                    < V ^8  d   QhRS[ /# r   r    )r"   rg   s   "r#   r$   r      s     I IC Ir%   c                   \        \        P                  R7      pVP                  R/ 4      p\	        V\
        4      '       g   \        P                  ! V4      pVP                  R4      V P                  P                  R4      8H  # )z%Return True if instance_id unchanged.metadata_keysr   zinstance-id)	r   MetaDataKeys	META_DATAr   r   r   r   r   r   )rT   sys_cfgresponsemds   &&  r#   check_instance_idDataSourceLXD.check_instance_id   s`     |/E/EF\\+r*"d###Bvvm$(9(9-(HHHr%   c                    < V ^8  d   QhRS[ /# r   )r   )r"   rg   s   "r#   r$   r      s     0 0 0r%   c                .   V P                   \        P                  8X  Ed   V P                  \        P                  8X  d   V P	                  4        \        V P                  \        4      '       d   V P                  P                  R4      '       d/   \        P                  R4       V P                  R,          V n         MuV P                  P                  R4      '       dU   V P                  R,          P                  4        UUu. uF  w  rVR,          R8X  g   K  VNK  	  ppp\        V4      V n         V P                   \        P                  8X  d%   \        P                  R4       \        4       V n         \        \        V P                   4      # u uppi )z~Network config read from LXD socket config/user.network-config.

If none is present, then we generate fallback configuration.
r   z,LXD datasource using provided network configdevicesrA   nicz8LXD datasource generating network config using fallback.)r   r   UNSETr   r   r   r   r   r2   rG   itemsrI   r   )rT   kvr   s   &   r#   network_configDataSourceLXD.network_config   s5    7==0%%6 $00$77))--.>??IILM+/+A+A(,D( ++//	::
 %)$:$:9$E$K$K$M*$MDAV9- $M  *
 ,C7+KD(7==0IIJ $;#<D D$..//*s   FFc                   < V ^8  d   Qh/ S[ S[S[3,          ;R&   S[S[ S[S[3,          ,          ;R&   S[S[R3,          ;R&   # )r   r   r   .sensitive_metadata_keys)r
   r   r!   r   r	   )r"   rg   s   "r#   r$   r      sM      49%5	 
  dCi 01A  #38_ 	 r%   )r   r   r   r   r   r   )r   r   r   r   r   )r_   r`   ra   rb   dsnamer   r   r   r   
DataSourcer   r   r   staticmethodr   r   r   r   propertyr   __annotate_func__rc   rd   re   rf   s   @@r#   r   r      s     F(/O4;MM 	22
	
  ( (   ,
 
I I 0 0Q  r%   r   c                P    V ^8  d   QhR\         P                  R\        R\        /# )r   sessionrs   do_raise)requestsSessionr!   r   )r"   s   "r#   r$   r$     s*      $'37r%   c           	         \        WV4      pVP                  '       g>   \        P                  R VVP                  VP
                  P                  R4      4       / #  VP                  4       #   \         dF   p\        P                  ! RP                  YP
                  P                  R4      R7      4      ThRp?ii ; i)Skipping %s on [HTTP:%d]:%sutf-8zFUnable to process LXD config at {url}. Expected JSON but found: {resp})rs   respN)_do_requestokr2   rG   status_codecontentdecodejsonr   r   r   r"   )r   rs   r   url_responser   s   &&&  r#   _get_json_responser     s     wX6L???		)$$  ''0		
 	  "" ..//5v2299'B 06 0

 	s   A- -B=8A B88B=c                p    V ^8  d   QhR\         P                  R\        R\        R\         P                  /# )r   r   rs   r   r   )r   r   r!   r   Response)r"   s   "r#   r$   r$   ,  s8      $'37r%   c           	         \        ^^ R4       F_  pV P                  V4      pRVP                  8X  d;   \        P                  ! R4       \
        P                  RVP                  VV4       K_   M	  \
        P                  RXP                  V4       V'       d^   VP                  '       gL   \        P                  ! RP                  VP                  VVP                  P                  R4      R7      4      hV# )	   i  g?z,[GET] [HTTP:%d] %s, retrying %d more time(s)z[GET] [HTTP:%d] %sz3Invalid HTTP response [{code}] from {route}: {resp}r   )coderouter   )ranger   r   timesleepr2   r3   rG   r   r   r   r"   r   r   )r   rs   r   retriesr   s   &&&  r#   r   r   ,  s     Q#;;s#(&&& JJsOKK>$$	  $ II"H$8$8#>..AHH))%%,,W5 I 
 	
 Or%   c                   n    ] tR tRt]! 4       t]! 4       t]! 4       t]! 4       t]],          ],          t	Rt
R# )r   iI  r}   N)r_   r`   ra   rb   r   NONECONFIGDEVICESr   ALLrc   r}   r%   r#   r   r   I  s-    6DVFfGI
7
Y
&Cr%   r   c                   \   a  ] tR tRt o ]3V 3R lR lltV 3R lR ltV 3R lR ltRtV t	R	# )
_MetaDataReaderiQ  c                    < V ^8  d   QhRS[ /# )r   api_versionr    )r"   rg   s   "r#   r$   _MetaDataReader.__annotate__R  s     N NC Nr%   c                f    Wn         \        P                  ! \        V P                   4      V n        R # rX   )r   r   combine_urlLXD_URL_version_url)rT   r   s   &&r#   rP   _MetaDataReader.__init__R  s#    &&227D<L<LMr%   c                :   < V ^8  d   QhRS[ P                  RS[/# )r   r   r   )r   r   r   )r"   rg   s   "r#   r$   r   V  s!     4 4x'7'7 4D 4r%   c           
     r   R/ /p\         P                  ! V P                  R4      p\        W4      p\	        V4       F  p\         P                  ! \
        V4      p\        WRR7      pVP                  P                  R4      pVP                  '       g%   \        P                  RVVP                  V4       K|  VP                  R4      R
,          p	WR,          V	&   V	\        9   g   K  \        V	,          V9  d   W\        V	,          &   K  \        P                  RV	V	P!                  RR	^4      4       K  	  V# )ab  Iterate on LXD API config items. Promoting CONFIG_KEY_ALIASES

Any CONFIG_KEY_ALIASES which affect cloud-init behavior are promoted
as top-level configuration keys: user-data, network-data, vendor-data.

LXD's cloud-init.* config keys override any user.* config keys.
Log debug messages if any user.* keys are overridden by the related
cloud-init.* key.
r@   Fr   r   r   /z,Ignoring LXD config %s in favor of %s value.userz
cloud-initr   )r   r   r   r   sortedr   r   r   r   r   r2   rG   r   
rpartitionCONFIG_KEY_ALIASESr3   replace)
rT   r   r@   
config_urlconfig_routesconfig_routeconfig_route_urlconfig_route_responseresponse_textcfg_keys
   &&        r#   _process_config_MetaDataReader._process_configV  s     !"~++D,=,=xH
 +7?
 #=1L)55g|L$/E%! 299@@IM(+++		1$)55!	 "--c226G )68W%,, &g.f<:G-g67KKFa@9 2B r%   c                &   < V ^8  d   QhRS[ RS[/# )r   r   r   )r   r   )r"   rg   s   "r#   r$   r     s       $ r%   c                  \         P                  ! 4       ;_uu_ 4       pVP                  V P                  \	        4       4       R V P
                  /p\        P                  V9   dI   \        P                  ! V P                  R4      p\        W$4      P                  P                  R4      VR&   \        P                  V9   d!   VP                  V P                  V4      4       \        P                   V9   d;   \        P                  ! V P                  R4      p\#        W%RR7      pV'       d   WcR&   VuuRRR4       #   + '       g   i     R# ; i)_metadata_api_versionr   r   r   Fr  N)r   r   mountr   rp   r   r   r   r   r   r   r   r   r   r   r  r   r   )rT   r   r   r   md_routers   r   s   &$     r#   __call___MetaDataReader.__call__  s    7MM$++-=-?@/1A1ABB%%6%11%%{ #.#'&&/ ; ""m3		$..w78##}4 ,,T->->	J,WEJ$+yM%  s   DD>>E	)r   r   N)
r_   r`   ra   rb   r   rP   r  r  rc   rd   r~   s   @r#   r   r   Q  s)     *@ N N4 4l r%   r   c                <    V ^8  d   QhR\         R\        R\        /# )r   r   r   r   )r!   r   r   )r"   s   "r#   r$   r$     s&     % %%% 
%r%   c                (    \        V R7      ! VR7      # )a  Fetch metadata from the /dev/lxd/socket routes.

Perform a number of HTTP GETs on known routes on the devlxd socket API.
Minimally all containers must respond to <LXD_SOCKET_API_VERSION>/meta-data
when the LXD configuration setting `security.devlxd` is true.

When `security.devlxd` is false, no /dev/lxd/socket file exists. This
datasource will return False from `ds_detect` in that case.

Perform a GET of <LXD_SOCKET_API_VERSION>/config` and walk all `user.*`
configuration keys, storing all keys and values under a dict key
    LXD_SOCKET_API_VERSION: config {...}.

In the presence of the following optional user config keys,
create top level aliases:
  - user.user-data -> user-data
  - user.vendor-data -> vendor-data
  - user.network-config -> network-config

:param api_version:
    LXD API version to operated with.
:param metadata_keys:
    Instance of `MetaDataKeys` indicating what keys to fetch.
:return:
    A dict with the following optional keys: meta-data, user-data,
    vendor-data, network-config, network_mode, devices.

    Below <LXD_SOCKET_API_VERSION> is a dict representation of all raw
    configuration keys and values provided to the container surfaced by
    the socket under the /1.0/config/ route.
)r   r   )r   )r   r   s   &&r#   r   r     s    F {3# r%   c                 8    \         P                  ! V \        4      # rX   )r   list_from_dependsdatasources)dependss   &r#   get_datasource_listr     s    $$Wk::r%   __main__z*Query LXD metadata and emit a JSON object.)descriptionr   rX   )T)A__doc__loggingr   rY   r   r   enumr   r   json.decoderr   typingr   r   r   r   r	   r
   r   r   requests.adaptersr   urllib3.connectionr   urllib3.connectionpoolr   	cloudinitr   r   r   r   r   cloudinit.netr   	getLoggerr_   r2   rr   r   r   r  r;   rI   rK   ri   rp   r   r   r   r   r   r   r   r   r   DEP_FILESYSTEMr  r   argparser"  ArgumentParserparser
parse_argsprint
json_dumpsr}   r%   r#   <module>r5     s    	     ( @ @ @  ) . 5 D D +!! 
 K!1mk+ 4#L,> ,6- 6	9{ 	9:f0G&& f0R.:'4 'N Nd ."."2"2%T W++-.; zBK$$=F
	  \=M=M!NO r%   