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)