improved install.py

install.py is now also dealing with ip addresses
This commit is contained in:
2021-03-24 16:10:46 +01:00
parent cd2cbf245d
commit 53af769c3f
6 changed files with 154 additions and 9 deletions

132
install.py Normal file → Executable file
View File

@ -1,4 +1,5 @@
"""install.py: #!/usr/bin/python3
"""install.py
copy files from to_system into system directories copy files from to_system into system directories
""" """
@ -6,11 +7,15 @@ copy files from to_system into system directories
import os import os
import filecmp import filecmp
import shutil import shutil
from glob import glob
from ipaddress import IPv4Interface
from configparser import ConfigParser
from os.path import join, getmtime, exists from os.path import join, getmtime, exists
os.chdir('to_system') os.chdir('to_system')
DEL = '__to_delete__' DEL = '__to_delete__'
CFGPATH = '/root/aputools/servercfg/%s.cfg'
def walk(action): def walk(action):
for dirpath, _, files in os.walk('.'): for dirpath, _, files in os.walk('.'):
@ -43,7 +48,10 @@ def walk(action):
action.missing(missing) action.missing(missing)
class Show: class Show:
dirty = False
def show(self, title, files): def show(self, title, files):
self.dirty = True
print('%s %s:\n %s' % (title, self.syspath, ' '.join(files))) print('%s %s:\n %s' % (title, self.syspath, ' '.join(files)))
def newer(self, files): def newer(self, files):
@ -74,7 +82,121 @@ class Do:
for file in files: for file in files:
os.remove(join(self.syspath, file)) os.remove(join(self.syspath, file))
walk(Show())
answer = input('do above?') def network(doit):
if answer.lower().startswith('y'): result = None
walk(Do()) dirty = None
with open('/sys/class/net/enp1s0/address') as f:
netaddr = f.read().strip().lower()
action = 'doit' if doit else 'check'
addrdict = {}
for cfgfile in glob(CFGPATH % '*'):
parser = ConfigParser()
try:
parser.read(cfgfile)
address = parser['NETWORK']['address'].lower()
if address in addrdict:
print(cfgfile)
print(addrdict[address])
print('ERROR: duplicate address %s in above files' % address)
result = 'failed'
addrdict[address] = cfgfile
except Exception as e:
print('ERROR: can not read %s: %r' % (cfgfile, e))
result = 'failed'
cfgfile = addrdict.get(netaddr)
if cfgfile is None:
print('can not find cfg file for %s' % netaddr)
result = 'failed'
for ntry in range(1 + bool(doit)):
with open('/etc/hostname') as f:
hostname = f.read().strip()
if CFGPATH % hostname == cfgfile:
break
if doit:
if ntry == 0:
os.system('sh sethostname.sh')
else:
print('ERROR: can not set host name')
result = 'failed'
else:
print('host name does not match')
dirty = 'dirty'
break
if result:
return False
ifname = ''
parser = ConfigParser()
try:
parser.read(CFGPATH % hostname)
network = dict(parser['NETWORK'])
address = network.pop('address', None)
main = None
for ifname, value in network.items():
try:
with open('/etc/sysconfig/network-scripts/ifcfg-%s' % ifname) as f:
original = f.read().strip().split('\n')
except FileNotFoundError:
raise ValueError('unknown interface %s' % ifname)
content = {}
for line in original:
key, _, val = line.strip().partition('=')
if val:
content[key] = val
if content['NAME'] != ifname:
print('ERROR: name %s does not match' % content['NAME'])
result = 'failed'
original = dict(content)
if value == 'dhcp':
if main:
print('ERROR: only one interface with DHCP allowed')
result = 'failed'
main = ifname
content.pop('IPADDR', None)
content['ONBOOT'] = 'yes'
content['BOOTPROTO'] = 'dhcp'
else:
interface = IPv4Interface(value)
if '/' not in value:
if interface < IPv4Interface('128.0.0.0'):
value += '/8'
elif interface < IPv4Interface('192.0.0.0'):
value += '/16'
else:
value += '/24'
interface = IPv4Interface(value)
content['IPADDR'], content['NETMASK'] = interface.with_netmask.split('/')
_, content['PREFIX'] = interface.with_prefixlen.split('/')
content['ONBOOT'] = 'yes'
content['BOOTPROTO'] = 'none'
if content != original:
if doit:
with open('/etc/sysconfig/network-scripts/ifcfg-%s' % ifname, 'w') as f:
f.write('%s\n' % '\n'.join('%s=%s' % kv for kv in content.items()))
else:
dirty = 'dirty'
print('%s changed:' % ifname)
diff = dict(content)
diff.update({k: '' for k in original if k not in diff})
print(' %s' % ', '.join('%s=%s' % (k, v) for k, v in diff.items() if v != original.get(k)))
except Exception as e:
print('ERROR: can not handle %s %s: %r' % (hostname, ifname, e))
result = 'failed'
return result or dirty
print('---')
show = Show()
walk(show)
result = network(False)
if result == 'failed':
print('fix first above errors')
elif result == 'dirty' or show.dirty:
print('---')
answer = input('do above? ')
if answer.lower().startswith('y'):
network(True)
walk(Do())
else:
print('nothing to do')

View File

@ -1,5 +1,6 @@
[NETWORK] [NETWORK]
address=00:0d:b9:59:1f:ac address=00:0d:b9:59:1f:ac
enp1s0=dhcp
enp2s0=192.168.127.2/24 enp2s0=192.168.127.2/24
enp3s0=192.168.2.3/24 enp3s0=192.168.2.3/24
enp4s0=192.168.2.4/24 enp4s0=192.168.2.4/24

View File

@ -1,7 +1,6 @@
[HOSTNAME]
apuslave1=00:0d:b9:59:20:a8
[NETWORK] [NETWORK]
address=00:0d:b9:59:20:a8
enp1s0=dhcp
enp2s0=192.168.127.2/24 enp2s0=192.168.127.2/24
enp3s0=192.168.2.3/24 enp3s0=192.168.2.3/24
enp4s0=192.168.2.4/24 enp4s0=192.168.2.4/24

11
servercfg/apuslave2.cfg Normal file
View File

@ -0,0 +1,11 @@
[NETWORK]
address=00:0d:b9:5a:58:e4
enp1s0=dhcp
enp2s0=192.168.2.2/24
enp3s0=192.168.2.3/24
enp4s0=192.168.127.4/24
[ROUTER]
3000=/dev/ttyUSB0
5900=192.168.2.33
8080=192.168.127.254:80

11
servercfg/dilsc.cfg Normal file
View File

@ -0,0 +1,11 @@
[NETWORK]
address=00:0d:b9:5a:4c:90
enp1s0=dhcp
enp2s0=192.168.2.2/24
enp3s0=192.168.2.3/24
enp4s0=192.168.127.4/24
[ROUTER]
3000=/dev/ttyUSB0
5900=192.168.2.33
8080=192.168.127.254:80

View File

@ -1,2 +1,3 @@
echo "Welcome to $HOSTNAME $(hostname -I) $(cat /sys/class/net/enp1s0/address)" echo "Welcome to $HOSTNAME $(hostname -I)"
echo "$(cat /sys/class/net/enp1s0/address)"
export EDITOR=nano export EDITOR=nano