name : DataSourceLXD.cpython-39.opt-1.pyc
a

'�Dg�D�@s:dZddlZddlZddlZddlZddlZddlmZmZddl	m
Z
ddlmZm
Z
mZmZmZmZmZddlZddlmZddlmZddlmZdd	lmZmZmZmZmZdd
l m!Z!e�"e#�Z$dZ%dZ&d
Z'ddddddd�Z(e)d�dd�Z*d9eee)e
e)efd�dd�Z+Gdd�de�Z,Gdd�de�Z-Gdd�de�Z.e)e/d�dd �Z0Gd!d"�d"ej1�Z2e3d�d#d$�Z4d:ej5e)e3d&�d'd(�Z6d;ej5e)e3ej7d)�d*d+�Z8Gd,d-�d-e�Z9Gd.d/�d/�Z:e&e9j;fe)e9e/d0�d1d2�Z<e2ej=ffgZ>d3d4�Z?e#d5k�r6ddl@Z@d6ZAe@jBeAd7�ZCeC�D�eEe�Fe<e9j;d8���dS)<a�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/sockz1.0z
http://lxd�	user-data�network-config�vendor-data)�cloud-init.user-datazcloud-init.network-config�cloud-init.vendor-data�user.user-datazuser.network-config�user.vendor-data��returnc
Cs�d}t�d�r�zt�dg�\}}Wn6tjyX}zt�d|�|WYd}~Sd}~00|��dvr�t��dd}|dkr�dS|d	kr�d
SdS|S)NZeth0zsystemd-detect-virtzHUnable to run systemd-detect-virt: %s. Rendering default network config.)ZkvmZqemu�uname�Zppc64leZenp0s5Zs390xZenc9Zenp5s0)r�whichZProcessExecutionError�LOG�warning�striprZsystem_info)Zdefault_nameZ	virt_type�_�errZarch�r&�C/usr/lib/python3.9/site-packages/cloudinit/sources/DataSourceLXD.py�_get_fallback_interface_name/s$
�r()�nicsrcCsFt�}|rt�d|�nt�}t�d|�dd|ddd�gd�gd	�S)
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�ZphysicalZdhcpr)�typeZcontrol)r+�name�subnets)�version�config)rr!�debugr()r)Zprimary_nicr&r&r'�generate_network_configIs$��
���r1cs$eZdZ�fdd�Zdd�Z�ZS)�SocketHTTPConnectioncst��d�||_d|_dS�NZ	localhost)�super�__init__�socket_path�sock��selfr6��	__class__r&r'r5pszSocketHTTPConnection.__init__cCs$t�tjtj�|_|j�|j�dS�N)�socketZAF_UNIXZSOCK_STREAMr7�connectr6�r9r&r&r'r>uszSocketHTTPConnection.connect)�__name__�
__module__�__qualname__r5r>�
__classcell__r&r&r:r'r2osr2cs$eZdZ�fdd�Zdd�Z�ZS)�SocketConnectionPoolcs||_t��d�dSr3)r6r4r5r8r:r&r'r5{szSocketConnectionPool.__init__cCs
t|j�Sr<)r2r6r?r&r&r'�	_new_connszSocketConnectionPool._new_conn)r@rArBr5rErCr&r&r:r'rDzsrDc@s eZdZddd�Zddd�ZdS)�LXDSocketAdapterNcCstt�Sr<)rD�LXD_SOCKET_PATH)r9�url�proxiesr&r&r'�get_connection�szLXDSocketAdapter.get_connectioncCs|�|j|�Sr<)rJrH)r9ZrequestZverifyrIZcertr&r&r'�get_connection_with_tls_context�sz0LXDSocketAdapter.get_connection_with_tls_context)N)NN)r@rArBrJrKr&r&r&r'rF�s
�rF)�
metadata_typerc
Cs�t|t�r|S|duriSzt�|�}Wn:tyb}z"t�dj||d��|�WYd}~n
d}~00|dur�t�dj||d���|S)a6Convert 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})Zmd_type�valuez:Invalid {md_type} format. Expected YAML but found: {value})�
isinstance�dictr�	load_yaml�AttributeErrorr�InvalidMetaDataException�format)rLZmetadata_valueZparsed_metadata�excr&r&r'�_raw_instance_data_to_dict�s*

�����rUcs�eZdZUdZejZeee	fe
d<ejZeeee	fe
d<ej
jdZee	dfe
d<dZedd	��fd
d�Zeed�d
d��Zed�dd�Ze	d�dd�Ze	d�dd�Zeed�dd��Z�ZS)�
DataSourceLXDZLXD�_network_config�_crawled_metadata)�user.meta-datarrrr.�sensitive_metadata_keysTN)�ci_pkl_versionrcst��|�d|_dS)NT)r4�	_unpickle�skip_hotplug_detect)r9r[r:r&r'r\�szDataSourceLXD._unpicklercCst�S)z@Check platform environment to report if this datasource may run.)�is_platform_viabler&r&r&r'�	ds_detect�szDataSourceLXD.ds_detectcCs�t�|_td|j�d��|_|j�di�}|�di�}|rL|j�td|��d|jvrb|jd|_d|jvr~td|jd�|_d|jvr�|jd|_dS)z=Crawl LXD socket API instance data and return True on success�	meta-datar/rYrrrT)	�
read_metadatarXrU�get�metadata�updateZuserdata_rawrWZvendordata_raw)r9r/Z
user_metadatar&r&r'�	_get_data�s&��


