MAC address matching and stuff.
parent
a3bba233cd
commit
eb1f6b64cb
|
@ -0,0 +1,29 @@
|
||||||
|
import cStringIO
|
||||||
|
import time
|
||||||
|
|
||||||
|
from khepri import hook, get_mac
|
||||||
|
|
||||||
|
@hook(r"^pxelinux.cfg/default$")
|
||||||
|
def pxelinux_default(path, match, remote):
|
||||||
|
(raddress, rport) = remote
|
||||||
|
mac = get_mac(raddress)
|
||||||
|
if not mac:
|
||||||
|
s = "localboot 0"
|
||||||
|
else:
|
||||||
|
s = """ default menu.c32
|
||||||
|
prompt 0
|
||||||
|
|
||||||
|
menu title "Khepri Boot Menu generated at %s for %s:%i"
|
||||||
|
menu INCLUDE pxelinux.cfg/graphics.conf
|
||||||
|
MENU AUTOBOOT Starting Xen Node in # seconds
|
||||||
|
|
||||||
|
label xen
|
||||||
|
menu label ^Xen Node
|
||||||
|
menu default
|
||||||
|
timeout 80
|
||||||
|
kernel xen/vmlinuz
|
||||||
|
append rootfstype=nfs root=/dev/nfs nfsroot=10.8.1.1:/var/khepri/nfs/xen,v4,rsize=16384,wsize=16384 ip=:::::eth0:dhcp
|
||||||
|
""" % (time.strftime("%d/%m/%Y at %H:%M:%S"), raddress, rport)
|
||||||
|
return cStringIO.StringIO(s)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import sys, logging
|
||||||
|
import tftpy
|
||||||
|
import re
|
||||||
|
|
||||||
|
LEASES_FILE = "/var/lib/dhcp/dhcpd.leases"
|
||||||
|
|
||||||
|
def get_mac(address):
|
||||||
|
"""Gets MAC address from dhcpd leases based on IP address."""
|
||||||
|
f = open(LEASES_FILE,"r")
|
||||||
|
in_lease = False
|
||||||
|
for line in f:
|
||||||
|
line = line.split("#")[0]
|
||||||
|
parts = line.strip().split()
|
||||||
|
if not parts:
|
||||||
|
continue
|
||||||
|
if not in_lease and parts[0] == "lease":
|
||||||
|
in_lease = parts[1]
|
||||||
|
continue
|
||||||
|
field_name = parts[0]
|
||||||
|
if field_name == "hardware" and in_lease == address:
|
||||||
|
return parts[2][:-1]
|
||||||
|
elif field_name == "}":
|
||||||
|
in_lease = False
|
||||||
|
return None
|
||||||
|
|
||||||
|
file_hooks = {}
|
||||||
|
def hook_dispatcher(path, remote):
|
||||||
|
for pattern, hook in file_hooks.iteritems():
|
||||||
|
match = re.match(pattern, path)
|
||||||
|
if match:
|
||||||
|
data = hook(path, match, remote)
|
||||||
|
if data:
|
||||||
|
return data
|
||||||
|
return None
|
||||||
|
|
||||||
|
def hook(pattern, match_mac=None):
|
||||||
|
def decorator(f):
|
||||||
|
def wrapper(path, match, remote):
|
||||||
|
if match_mac:
|
||||||
|
mac = get_mac([0])
|
||||||
|
if match_mac and mac != match_mac:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return f(path, match, remote)
|
||||||
|
file_hooks[pattern] = wrapper
|
||||||
|
return f
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
import hooks
|
||||||
|
|
||||||
|
def main():
|
||||||
|
server = tftpy.TftpServer("/var/khepri/tftp-root/", dyn_file_func=hook_dispatcher)
|
||||||
|
try:
|
||||||
|
server.listen("10.8.1.1", 5000)
|
||||||
|
except tftpy.TftpException, err:
|
||||||
|
sys.stderr.write("%s\n" % str(err))
|
||||||
|
sys.exit(1)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
|
|
@ -1,53 +1,4 @@
|
||||||
#!/usr/bin/env python
|
import khepri
|
||||||
|
|
||||||
import sys, logging
|
if __name__ == "__main__":
|
||||||
import tftpy
|
khepri.main()
|
||||||
import re
|
|
||||||
import cStringIO
|
|
||||||
import time
|
|
||||||
|
|
||||||
file_hooks = {}
|
|
||||||
def hook_dispatcher(path):
|
|
||||||
for pattern, hook in file_hooks.iteritems():
|
|
||||||
match = re.match(pattern, path)
|
|
||||||
if match:
|
|
||||||
return hook(path, match)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def hook(pattern):
|
|
||||||
def decorator(f):
|
|
||||||
file_hooks[pattern] = f
|
|
||||||
return f
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
@hook(r"^pxelinux.cfg/default$")
|
|
||||||
def pxelinux_default(path, match):
|
|
||||||
s = """default menu.c32
|
|
||||||
prompt 0
|
|
||||||
|
|
||||||
menu title "Khepri Boot Menu generated at %s"
|
|
||||||
menu INCLUDE pxelinux.cfg/graphics.conf
|
|
||||||
MENU AUTOBOOT Starting Xen Node in # seconds
|
|
||||||
|
|
||||||
label xen
|
|
||||||
menu label ^Xen Node
|
|
||||||
menu default
|
|
||||||
timeout 80
|
|
||||||
kernel xen/vmlinuz
|
|
||||||
append rootfstype=nfs root=/dev/nfs nfsroot=10.8.1.1:/var/khepri/nfs/xen,v4,rsize=16384,wsize=16384 ip=:::::eth0:dhcp
|
|
||||||
""" % time.strftime("%d/%m/%Y at %H:%M:%S")
|
|
||||||
return cStringIO.StringIO(s)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
server = tftpy.TftpServer("/var/khepri/tftp-root/", dyn_file_func=hook_dispatcher)
|
|
||||||
try:
|
|
||||||
server.listen("10.8.1.1", 5000)
|
|
||||||
except tftpy.TftpException, err:
|
|
||||||
sys.stderr.write("%s\n" % str(err))
|
|
||||||
sys.exit(1)
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
|
|
|
@ -285,7 +285,7 @@ class TftpStateServerRecvRRQ(TftpServerState):
|
||||||
elif self.context.dyn_file_func:
|
elif self.context.dyn_file_func:
|
||||||
log.debug("No such file %s but using dyn_file_func" % path)
|
log.debug("No such file %s but using dyn_file_func" % path)
|
||||||
self.context.fileobj = \
|
self.context.fileobj = \
|
||||||
self.context.dyn_file_func(self.context.file_to_transfer)
|
self.context.dyn_file_func(self.context.file_to_transfer, (raddress, rport))
|
||||||
|
|
||||||
if self.context.fileobj is None:
|
if self.context.fileobj is None:
|
||||||
log.debug("dyn_file_func returned 'None', treating as "
|
log.debug("dyn_file_func returned 'None', treating as "
|
||||||
|
|
Reference in New Issue