Files
boxtools/install.py
LIN SE 147bd4efa5 do not set UUID
+ other fixes
2021-04-27 14:10:39 +02:00

204 lines
6.0 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, basename
os.chdir('/root/aputools/to_system')
DEL = '__to_delete__'
CFGPATH = '/root/aputools/servercfg/%s.cfg'
def write_when_new(filename, content, doit):
if not content.endswith('\n'):
content += '\n'
with open(filename) as fil:
old = fil.read()
if old == content:
return False
if doit:
with open(filename, 'w') as fil:
fil.write(content)
return True
def create_if(name, cfg, mac):
result = dict(
TYPE='Ethernet',
NAME=name,
DEVICE=name,
BOOTPROTO='none',
ONBOOT='yes',
PROXY_METHOD='none',
BROWSER_ONLY='no',
IPV4_FAILURE_FATAL='yes',
IPV6INIT='no')
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):
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]]
apuid = int(''.join(netaddr.split(':')[-3:]), 16) & 0xfffffc
cfgfile = None
cfgfiles = []
for i in range(4):
# goodie: look for mac addresses of all 4 ports
cfgfiles += glob(CFGPATH % ('*_%6.6x' % (apuid + i)))
if not cfgfiles:
print('no cfg file found for %s' % netaddr)
elif len(cfgfiles) > 1:
print('ERROR: ambiguous cfg files: %s' % ', '.join(cfgfiles))
else:
cfgfile = cfgfiles[0]
for ntry in range(1 + bool(doit)):
with open('/etc/hostname') as f:
hostname = f.read().strip()
if cfgfile == CFGPATH % ('%s_%6.6x' % (hostname, apuid)):
break
if doit:
if ntry == 0:
os.system('sh sethostname.sh')
else:
print('ERROR: can not set host name')
return False
else:
if cfgfile:
print('host name does not match %r -> %r' % (hostname, basename(cfgfile).rpartition('_')[0]))
show.dirty = True
break
if cfgfile is None:
return False
ifname = ''
parser = ConfigParser()
try:
parser.read(cfgfile)
network = dict(parser['NETWORK'])
for ifname in IFNAMES:
content = create_if(ifname, network.get(ifname, 'off'), netaddr_dict[ifname])
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
except Exception as e:
print('ERROR: can not handle %s %s: %r' % (hostname, ifname, e))
return False
return True
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')