better documentation

This commit is contained in:
2021-12-01 18:15:55 +01:00
parent 4ce7c3a9d3
commit f8168b0865
3 changed files with 97 additions and 59 deletions

View File

@ -2,6 +2,44 @@
The APU is a Linux box to be used as a control box at LIN sample environment
servercfg/(hostname).cfg contain the configuration for all boxes
servercfg/ contains the configuration files for all boxes
to_system/ contains the files to be installed in the system
## config files
filename: servercfg/(hostname)_(hexdigits).cfg
* (hostname) the hostname to be given on startup
* (hexdigits) the last six digits of one of the ethernet adresses of the interfaces on the APU
content of the config files:
[NETWORK]
```
# leftmost socket next to the console:
enp1s0=wan # the uplink, DHCP enabled, in netwoork n.x.y.z for 0 <= n < 192
enp1s0=wan,192.168.1.0/24 # the uplink, DHCP enabled, may be in addition in local network 192.168.1.x
# several networks might be specified, with comma separation
# must not contain addresses defined on other interfaces!
enp2s0=192.168.3.5 # the ip address of the device to be connected (DHCP or static),
# must be odd (the value one lower is used for the APU address in this interface)
enp3s0=off # disabled
enp4s0=192.168.3.1/24 # our ip address, the static address of the connected device must
# be within 1-254 and not match our own
# rightmost socket, next to the usb plugs
[ROUTER]
3000=/dev/ttyUSB0 # routing 3000 to the internal serial port /dev/ttyUSB0
5900=192.168.2.33 # routing VNC (local port 5900 to port 5900 on 192.168.2.33
8080=192.168.127.254:80 # routing 8080 to port 80 of 192.168.127.254
[FRAPPY]
cfg=uniax # the cfg file for the frappy server
port=5000 # the port for the frappy server
```
to_system contains the files to be installed in the system

View File

