ó
    x[hÐ�  ã                   óö  • S SK r S SKrS SKrS SKrS SKrS SKrS SKrS SKrS SKrS SK	J
r
  S SKJr  S SKJr  S SKJrJrJrJrJrJr  S SKrS SKJrJrJr  S SKJrJr  \R<                  " \5      r Sr!S	r"S
r#Sr$ " S S\%5      r& " S S\&5      r' " S S\&5      r( " S S\&5      r) S!S\\*\4   4S jjr+S r,S"S jr-S"S jr. " S S\ R^                  5      r0 " S S\05      r1 " S S\05      r2 " S S \05      r3\2\1\3/r4g)#é    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                   ó   • \ rS rSrSrSrg)ÚNoDHCPLeaseErroréA   z'Raised when unable to get a DHCP lease.© N©Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__static_attributes__r   ó    Ú4/usr/lib/python3/dist-packages/cloudinit/net/dhcp.pyr   r   A   s   † Ü1r   r   c                   ó   • \ rS rSrSrSrg)ÚInvalidDHCPLeaseFileErroréE   z›Raised when parsing an empty or invalid dhclient.lease file.

Current uses are DataSourceAzure and DataSourceEc2 during ephemeral
boot to scrape metadata.
r   Nr   r   r   r   r   r   E   s   † ôr   r   c                   ó   • \ rS rSrSrSrg)ÚNoDHCPLeaseInterfaceErroréM   z7Raised when unable to find a viable interface for DHCP.r   Nr   r   r   r   r"   r"   M   s   † ÜAr   r"   c                   ó   • \ rS rSrSrSrg)ÚNoDHCPLeaseMissingDhclientErroréQ   z$Raised when unable to find dhclient.r   Nr   r   r   r   r%   r%   Q   s   † Ü.r   r%   Úreturnc                 ó¨   • U=(       d    U R                   nUc  [        R                  S5        [        5       eU R                  R                  X2U 5      $ )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_discoveryr2   U   sI   € ð ×0�v×0Ñ0€IØÑÜ�	‰	ÐEÔFÜ'Ó)Ð)à×Ñ×,Ñ,¨YÀvÓNÐNr   c                 óP   • [        [        R                  " [        U 5      SS95      $ )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_leaser9   l   s!   € ô ”	×#Ò#¤H¨WÓ$5À5ÑIÓJÐJr   c           	      ó  • U c  [         n 0 n[        R                  R                  U 5      (       d  U$ [        R                  " U 5       HA  n[        [        R                  " [        R                  R                  X5      5      5      X'   MC     U$ )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Úlistdirr9   r   Úload_text_fileÚjoin)Úleases_dÚretÚlfiles      r   Únetworkd_load_leasesrE   w   sm   € ð ÑÜ&ˆà€CÜ�7‰7�=‰=˜×"Ñ"Øˆ
Ü—’˜HÖ%ˆÜ)Ü×Ò¤§¡§¡¨XÓ =Ó>ó
ˆ‹
ñ &ð €Jr   c                 ó¤   • Uc  [         n[        US9n[        UR                  5       5       H!  u  p4UR	                  U 5      (       d  M  X@   s  $    g )N)rB   )r;   rE   ÚsortedÚitemsÚget)ÚkeynamerB   ÚleasesÚ_ifindexÚdatas        r   Únetworkd_get_option_from_leasesrN   Š   sJ   € ØÑÜ&ˆÜ!¨8Ñ4€FÜ  §¡£Ö0‰ˆØ�8‰8�G×ÓØ‘=Ò ñ 1ð r   c            
       óB  • \ rS rSrSrSrS r\S 5       r\S 5       r	\S\
4S j5       r\S\
4S	 j5       r\R                  S
\
S\\
\4   4S j5       r\\R                  S\
S\\\
\
4      4S j5       5       r\R                    SS
\
S\\   S\\
\4   4S jj5       rSrg)Ú
DhcpClienté”   Ú é
   c                 ó„   • [         R                  " U R                  5      U l        U R                  (       d
  [	        5       eg ©N)r   ÚwhichÚclient_nameÚdhcp_client_pathr%   )Úselfs    r   Ú__init__ÚDhcpClient.__init__˜   s0   € Ü $§
