dspawn/dspawn/netconf.py

107 lines
2.6 KiB
Python

#!/usr/bin/env python
import os
nameserver = '9.9.9.9'
modes = {'zone': '[Network]\nZone=Containers',
'bridge': '[Network]\nBridge=br0',
'private': ''}
nettpl_bridge = '''[Match]
Name=host0
[Network]
Address=%s/24
Gateway=%s
DNS=%s'''
nettpl_bridge_mac = '''[Match]
Name=host0
[Network]
Address=%s/32
Gateway=%s
DNS=%s
[Link]
MACAddress=%s
[Route]
Destination=0.0.0.0/0
'''
nettpl = '''[Match]
Virtualization=container
Name=host0
[Network]
Address=%s
Gateway=%s
'''
private_off = '''
[Exec]
PrivateUsers=no'''
bind_mount = '''
[Files]
Bind=%s
'''
def get_default_gateway(macaddress):
import socket
import struct
"""Read the default gateway directly from /proc."""
with open("/proc/net/route") as fh:
for line in fh:
fields = line.strip().split()
if fields[1] != '00000000' or not int(fields[3], 16) & 2:
continue
return socket.inet_ntoa(struct.pack("<L", int(fields[2], 16)))
class MachineConfig:
def __init__(self, machine):
self.machine = machine
self.mode = self.machine.mode
self.address = self.machine.address
self.macaddress = self.machine.macaddress
def realize(self):
with open(self.machine.config_file, 'w') as cf:
cf.write(modes[self.mode])
if self.address:
self.netconf()
self.resolvconf()
if self.machine.privateoff:
with open(self.machine.config_file, 'a') as cf:
cf.write(private_off)
if self.machine.bind:
p = self.machine.bind
if not os.path.isdir(p):
os.makedirs(p)
with open(self.machine.config_file, 'a') as cf:
cf.write(bind_mount % self.machine.bind)
def netconf(self):
cf = os.path.join(
self.machine.path, 'etc/systemd/network/80-container-host0.network')
with open(cf, 'w') as fh:
if self.mode == 'bridge' and self.macaddress:
gw = get_default_gateway(self.macaddress)
fh.write(nettpl_bridge_mac % (self.address, gw, nameserver,
self.macaddress))
elif self.mode == 'bridge' and not self.macaddress:
gw = get_default_gateway(self.macaddress)
fh.write(nettpl_bridge % (self.address, gw, nameserver))
else:
gw = '10.0.0.1'
fh.write(nettpl % (self.address, gw))
def resolvconf(self):
rc = os.path.join(self.machine.path, 'etc/resolv.conf')
with open(rc, 'w') as rch:
rch.write("nameserver %s" % nameserver)