@ -5,9 +5,12 @@
- set host name / network settings from aputools/servercfg file
"""
if bytes == str:
raise NotImplementedError('python2 not supported')
import os
import filecmp
import shutil
import time
from glob import glob
from ipaddress import IPv4Interface
from configparser import ConfigParser
@ -17,15 +20,20 @@ os.chdir('/root/aputools/to_system')
DEL = '__to_delete__'
CFGPATH = '/root/aputools/servercfg/%s_%6.6x.cfg'
COMMENT = "; please refer to README.md for help"
TEMPLATE_CFG = """[NETWORK]
%s
enp1s0=192.168.127.1/24
enp2s0=192.168.2.1/24
enp3s0=192.168.3.1/24
enp4s0=dhcp
[ROUTER]
%s
3001=192.168.127.254:3001
"""
""" % (COMMENT, COMMENT)
DHCP_HEADER = """
default-lease-time 600;
@ -33,14 +41,6 @@ max-lease-time 7200;
authoritative;
"""
DHCP_ITEM = """
subnet %s netmask %s {
option routers %s;
option subnet-mask %s;
range %s %s;
}
"""
def write_when_new(filename, content, doit):
if not content.endswith('\n'):
content += '\n'
@ -60,7 +60,7 @@ def write_when_new(filename, content, doit):
return True
def create_if(name, cfg, mac):
def create_if(name, cfg, mac, dhcp_server_cfg):
result = dict(
TYPE='Ethernet',
NAME=name,
@ -73,47 +73,28 @@ def create_if(name, cfg, mac):
IPV6INIT='no')
if cfg == 'off':
result['ONBOOT']='no'
elif cfg == 'dhcp':
elif cfg.startswith('wan') or cfg == 'dhcp':
result['BOOTPROTO']='dhcp'
# default: all <= 192.0.0.0
# others have to be added explicitly
dhcp_server_cfg.append((('0.0.0.0','128.0.0.0'), []))
dhcp_server_cfg.append((('128.0.0.0','192.0.0.0'), []))
for nw in cfg.split(',')[1:]:
nw = IPv4Interface(cfg).network
dhcp_server_cfg.append((nw.with_netmask.split('/'), []))
else:
error = None
cfgdict = {'own': cfg, 'prefix': '', 'other': ''}
if ':' in cfg:
for cfgitem in cfg.split(','):
k, _, v = cfgitem.partition(':')
k = k.strip()
if k not in cfgdict:
error = 'bad formed'
cfgdict[k] = v.strip()
ownip, _, prefix = cfgdict['own'].partition('/')
prefix = cfgdict['prefix'] or prefix
if prefix:
try:
prefix = int(prefix)
if not 16 <= prefix < 32:
error = 'illegal prefix in'
except ValueError:
error = 'illegal prefix in'
if error:
print('Allowed forms:\n')
print('%s=n.n.n.n/24' % name)
print('%s=prefix:24,own:n.n.n.n,other:m.m.m.m\n' % name)
raise ValueError('%s network config: %s=%s' % (error, name, cfg))
if not prefix:
interface = IPv4Interface(ownip)
if interface < IPv4Interface('128.0.0.0'):
prefix = 8
elif interface < IPv4Interface('192.0.0.0'):
prefix = 16
else:
prefix = 24
interface = IPv4Interface('%s/%d' % (ownip, prefix))
result['IPADDR'], result['NETMASK'] = interface.with_netmask.split('/')
_, result['PREFIX'] = interface.with_prefixlen.split('/')
other = cfgdict['other']
if other:
adrs = cfgdict['other'].split('-')
result['dhcprange'] = (adrs[0], adrs[-1])
cfgip = IPv4Interface(cfg)
network = cfgip.network
if network.prefixlen == 32:
otherip = IPv4Interface('%s/31' % cfgip.ip)
network = otherip.network
cfgip = network.network_address + (1 - int(otherip) % 2)
dhcp_server_cfg.append((network.with_netmask, [(str(otherip.ip), str(otherip.ip))]))
result['IPADDR'] = str(cfgip)
else: # subnet with multiple adresses -> static adresses only. dhcp range not yet implemented
result['IPADDR'] = str(cfgip.ip)
result['NETMASK'] = network.netmask
result['PREFIX'] = str(network.prefixlen)
return result
@ -230,23 +211,40 @@ def network(doit):
try:
parser.read(cfgfile)
network = dict(parser['NETWORK'])
dhcp_server_cfg = []
for ifname in IFNAMES:
content = create_if(ifname, network.get(ifname, 'off'), netaddr_dict[ifname])
dhcprange = content.pop('dhcprange', None)
if dhcprange:
ip_mask = content['IPADDR'], content['NETMASK']
dh.append(ip_mask + ip_mask + dhcprange)
content = create_if(ifname, network.pop(ifname, 'off'), netaddr_dict[ifname], dhcp_server_cfg)
content = '\n'.join('%s=%s' % kv for kv in content.items())
todo = write_when_new('/etc/sysconfig/network-scripts/ifcfg-%s' % ifname, content, doit)
if todo:
print('change ', ifname)
show.dirty = True
if dh:
content = DHCP_HEADER + '\n'.join([DHCP_ITEM % d for d in dh])
content = [DHCP_HEADER]
for subnet, rangelist in dhcp_server_cfg:
dh.append('subnet %s netmask %s {\n' % subnet)
dh.append(' option netmask %s;\n' % subnet[1])
for rng in rangelist:
dh.append(' range %s %s;\n' % rng)
dh.append('}\n')
content = ''.join(content)
todo = write_when_new('/etc/dhcp/dhcpd.conf', content, doit)
if todo:
print('change ', ifname)
show.dirty = True
content = []
dirty = False
for section in parser.sections():
if COMMENT not in parser[section]:
dirty = True
content.append('[%s]' % section)
content.append(COMMENT)
for key, value in parser[section].items():
content.append('%s=%s' % (key, value))
content.append('')
if dirty:
with open(cfgfile, 'w') as f:
f.write('\n'.join(content))
except Exception as e:
print('ERROR: can not handle %s %s: %r' % (hostname, ifname, e))
raise

View File

@ -1,10 +1,12 @@
[NETWORK]
; please refer to README.md for help
enp1s0=dhcp
enp2s0=own:192.168.2.2,prefix:24,other:192.168.2.15
enp3s0=192.168.2.3/24
enp2s0=192.168.2.15
enp3s0=192.168.3.3/24
enp4s0=192.168.127.4/24
[ROUTER]
; please refer to README.md for help
3000=/dev/ttyUSB0
5900=192.168.2.33
8080=192.168.127.254:80