¢
¨4×+;Ñ+;Ó <ˆÔØ×$×$Ü1Ó3Ð3ð %r   c                 óJ   • [         R                   " SU R                  /SS/S9  g )NÚpkillr   é   ©Úrcs)r   rW   )Úclss    r   Úkill_dhcp_clientÚDhcpClient.kill_dhcp_client�   s   € ä�	Š	�7˜CŸO™OÐ,°1°a°&Ó9r   c                 óŽ   • U R                  5         [        R                  " S5      nU H  n[        R                  " U5        M     g )Nz/var/lib/dhcp/*)rb   Úglobr<   Úremove)ra   ÚfilesÚfiles      r   Úclear_leasesÚDhcpClient.clear_leases¡   s2   € à×ÑÔÜ—	’	Ð+Ó,ˆÛˆDÜ�IŠI�dŽOò r   Údhcp_interfacec                 ó@   • UR                  SU R                  USS/S9  g )NÚstartr   r^   r_   ©Úmanage_servicerW   ©ra   rk   r.   s      r   Ústart_serviceÚDhcpClient.start_service¨   s&   € à×ÑØ�S—_‘_ n¸1¸a¸&ð 	ò 	
r   c                 ó>   • UR                  SU R                  SS/S9  g )NÚstopr   r^   r_   rn   rp   s      r   Ústop_serviceÚDhcpClient.stop_service®   s   € à×Ñ˜f c§o¡o¸A¸q¸6ÐÒBr   r1   r'   c                 ó   • 0 $ )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   ©rY   r1   s     r   Úget_newest_leaseÚDhcpClient.get_newest_lease²   s	   € ð ˆ	r   Úroutesc                 ó   • / $ )a8  
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   )r{   s    r   Úparse_static_routesÚDhcpClient.parse_static_routes»   s	   € ð ˆ	r   Nr0   c                 ó   • 0 $ )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   )rY   r1   r0   r.   s       r   r-   ÚDhcpClient.dhcp_discoveryÊ   s	   € ð$ ˆ	r   )rX   ©NN)r   r   r   r   rW   ÚtimeoutrZ   Úclassmethodrb   ri   Ústrrq   ru   ÚabcÚabstractmethodr   r   ry   Ústaticmethodr	   r   r}   r
   r   r-   r   r   r   r   rP   rP   ”   s*  † Ø€KØ€Gò4ð
 ñ:ó ð:ð ñó ðð ð
¨3ó 
ó ð
ð
 ðC¨#ó Có ðCð 	×Ñð¨#ð °$°s¸C°x±.ó ó ðð Ø×Ñð Cð ¨D°°s¸C°x±Ñ,Aó ó ó ðð 	×Ñð -1Øñ	àðð   Ñ)ðð
 
ˆc�3ˆh‰ôó ór   rP   c            	       ó
  ^ • \ rS rSrSrU 4S jr\S\S\\	\\
