Files
boxtools/install.py
LIN SE 2fadf63da8 ifcfg scripts are now created from scratch
- ifcfg script do not contain UUID any more
2021-04-08 07:02:57 +02:00

184 lines
5.7 KiB
Python
Executable File

#!/usr/bin/python3
"""install.py
copy files from to_system into system directories
"""
import os
import filecmp
import shutil
from glob import glob
from ipaddress import IPv4Interface
from configparser import ConfigParser
from os.path import join, getmtime, exists
os.chdir('to_system')
DEL = '__to_delete__'
CFGPATH = '/root/aputools/servercfg/%s.cfg'
def create_if(name, mac, cfg):
result=dict(TYPE='Ethernet', NAME=name, DEVICE=name,
BOOTPROTO='none', ONBOOT='yes')
if cfg == 'off':
result['ONBOOT']='no'
elif cfg == 'dhcp':
result['BOOTPROTO']='dhcp'
else:
interface = IPv4Interface(cfg)
if '/' not in cfg:
if interface < IPv4Interface('128.0.0.0'):
cfg += '/8'
elif interface < IPv4Interface('192.0.0.0'):
cfg += '/16'
else:
cfg += '/24'
interface = IPv4Interface(cfg)
result['IPADDR'], result['NETMASK'] = interface.with_netmask.split('/')
_, result['PREFIX'] = interface.with_prefixlen.split('/')
return result
def walk(action):
for dirpath, _, files in os.walk('.'):
syspath = dirpath[1:] # remove leading '.'
action.dirpath = dirpath
action.syspath = syspath
if files:
match, mismatch, missing = filecmp.cmpfiles(dirpath, syspath, files)
if mismatch:
newer = [f for f in mismatch if getmtime(join(syspath, f)) > getmtime(join(dirpath, f))]
if newer:
action.newer(newer)
if len(newer) < len(mismatch):
newer = set(newer)
action.older([f for f in mismatch if f not in newer])
if missing:
if DEL in missing:
missing.remove(DEL)
with open(join(dirpath, DEL)) as fil:
to_delete = []
for f in fil:
f = f.strip()
if f and exists(join(syspath, f)):
if exists(join(dirpath, f)):
print('ERROR: %s in %s, but also in repo -> ignored' % (f, DEL))
else:
to_delete.append(f)
action.delete(to_delete)
if missing:
action.missing(missing)
class Show:
dirty = False
def show(self, title, files):
self.dirty = True
print('%s %s:\n %s' % (title, self.syspath, ' '.join(files)))
def newer(self, files):
self.show('get from', files)
def older(self, files):
self.show('replace in', files)
def missing(self, files):
self.show('install in', files)
def delete(self, files):
self.show('remove from', files)
class Do:
def newer(self, files):
for file in files:
shutil.copy(join(self.syspath, file), join(self.dirpath, file))
def older(self, files):
for file in files:
shutil.copy(join(self.dirpath, file), join(self.syspath, file))
def missing(self, files):
self.older(files)
def delete(self, files):
for file in files:
os.remove(join(self.syspath, file))
IFNAMES = ['enp%ds0' % i for i in range(1,5)]
def network(doit):
result = True
netaddr_dict = {}
for ifname in IFNAMES:
with open('/sys/class/net/%s/address' % ifname) as f:
netaddr_dict[ifname] = f.read().strip().lower()
netaddr = netaddr_dict[IFNAMES[0]]
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)
addrdict[address] = cfgfile
except Exception as e:
print('ERROR: can not read %s: %r' % (cfgfile, e))
result = False
cfgfile = addrdict.get(netaddr)
if cfgfile is None:
print('can not find cfg file for %s' % netaddr)
result = False
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 = False
else:
print('host name does not match')
break
if not result:
return False
ifname = ''
parser = ConfigParser()
try:
parser.read(CFGPATH % hostname)
network = dict(parser['NETWORK'])
address = network.pop('address', None)
main = None
for ifname in IFNAMES:
content = create_if(ifname, netaddr_dict[ifname],
network.get(ifname, 'off'))
with open('etc/sysconfig/network-scripts/ifcfg-%s' % ifname, 'w') as f:
f.write('\n'.join('%s=%s' % kv for kv in content.items())+ '\n')
except Exception as e:
print('ERROR: can not handle %s %s: %r' % (hostname, ifname, e))
result = False
return result
print('---')
show = Show()
result = network(False)
walk(show)
if not result:
print('fix first above errors')
elif show.dirty:
print('---')
answer = input('do above? ')
if answer.lower().startswith('y'):
network(True)
walk(Do())
else:
print('nothing to do')