o
    i!                  
   @   s  U d dl Z d dlZd dlmZ d dlmZ d dlmZ d dlm	Z	 d dl
mZ d dlmZ e eZdZd	Zd
ZddddZdZdZdZdZdZddgeegdZeed< dedefddZdefddZdeeef defdd Z d!e!dedefd"d#Z"d$e!de	d%ed&e#ddf
d'd(Z$dS ))    N)Union)subp)Cloud)Config)
MetaSchema)PER_INSTANCErpi
interfacesenable_usb_gadgetdo_spido_i2c
do_onewire)spii2conewireserialdo_serial_consdo_serial_hwz/usr/bin/rpi-usb-gadgetz(Rebooting to apply config.txt changes...cc_raspberry_pizraspberry-pi-os)iddistros	frequencyactivate_by_schema_keysmetaenablereturnc              
   C   s   t d|  tjtst dt dS ztjt| rdnddgddd W d	S  tjy@ } zt d
| W Y d}~dS d}~ww )zEnable / Disable Raspberry Pi USB gadget mode when
    the script is present.

    Returns True when a reboot is required.
    zEnable rpi-usb-gadget mode: %sz#rpi-usb-gadget script not found: %sFonoffz-f   )capturetimeoutTz&Failed to configure rpi-usb-gadget: %sN)	LOGdebugospathexistsRPI_USB_GADGET_SCRIPTerrorr   ProcessExecutionError)r   e r*   B/usr/lib/python3/dist-packages/cloudinit/config/cc_raspberry_pi.pyconfigure_usb_gadget(   s&   
r,   c                   C   s,   z
t  g d W dS  t jy   Y dS w )N)/usr/bin/raspi-confignonint	is_pifiveTF)r   r(   r*   r*   r*   r+   r/   K   s   r/   cfgc              
   C   s
  ddt dtfdd}d}d}t| t r|| d}|| d}nt| tr%| }t s,|r,d}ztd	d
tt|r7dndg W n tjyW } zt	d| W Y d}~dS d}~ww ztd	d
t
t|rcdndg W dS  tjy } zt	d| W Y d}~dS d}~ww )au  Configure the serial (UART) interface on Raspberry Pi.

    Depending on the configuration, this enables or disables
    the serial console and the hardware UART by invoking
    `raspi-config` non-interactively.

    Args:
        cfg: Either a boolean or a dictionary:
            - If a bool, enables or disables the serial
              console and hardware UART together.
            - If a dict, may contain the keys `console`
              and `hardware` with boolean values controlling
              each individually.

    Returns:
        True if the configuration was applied successfully,
        False otherwise.
    Fcfg_dictnamec                 S   s.   |  ||}t|tstdt|| |S |S )Nz"Invalid value for %s.serial.%s: %s)get
isinstanceboolr!   warningRPI_INTERFACES_KEY)r1   r2   defaultvalr*   r*   r+   get_bool_fieldg   s   
z2configure_serial_interface.<locals>.get_bool_fieldconsolehardwareTr-   r.   r      z&Failed to configure serial console: %sNz'Failed to configure serial hardware: %s)F)dictstrr4   r5   r/   r   RASPI_CONFIG_SERIAL_CONS_FNr(   r!   r'   RASPI_CONFIG_SERIAL_HW_FN)r0   r:   enable_console	enable_hwr)   r*   r*   r+   configure_serial_interfaceS   sJ   



rD   ifacec              
   C   sz   | t  v sJ d|  ztddt |  t|rdndg W dS  tjy< } ztd| | W Y d}~d	S d}~ww )
a  Enable or disable a supported hardware interface.

    Supported interfaces are defined in `SUPPORTED_INTERFACES` and
    currently include SPI, I2C, and 1-Wire. The function applies
    the change using `raspi-config` in non-interactive mode.

    Args:
        iface: The interface name (e.g. `"spi"` or `"i2c"`).
        enable: True to enable the interface, False to disable it.

    Returns:
        True if the interface configuration succeeded, False otherwise.
    zUnsupported interface: r-   r.   r   r=   TzFailed to configure %s: %sNF)SUPPORTED_INTERFACESkeysr   r?   r(   r!   r'   )rE   r   r)   r*   r*   r+   configure_interface   s"   	rH   r2   cloudargsc           
      C   s  t |vrd S t|t  tstdt |t   d S |t  s$tdt  d S d}|t  D ]}|tkrJ|t  | }t|trB|t|O }nt	dt q*|t
krt|t  | tsetdt |t  |   d S |t  | sttd|  d S t|t  |  }|D ]L}|t vr|tkrtdt
| q|t  | | }|tkrt|ttfstdt
|| n|t|O }qt|tr|t||O }qtdt
|| qq*td| q*|du r|jjd	d
td}	t|	 d S d S )NzInvalid value for %s: %szEmpty value for %s. Skipping...FzInvalid value for zInvalid key for %s: %szInvalid value for %s.%s: %szUnsupported key: %sTrebootnow)modedelaymessage)RPI_BASE_KEYr4   r>   r!   r6   r"   ENABLE_USB_GADGET_KEYr5   r,   
ValueErrorr7   listrG   rF   SERIAL_INTERFACErD   rH   distroshutdown_command
REBOOT_MSGr   )
r2   r0   rI   rJ   want_rebootkeyr   subkeyssubkeycmdr*   r*   r+   handle   s   


"r]   )%loggingr#   typingr   	cloudinitr   cloudinit.cloudr   cloudinit.configr   cloudinit.config.schemar   cloudinit.settingsr   	getLogger__name__r!   rP   r7   rQ   rF   rT   r@   rA   r&   rW   r   __annotations__r5   r,   r/   r>   rD   r?   rH   rS   r]   r*   r*   r*   r+   <module>   s>   

#N""