jbc@sddlZddlZddlZddlZddlmZddlmZddlm Z ddl m Z m Z ej eZdZdZejdd Zd Zd d Zddddd ZddZdZdZdZdZdZdZdZddZ dZ!dZ"ddZ#ddZ$ddZ%dZ&dZ'dZ(dZ)d Z*d!Z+d"Z,d#Z-d$e.fd%YZ/d&Z0dd'Z1ddd(Z2d)Z3e4d*Z5e4e4d+Z6e7d,Z8e4d-Z9e4e4dd.Z:d/Z;d0Z<d1Z=d2Z>d3Z?d4Z@d5eAfd6YZBd7eCfd8YZDdS(9iN(tpartial(tmask_to_net_prefix(tutil(tUrlErrortreadurls/sys/class/net/teth0s([0-9]+)cCsAgtj||D]*}|jr1t|n |j^qS(sDSorting for Humans: natural sort order. Can be use as the key to sort functions. This will sort ['eth0', 'ens3', 'ens10', 'ens12', 'ens8', 'ens0'] as ['ens0', 'ens3', 'ens8', 'ens10', 'ens12', 'eth0'] instead of the simple python way which will produce ['ens0', 'ens10', 'ens12', 'ens3', 'ens8', 'eth0'].(tretsplittisdigittinttlower(tst_nsrettext((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytnatural_sort_keyscCstS(s3Simple function to return the global SYS_CLASS_NET.(t SYS_CLASS_NET(((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytget_sys_class_path"stcCst|d|S(Nt/(R(tdevnametpath((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyt sys_dev_path'sc Cst||}ytj|}Wnttfk r}t|dd} | tjtj fkr}|dk r}||Sn| tj fkr|dk r||SnnX|j }|dkr|Sy ||SWn?t k r}|dk r||St jd||nXdS(Nterrnos5Found unexpected (not translatable) value '%s' in '%s(RRt load_filetOSErrortIOErrortgetattrtNoneRtENOENTtENOTDIRtEINVALtstriptKeyErrortLOGtdebug( RRt translatet on_enoentt on_keyerrort on_einvaltdev_pathtcontentstete_errno((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyt read_sys_net+s.           c Cs.d}t||d|d|d|d|S(NcSstS(N(tFalse(R)((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyt on_excp_falseIsR%R$R&R#(R+(tifacetfieldR#R-((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytread_sys_net_safeHs   cCsFt||}|tkrdSyt|SWntk rAdSXdS(N(R0R,RR t ValueError(R.R/tval((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytread_sys_net_intRs  cCs.itd6td6td6}t|dd|S(Ntuptunknowntdownt operstateR#(tTrueR,R0(RR#((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytis_up\scCstjjt|dS(Ntwireless(tosRtexistsR(R((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyt is_wirelessdscCstjjt|dS(Ntbridge(R;RR<R(R((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyt is_bridgehscCstjjt|dS(Ntbonding(R;RR<R(R((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytis_bondlscCs,t|dd}tjj|r(|SdS(s8Return the master path for devname, or None if no masterRtmasterN(RR;RR<R(RR((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyt get_masterpscCsht|}|dkrtStjj|d}tjj|d}tjj|pgtjj|S(s@Return a bool indicating if devname's master is a bridge or bondR@R>N(RCRR,R;RtjoinR<(Rt master_patht bonding_patht bridge_path((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytmaster_is_bridge_or_bondxs   cCsA|dkrt|}nt||s9t||r=tStS(s netfailover driver uses 3 nics, master, primary and standby. this returns True if the device is either the primary or standby as these devices are to be ignored. N(Rt device_drivertis_netfail_primarytis_netfail_standbyR8R,(Rtdriver((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytis_netfailovers   cCs1d}yt|d}Wntk r,nX|S(sE Returns a str from reading /sys/class/net//device/features.Rsdevice/features(R+t Exception(Rtfeatures((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytget_dev_featuress  cCs7t|}| s%t|dkr)tS|ddkS(s Return True if VIRTIO_NET_F_STANDBY bit (62) is set. https://github.com/torvalds/linux/blob/ 089cf7f6ecb266b6a4164919a2e69bd2f938374a/ include/uapi/linux/virtio_net.h#L60 i@i>t1(RPtlenR,(RRO((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pythas_netfail_standby_features cCsUt|dk rtS|dkr1t|}n|dkrAtSt|sQtStS(s A device is a "netfail master" device if: - The device does NOT have the 'master' sysfs attribute - The device driver is 'virtio_net' - The device has the standby feature bit set Return True if all of the above is True. t virtio_netN(RCRR,RIRSR8(RRL((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytis_netfail_masters    cCst|dd}tjj|s(tS|dkrCt|}n|dkrStStjjtjj|}t|}|dkrtSt |}|stSt S(sL A device is a "netfail primary" device if: - the device has a 'master' sysfs file - the device driver is not 'virtio_net' - the 'master' sysfs file points to device with virtio_net driver - the 'master' device has the 'standby' feature bit set Return True if all of the above is True. RRBRTN( RR;RR<R,RRItbasenametrealpathRSR8(RRLtmaster_sysfs_pathtmaster_devnamet master_drivertmaster_has_standby((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyRJs      cCsUt|dkrtS|dkr1t|}n|dkrAtSt|sQtStS(s A device is a "netfail standby" device if: - The device has a 'master' sysfs attribute - The device driver is 'virtio_net' - The device has the standby feature bit set Return True if all of the above is True. RTN(RCRR,RIRSR8(RRL((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyRKs    cCs)t|d}|r%|dkr%tStS(s /* interface name assignment types (sysfs name_assign_type attribute) */ #define NET_NAME_UNKNOWN 0 /* unknown origin (not exposed to user) */ #define NET_NAME_ENUM 1 /* enumerated by kernel */ #define NET_NAME_PREDICTABLE 2 /* predictably named by the kernel */ #define NET_NAME_USER 3 /* provided by user-space */ #define NET_NAME_RENAMED 4 /* renamed by user-space */ tname_assign_typet3t4(R]R^(R0R8R,(RR\((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyt is_renameds cCs%tt|d}d|jkS(Ntuevents DEVTYPE=vlan(tstrR0t splitlines(RR`((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytis_vlanscCs`t|d}|dkrtSt|s/tStjd|t|dditd6td6S(Ntiflinkt2s/'%s' is wireless, basing 'connected' on carriertcarrierR#t0RQ(R0R8R=R,R!R"(RRd((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyt is_connected s   cCstjjt|dS(Ntdevice(R;RR<R(R((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyt is_physicalscCstjjt|S(N(R;RR<R(R((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyt is_presentscCsId}t|d}tjj|rEtjjtj|}n|S(s8Return the device driver for net device named 'devname'.s device/driverN(RRR;RtislinkRVtreadlink(RRLt driver_path((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyRI!s cCs#t|d}|tkrdS|S(s;Return the device id string for net device named 'devname'.s device/deviceN(R0R,R(Rtdev_id((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyt device_devid,s cCsNytjt}Wn1tk rI}|jtjkrCg}qJnX|S(N(R;tlistdirRRRR(tdevsR)((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytget_devicelist5s t ParserErrorcBseZdZRS(s6Raised when a parser has issue parsing a file/content.(t__name__t __module__t__doc__(((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyRt@scCs.| st|t rtS|jddkS(Ntconfigtdisabled(t isinstancetdictR,tget(tcfg((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytis_disabled_cfgDscCs`|sg}ndtjkr1tjdnvgtD]%}|dkr;t| r;|^q;}t|rtjd|d}tjtj|dtjnt dg}t gtD]}t ||kr|^q}|j |}g}g}x|D]}|j dr'q nt |r9q nt|rKq nt|r]q nt|d} | r|j|q nt|d } | r|j|q nt|d } | dkr |j|q q q W|r|}n|}tt|dt} t| kr8| jt| jdtnx!| D]} t| dr?| Sq?WdS(s1Return the name of the 'fallback' network device.s net.ifnames=0s9Stable ifnames disabled by net.ifnames=0 in /proc/cmdlinetlos4Found unstable nic names: %s; calling udevadm settles!Waiting for udev events to settletfunctvethRftdormantR7R6tlowerlayerdownR5tkeyitaddress(sdormantsdownRsunknownN(Rt get_cmdlineR!R"RsR_RRtlog_timetudevadm_settletsetRIt differencet startswithR?RARMR3tappendR0tlisttsortedRtDEFAULT_PRIMARY_INTERFACEtremovetinsertR(tblacklist_driversRitunstabletmsgtinvalid_interfacestpotential_interfacest connectedtpossibly_connectedt interfaceRfRR7tnamestname((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytfind_fallback_nicJsd %                cCs|st}ntd|}|s(d St|rDi|d6}nit|djd6}itd6|d6|d6}|rt|}|r||ddytt|Wn#tk r9}td|nXdS(sread the network config and rename devices accordingly. if strict_present is false, then do not raise exception if no devices match. if strict_busy is false, then do not raise exception if the device cannot be renamed because it is currently configured. renames are only attempted for interfaces of type 'physical'. It is expected that the network system will create other devices with the correct name in place.s(Failed to apply network config names: %sN(t_rename_interfacesRR(Rtstrict_presentt strict_busyR)((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytapply_network_config_namess cCs>t|d}|dkr4|r0tdntS|dkS(sreturn True if the provided interface has its own address. Based on addr_assign_type in /sys. Return true for any interface that does not have a 'stolen' address. Examples of such devices are bonds or vlans that inherit their mac from another device. Possible values are: 0: permanent address 2: stolen from another device 1: randomly generated 3: set using dev_set_mac_addresstaddr_assign_types%s had no addr_assign_type.iiiN(iii(R3RR1R8(tifnameRt assign_type((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytinterface_has_own_macs  c CsJi}x]tD]R\}}}}idd6|d6|d6|jd6|d6t|d6||fs(R{R(tbymac(R(s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyt update_bynamees cSs)tjddd|d|gdtdS(NRtlinkRRR(RRR8(tcurtnew((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytrenameiscSs&tjddd|dgdtdS(NRRRR6R(RRR8(R((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyR6lscSs&tjddd|dgdtdS(NRRRR4R(RRR8(R((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyR4oss cirename%dicSs|r@|r@|r@|d|ko?|d|ko?|d|kS|rj|rj|d|koi|d|kS|r~|d|kStS(smatch if set and in dataRRLR(R,(RRRLR((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyt entry_matchys csgjD]!}||||r |^q }t|rt|dkrwd||||f}t|n|dSdS(NisjFailed to match a single device. Matched devices "%s" with search values "(mac:%s driver:%s device_id:%s)"i(RRRR1R(RRLRRRR(RR(s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyt find_entrys! s<[nic not present] Cannot rename mac=%s to %s, not available.R4s*[busy] Error renaming mac=%s from %s to %sRR6s2[busy-target] Error renaming mac=%s from %s to %s.iRis(unable to do any work for renaming of %ss$no work necessary for renaming of %ss$achieving renaming of %s with ops %ss.[unknown] Error performing %s%s for %s, %s: %ss ( RRR!R"RRtitemstcopyR|R RR,RNRD(trenamesRRt current_infoRRRRRR6R4topsterrorstupst cur_bynamet tmpname_fmtttmpiRRtnew_nameRLRtcur_opstcur_nameRttargetttmp_nametopmaptopRR)((RRs:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyRSs                        "#    cCs7d}tjjt|dr*d}nt||S(s6Returns the string value of an interface's MAC AddressRt bonding_slavesbonding_slave/perm_hwaddr(R;RtisdirRR0(RR((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytget_interface_macs cCsMt|ddkrIt|}|rE|rE|dd!|d}n|SdS(sReturns the string value of an Infiniband interface's hardware address. If ethernet_format is True, an Ethernet MAC-style 6 byte representation of the address will be returned. Rt32i$ii3N(R0R(Rtethernet_formatR((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytget_ib_interface_hwaddrs   cCsi}xtD]\}}}}||krNtd||||fn|||Perform ephemeral network setup if interface is not connected.s=Skip ephemeral network setup, instance has connectivity to %sN( RR R!R"t_bringup_deviceRt_bringup_static_routesRt_bringup_router(R((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyt __enter__s     cCs+x$|jD]}tj|dtq WdS(sTeardown anything we set up.RN(RRRR8(Rt excp_typet excp_valuetexcp_tracebacktcmd((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyt__exit__sc Cs<tjdddddd||fd|jgdtd S( s7Perform the ip command to remove the specified address.Rs-familytinetRtdels%s/%stdevRN(RRRR8(RRR((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyt_delete_addresssc CsKdj|j|j}tjd|j||jyHtjddddd|d|jd |jg d t d id d 6WnDtj k r}d|j krntjd|j|jnXtjdddddd |jdgd t |j j dddddd |jdg|j j ddddd|d |jgdS(s1Perform the ip comands to fully setup the device.s{0}/{1}s:Attempting setup of ephemeral network on %s with %s brd %sRs-familyR#RtaddRR%Rt update_envtCtLANGs File existss7Skip ephemeral network setup, %s already has address %sRRR4R6R$N(RRRR!R"RRRRR8tProcessExecutionErrortstderrRR(RtcidrR)((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyRs0   cCsx|jD]\}}g}|dkr7d|g}ntjdddd|g|d|jgdt|jjd dddd |g|d|jgq WdS( Ns 0.0.0.0/0tviaRs-4trouteRR%RiR$(RRRRR8RR(Rt net_addresstgatewaytvia_arg((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyRs  c Cs$tjddddgdt\}}d|krStjd|j|jdStjdd dd |jd |jd |jg dt|j j d dd dd|jd |jd |jg tjdd dd dd|jd |jg dt|j j d dd dddd |jgdS(s<Perform the ip commands to fully setup the router if needed.RR/Rs 0.0.0.0/0Rtdefaults<Skip ephemeral route setup. %s already has default route: %sNs-4R'R%tsrciR$R.( RRR8R!R"RRRRRR(RtoutR((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyRs$'   N( RuRvRwRRRR"R&RRR(((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyRVs      tRendererNotFoundErrorcBseZRS((RuRv(((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pyR6s(ERtloggingR;Rt functoolsRtcloudinit.net.network_stateRt cloudinitRtcloudinit.url_helperRRt getLoggerRuR!RRRRRRRR+R0R3R9R=R?RARCRHRMRPRSRURJRKR_RcRhRjRkRIRpRsRNRtR~RRRR8RRR,RRRRRRRR R tobjectRRR6(((s:/usr/lib/python2.7/site-packages/cloudinit/net/__init__.pytsr              !         K 1 %  +