�
zDataSourceLXD._get_datacCsdjttd�S)z.Return subplatform details for this datasourcez"LXD socket API v. {ver} ({socket}))Zverr=)rS�LXD_SOCKET_API_VERSIONrGr?r&r&r'�_get_subplatform�s�zDataSourceLXD._get_subplatformcCsBttjd�}|�di�}t|t�s,t�|�}|�d�|j�d�kS)z%Return True if instance_id unchanged.��
metadata_keysr`zinstance-id)	ra�MetaDataKeys�	META_DATArbrNrOrrPrc)r9Zsys_cfg�response�mdr&r&r'�check_instance_id�s


zDataSourceLXD.check_instance_idcCs�|jtjkr~|jtjkr |��t|jt�r~|j�d�rPt�	d�|jd|_n.|j�d�r~dd�|jd�
�D�}t|�|_|jtjkr�t�	d�t�|_tt|j�S)z�Network config read from LXD socket config/user.network-config.

        If none is present, then we generate fallback configuration.
        rz,LXD datasource using provided network config�devicescSs g|]\}}|ddkr|�qS)r+Znicr&)�.0�k�vr&r&r'�
<listcomp>�s�z0DataSourceLXD.network_config.<locals>.<listcomp>z8LXD datasource generating network config using fallback.)
rWr�UNSETrXrerNrOrbr!r0�itemsr1r)r9ror&r&r'�network_config�s(
��
�zDataSourceLXD.network_config)r@rArBZdsnamerrtrWr
r�str�__annotations__rXr�
DataSourcerZr	r]�intr\�staticmethod�boolr_rergrn�propertyrOrvrCr&r&r:r'rV�s 
��rVcCs"tj�t�rt�t�t�j�SdS)z=Return True when this platform appears to have an LXD socket.F)�os�path�existsrG�stat�S_ISSOCK�lstat�st_moder&r&r&r'r^sr^T)�sessionrH�do_raisec
Cs�t|||�}|js0t�d||j|j�d��iSz
|��WSty|}z*t	�
dj||j�d�d��|�WYd}~n
d}~00dS)N�Skipping %s on [HTTP:%d]:%s�utf-8zFUnable to process LXD config at {url}. Expected JSON but found: {resp})rH�resp)�_do_request�okr!r0�status_code�content�decodeZjsonrrrRrS)r�rHr�Zurl_responserTr&r&r'�_get_json_responses&
�
���r�)r�rHr�rcCs�tddd�D]:}|�|�}d|jkrBt�d�t�d|j||�qqHqt�d|j|�|r�|js�t	�
dj|j||j�
d	�d
���|S)N�r���i�g�������?z,[GET] [HTTP:%d] %s, retrying %d more time(s)z[GET] [HTTP:%d] %sz3Invalid HTTP response [{code}] from {route}: {resp}r�)�codeZrouter�)�rangerbr��time�sleepr!r"r0r�rrRrSr�r�)r�rHr�Zretriesrlr&r&r'r�-s*


�

��r�c@s0eZdZe�Ze�Ze�Ze�ZeeBeBZdS)rjN)	r@rArBrZNONE�CONFIG�DEVICESrk�ALLr&r&r&r'rjJs
rjc@s@eZdZefed�dd�Zejed�dd�Z	e
ed�dd	�Zd
S)�_MetaDataReader��api_versioncCs||_t�t|j�|_dSr<)r�r�combine_url�LXD_URL�_version_url)r9r�r&r&r'r5Ssz_MetaDataReader.__init__)r�rc

Cs�dii}t�|jd�}t||�}t|�D]�}t�t|�}t||dd�}|j�d�}|j	slt
�d||j|�q(|�
d�d}	||d|	<|	tvr(t|	|vr�||t|	<q(t
�d|	|	�d	d
d��q(|S)a�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��/r�z,Ignoring LXD config %s in favor of %s value.�userz
cloud-initr*)rr�r�r��sortedr�r�r�r�r�r!r0r��
rpartition�CONFIG_KEY_ALIASESr"�replace)
r9r�r/Z
config_urlZ
config_routesZconfig_routeZconfig_route_urlZconfig_route_responseZ
response_textZcfg_keyr&r&r'�_process_configWs8

���z_MetaDataReader._process_config)rircCs�t����}|�|jt��d|ji}tj|vrRt�	|jd�}t
||�j�d�|d<tj
|vrl|�|�|��tj|vr�t�	|jd�}t||dd�}|r�||d<|Wd�S1s�0YdS)NZ_metadata_api_versionr`r�roFr�)�requests�SessionZmountr�rFr�rjrkrr�r�r�r�r�rdr�r�r�)r9rir�rmZmd_routerHror&r&r'�__call__�s(


���

z_MetaDataReader.__call__N)r@rArBrfrwr5r�r�rOr�rjr�r&r&r&r'r�Rs6r�)r�rircCst|d�|d�S)a8Fetch 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 `is_platform_viable` 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�rh)r�)r�rir&r&r'ra�s#�racCst�|t�Sr<)rZlist_from_depends�datasources)Zdependsr&r&r'�get_datasource_list�sr��__main__z*Query LXD metadata and emit a JSON object.)�descriptionrh)N)T)T)G�__doc__Zloggingr~r=r�r��enumrrZjson.decoderr�typingrrrrr	r
rr�Zrequests.adaptersrZurllib3.connectionr
Zurllib3.connectionpoolrZ	cloudinitrrrrrZ
cloudinit.netrZ	getLoggerr@r!rGrfr�r�rwr(r1r2rDrFrOrUryrVr|r^r�r�ZResponser�rjr�r�raZDEP_FILESYSTEMr�r��argparser��ArgumentParser�parser�
parse_args�printZ
json_dumpsr&r&r&r'�<module>s�
$
�
�

�&	c����R��*
�
�

© 2025 Cubjrnet7