mirror of
https://github.com/xcat2/confluent.git
synced 2026-01-13 03:22:30 +00:00
Get closer to replying to PXE
Monitor and maintain a uuid and mac map to node in preparation for efficient handling of DISCOVERs/REQUESTS from ONIE and/or PXE.
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
|
||||
# option 97 = UUID (wireformat)
|
||||
|
||||
import confluent.config.configmanager as cfm
|
||||
import ctypes
|
||||
import ctypes.util
|
||||
import eventlet.green.socket as socket
|
||||
@@ -96,6 +97,10 @@ pxearchs = {
|
||||
}
|
||||
|
||||
|
||||
uuidmap = {}
|
||||
macmap = {}
|
||||
attribwatcher = None
|
||||
|
||||
def stringify(value):
|
||||
string = bytes(value)
|
||||
if not isinstance(string, str):
|
||||
@@ -185,6 +190,11 @@ def snoop(handler, protocol=None):
|
||||
#prominent
|
||||
#TODO(jjohnson2): enable unicast replies. This would suggest either
|
||||
# injection into the neigh table before OFFER or using SOCK_RAW.
|
||||
global attribwatcher
|
||||
cfg = cfm.ConfigManager(None)
|
||||
remap_nodes(cfg.list_nodes(), cfg)
|
||||
attribwatcher = cfg.watch_attributes(cfg.list_nodes(), ('id.uuid', 'net.*hwaddr'), remap_nodes)
|
||||
cfg.watch_nodecollection(new_nodes)
|
||||
net4 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
net4.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
net4.setsockopt(socket.IPPROTO_IP, IP_PKTINFO, 1)
|
||||
@@ -250,21 +260,69 @@ def snoop(handler, protocol=None):
|
||||
uuid, arch, vivso = find_info_in_options(rq, optidx)
|
||||
if vivso:
|
||||
# info['modelnumber'] = info['attributes']['enclosure-machinetype-model'][0]
|
||||
handler({'hwaddr': netaddr, 'uuid': uuid,
|
||||
info = {'hwaddr': netaddr, 'uuid': uuid,
|
||||
'architecture': vivso.get('arch', ''),
|
||||
'services': (vivso['service-type'],),
|
||||
'netinfo': {'ifidx': idx, 'recvip': recv, 'txid': txid},
|
||||
'attributes': {'enclosure-machinetype-model': [vivso.get('machine', '')]}})
|
||||
'attributes': {'enclosure-machinetype-model': [vivso.get('machine', '')]}}
|
||||
handler(info)
|
||||
consider_discover(info, rq, net4)
|
||||
continue
|
||||
if uuid is None:
|
||||
continue
|
||||
# We will fill out service to have something to byte into,
|
||||
# but the nature of the beast is that we do not have peers,
|
||||
# so that will not be present for a pxe snoop
|
||||
handler({'hwaddr': netaddr, 'uuid': uuid, 'architecture': arch,
|
||||
info = {'hwaddr': netaddr, 'uuid': uuid, 'architecture': arch,
|
||||
'netinfo': {'ifidx': idx, 'recvip': recv, 'txid': txid},
|
||||
'services': ('pxe-client',)})
|
||||
'services': ('pxe-client',)}
|
||||
handler(info)
|
||||
consider_discover(info, rq, net4)
|
||||
|
||||
|
||||
def clear_nodes(nodes):
|
||||
for nodename in nodes:
|
||||
for ent in list(macmap):
|
||||
if macmap[ent] == nodename:
|
||||
del macmap[ent]
|
||||
for ent in list(uuidmap):
|
||||
if uuidmap[ent] == nodename:
|
||||
del uuidmap[ent]
|
||||
|
||||
|
||||
def new_nodes(added, deleting, renamed, configmanager):
|
||||
global attribwatcher
|
||||
configmanager.remove_watcher(attribwatcher)
|
||||
alldeleting = set(deleting) | set(renamed)
|
||||
clear_nodes(alldeleting)
|
||||
attribwatcher = configmanager.watch_attributes(configmanager.list_nodes(),
|
||||
('id.uuid', 'net.*hwaddr'), remap_nodes)
|
||||
|
||||
|
||||
def remap_nodes(nodeattribs, configmanager):
|
||||
global macmap
|
||||
global uuidmap
|
||||
updates = configmanager.get_node_attributes(nodeattribs, ('id.uuid', 'net.*hwaddr'))
|
||||
clear_nodes(nodeattribs)
|
||||
for node in updates:
|
||||
for attrib in updates[node]:
|
||||
if attrib == 'id.uuid':
|
||||
uuidmap[updates[node][attrib]['value']] = node
|
||||
elif 'hwaddr' in attrib:
|
||||
macmap[updates[node][attrib]['value']] = node
|
||||
|
||||
|
||||
def check_reply(node, info, packet, sock):
|
||||
print('Thinking about reply to {0}'.format(node))
|
||||
|
||||
|
||||
def consider_discover(info, packet, sock):
|
||||
if info.get('hwaddr', None) in macmap:
|
||||
check_reply(macmap[info['hwaddr']], info, packet, sock)
|
||||
elif info.get('uuid', None) in uuidmap:
|
||||
check_reply(uuidmap[info['uuid']], info, packet, sock)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
def testsnoop(info):
|
||||
print(repr(info))
|
||||
|
||||
Reference in New Issue
Block a user