Ë
    x[hÐ�  ã                   óî  — 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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mZmZmZmZmZ d dlZd dlmZmZmZ d dlmZmZ  ej<                  e«      Z dZ!d	Z"d
Z#dZ$ G d„ de%«      Z& G d„ de&«      Z' G d„ de&«      Z( G d„ de&«      Z)	 d!dee*ef   fd„Z+d„ Z,d"d„Z-d"d„Z. G d„ de j^                  «      Z0 G d„ de0«      Z1 G d„ de0«      Z2 G d„ d e0«      Z3e2e1e3gZ4y)#é    N)Úsuppress)ÚStringIO)ÚTimeoutExpired)ÚAnyÚCallableÚDictÚListÚOptionalÚTuple)ÚsubpÚ
temp_utilsÚutil)Úget_interface_macÚis_ib_interfacez/run/systemd/netif/leasesz/var/lib/dhclientz.+\.leases?$aN  #!/bin/sh
log() {
    echo "udhcpc[$PPID]" "$interface: $2"
}
[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1
case $1 in
    bound|renew)
    cat <<JSON > "$LEASE_FILE"
{
    "interface": "$interface",
    "fixed-address": "$ip",
    "subnet-mask": "$subnet",
    "routers": "${router%% *}",
    "static_routes" : "${staticroutes}"
}
JSON
    ;;
    deconfig)
    log err "Not supported"
    exit 1
    ;;
    leasefail | nak)
    log err "configuration failed: $1: $message"
    exit 1
    ;;
    *)
    echo "$0: Unknown udhcpc command: $1" >&2
    exit 1
    ;;
esac
c                   ó   — e Zd ZdZy)ÚNoDHCPLeaseErrorz'Raised when unable to get a DHCP lease.N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__© ó    ú4/usr/lib/python3/dist-packages/cloudinit/net/dhcp.pyr   r   A   s   „ Ú1r   r   c                   ó   — e Zd ZdZy)ÚInvalidDHCPLeaseFileErrorz§Raised when parsing an empty or invalid dhclient.lease file.

    Current uses are DataSourceAzure and DataSourceEc2 during ephemeral
    boot to scrape metadata.
    Nr   r   r   r   r   r   E   s   „ òr   r   c                   ó   — e Zd ZdZy)ÚNoDHCPLeaseInterfaceErrorz7Raised when unable to find a viable interface for DHCP.Nr   r   r   r   r   r   M   s   „ ÚAr   r   c                   ó   — e Zd ZdZy)ÚNoDHCPLeaseMissingDhclientErrorz$Raised when unable to find dhclient.Nr   r   r   r   r    r    Q   s   „ Ú.r   r    Úreturnc                 óž   — |xs | j                   }|€t        j                  d«       t        «       ‚| j                  j                  ||| «      S )a  Perform dhcp discovery if nic valid and dhclient command exists.

    If the nic is invalid or undiscoverable or dhclient command is not found,
    skip dhcp_discovery and return an empty dict.

    @param nic: Name of the network interface we want to run dhclient on.
    @param dhcp_log_func: A callable accepting the dhclient output and error
        streams.
    @return: A list of dicts representing dhcp options for each lease obtained
        from the dhclient discovery if run, otherwise an empty list is
        returned.
    z1Skip dhcp_discovery: Unable to find fallback nic.)Úfallback_interfaceÚLOGÚdebugr   Údhcp_clientÚdhcp_discovery)ÚdistroÚnicÚdhcp_log_funcÚ	interfaces       r   Úmaybe_perform_dhcp_discoveryr,   U   sK   € ð Ò0�v×0Ñ0€IØÐÜ�	‰	ÐEÔFÜ'Ó)Ð)à×Ñ×,Ñ,¨Y¸ÀvÓNÐNr   c                 óT   — t        t        j                  t        | «      d¬«      «      S )zÛParse a systemd lease file content as in /run/systemd/netif/leases/

    Parse this (almost) ini style file even though it says:
      # This is private data. Do not parse.

    Simply return a dictionary of key/values.F)Úlist_values)ÚdictÚ	configobjÚ	ConfigObjr   )Úcontents    r   Únetworkd_parse_leaser3   l   s!   € ô ”	×#Ñ#¤H¨WÓ$5À5ÔIÓJÐJr   c           	      ó  — | €t         } i }t        j                  j                  | «      s|S t        j                  | «      D ]A  }t        t        j                  t        j                  j                  | |«      «      «      ||<   ŒC |S )zŸReturn a dictionary of dictionaries representing each lease
    found in lease_d.i

    The top level key will be the filename, which is typically the ifindex.)	ÚNETWORKD_LEASES_DIRÚosÚpathÚisdirÚlistdirr3   r   Úload_text_fileÚjoin)Úleases_dÚretÚlfiles      r   Únetworkd_load_leasesr?   w   ss   € ð ÐÜ&ˆà€CÜ�7‰7�=‰=˜Ô"Øˆ
Ü—‘˜HÓ%ò 
ˆÜ)Ü×Ñ¤§¡§¡¨X°uÓ =Ó>ó
ˆˆEŠ
ð
ð €Jr   c                 óž   — |€t         }t        |¬«      }t        |j                  «       «      D ]  \  }}|j	                  | «      sŒ||    c S  y )N)r<   )r5   r?   ÚsortedÚitemsÚget)Úkeynamer<   ÚleasesÚ_ifindexÚdatas        r   Únetworkd_get_option_from_leasesrH   Š   sP   € ØÐÜ&ˆÜ!¨8Ô4€FÜ  §¡£Ó0ò !‰ˆ�$Ø�8‰8�GÕØ˜‘=Ò ð!ð r   c            
       ó.  — e Zd ZdZdZd„ Zed„ «       Zed„ «       Zede	fd„«       Z
ede	fd„«       Zej                  d	e	d
ee	ef   fd„«       Zeej                  de	d
eee	e	f      fd„«       «       Zej                  	 	 dd	e	dee   d
ee	ef   fd„«       Zy)Ú
DhcpClientÚ é
   c                 óx   — t        j                  | j                  «      | _        | j                  s