4      4S j5       r\S 5       rS\S\	\\
4   4S	 jr  SS\S
\\   S\	\\
4   4S jjr\S\S\\\\4      4S j5       r\S\\   4S j5       rS\4S jrSrU =r$ )ÚIscDhclientéß   Údhclientc                 ó0   >• [         TU ]  5         SU l        g )Nz/run/dhclient.lease©ÚsuperrZ   Ú
lease_file©rY   Ú	__class__s    €r   rZ   ÚIscDhclient.__init__â   s   ø€ Ü‰ÑÔØ/ˆ�r   Úlease_contentr'   c                 ó  • [         R                  " S[         R                  5      n/ nU (       d  / $ UR                  U 5       HÃ  n/ nUR	                  S5       H]  nUR                  5       R                  SS5      R                  SS5      nU(       d  M<  UR                  UR	                  SS5      5        M_     [        U5      nUR                  S5      nU(       a  [        R                  U5      US'   UR                  U5        MÅ     U$ )	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Ú;Ú"rR   zoption Ú r^   úunknown-245)ÚreÚcompileÚDOTALLÚfindallÚsplitÚstripÚreplaceÚappendr5   rI   r‰   Úget_ip_from_lease_value)r“   Úlease_regexÚdhcp_leasesÚleaseÚlease_optionsÚlineÚoptionsÚopt_245s           r   Úparse_leasesÚIscDhclient.parse_leasesæ   sã   € ô —j’jÐ!<¼b¿i¹iÓHˆØ"$ˆÞØˆIØ ×(Ñ(¨Ö7ˆEØˆMØŸ™ CÖ(�à—z‘z“|×+Ñ+¨C°Ó4×<Ñ<¸YÈÓK�ß�4Ø!×(Ñ(¨¯©°C¸Ó);Ö<ñ	 )ô
 ˜=Ó)ˆGØ—k‘k -Ó0ˆGÞÜ)4×)LÑ)LØó*�˜Ñ&ð ×Ñ˜wÖ'ñ 8ð Ðr   c           	      óZ  • U R                  SS5      n[        U5      S:”  ad  SnUR                  S5       H  n[        U5      S:X  a  SU-   nX#-  nM     [        R                  " S[        UR                  SS5      S5      5      nOUR                  S	5      n[        R                  " U5      $ )
