70 lines
2.0 KiB
Python
70 lines
2.0 KiB
Python
|
|
import os, sys
|
||
|
|
from string import Template
|
||
|
|
from subprocess import PIPE, Popen,call
|
||
|
|
|
||
|
|
BUSYBOX_BINARY = "busybox"
|
||
|
|
TEMPLATE_FILE = os.path.dirname(os.path.realpath(__file__)) + "/udhcpd.conf.template"
|
||
|
|
|
||
|
|
class VMdhcpd:
|
||
|
|
def __init__(self, vmid ,config):
|
||
|
|
self.__config = config
|
||
|
|
self.__vmid = vmid
|
||
|
|
|
||
|
|
def start(self):
|
||
|
|
self.__kill()
|
||
|
|
|
||
|
|
if ('VMs' in self.__config) and (self.__vmid in self.__config['VMs']):
|
||
|
|
config = self.__config['VMs'][self.__vmid]
|
||
|
|
else:
|
||
|
|
raise Exception("No such VM configuration")
|
||
|
|
|
||
|
|
if "network" in config and "ip" in config["network"]:
|
||
|
|
config_file_str = None
|
||
|
|
with open(TEMPLATE_FILE) as f:
|
||
|
|
config_file_str = f.read()
|
||
|
|
|
||
|
|
template_params = {
|
||
|
|
"ip_address" : config['network']['ip'][0],
|
||
|
|
"interface" : config['network']['dev'],
|
||
|
|
"pidfile" : self.__config['dhcpd']['pidfile'].replace("$VMID", self.__vmid),
|
||
|
|
"router" : self.__config['dhcpd']['router'],
|
||
|
|
"dns1" : self.__config['dhcpd']['dns1'],
|
||
|
|
"dns2" : self.__config['dhcpd']['dns2']
|
||
|
|
}
|
||
|
|
|
||
|
|
config_file_str = Template(config_file_str).substitute(template_params)
|
||
|
|
|
||
|
|
#imake sure the interface has some address as udhcpd can't use it without
|
||
|
|
call(["ip", "addr", "replace", "dev", config['network']['dev'], "192.168.123.221/32"], stdout=open("/dev/null"))
|
||
|
|
|
||
|
|
command = BUSYBOX_BINARY + " udhcpd -f - << EOFEOFEOF\n" + config_file_str + "\nEOFEOFEOF"
|
||
|
|
Popen(command, stdout=open("/dev/null"), stderr=open("/dev/null"), shell=True, start_new_session=True)
|
||
|
|
#os.system(command)
|
||
|
|
|
||
|
|
|
||
|
|
def stop(self):
|
||
|
|
self.__kill()
|
||
|
|
|
||
|
|
def __kill(self):
|
||
|
|
pid,filename = self.getPid()
|
||
|
|
if(pid is not None):
|
||
|
|
os.kill(pid,9)
|
||
|
|
|
||
|
|
try:
|
||
|
|
os.remove(filename)
|
||
|
|
except OSError:
|
||
|
|
pass
|
||
|
|
|
||
|
|
def getPid(self) -> "(int or None, filname)":
|
||
|
|
result = None
|
||
|
|
filename = self.__config['dhcpd']['pidfile'].replace("$VMID", self.__vmid)
|
||
|
|
try:
|
||
|
|
with open(filename) as pidfd:
|
||
|
|
firstline = pidfd.readline().strip()
|
||
|
|
result = int(firstline) if firstline.isdigit() else None
|
||
|
|
except IOError:
|
||
|
|
pass
|
||
|
|
return (result,filename)
|
||
|
|
|
||
|
|
|