t	        «       ‚y ©N)r   ÚwhichÚclient_nameÚdhcp_client_pathr    )Úselfs    r   Ú__init__zDhcpClient.__init__˜   s0   € Ü $§
¡
¨4×+;Ñ+;Ó <ˆÔØ×$Ò$Ü1Ó3Ð3ð %r   c                 óN   — t        j                   d| j                  gddg¬«       y )NÚpkillr   é   ©Úrcs)r   rP   )Úclss    r   Úkill_dhcp_clientzDhcpClient.kill_dhcp_client�   s   € ä�	‰	�7˜CŸO™OÐ,°1°a°&Ö9r   c                 ó†   — | j                  «        t        j                  d«      }|D ]  }t        j                  |«       Œ y )Nz/var/lib/dhcp/*)rZ   Úglobr6   Úremove)rY   ÚfilesÚfiles      r   Úclear_leaseszDhcpClient.clear_leases¡   s7   € à×ÑÔÜ—	‘	Ð+Ó,ˆØò 	ˆDÜ�I‰I�d�Oñ	r   Údhcp_interfacec                 óF   — |j                  d| j                  |ddg¬«       y )NÚstartr   rV   rW   ©Úmanage_servicerP   ©rY   ra   r(   s      r   Ústart_servicezDhcpClient.start_service¨   s&   € à×ÑØ�S—_‘_ n¸1¸a¸&ð 	õ 	
r   c                 óD   — |j                  d| j                  ddg¬«       y )NÚstopr   rV   rW   rd   rf   s      r   Ústop_servicezDhcpClient.stop_service®   s   € à×Ñ˜f c§o¡o¸A¸q¸6ÐÕBr   r+   r!   c                 ó   — i S )z´Get the most recent lease from the ephemeral phase as a dict.

        Return a dict of dhcp options. The dict contains key value
        pairs from the most recent lease.
        r   ©rR   r+   s     r   Úget_newest_leasezDhcpClient.get_newest_lease²   s	   € ð ˆ	r   Úroutesc                 ó   — g S )ap  
        parse classless static routes from string

        The tuple is composed of the network_address (including net length) and
        gateway for a parsed static route.

        @param routes: string containing classless static routes
        @returns: list of tuple(str, str) for all valid parsed routes until the
                  first parsing error.
        r   )rn   s    r   Úparse_static_routeszDhcpClient.parse_static_routes»   s	   € ð ˆ	r   Nr*   c                 ó   — i S )aì  Run dhcp client on the interface without scripts or filesystem
        artifacts.

        @param interface: Name of the network interface on which to send a
            dhcp request
        @param dhcp_log_func: A callable accepting the client output and
            error streams.
        @param distro: a distro object for network interface manipulation
        @return: dict of lease options representing the most recent dhcp lease
            parsed from the dhclient.lease file
        r   )rR   r+   r*   r(   s       r   r'   zDhcpClient.dhcp_discoveryÊ   s	   € ð$ ˆ	r   ©NN)r   r   r   rP   ÚtimeoutrS   ÚclassmethodrZ   r`   Ústrrg   rj   ÚabcÚabstractmethodr   r   rm   Ústaticmethodr	   r   rp   r
   r   r'   r   r   r   rJ   rJ   ”   s*  „ Ø€KØ€Gò4ð
 ñ:ó ð:ð ñó ðð ð
¨3ò 
ó ð
ð
 ðC¨#ò Có ðCð 	×Ñð¨#ð °$°s¸C°x±.ò ó ðð Ø×Ñð Cð ¨D°°s¸C°x±Ñ,Aò ó ó ðð 	×Ñð -1Øñ	àðð   Ñ)ðð
 
ˆc�3ˆh‰òó ñr   rJ   c            	       óò   ‡ — e Zd ZdZˆ fd„Zededeeee	f      fd„«       Z
ed„ «       Zdedeee	f   fd„Z	 	 dded	ee   deee	f   fd
„Zededeeeef      fd„«       Zedee   fd„«       Zdefd„Zˆ xZS )ÚIscDhclientÚdhclientc                 ó0   •— t         ‰| �  «        d| _        y )Nz/run/dhclient.lease©ÚsuperrS   Ú
lease_file©rR   Ú	__class__s    €r   rS   zIscDhclient.__init__â   s   ø€ Ü‰ÑÔØ/ˆ�r   Úlease_contentr!   c                 óì  — t        j                  dt         j                  «      }g }| sg S |j                  | «      D ]µ  }g }|j	                  d«      D ]V  }|j                  «       j                  dd«      j                  dd«      }|sŒ6|j                  |j	                  dd«      «       ŒX t        |«      }|j                  d«      }|rt        j                  |«      |d<   |j                  |«       Œ· |S )	zÃparse the content of a lease file

        @param lease_content: a string containing the contents of an
            isc-dhclient lease
        @return: a list of leases, most recent last
        zlease {(?P<lease>.*?)}\nú;ú"rK   zoption ú rV   úunknown-245)ÚreÚcompileÚDOTALLÚfindallÚsplitÚstripÚreplaceÚappendr/   rC   rz   Úget_ip_from_lease_value)r‚   Úlease_regexÚdhcp_leasesÚleaseÚlease_optionsÚlineÚoptionsÚopt_245s           r   Úparse_leaseszIscDhclient.parse_leasesæ   së   € ô —j‘jÐ!<¼b¿i¹iÓHˆØ"$ˆÙØˆIØ ×(Ñ(¨Ó7ò 	(ˆEØˆMØŸ™ CÓ(ò =�à—z‘z“|×+Ñ+¨C°Ó4×<Ñ<¸YÈÓK�ÚØ!×(Ñ(¨¯©°C¸Ó);Õ<ð	=ô
 ˜=Ó)ˆGØ—k‘k -Ó0ˆGÙÜ)4×)LÑ)LØó*�˜Ñ&ð ×Ñ˜wÕ'ð	(ð Ðr   c           	      óP  — | j                  dd«      }t        |«      dkD  rad}|j                  d«      D ]  }t        |«      dk(  rd|z   }||z  }Œ t        j                  dt        |j                  dd«      d«      «      }n|j                  d	«      }t        j                  |«      S )
Nú\rK   é   ú:rV   Ú0z>Lé   zutf-8)	rŽ   ÚlenrŒ   ÚstructÚpackÚintÚencodeÚsocketÚ	inet_ntoa)Úfallback_lease_valueÚunescaped_valueÚ
hex_stringÚhex_pairÚpacked_bytess        r   r�   z#IscDhclient.get_ip_from_lease_value  s«   € à.×6Ñ6°t¸RÓ@ˆÜˆÓ !Ò#ØˆJØ+×1Ñ1°#Ó6ò '�Ü�x“= AÒ%Ø" X™~�HØ˜hÑ&‘
ð'ô "Ÿ;™;Ø”c˜*×,Ñ,¨S°"Ó5°rÓ:ó‰Lð +×1Ñ1°'Ó:ˆLÜ×Ñ Ó-Ð-r   r+   c                 óÔ   — t        t        «      5  t        j                  | j                  «      }|r!| j                  |«      }|r|d   cddd«       S ddd«       i S # 1 sw Y   i S xY w)aØ  Get the most recent lease from the ephemeral phase as a dict.

        Return a dict of dhcp options. The dict contains key value
        pairs from the most recent lease.

        @param interface: an interface string - not used in this class, but
            required for function signature compatibility with other classes
            that require a distro object
        @raises: InvalidDHCPLeaseFileError on empty or unparsable leasefile
            content.
        éÿÿÿÿN)r   ÚFileNotFoundErrorr   r:   r   r˜   )rR   r+   r2   r’   s       r   rm   zIscDhclient.get_newest_lease  sf   € ô Ô'Ó(ñ 	+Ü×)Ñ)¨$¯/©/Ó:ˆGÙØ"×/Ñ/°Ó8�ÙØ& r™?÷	+÷ 	+ñ 	+ð ˆ	÷	+ð ˆ	ús   �9AÁA'r*   c           	      óž  — t         j                  d|«       d}d}d}t        | j                  |z  «      }t        | j                  dz  «      }t	        t
        «      5  t        j                  |«       t        j                  | j                  «       ddd«       |j                  j                  |«       t        |«      ridt        |«      dd z  }	d|›d	|	›d
�}
t        j                  d¬«      }t        j                  j!                  ||dz   «      }t#        j$                  ||
«       	 t'        j&                  |j)                  | j*                  | j                  |||«      «      \  }}t#        j6                  || j                  g|d¬«      }|r.t         j9                  ddj!                  d„ |D «       «      «       i S d}d}d}d}t;        |«      D ]š  }	 t#        j<                  |«      j?                  «       }t        |«      }|jA                  |«      }|dk(  r>t         j                  d|«       t        jB                  |tD        jF                  «       d} n,tK        jL                  |«       Œœ t         j                  |«       |st         jO                  d||d«       |�	 |||«       | jQ                  |«      }|r|S tS        «       ‚# 1 sw Y   �Œ6xY w# t&        j,                  $ rB}t         j                  d|j.                  |j0                  |j2                  «       t4        |‚d}~ww xY w# t
        $ r	 d|› d�}Y ŒætH        $ r	 d|› d�}Y Œöw xY w)aà  Run dhclient on the interface without scripts/filesystem artifacts.

        @param interface: Name of the network interface on which to send a
            dhcp request
        @param dhcp_log_func: A callable accepting the dhclient output and
            error streams.
        @param distro: a distro object for network interface manipulation
        @return: dict of lease options representing the most recent dhcp lease
            parsed from the dhclient.lease file
        ú!Performing a dhcp discovery on %sz/run/dhclient.pidNç{®Gáz„?é   z20:%sé$   zinterface "z" {send dhcp-client-identifier z;}T©Ú	needs_exez-dhclient.confz3dhclient exited with code: %s stderr: %r stdout: %r)ÚmaxwaitÚnaplenz+dhclient did not produce expected files: %sz, c              3   óZ   K  — | ]#  }t         j                  j                  |«      –— Œ% y ­wrN   )r6   r7   Úbasename)Ú.0Úfs     r   ú	<genexpr>z-IscDhclient.dhcp_discovery.<locals>.<genexpr>}  s   è ø€ Ò?°!œ"Ÿ'™'×*Ñ*¨1×-Ñ?ùs   ‚)+ÚunknownFrK   rV   zkilling dhclient with pid=%súNo PID file found at z, dhclient is still runningúPID file contained [z], dhclient is still runningzCdhclient(pid=%s, parentpid=%s) failed to daemonize after %s secondsg      $@)*r$   r%   r¢   rs   r   r­   r6   r]   r   Únet_opsÚlink_upr   r   r   Úget_tmp_ancestorr7   r;   r   Ú
write_filer   Úbuild_dhclient_cmdrQ   ÚProcessExecutionErrorÚ	exit_codeÚstderrÚstdoutr   Úwait_for_filesÚwarningÚranger:   r�   Úget_proc_ppidÚkillÚsignalÚSIGKILLÚ
ValueErrorÚtimeÚsleepÚerrorrm   r   )rR   r+   r*   r(   Úpid_fileÚconfig_fileÚ
sleep_timeÚsleep_cyclesrµ   Údhcp_client_identifierÚinterface_dhclient_contentÚtmp_dirÚoutÚerrrÒ   ÚmissingÚppidÚ
daemonizedÚpid_contentÚ	debug_msgÚ_Úpidr“   s                          r   r'   zIscDhclient.dhcp_discovery&  s"  € ô  	�	‰	Ð5°yÔAð
 'ˆØˆØˆ
Ü˜4Ÿ<™<¨*Ñ4Ó5ˆÜ�d—l‘l QÑ&Ó'ˆô Ô'Ó(ñ 	'Ü�I‰I�hÔÜ�I‰I�d—o‘oÔ&÷	'ð 	�‰×Ñ˜yÔ)ô
 ˜9Ô%àÔ+¨IÓ6°r°sÐ;Ñ;ñ #ò Ò4ð6ð 'ô
 !×1Ñ1¸DÔAˆGÜŸ'™'Ÿ,™, w°	Ð<LÑ0LÓMˆKÜ�O‰O˜KÐ)CÔDð	.Ü—y‘yØ×)Ñ)Ø×)Ñ)Ø—O‘OØØØóó‰HˆC�ô2 ×%Ñ%Ø�t—‘Ð'°Àô
ˆñ Ü�K‰KØ=Ø—	‘	Ñ?°wÔ?Ó?ôð ˆIàˆØˆ
ØˆØˆ	Ü�|Ó$ò 	!ˆAðÜ"×1Ñ1°(Ó;×AÑAÓC�Ü˜+Ó&�ð ×+Ñ+¨CÓ0�Ø˜1’9Ü—I‘IÐ<¸cÔBÜ—G‘G˜C¤§¡Ô0Ø!%�JÙÜ�J‰J�zÕ"ð+	!ô. �I‰I�iÔ áÜ�I‰IðàØØôð Ð$Ù˜#˜sÔ#Ø×%Ñ% iÓ0ˆÙØˆLÜ'Ó)Ð)÷Q	'ñ 	'ûôH ×)Ñ)ò 	.Ü�I‰IØEØ—‘Ø—‘Ø—‘ô	ô #¨Ð-ûð	.ûôD %ò à+¨H¨:ð 60ð 0ò ô ò à*¨;¨-ð 80ð 0ò ðús<   Á5KÄ)?K Ç.L*ËKËL'Ë%=L"Ì"L'Ì*MÌ;MÍMrn   c           
      ó  ‡— | j                  d«      Št        j                  d‰«      D �cg c]  }|sŒ|‘Œ	 }}g }d‰v r"|D �cg c]  }t        t	        |d«      «      ‘Œ }}ˆfd„}d}t        |«      D �]�  \  }}||k  rŒt	        |«      }|t        dd«      v rhd	}t        ||d
 «      |k  r |||t        ||d
 «      «       |c S dj                  ||dz   |dz    «      }	dj                  ||dz   ||z    «      }
||z   }�nÜ|t        dd«      v rld}t        ||d
 «      |k  r |||t        ||d
 «      «       |c S dj                  ||dz   |dz    dgz   «      }	dj                  ||dz   ||z    «      }
||z   }�nb|t        d	d«      v rld}t        ||d
 «      |k  r |||t        ||d
 «      «       |c S dj                  ||dz   |dz    ddgz   «      }	dj                  ||dz   ||z    «      }
||z   }nè|t        dd	«      v rld}t        ||d
 «      |k  r |||t        ||d
 «      «       |c S dj                  ||dz   |dz    g d¢z   «      }	dj                  ||dz   ||z    «      }
||z   }nn|dk(  rOd}t        ||d
 «      |k  r |||t        ||d
 «      «       |c S d}	dj                  ||dz   ||z    «      }
||z   }nt        j                  d|«       |c S |j                  |	›d|›�|
f«       �Œ„ |S c c}w c c}w )a(  
        parse rfc3442 format and return a list containing tuple of strings.

        The tuple is composed of the network_address (including net length) and
        gateway for a parsed static route.  It can parse two formats of
        rfc3442, one from dhcpcd and one from dhclient (isc).

        @param rfc3442: string in rfc3442 format (isc or dhcpd)
        @returns: list of tuple(str, str) for all valid parsed routes until the
            first parsing error.

        e.g.:

        sr=parse_static_routes(        "32,169,254,169,254,130,56,248,255,0,130,56,240,1")
        sr=[
            ("169.254.169.254/32", "130.56.248.255"),         ("0.0.0.0/0", "130.56.240.1")
        ]

        sr2 = parse_static_routes(        "24.191.168.128 192.168.128.1,0 192.168.128.1")
        sr2 = [
            ("191.168.128.0/24", "192.168.128.1"),        ("0.0.0.0/0", "192.168.128.1")
        ]

        # unknown-121 option format
        sr3 = parse_static_routes(        "0:a:0:0:1:20:a8:3f:81:10:a:0:0:1:20:a9:fe:a9:fe:a:0:0:1")
        sr3 = [
            ("0.0.0.0/0", "10.0.0.1"),
            ("168.63.129.16/32", "10.0.0.1"),
            ("169.254.169.254/32", "10.0.0.1"),
        ]

        Python version of isc-dhclient's hooks:
           /etc/dhcp/dhclient-exit-hooks.d/rfc3442-classless-routes
        r„   z[, . :]rœ   rž   c                 óL   •— d| ›d|›d|›d‰›�}t         j                  |«       y )Nz5RFC3442 string malformed.  Current route has CIDR of z and requires z significant octets, but only z< remain. Verify DHCP rfc3442-classless-static-routes value: )r$   rÒ   )ÚcidrÚrequiredÚremainÚmsgÚrfc3442s       €r   Ú_trunc_errorz5IscDhclient.parse_static_routes.<locals>._trunc_errorß  s%   ø� ò
 š¢6©7ð4ð ô �I‰I�c�Nr   r   é   é!   é	   Nú.rV   é   é   é   r›   r�   é   é   é   r±   )r�   r�   r�   z0.0.0.0zSParsed invalid net length "%s".  Verify DHCP rfc3442-classless-static-routes value.ú/)Úrstriprˆ   rŒ   ru   r¢   Ú	enumeraterÊ   rŸ   r;   r$   rÒ   r�   )rn   ÚtokÚtokensÚstatic_routesrê   Úcurrent_idxÚidxÚ
net_lengthÚreq_toksÚnet_addressÚgatewayré   s              @r   rp   zIscDhclient.parse_static_routes­  s~  ø€ ðT —-‘- Ó$ˆÜ!#§¡¨*°gÓ!>ÖF˜#Â#’#ÐFˆÐFØ/1ˆð �'‰>Ø39Ö:¨C”cœ#˜c 2›,Õ'Ð:ˆFÐ:ô	ð ˆÜ! &Ó)ó 8	‰HˆC�Ø�[Ò ØÜ˜S›ˆJØœU 2 r›]Ñ*Ø�Ü�v˜c˜d�|Ó$ xÒ/Ù  ¨X´s¸6À#À$¸<Ó7HÔIØ(Ò(Ø!Ÿh™h v¨c°A©g¸¸a¹Ð'@ÓA�ØŸ(™( 6¨#°©'°C¸(±NÐ#CÓD�Ø! H™n’Øœu R¨›}Ñ,Ø�Ü�v˜c˜d�|Ó$ xÒ/Ù  ¨X´s¸6À#À$¸<Ó7HÔIØ(Ò(Ø!Ÿh™h v¨c°A©g¸¸a¹Ð'@ÀCÀ5Ñ'HÓI�ØŸ(™( 6¨#°©'°C¸(±NÐ#CÓD�Ø! H™n’Øœu Q¨›|Ñ+Ø�Ü�v˜c˜d�|Ó$ xÒ/Ù  ¨X´s¸6À#À$¸<Ó7HÔIØ(Ò(Ø!Ÿh™h v¨c°A©g¸¸a¹Ð'@ÀCÈÀ:Ñ'MÓN�ØŸ(™( 6¨#°©'°C¸(±NÐ#CÓD�Ø! H™n‘Øœu Q¨›{Ñ*Ø�Ü�v˜c˜d�|Ó$ xÒ/Ù  ¨X´s¸6À#À$¸<Ó7HÔIØ(Ò(Ø!Ÿh™hØ˜3 ™7 S¨1¡WÐ-²Ñ?ó�ð Ÿ(™( 6¨#°©'°C¸(±NÐ#CÓD�Ø! H™n‘Ø˜q’Ø�Ü�v˜c˜d�|Ó$ xÒ/Ù  ¨X´s¸6À#À$¸<Ó7HÔIØ(Ò(Ø'�ØŸ(™( 6¨#°©'°C¸(±NÐ#CÓD�Ø! H™n‘ä—	‘	ð=àôð
 %Ò$à× Ñ Ú'©Ð4°gÐ>öðm8	ðt ÐùòW Gùò
 ;s   «K:³K:ÁK?c                 ó’  — d}| j                   | j                  ft        t        ffD ]�  \  }}|sŒ	g }	 t	        j
                  |«      }d}|D ]b  }t        j                  ||«      sŒt        j                  j                  ||«      }t        j                  j                  |«      }||kD  sŒ_|}|}Œd |sŒ�|c S  y# t        $ r Y Œžw xY w)züGet the latest lease file from a distro-managed dhclient

        Doesn't consider the ephemeral timeframe lease.

        @param distro: used for distro-specific lease location and filename
        @return: The most recent lease file, or None
        Ng      ð¿)Údhclient_lease_directoryÚdhclient_lease_file_regexÚDHCLIENT_FALLBACK_LEASE_DIRÚDHCLIENT_FALLBACK_LEASE_REGEXr6   r9   r­   rˆ   Úsearchr7   r;   Úgetmtime)	r(   Úlatest_fileÚ	directoryÚregexÚlease_filesÚlatest_mtimeÚfnameÚabs_pathÚmtimes	            r   Ú!get_newest_lease_file_from_distroz-IscDhclient.get_newest_lease_file_from_distro%  sè   € ð ˆð
 ×/Ñ/Ø×0Ñ0ðô )Ô*GÐHð!
ò 	#ÑˆI�uñ ØàˆKðÜ Ÿj™j¨Ó3�ð  ˆLØ$ò +�Ü—y‘y ¨Ô.ØäŸ7™7Ÿ<™<¨	°5Ó9�ÜŸ™×(Ñ(¨Ó2�Ø˜<Ó'Ø#(�LØ"*‘Kð+ò Ø"Ò"ð;	#ð< øô# %ò Ùðús   ³B:Â:	CÃCÚkeyc                 óÈ   — | j                  |«      }|rOt        j                  |«      }|r7t        | j	                  |«      «      D ]  }|j                  |«      }|sŒ|c S  yyy)a8  Get a key from the latest lease from distro-managed dhclient

        Doesn't consider the ephemeral timeframe lease.

        @param lease_dir: distro-specific lease to check
        @param lease_file_regex: distro-specific regex to match lease name
        @return: The most recent lease file, or None
        N)r  r   r:   Úreversedr˜   rC   )rR   r(   r  r   r2   r“   Úservers          r   Úget_key_from_latest_leasez%IscDhclient.get_key_from_latest_leaseQ  sh   € ð ×;Ñ;¸FÓCˆ
ÙÜ×)Ñ)¨*Ó5ˆGÙÜ% d×&7Ñ&7¸Ó&@ÓAò &�EØ"ŸY™Y s›^�FÚØ%šñ&ð ð r   rr   )r   r   r   rP   rS   rx   ru   r	   r   r   r˜   r�   rm   r
   r   r'   r   rp   r  r  Ú__classcell__©r�   s   @r   rz   rz   ß   s  ø„ Ø€Kô0ð ð Cð ¨D°°c¸3°h±Ñ,@ò ó ðð6 ñ.ó ð.ð¨#ð °$°s¸C°x±.ó ð. -1Øñ	E*àðE*ð   Ñ)ðE*ð
 
ˆc�3ˆh‰óE*ðN ðu Cð u¨D°°s¸C°x±Ñ,Aò uó ðuðn ð)°X¸c±]ò )ó ð)ðV&°S÷ &r   rz   c            	       óÄ   — e Zd ZdZdZ	 	 ddedee   deee	f   fd„Z
eded	edee   fd
„«       Zedededefd„«       Zdedeee	f   fd„Zededeeeef      fd„«       Zy)ÚDhcpcdÚdhcpcdi,  Nr+   r*   r!   c                 óB  — t         j                  d|«       d}t        | j                  |z  «      }g }|j                  j                  |«       	 t        |«      rdg}| j                  dddddg|¢|‘}t        j                  || j                  ¬	«      \  }}	|�	 |||	«       | j                  |«      }
|
rât        j                  g |¢d‘«      j                  j                  «       }d
}d}d}t        |«      D ]†  }	 t        j                  |«      j                  «       }t        |«      }|j                  |«      }|r>t         j                  d||«       t!        j"                  |t$        j&                  «        |
S 	 |
c S  t         j                  |«       |
S t3        d«      ‚# t(        $ r t         j                  d|«       Y  |
S t*        $ r	 d|› d�}Y nt,        $ r	 d|› d�}Y nw xY wt/        j0                  |«       �Œ	# t4        $ rB}t         j                  d|j                  |j6                  |j                  «       t2        |‚d
}~wt        j8                  $ rB}t         j                  d|j:                  |j6                  |j                  «       t2        |‚d
}~ww xY w)aÜ  Run dhcpcd on the interface without scripts/filesystem artifacts.

        @param interface: Name of the network interface on which to send a
            dhcp request
        @param dhcp_log_func: A callable accepting the client output and
            error streams.
        @param distro: a distro object for network interface manipulation
        @return: dict of lease options representing the most recent dhcp lease
            parsed from the dhclient.lease file
        r¯   r°   z
--clientidú
--ipv4onlyz--waitipz--persistentz--noarpz--script=/bin/true)rs   Nz-PFrK   z!killing dhcpcd with pid=%s gid=%sz9Process group id [%s] has already exited, nothing to killr½   z, dhcpcd is still runningr¾   z], dhcpcd is still runningzNo lease foundz8dhcpcd timed out after %s seconds: stderr: %r stdout: %rú1dhcpcd exited with code: %s stderr: %r stdout: %r)r$   r%   r¢   rs   r¿   rÀ   r   rP   r   rm   rÇ   r�   rÊ   r   r:   Úget_proc_pgidr6   ÚkillpgrÍ   rÎ   ÚProcessLookupErrorr­   rÏ   rÐ   rÑ   r   r   rÆ   rÄ   rÅ   )rR   r+   r*   r(   rÕ   rÖ   Úinfiniband_argumentÚcommandrÚ   rÛ   r“   rÓ   rß   Úgidrà   rá   râ   rÒ   s                     r   r'   zDhcpcd.dhcp_discoveryh  s·  € ô  	�	‰	Ð5°yÔAØˆ
Ü˜4Ÿ<™<¨*Ñ4Ó5ˆØ Ðð 	�‰×Ñ˜yÔ)ð[	.ô ˜yÔ)Ø'3 nÐ#à× Ñ ØØØØØ$ð	ð %ð	ð ð	ˆGô —y‘yØØŸ™ô‰HˆC�ð Ð(Ù˜c 3Ô'Ø×)Ñ)¨)Ó4ˆEñ ô  Ÿ9™9Ð%5 wÐ%5°Ð%5Ó6×=Ñ=×CÑCÓE�Ø"�Ø�Ø�	Ü˜|Ó,ò  )�Að%Ü&*×&9Ñ&9¸(Ó&C×&IÑ&IÓ&K˜Ü! +Ó.˜Ø$×2Ñ2°3Ó7˜ÙÜŸI™IØ CÀSÈ#ôô ŸI™I c¬6¯>©>Ô:Ø!ð. �ð9 ð0  %šð; )ô@ —I‘I˜iÔ(Ø�Ü"Ð#3Ó4Ð4øô/ .ò ÜŸ	™	ð.àôñ
 ð  �ô -ò à3°H°:ð >6ð 6ò "ô &ò à2°;°-ð @6ð 6ò "ðúô —J‘J˜zÖ*øô ò 	.Ü�I‰IØJØ—‘Ø—‘Ø—‘ô	ô #¨Ð-ûÜ×)Ñ)ò 	.Ü�I‰IØCØ—‘Ø—‘Ø—‘ô	ô #¨Ð-ûð	.úst   ÁB+H  Ã;A<F"Å7H  Å;H  Å?H  ÆH  Æ"G&ÇH  ÇG&ÇH  ÇG&Ç#H  Ç%G&Ç&H  È 	JÈ	=IÉJÉ=JÊJrG   Údhcp_option_numberc                 ó\   — d}dt         dt        fd„} || |«      D ]  \  }}||k(  sŒ|c S  y)aV  get a specific option from a binary lease file

        This is required until upstream dhcpcd supports unknown option 245
        upstream bug: https://github.com/NetworkConfiguration/dhcpcd/issues/282

        @param data: Binary lease data
        @param number: Option number to return
        @return: the option (bytes) or None
        éð   rG   Úindexc              3   ó¦   K  — t        | «      |dz   k\  r<| |   }| d|z      }| d|z   d|z   |z    }||f–— d|z   |z   }t        | «      |dz   k\  rŒ;yy­w)zÎoptions are variable length, and consist of the following format

            option number: 1 byte
            option length: 1 byte
            option data: variable length (see length field)
            r±   rV   N)rŸ   )rG   r'  ÚcodeÚlengthÚoptions        r   Úiter_optionsz>Dhcpcd.parse_unknown_options_from_packet.<locals>.iter_optionsø  sq   è ø€ ô �d“)˜u q™yÒ(Ø˜E‘{�Ø˜a %™i™�Ø˜a %™i¨!¨e©)°fÑ*<Ð=�Ø˜F�lÒ"Ø˜F™
 UÑ*�ô �d“)˜u q™yÕ(ùs   ‚AAÁAN)Úbytesr¢   )rG   r$  ÚINDEXr,  r)  r+  s         r   Ú!parse_unknown_options_from_packetz(Dhcpcd.parse_unknown_options_from_packetß  sK   € ð. ˆð	+œuð 	+¬Só 	+ñ )¨¨uÓ5ò 	‰LˆD�&ØÐ)Ó)Ø’ð	ð r   Ú
lease_dumpc           	      ó  — t         j                  d|| «       	 t        | j                  «       j	                  dd«      j                  d«      D �cg c]  }d|v r|j                  dd¬«      ‘Œ c}«      }|s&d}t         j                  || «       t        || z  «      ‚	 ||d<   |j                  «       D ��ci c]  \  }}|j	                  dd«      |“Œ }}}dddœ}|j                  «       D ]  \  }	}
|	|v sŒ|j                  |	«      ||
<   Œ  t        j                  d|› d�«      }t        j                  |d«      }|rt        j                   |«      |d<   |S c c}w # t        $ r"}t         j                  d	| «       t        |‚d
}~ww xY wc c}}w )a`  parse the output of dhcpcd --dump

        map names to the datastructure we create from dhclient

        example dhcpcd output:

        broadcast_address='192.168.15.255'
        dhcp_lease_time='3600'
        dhcp_message_type='5'
        dhcp_server_identifier='192.168.0.1'
        domain_name='us-east-2.compute.internal'
        domain_name_servers='192.168.0.2'
        host_name='ip-192-168-0-212'
        interface_mtu='9001'
        ip_address='192.168.0.212'
        network_number='192.168.0.0'
        routers='192.168.0.1'
        subnet_cidr='20'
        subnet_mask='255.255.240.0'
        z)Parsing dhcpcd lease for interface %s: %rú'rK   ú
ú=rV   )Úmaxsplitz;No valid DHCP lease configuration found in dhcpcd lease: %rzError parsing dhcpcd lease: %rNr+   rá   ú-zfixed-addressrú   )z
ip-addresszclassless-static-routesz/var/lib/dhcpcd/z.leaseéõ   r‡   )r$   r%   r/   r�   rŽ   rŒ   rÒ   r   rÏ   rB   Úpopr   Úload_binary_filer  r/  r¤   r¥   )r0  r+   Úar“   rè   rÒ   r  ÚvalueÚname_mapÚsourceÚdestinationÚdhcp_messager—   s                r   Úparse_dhcpcd_leasezDhcpcd.parse_dhcpcd_lease  s­  € ô, 	�	‰	Ø7¸ÀJô	
ð
	7Üð (×-Ñ-Ó/×7Ñ7¸¸RÓ@×FÑFÀtÓLöàØ˜a‘xð —G‘G˜C¨!�GÕ,òóˆEñ ð0ð ô —	‘	˜#˜zÔ*Ü/°°jÑ0@ÓAÐAð ð 'ˆˆkÑð AFÇÁÃ×N±*°#°u�—‘˜S #Ó&¨Ñ-ÐNˆÑNð *Ø'6ñ
ˆð $,§>¡>Ó#3ò 	7ÑˆF�KØ˜ŠØ%*§Y¡Y¨vÓ%6��kÒ"ð	7ô ×,Ñ,Ø˜y˜k¨Ð0ó
ˆô ×:Ñ:¸<ÈÓMˆÙÜ#)×#3Ñ#3°GÓ#<ˆE�-Ñ ØˆùòUøô ò 	7Ü�I‰IÐ6¸
ÔCÜ+°Ð6ûð	7üó Os/   ™6E ÁEÁ-/E Â5F	ÅE Å	FÅ$FÆFc                 ó.  — 	 | j                  t        j                  | j                  dd|g«      j                  |«      S # t        j                  $ rB}t
        j                  d|j                  |j                  |j                  «       t        |‚d}~ww xY w)zÊReturn a dict of dhcp options.

        @param interface: which interface to dump the lease from
        @raises: InvalidDHCPLeaseFileError on empty or unparsable leasefile
            content.
        z--dumpleaser  r  N)
r@  r   rP   rÇ   rÄ   r$   r%   rÅ   rÆ   r   )rR   r+   rÒ   s      r   rm   zDhcpcd.get_newest_leaseT  s�   € ð	.Ø×*Ñ*Ü—	‘	à×(Ñ(Ø%Ø$Ø!ð	ó÷ ‘&Øó
ð 
øô ×)Ñ)ò 	.Ü�I‰IØCØ—‘Ø—‘Ø—‘ô	ô #¨Ð-ûð	.ús   ‚<? ¿BÁ=BÂBrn   c                 ó¬   — | j                  «       }|r&t        |ddd…   |ddd…   «      D �cg c]  }|‘Œ c}S t        j                  d| «       g S c c}w )aš  
        classless static routes as returned from dhcpcd --dumplease and return
        a list containing tuple of strings.

        The tuple is composed of the network_address (including net length) and
        gateway for a parsed static route.

        @param routes: string containing classless static routes
        @returns: list of tuple(str, str) for all valid parsed routes until the
                  first parsing error.

        e.g.:

        sr=parse_static_routes(
            "0.0.0.0/0 10.0.0.1 168.63.129.16/32 10.0.0.1"
        )
        sr=[
            ("0.0.0.0/0", "10.0.0.1"),
            ("169.63.129.16/32", "10.0.0.1"),
        ]
        Nr±   rV   z'Malformed classless static routes: [%s])rŒ   Úzipr$   rÉ   ©rn   rú   Úis      r   rp   zDhcpcd.parse_static_routesq  sX   € ð. Ÿ™›ˆÙä" =±°1°Ñ#5°}ÀQÀTÈÀTÑ7JÓKÖL˜!’AÒLÐLÜ�‰Ð=¸vÔFØˆ	ùò Ms   ­	Arr   )r   r   r   rP   rs   ru   r
   r   r   r   r'   rx   r-  r¢   r/  r@  rm   r	   r   rp   r   r   r   r  r  d  sñ   „ Ø€KØ€Gð
 -1Øñ	u.àðu.ð   Ñ)ðu.ð
 
ˆc�3ˆh‰óu.ðn ð)Øð)Ø),ð)à	�%‰ò)ó ð)ðV ðF sð F°sð F¸tò Fó ðFðP.¨#ð .°$°s¸C°x±.ó .ð: ð Cð ¨D°°s¸C°x±Ñ,Aò ó ñr   r  c            	       ó�   ‡ — e Zd ZdZˆ fd„Z	 	 d
dedee   deee	f   fd„Z
dedeee	f   fd„Zededeeeef      fd	„«       Zˆ xZS )ÚUdhcpcÚudhcpcc                 ó0   •— t         ‰| �  «        d| _        y )NrK   r}   r€   s    €r   rS   zUdhcpc.__init__“  s   ø€ Ü‰ÑÔØˆ�r   r+   r*   r!   c                 óÖ  — t         j                  d|«       t        j                  d¬«      }t        j
                  j                  ||dz   «      | _        t        t        «      5  t	        j                  | j                  «       ddd«       |j                  j                  |«       t        j
                  j                  |d«      }t        j                  |t        d«       | j                   dd	d
|d|ddddg}t#        |«      r>|j%                  ddj'                  t)        |«      dd j+                  dd«      «      g«       	 t-        j,                  |d| j                  id¬«      \  }}|�	 |||«       | j9                  |«      S # 1 sw Y   �ŒxY w# t,        j.                  $ rB}	t         j                  d|	j0                  |	j2                  |	j4                  «       t6        |	‚d}	~	ww xY w)ar  Run udhcpc on the interface without scripts or filesystem artifacts.

        @param interface: Name of the network interface on which to run udhcpc.
        @param dhcp_log_func: A callable accepting the udhcpc output and
            error streams.
        @return: A list of dicts of representing the dhcp leases parsed from
            the udhcpc lease file.
        r¯   Tr³   z.lease.jsonNÚudhcpc_scriptií  z-OÚstaticroutesz-iz-sz-nz-qz-fz-vz-xz	0x3d:20{}r²   rœ   rK   Ú
LEASE_FILE)Ú
update_envÚcapturez1udhcpc exited with code: %s stderr: %r stdout: %r)r$   r%   r   rÁ   r6   r7   r;   r   r   r­   r]   r¿   rÀ   r   rÂ   ÚUDHCPC_SCRIPTrP   r   ÚextendÚformatr   rŽ   r   rÄ   rÅ   rÆ   rÇ   r   rm   )
rR   r+   r*   r(   rÙ   rK  ÚcmdrÚ   rÛ   rÒ   s
             r   r'   zUdhcpc.dhcp_discovery—  s­  € ô 	�	‰	Ð5°yÔAä×-Ñ-¸Ô=ˆÜŸ'™'Ÿ,™, w°	¸MÑ0IÓJˆŒÜÔ'Ó(ñ 	'Ü�I‰I�d—o‘oÔ&÷	'ð 	�‰×Ñ˜yÔ)äŸ™Ÿ™ W¨oÓ>ˆÜ�‰˜¤}°eÔ<ð ×ÑØØØØØØØØØØð
ˆô$ ˜9Ô%Ø�J‰JàØ×&Ñ&Ü)¨)Ó4°R°SÐ9×AÑAÀ#ÀrÓJóðôð	.Ü—y‘yØ ¨t¯©Ð ?Èô‰HˆC�ð Ð$Ù˜#˜sÔ#à×$Ñ$ YÓ/Ð/÷i	'ñ 	'ûôP ×)Ñ)ò 	.Ü�I‰IØCØ—‘Ø—‘Ø—‘ô	ô #¨Ð-ûð	.ús$   Á$ FÅ'F ÆFÆG(Æ&=G#Ç#G(c                 óf   — t        j                  t        j                  | j                  «      «      S )aÖ  Get the most recent lease from the ephemeral phase as a dict.

        Return a dict of dhcp options. The dict contains key value
        pairs from the most recent lease.

        @param interface: an interface name - not used in this class, but
            required for function signature compatibility with other classes
            that require a distro object
        @raises: InvalidDHCPLeaseFileError on empty or unparsable leasefile
            content.
        )r   Ú	load_jsonr:   r   rl   s     r   rm   zUdhcpc.get_newest_leaseß  s"   € ô �~‰~œd×1Ñ1°$·/±/ÓBÓCÐCr   rn   c                 ó€   — | j                  «       }|r&t        |d d d…   |dd d…   «      D �cg c]  }|‘Œ c}S g S c c}w )Nr±   rV   )rŒ   rC  rD  s      r   rp   zUdhcpc.parse_static_routesí  sG   € àŸ™›ˆÙä" =±°1°Ñ#5°}ÀQÀTÈÀTÑ7JÓKÖL˜!’AÒLÐLØˆ	ùò Ms   ­	;rr   )r   r   r   rP   rS   ru   r
   r   r   r   r'   rm   rx   r	   r   rp   r  r  s   @r   rG  rG  �  s•   ø„ Ø€Kôð -1Øñ	F0àðF0ð   Ñ)ðF0ð
 
ˆc�3ˆh‰óF0ðPD¨#ð D°$°s¸C°x±.ó Dð ð Cð ¨D°°s¸C°x±Ñ,Aò ó ôr   rG  rr   rN   )5rv   r\   Úloggingr6   rˆ   rÍ   r¤   r    rÐ   Ú
contextlibr   Úior   Ú
subprocessr   Útypingr   r   r   r	   r
   r   r0   Ú	cloudinitr   r   r   Úcloudinit.netr   r   Ú	getLoggerr   r$   r5   r  r  rP  Ú	Exceptionr   r   r   r    ru   r,   r3   r?   rH   ÚABCrJ   rz   r  rG  ÚALL_DHCP_CLIENTSr   r   r   ú<module>rb     s  ðó Û Û Û 	Û 	Û Û Û Û Ý Ý Ý %ß =× =ã ç ,Ñ ,ß <à€g×Ñ˜Ó!€à1Ð Ø1Ð à /Ð ð€ôB2�yô 2ôÐ 0ô ôBÐ 0ô Bô/Ð&6ô /ð
 %)ñOà	ˆ#ˆsˆ(�^óOò.Kóó&ôH�—‘ô HôVB&�*ô B&ôJiˆZô iôX	cˆZô cðL ˜K¨Ð0Ñ r   