NÚ\rR   é   Ú:r^   Ú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¡   Ú#IscDhclient.get_ip_from_lease_value  s¤   € à.×6Ñ6°t¸RÓ@ˆÜˆÓ !Ó#ØˆJØ+×1Ñ1°#Ö6�Ü�x“= AÓ%Ø" X™~�HØÑ&’
ñ 7ô "Ÿ;š;Ø”c˜*×,Ñ,¨S°"Ó5°rÓ:ó‰Lð +×1Ñ1°'Ó:ˆLÜ×Ò Ó-Ð-r   r1   c                 óô   • [        [        5         [        R                  " U R                  5      nU(       a&  U R                  U5      nU(       a  US   sSSS5        $ SSS5        0 $ ! , (       d  f       0 $ = f)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©   )rY   r1   r8   r£   s       r   ry   ÚIscDhclient.get_newest_lease  s`   € ô Ô'Õ(Ü×)Ò)¨$¯/©/Ó:ˆGÞØ"×/Ñ/°Ó8�ÞØ& r™?÷ )×(Ñ(ð ˆ	÷ )Ô(ð ˆ	ús   �AA(Á(
A7r0   c           	      óâ  • [         R                  SU5        SnSnSn[        U R                  U-  5      n[        U R                  S-  5      n[	        [
        5         [        R                  " U5        [        R                  " U R                  5        SSS5        UR                  R                  U5        [        U5      (       ah  S[        U5      SS -  n	SU< S	U	< S
3n
[        R                  " SS9n[        R                  R!                  X±S-   5      n["        R$                  " XZ5         [&        R&                  " UR)                  U R*                  U R                  UUU5      5      u  pÍ["        R6                  " X@R                  /USS9nU(       a.  [         R9                  SSR!                  S U 5       5      5        0 $ SnSnSnSn[;        U5       H   n ["        R<                  " U5      R?                  5       n[        U5      nURA                  U5      nUS:X  a?  [         R                  SU5        [        RB                  " U[D        RF                  5        Sn  O0 [J        RL                  " U5        M¢     [         R                  U5        U(       d  [         RO                  SUUS5        Ub  U" XÍ5        U RQ                  U5      nU(       a  U$ [S        5       e! , (       d  f       GNR= f! [&        R,                   aB  n[         R                  SUR.                  UR0                  UR2                  5        [4        UeSnAff = f! [
         a	    SU S3n Nú[H         a
    SU S3n GNf = f)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   ó`   #   • U  H$  n[         R                  R                  U5      v •  M&     g 7frU   )r<   r=   Úbasename)Ú.0Úfs     r   Ú	<genexpr>Ú-IscDhclient.dhcp_discovery.<locals>.<genexpr>}  s"   é € Ð?²w°!œ"Ÿ'™'×*Ñ*¨1×-Ð-²wùs   ‚,.ÚunknownFrR   r^   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´   r‚   r   rÀ   r<   rf   r�   Únet_opsÚlink_upr   r   r   Úget_tmp_ancestorr=   rA   r   Ú
write_filer   Úbuild_dhclient_cmdrX   ÚProcessExecutionErrorÚ	exit_codeÚstderrÚstdoutr   Úwait_for_filesÚwarningÚranger@   rž   Úget_proc_ppidÚkillÚsignalÚSIGKILLÚ
ValueErrorÚtimeÚsleepÚerrorry   r   )rY   r1   r0   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-   Ú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ÔDð	.Ü—y’yØ×)Ñ)Ø×)Ñ)Ø—O‘OØØØóó‰HˆCô2 ×%Ò%Ø—‘Ð'°Àñ
ˆö Ü�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ðàØØôð Ñ$Ù˜#Ô#Ø×%Ñ% iÓ0ˆÞØˆLÜ'Ó)Ð)÷Q )Ö(ûôH ×)Ñ)ó 	.Ü�I‰IØEØ—‘Ø—‘Ø—‘ô	ô #¨Ð-ûð	.ûôD %ó à+¨H¨:ð 60ð 0ò ô ó à*¨;¨-ð 80ð 0ó ðús<   Á7KÄ/?K0 Ç/M	Ë
K-Ë0MÌ=MÍMÍ	M.ÍM.Í-M.r{   c           
      ó  ^• U R                  S5      m[        R                  " ST5       Vs/ s H  o(       d  M  UPM     nn/ nST;   a%  U Vs/ s H  n[        [	        US5      5      PM     nnU4S jnSn[        U5       GHp  u  paXe:  a  M  [	        U5      nU[        SS5      ;   ab  S	n[        X&S
 5      U:  a  U" Xx[        X&S
 5      5        Us  $ SR                  X&S-   US-    5      n	SR                  X&S-   Xh-    5      n
Xh-   nGOÌU[        SS5      ;   af  Sn[        X&S
 5      U:  a  U" Xx[        X&S
 5      5        Us  $ SR                  X&S-   US-    S/-   5      n	SR                  X&S-   Xh-    5      n
Xh-   nGOVU[        S	S5      ;   af  Sn[        X&S
 5      U:  a  U" Xx[        X&S
 5      5        Us  $ SR                  X&S-   US-    SS/-   5      n	SR                  X&S-   Xh-    5      n
Xh-   nOàU[        SS	5      ;   af  Sn[        X&S
 5      U:  a  U" Xx[        X&S
 5      5        Us  $ SR                  X&S-   US-    / SQ-   5      n	SR                  X&S-   Xh-    5      n
Xh-   nOjUS:X  aJ  Sn[        X&S
 5      U:  a  U" Xx[        X&S
 5      5        Us  $ Sn	SR                  X&S-   Xh-    5      n
Xh-   nO[        R                  SU5        Us  $ UR                  U	< SU< 3U
45        GMs     U$ s  snf s  snf )aX  
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                 óT   >• SU < SU< SU< ST< 3n[         R                  U5        g )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_errorÚ5IscDhclient.parse_static_routes.<locals>._trunc_errorß  s%   ø� ó
 ›£6ª7ð4ð ô �I‰I�c�Nr   r   é   é!   é	   NÚ.r^   é   é   é   r­   r¯   é   é   é   rÅ   )r¯   r¯   r¯   z0.0.0.0zSParsed invalid net length "%s".  Verify DHCP rfc3442-classless-static-routes value.Ú/)Úrstripr™   r�   r„   r´   Ú	enumeraterß   r±   rA   r*   rç   r    )r{   ÚtokÚtokensÚstatic_routesr   Úcurrent_idxÚidxÚ
net_lengthÚreq_toksÚnet_addressÚgatewayrÿ   s              @r   r}   ÚIscDhclient.parse_static_routes­  s5  ø€ ðT —-‘- Ó$ˆÜ!#§¢¨*°gÔ!>ÓFÒ!>˜#Ã#—#Ñ!>ˆÐFØ/1ˆð �'‹>Ù39Ó:²6¨C”cœ#˜c 2›,Ö'±6ˆFÐ:õ	ð ˆÜ! &×)‰HˆCØÓ ÙÜ˜S›ˆJØœU 2 r›]Ó*Ø�Ü�v˜d�|Ó$ xÓ/Ù  ´s¸6À$¸<Ó7HÔIØ(Ò(Ø!Ÿh™h v°A©g¸¸a¹Ð'@ÓA�ØŸ(™( 6°©'°C±NÐ#CÓD�Ø!™n’Øœu R¨›}Ó,Ø�Ü�v˜d�|Ó$ xÓ/Ù  ´s¸6À$¸<Ó7HÔIØ(Ò(Ø!Ÿh™h v°A©g¸¸a¹Ð'@ÀCÀ5Ñ'HÓI�ØŸ(™( 6°©'°C±NÐ#CÓD�Ø!™n’Øœu Q¨›|Ó+Ø�Ü�v˜d�|Ó$ xÓ/Ù  ´s¸6À$¸<Ó7HÔIØ(Ò(Ø!Ÿh™h v°A©g¸¸a¹Ð'@ÀCÈÀ:Ñ'MÓN�ØŸ(™( 6°©'°C±NÐ#CÓD�Ø!™n‘Øœu Q¨›{Ó*Ø�Ü�v˜d�|Ó$ xÓ/Ù  ´s¸6À$¸<Ó7HÔIØ(Ò(Ø!Ÿh™hØ ™7 S¨1¡WÐ-²Ñ?ó�ð Ÿ(™( 6°©'°C±NÐ#CÓD�Ø!™n‘Ø˜q“Ø�Ü�v˜d�|Ó$ xÓ/Ù  ´s¸6À$¸<Ó7HÔIØ(Ò(Ø'�ØŸ(™( 6°©'°C±NÐ#CÓD�Ø!™n‘ä—	‘	ð=àôð
 %Ò$à× Ñ Û'ªÐ4°gÐ>÷ñm *ðt ÐùòW Gùò
 ;s   ¬
K9ºK9ÁK>c                 óÀ  • SnU R                   U R                  4[        [        44 H£  u  p#U(       d  M  / n [        R
                  " U5      nSnU Hi  n[        R                  " X65      (       d  M   [        R                  R                  X&5      n[        R                  R                  U5      nX…:”  d  Me  UnUnMk     U(       d  M¡  Us  $    g! [         a     Mµ  f = f)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_REGEXr<   r?   rÀ   r™   Úsearchr=   rA   Úgetmtime)	r.   Úlatest_fileÚ	directoryÚregexÚlease_filesÚlatest_mtimeÚfnameÚabs_pathÚmtimes	            r   Ú!get_newest_lease_file_from_distroÚ-IscDhclient.get_newest_lease_file_from_distro%  sÛ   € ð ˆð
 ×/Ñ/Ø×0Ñ0ðô )Ô*GÐHó!
ÑˆIö ÙàˆKðÜ Ÿjšj¨Ó3�ð  ˆLÛ$�Ü—y’y ×.Ñ.ÙäŸ7™7Ÿ<™<¨	Ó9�ÜŸ™×(Ñ(¨Ó2�ØÕ'Ø#(�LØ"*’Kñ %÷ ˆ{Ø"Ò"ñ;!
ð< øô# %ó Úðús   ¸CÃ
CÃCÚkeyc                 óì   • U R                  U5      nU(       a\  [        R                  " U5      nU(       a>  [        U R	                  U5      5       H  nUR                  U5      nU(       d  M  Us  $    ggg)a  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©   rI   )rY   r.   r*  r�   r8   r¤   Úservers          r   Úget_key_from_latest_leaseÚ%IscDhclient.get_key_from_latest_leaseQ  sf   € ð ×;Ñ;¸FÓCˆ
ÞÜ×)Ò)¨*Ó5ˆGÞÜ% d×&7Ñ&7¸Ó&@ÖA�EØ"ŸY™Y s›^�Fß�vØ%šò Bð ð r   ©r�   r�   )r   r   r   r   rW   rZ   r‡   r„   r	   r   r   r©   r¡   ry   r
   r   r-   r   r}   r(  r.  r   Ú__classcell__©r‘   s   @r   r‰   r‰   ß   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   r‰   c            	       óØ   • \ rS rSrSrSr  SS\S\\   S\	\\
4   4S jjr\S	\S
\S\\   4S j5       r\S\S\S\	4S j5       rS\S\	\\
4   4S jr\S\S\\\\4      4S j5       rSrg)ÚDhcpcdid  Údhcpcdi,  Nr1   r0   r'   c                 óp  • [         R                  SU5        Sn[        U R                  U-  5      n/ nUR                  R                  U5         [        U5      (       a  S/nU R                  SSSSS/UQUPn[        R                  " UU R                  S	9u  p‰Ub  U" X‰5        U R                  U5      n
U
(       aë  [        R                  " / UQSP5      R                  R                  5       nS
nSnSn[        U5       H�  n [        R                  " U5      R                  5       n[        U5      nUR                  U5      nU(       a?  [         R                  SUU5        [         R"                  " U[$        R&                  5          U
$  U
s  $    [         R                  U5        U
$ [3        S5      e! [(         a    [         R                  SU5           U
$ [*         a	    SU S3n O[,         a	    SU S3n Of = f[.        R0                  " U5        GM  ! [4         aB  n[         R                  SUR                  UR6                  UR                  5        [2        UeS
nAf[        R8                   aB  n[         R                  SUR:                  UR6                  UR                  5        [2        UeS
nAff = f)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)r‚   Nz-PFrR   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´   r‚   rÔ   rÕ   r   rW   r   ry   rÜ   rž   rß   r   r@   Úget_proc_pgidr<   Úkillpgrâ   rã   ÚProcessLookupErrorrÀ   rä   rå   ræ   r   r   rÛ   rÙ   rÚ   )rY   r1   r0   r.   rê   rë   Úinfiniband_argumentÚcommandrï   rð   r¤   rè   rô   Úgidrõ   rö   r÷   rç   s                     r   r-   ÚDhcpcd.dhcp_discoveryh  s±  € ô  	�	‰	Ð5°yÔAØˆ
Ü˜4Ÿ<™<¨*Ñ4Ó5ˆØ Ðð 	�‰×Ñ˜yÔ)ð[	.ô ˜y×)Ñ)Ø'3 nÐ#à× Ñ ØØØØØ$ð	ð %ð	ð ð	ˆGô —y’yØØŸ™ñ‰HˆCð Ñ(Ù˜cÔ'Ø×)Ñ)¨)Ó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   ÁB3H ÄBF2ÆH Æ
H ÆH Æ'H Æ2 G9ÇH ÇG9Ç%H Ç'G9Ç6H Ç8G9Ç9H È
J5È=IÉJ5É3=J0Ê0J5rM   Údhcp_option_numberc                 ó^   • SnS[         S[        4S jnU" X5       H  u  pEXA:X  d  M  Us  $    g)a&  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
éð   rM   Úindexc              3   ó¨   #   • [        U 5      US-   :¼  a<  X   nU SU-      nU SU-   SU-   U-    nX$4v •  SU-   U-   n[        U 5      US-   :¼  a  M;  gg7f)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Å   r^   N)r±   )rM   rC  ÚcodeÚlengthÚoptions        r   Úiter_optionsÚ>Dhcpcd.parse_unknown_options_from_packet.<locals>.iter_optionsø  sl   é € ô �d“)˜u q™yÓ(Ø‘{�Ø˜a %™i™�Ø˜a %™i¨!¨e©)°fÑ*<Ð=�Ø�lÒ"Ø˜F™
 UÑ*�ô �d“)˜u q™y×(ùs   ‚AAÁAN)Úbytesr´   )rM   r@  ÚINDEXrH  rE  rG  s         r   Ú!parse_unknown_options_from_packetÚ(Dhcpcd.parse_unknown_options_from_packetß  s?   € ð. ˆð	+œuð 	+¬Sô 	+ñ )¨Ö5‰LˆDØÕ)Ø’ñ 6ð r   Ú
lease_dumpc           
      ó@  • [         R                  SX5         [        U R                  5       R	                  SS5      R                  S5       Vs/ s H  nSU;   d  M  UR                  SSS9PM     sn5      nU(       d$  Sn[         R                  X@5        [        X@-  5      e XS'   UR                  5        VVs0 s H  u  pgUR	                  SS5      U_M     nnnSSS.nUR                  5        H  u  pšX“;   d  M  UR                  U	5      X:'   M!     [        R                  " SU S35      n[        R                  US5      nU(       a  [        R                   " U5      US'   U$ s  snf ! [         a"  n[         R                  S	U 5        [        UeS
nAff = fs  snnf )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Ú'rR   Ú
Ú=r^   )Úmaxsplitz;No valid DHCP lease configuration found in dhcpcd lease: %rzError parsing dhcpcd lease: %rNr1   rö   Ú-zfixed-addressr  )z
ip-addresszclassless-static-routesz/var/lib/dhcpcd/z.leaseéõ   r˜   )r*   r+   r5   rž   rŸ   r�   rç   r   rä   rH   Úpopr   Úload_binary_filer4  rL  r¶   r·   )rN  r1   Úar¤   rþ   rç   r*  ÚvalueÚname_mapÚsourceÚdestinationÚdhcp_messager¨   s                r   Úparse_dhcpcd_leaseÚDhcpcd.parse_dhcpcd_lease  s   € ô, 	�	‰	Ø7¸ô	
ð
	7Üð (×-Ñ-Ó/×7Ñ7¸¸RÓ@×FÑFÀtÔLóâL˜Ø˜a‘xó -�A—G‘G˜C¨!�GÓ,ÙLñóˆEö ð0ð ô —	‘	˜#Ô*Ü/°Ñ0@ÓAÐAð ð 'ˆkÑð AFÇÁÄÔNÂ±*°#�—‘˜S #Ó&¨Ò-ÁˆÑNð *Ø'6ñ
ˆð $,§>¡>Ö#3ÑˆFØ�Ø%*§Y¡Y¨vÓ%6�Ó"ñ $4ô ×,Ò,Ø˜y˜k¨Ð0ó
ˆô ×:Ñ:¸<ÈÓMˆÞÜ#)×#3Ò#3°GÓ#<ˆE�-Ñ ØˆùòUøô ó 	7Ü�I‰IÐ6¸
ÔCÜ+°Ð6ûð	7üó Os5   ˜6E+ Á
E&ÁE&Á02E+ Â:FÅ&E+ Å+
FÅ5FÆFc                 ó2  •  U R                  [        R                  " U R                  SSU/5      R                  U5      $ ! [        R                   aB  n[
        R                  SUR                  UR                  UR                  5        [        UeSnAff = f)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--dumpleaser7  r8  N)
r^  r   rW   rÜ   rÙ   r*   r+   rÚ   rÛ   r   )rY   r1   rç   s      r   ry   ÚDhcpcd.get_newest_leaseT  s�   € ð	.Ø×*Ñ*Ü—	’	à×(Ñ(Ø%Ø$Ø!ð	ó÷ ‘&Øó
ð 
øô ×)Ñ)ó 	.Ü�I‰IØCØ—‘Ø—‘Ø—‘ô	ô #¨Ð-ûð	.ús   ‚=A  Á BÁ=BÂBr{   c                 óº   • U R                  5       nU(       a(  [        USSS2   USSS2   5       Vs/ s H  o"PM     sn$ [        R                  SU 5        / $ s  snf )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Å   r^   z'Malformed classless static routes: [%s])r�   Úzipr*   rÞ   ©r{   r  Úis      r   r}   ÚDhcpcd.parse_static_routesq  s^   € ð. Ÿ™›ˆÞä" =±°1°Ñ#5°}ÀQÀTÈÀTÑ7JÔKÓLÒK˜!’AÑKÑLÐLÜ�‰Ð=¸vÔFØˆ	ùò Ms   ²Ar   r�   )r   r   r   r   rW   r‚   r„   r
   r   r   r   r-   r‡   rJ  r´   rL  r^  ry   r	   r   r}   r   r   r   r   r4  r4  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   r4  c            	       ó¢   ^ • \ rS rSrSrU 4S jr  SS\S\\   S\	\\
4   4S jjrS\S\	\\
4   4S jr\S	\S\\\\4      4S
 j5       rSrU =r$ )ÚUdhcpci�  Úudhcpcc                 ó0   >• [         TU ]  5         SU l        g )NrR   r�   r�   s    €r   rZ   ÚUdhcpc.__init__“  s   ø€ Ü‰ÑÔØˆ�r   r1   r0   r'   c                 óä  • [         R                  SU5        [        R                  " SS9n[        R
                  R                  XAS-   5      U l        [        [        5         [        R                  " U R                  5        SSS5        UR                  R                  U5        [        R
                  R                  US5      n[        R                  " U[        S5        U R                   SS	S
USUSSSS/n[#        U5      (       a>  UR%                  SSR'                  [)        U5      SS R+                  SS5      5      /5         [,        R,                  " USU R                  0SS9u  pxUb  U" Xx5        U R9                  U5      $ ! , (       d  f       GN= f! [,        R.                   aB  n	[         R                  SU	R0                  U	R2                  U	R4                  5        [6        U	eSn	A	ff = f)aB  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®   rR   Ú
LEASE_FILE)Ú
update_envÚcapturez1udhcpc exited with code: %s stderr: %r stdout: %r)r*   r+   r   rÖ   r<   r=   rA   r�   r   rÀ   rf   rÔ   rÕ   r   r×   ÚUDHCPC_SCRIPTrW   r   ÚextendÚformatr   rŸ   r   rÙ   rÚ   rÛ   rÜ   r   ry   )
rY   r1   r0   r.   rî   rm  Úcmdrï   rð   rç   s
             r   r-   Ú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ð Ñ$Ù˜#Ô#à×$Ñ$ YÓ/Ð/÷i )Ö(ûôP ×)Ñ)ó 	.Ü�I‰IØCØ—‘Ø—‘Ø—‘ô	ô #¨Ð-ûð	.ús$   Á!!FÅ$F Æ
FÆG/Æ-=G*Ç*G/c                 ój   • [         R                  " [         R                  " U R                  5      5      $ )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�   rx   s     r   ry   ÚUdhcpc.get_newest_leaseß  s"   € ô �~Š~œd×1Ò1°$·/±/ÓBÓCÐCr   r{   c                 óŽ   • U R                  5       nU(       a(  [        US S S2   USS S2   5       Vs/ s H  o"PM     sn$ / $ s  snf )NrÅ   r^   )r�   rc  rd  s      r   r}   ÚUdhcpc.parse_static_routesí  sM   € àŸ™›ˆÞä" =±°1°Ñ#5°}ÀQÀTÈÀTÑ7JÔKÓLÒK˜!’AÑKÑLÐLØˆ	ùò Ms   ²Ar0  r�   )r   r   r   r   rW   rZ   r„   r
   r   r   r   r-   ry   r‡   r	   r   r}   r   r1  r2  s   @r   rh  rh  �  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   rh  r�   rU   )5r…   re   Úloggingr<   r™   râ   r¶   r²   rå   Ú
contextlibr   Úior   Ú
subprocessr   Útypingr   r   r   r	   r
   r   r6   Ú	cloudinitr   r   r   Úcloudinit.netr   r   Ú	getLoggerr   r*   r;   r  r  rr  Ú	Exceptionr   r   r"   r%   r„   r2   r9   rE   rN   ÚABCrP   r‰   r4  rh  ÚALL_DHCP_CLIENTSr   r   r   Ú<module>r‡     s  ðó Û Û Û 	Û 	Û Û Û Û Ý Ý Ý %ß =× =ã ç ,Ñ ,ß <à×Ò˜Ó!€à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   