add busybox udhcps functionality
This commit is contained in:
22
VMHelper.py
22
VMHelper.py
@@ -6,6 +6,7 @@ import time
|
|||||||
import sys
|
import sys
|
||||||
import pwd
|
import pwd
|
||||||
from qmp import QEMUMonitorProtocol
|
from qmp import QEMUMonitorProtocol
|
||||||
|
from VMdhcpd import VMdhcpd
|
||||||
|
|
||||||
class VMHelper:
|
class VMHelper:
|
||||||
def __init__(self, filename):
|
def __init__(self, filename):
|
||||||
@@ -94,6 +95,10 @@ class VMHelper:
|
|||||||
cmd.append("-qmp")
|
cmd.append("-qmp")
|
||||||
cmd.append("unix:" + self.config['kvm']['qmpsocket'].replace("$VMID", vmid) + ",server,nowait")
|
cmd.append("unix:" + self.config['kvm']['qmpsocket'].replace("$VMID", vmid) + ",server,nowait")
|
||||||
|
|
||||||
|
if "runas" in self.config["kvm"]:
|
||||||
|
cmd.append("-runas")
|
||||||
|
cmd.append(self.config["kvm"]["runas"])
|
||||||
|
|
||||||
cmd += ["-name", vmid]
|
cmd += ["-name", vmid]
|
||||||
|
|
||||||
default_args = self.config['kvm']['default_args'].replace("$VMID", vmid)
|
default_args = self.config['kvm']['default_args'].replace("$VMID", vmid)
|
||||||
@@ -244,8 +249,12 @@ class VMHelper:
|
|||||||
commands.append(["ip6tables", "-A", "FORWARD", "-j", chain])
|
commands.append(["ip6tables", "-A", "FORWARD", "-j", chain])
|
||||||
|
|
||||||
for cmd in commands:
|
for cmd in commands:
|
||||||
subprocess.call(cmd, stdout=open("/dev/null"))
|
subprocess.call(cmd, stdout=open("/dev/null")
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
VMdhcpd(vmid, self.config).start()
|
||||||
|
|
||||||
def teardownNetwork(self, vmid):
|
def teardownNetwork(self, vmid):
|
||||||
if ('VMs' in self.config) and (vmid in self.config['VMs']):
|
if ('VMs' in self.config) and (vmid in self.config['VMs']):
|
||||||
config = self.config['VMs'][vmid]
|
config = self.config['VMs'][vmid]
|
||||||
@@ -271,6 +280,8 @@ class VMHelper:
|
|||||||
for cmd in commands:
|
for cmd in commands:
|
||||||
subprocess.call(cmd, stdout=open("/dev/null"))
|
subprocess.call(cmd, stdout=open("/dev/null"))
|
||||||
|
|
||||||
|
VMdhcpd(vmid, self.config).stop()
|
||||||
|
|
||||||
def generateAuthorizedKeys(self):
|
def generateAuthorizedKeys(self):
|
||||||
userkeys = {}
|
userkeys = {}
|
||||||
keydir = os.path.join(self.config["ssh"]["homedir"], self.config["ssh"]["keydir"])
|
keydir = os.path.join(self.config["ssh"]["homedir"], self.config["ssh"]["keydir"])
|
||||||
@@ -279,12 +290,17 @@ class VMHelper:
|
|||||||
if len(fnsplit) == 2:
|
if len(fnsplit) == 2:
|
||||||
user = fnsplit[0]
|
user = fnsplit[0]
|
||||||
with open(os.path.join(keydir,filename)) as f:
|
with open(os.path.join(keydir,filename)) as f:
|
||||||
userkeys[user] = userkeys[user].append(f.readline().rstrip('\n')) if user in userkeys else [f.readline().rstrip('\n')]
|
keystring = f.readline().rstrip('\n')
|
||||||
|
if user in userkeys:
|
||||||
|
userkeys[user].append(keystring)
|
||||||
|
else:
|
||||||
|
userkeys[user] = [keystring]
|
||||||
|
|
||||||
authorized_keys = ""
|
authorized_keys = ""
|
||||||
for user, keys in userkeys.items():
|
for user, keys in userkeys.items():
|
||||||
prepend = 'no-agent-forwarding,no-user-rc,no-X11-forwarding,command="read",'
|
prepend = 'no-agent-forwarding,no-user-rc,no-X11-forwarding,command="read",'
|
||||||
for vm, vals in self.config["VMs"].items():
|
for vm, vals in self.config["VMs"].items():
|
||||||
if vals["owner"] in userkeys:
|
if vals["owner"] == user:
|
||||||
prepend += 'permitopen="localhost:{0}",'.format(vals["vnc"]["display"] + 5900)
|
prepend += 'permitopen="localhost:{0}",'.format(vals["vnc"]["display"] + 5900)
|
||||||
prepend += 'permitopen="127.0.0.1:{0}",'.format(vals["vnc"]["display"] + 5900)
|
prepend += 'permitopen="127.0.0.1:{0}",'.format(vals["vnc"]["display"] + 5900)
|
||||||
prepend += 'permitopen="[::1]:{0}",'.format(vals["vnc"]["display"] + 5900)
|
prepend += 'permitopen="[::1]:{0}",'.format(vals["vnc"]["display"] + 5900)
|
||||||
|
|||||||
69
VMdhcpd.py
Normal file
69
VMdhcpd.py
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
122
udhcpd.conf.template
Normal file
122
udhcpd.conf.template
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
# template udhcpd configuration file for vm-manager
|
||||||
|
|
||||||
|
# The start and end of the IP lease block
|
||||||
|
|
||||||
|
start ${ip_address} #default: 192.168.0.20
|
||||||
|
end ${ip_address} #default: 192.168.0.254
|
||||||
|
|
||||||
|
|
||||||
|
# The interface that udhcpd will use
|
||||||
|
|
||||||
|
interface ${interface} #default: eth0
|
||||||
|
|
||||||
|
|
||||||
|
# The maximim number of leases (includes addressesd reserved
|
||||||
|
# by OFFERs, DECLINEs, and ARP conficts
|
||||||
|
|
||||||
|
#max_leases 254 #default: 254
|
||||||
|
|
||||||
|
|
||||||
|
# If remaining is true (default), udhcpd will store the time
|
||||||
|
# remaining for each lease in the udhcpd leases file. This is
|
||||||
|
# for embedded systems that cannot keep time between reboots.
|
||||||
|
# If you set remaining to no, the absolute time that the lease
|
||||||
|
# expires at will be stored in the dhcpd.leases file.
|
||||||
|
|
||||||
|
#remaining yes #default: yes
|
||||||
|
|
||||||
|
|
||||||
|
# The time period at which udhcpd will write out a dhcpd.leases
|
||||||
|
# file. If this is 0, udhcpd will never automatically write a
|
||||||
|
# lease file. (specified in seconds)
|
||||||
|
|
||||||
|
#auto_time 7200 #default: 7200 (2 hours)
|
||||||
|
|
||||||
|
|
||||||
|
# The amount of time that an IP will be reserved (leased) for if a
|
||||||
|
# DHCP decline message is received (seconds).
|
||||||
|
|
||||||
|
#decline_time 3600 #default: 3600 (1 hour)
|
||||||
|
|
||||||
|
|
||||||
|
# The amount of time that an IP will be reserved (leased) for if an
|
||||||
|
# ARP conflct occurs. (seconds
|
||||||
|
|
||||||
|
#conflict_time 3600 #default: 3600 (1 hour)
|
||||||
|
|
||||||
|
|
||||||
|
# How long an offered address is reserved (leased) in seconds
|
||||||
|
|
||||||
|
#offer_time 60 #default: 60 (1 minute)
|
||||||
|
|
||||||
|
# If a lease to be given is below this value, the full lease time is
|
||||||
|
# instead used (seconds).
|
||||||
|
|
||||||
|
#min_lease 60 #defult: 60
|
||||||
|
|
||||||
|
|
||||||
|
# The location of the lease file
|
||||||
|
# we need no lease file as we give out always the same ip
|
||||||
|
lease_file /dev/null #defualt: /var/lib/misc/udhcpd.leases
|
||||||
|
|
||||||
|
# The location of the pid file
|
||||||
|
pidfile ${pidfile} #default: /var/run/udhcpd.pid
|
||||||
|
|
||||||
|
# Everytime udhcpd writes a leases file, the below script will be called.
|
||||||
|
# Useful for writing the lease file to flash every few hours.
|
||||||
|
|
||||||
|
#notify_file #default: (no script)
|
||||||
|
|
||||||
|
#notify_file dumpleases # <--- useful for debugging
|
||||||
|
|
||||||
|
# The following are bootp specific options, setable by udhcpd.
|
||||||
|
|
||||||
|
#siaddr 192.168.0.22 #default: 0.0.0.0
|
||||||
|
|
||||||
|
#sname zorak #default: (none)
|
||||||
|
|
||||||
|
#boot_file /var/nfs_root #default: (none)
|
||||||
|
|
||||||
|
# The remainer of options are DHCP options and can be specifed with the
|
||||||
|
# keyword opt or option. If an option can take multiple items, such
|
||||||
|
# as the dns option, they can be listed on the same line, or multiple
|
||||||
|
# lines. The only option with a default is lease.
|
||||||
|
|
||||||
|
#Examles
|
||||||
|
opt dns ${dns1} ${dns2}
|
||||||
|
option subnet 255.255.255.255
|
||||||
|
opt router ${router}
|
||||||
|
#opt wins 192.168.10.10
|
||||||
|
#option dns 44333 # appened to above DNS servers for a total of 3
|
||||||
|
#option domain fw
|
||||||
|
option lease 864000 # 10 days of seconds
|
||||||
|
|
||||||
|
|
||||||
|
# Currently supported options, for more info, see options.c
|
||||||
|
#opt subnet
|
||||||
|
#opt timezone
|
||||||
|
#opt router
|
||||||
|
#opt timesrv
|
||||||
|
#opt namesrv
|
||||||
|
#opt dns
|
||||||
|
#opt logsrv
|
||||||
|
#opt cookiesrv
|
||||||
|
#opt lprsrv
|
||||||
|
#opt bootsize
|
||||||
|
#opt domain
|
||||||
|
#opt swapsrv
|
||||||
|
#opt rootpath
|
||||||
|
#opt ipttl
|
||||||
|
#opt mtu
|
||||||
|
#opt broadcast
|
||||||
|
#opt wins
|
||||||
|
#opt lease
|
||||||
|
#opt ntpsrv
|
||||||
|
#opt tftp
|
||||||
|
#opt bootfile
|
||||||
|
#opt wpad
|
||||||
|
|
||||||
|
# Static leases map
|
||||||
|
#static_lease 00:60:08:11:CE:4E 192.168.0.54
|
||||||
|
#static_lease 00:60:08:11:CE:3E 192.168.0.44
|
||||||
|
|
||||||
Reference in New Issue
Block a user