wip temporary push
This commit is contained in:
31
display.py
31
display.py
@ -5,6 +5,10 @@ import serial
|
|||||||
import socket
|
import socket
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
|
# display tty device
|
||||||
|
tty = '/dev/ttyS1'
|
||||||
|
STARTUP_TEXT = '/root/aputools/startup_display.txt'
|
||||||
|
|
||||||
ESC = 0x1b
|
ESC = 0x1b
|
||||||
ESCESC = bytes((ESC, ESC))
|
ESCESC = bytes((ESC, ESC))
|
||||||
|
|
||||||
@ -57,8 +61,22 @@ class Display:
|
|||||||
def __init__(self, dev, timeout=0.5, daemon=False):
|
def __init__(self, dev, timeout=0.5, daemon=False):
|
||||||
self.event = threading.Event()
|
self.event = threading.Event()
|
||||||
self.term = serial.Serial(dev, baudrate=115200, timeout=timeout)
|
self.term = serial.Serial(dev, baudrate=115200, timeout=timeout)
|
||||||
if not daemon:
|
self.storage = bytearray()
|
||||||
self.storage = bytearray()
|
if daemon:
|
||||||
|
text = None
|
||||||
|
try:
|
||||||
|
with open(STARTUP_TEXT) as f:
|
||||||
|
text = f.read()
|
||||||
|
print('new startup text:')
|
||||||
|
print(text)
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
if text:
|
||||||
|
self.reset()
|
||||||
|
self.show(*todo_text.split('\n')[0:3])
|
||||||
|
self.set_startup()
|
||||||
|
else:
|
||||||
|
self.storage = None
|
||||||
self.gethost(False)
|
self.gethost(False)
|
||||||
self.reset()
|
self.reset()
|
||||||
if daemon:
|
if daemon:
|
||||||
@ -98,14 +116,6 @@ class Display:
|
|||||||
self.storage = None
|
self.storage = None
|
||||||
self.send(SET_STARTUP, data)
|
self.send(SET_STARTUP, data)
|
||||||
|
|
||||||
def standard_startup(self):
|
|
||||||
self.storage = bytearray()
|
|
||||||
self.reset()
|
|
||||||
with open('/sys/class/net/enp1s0/address') as f:
|
|
||||||
netaddr = f.read().strip().lower()
|
|
||||||
self.show('startup ...', netaddr)
|
|
||||||
self.set_startup()
|
|
||||||
|
|
||||||
def version(self):
|
def version(self):
|
||||||
self.term.write(bytes([ESC,ESC,1,0xf3]))
|
self.term.write(bytes([ESC,ESC,1,0xf3]))
|
||||||
reply = self.term.read(4)
|
reply = self.term.read(4)
|
||||||
@ -253,7 +263,6 @@ class Display:
|
|||||||
self.send(0xf0, 0xcb, 0xef, 0x20, 0x18)
|
self.send(0xf0, 0xcb, 0xef, 0x20, 0x18)
|
||||||
|
|
||||||
|
|
||||||
tty = '/dev/ttyS1'
|
|
||||||
daemon = False
|
daemon = False
|
||||||
|
|
||||||
for arg in sys.argv[1:]:
|
for arg in sys.argv[1:]:
|
||||||
|
105
install.py
105
install.py
@ -13,6 +13,7 @@ import os
|
|||||||
import filecmp
|
import filecmp
|
||||||
import shutil
|
import shutil
|
||||||
import serial
|
import serial
|
||||||
|
import types
|
||||||
from subprocess import Popen, PIPE
|
from subprocess import Popen, PIPE
|
||||||
from glob import glob
|
from glob import glob
|
||||||
from ipaddress import IPv4Interface
|
from ipaddress import IPv4Interface
|
||||||
@ -24,6 +25,7 @@ os.chdir('/root/aputools/to_system')
|
|||||||
|
|
||||||
DEL = '__to_delete__'
|
DEL = '__to_delete__'
|
||||||
CFGPATH = '/root/aputools/servercfg/%s_%6.6x.cfg'
|
CFGPATH = '/root/aputools/servercfg/%s_%6.6x.cfg'
|
||||||
|
STARTUP_TEXT = '/root/aputools/startup_display.txt'
|
||||||
|
|
||||||
COMMENT = "; please refer to README.md for help"
|
COMMENT = "; please refer to README.md for help"
|
||||||
|
|
||||||
@ -48,6 +50,9 @@ enp4s0=192.168.3.3
|
|||||||
|
|
||||||
[DISPLAY]
|
[DISPLAY]
|
||||||
{COMMENT}
|
{COMMENT}
|
||||||
|
line0=startup...
|
||||||
|
line1=HOST
|
||||||
|
line2=ADDR
|
||||||
"""
|
"""
|
||||||
|
|
||||||
DHCP_HEADER = """
|
DHCP_HEADER = """
|
||||||
@ -97,6 +102,11 @@ pip_requirements = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
net_addr = {} # dict <if name> of <ethernet address>
|
||||||
|
main_info = {} # info about WAN interface
|
||||||
|
dhcp_server_cfg = [] # configuration for dhcp
|
||||||
|
|
||||||
|
|
||||||
def frappy(cfg=None, port=None, requirements='', **kwds):
|
def frappy(cfg=None, port=None, requirements='', **kwds):
|
||||||
if not cfg:
|
if not cfg:
|
||||||
return None
|
return None
|
||||||
@ -120,7 +130,37 @@ def router(**opts):
|
|||||||
return ROUTER_TEMPLATE
|
return ROUTER_TEMPLATE
|
||||||
|
|
||||||
|
|
||||||
|
def display_update(cfg):
|
||||||
|
dirty = False
|
||||||
|
lines = []
|
||||||
|
for key in ['line0', 'line1', 'line2']:
|
||||||
|
value = cfg.get(key, '')
|
||||||
|
if value.startswith('HOST'):
|
||||||
|
line = main_info.get('hostname', '')
|
||||||
|
value = 'HOST: ' + line
|
||||||
|
elif value.startswith('ADDR'):
|
||||||
|
line = main_info.get('addr', '')
|
||||||
|
value = 'ADDR: ' + line
|
||||||
|
else:
|
||||||
|
line = value
|
||||||
|
lines.append(line)
|
||||||
|
if cfg.get(key) != value:
|
||||||
|
if doit:
|
||||||
|
cfg[key] = value
|
||||||
|
dirty = True
|
||||||
|
if dirty:
|
||||||
|
text = '\n'.join(lines)
|
||||||
|
if doit:
|
||||||
|
with open(STARTUP_TEXT, 'w') as f:
|
||||||
|
f.write(text)
|
||||||
|
else:
|
||||||
|
print('new startup text:')
|
||||||
|
print('\n'.join(lines))
|
||||||
|
|
||||||
|
|
||||||
def display(**opts):
|
def display(**opts):
|
||||||
|
if not opts:
|
||||||
|
return None
|
||||||
return DISPLAY_TEMPLATE
|
return DISPLAY_TEMPLATE
|
||||||
|
|
||||||
|
|
||||||
@ -215,7 +255,7 @@ def write_when_new(filename, content, ignore_reduction=False):
|
|||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
def create_if(name, cfg, mac, dhcp_server_cfg):
|
def create_if(name, cfg):
|
||||||
result = dict(
|
result = dict(
|
||||||
TYPE='Ethernet',
|
TYPE='Ethernet',
|
||||||
NAME=name,
|
NAME=name,
|
||||||
@ -229,6 +269,10 @@ def create_if(name, cfg, mac, dhcp_server_cfg):
|
|||||||
if cfg == 'off':
|
if cfg == 'off':
|
||||||
result['ONBOOT'] = 'no'
|
result['ONBOOT'] = 'no'
|
||||||
elif cfg.startswith('wan') or cfg == 'dhcp':
|
elif cfg.startswith('wan') or cfg == 'dhcp':
|
||||||
|
if main_info.get('mainif', name) != name:
|
||||||
|
raise ValueError('can not have more than one WAN/DHCP port')
|
||||||
|
main_info['mainif'] = name
|
||||||
|
main_info['addr'] = net_addr[name]
|
||||||
result['BOOTPROTO'] = 'dhcp'
|
result['BOOTPROTO'] = 'dhcp'
|
||||||
# default: all <= 192.0.0.0
|
# default: all <= 192.0.0.0
|
||||||
# others have to be added explicitly
|
# others have to be added explicitly
|
||||||
@ -337,68 +381,72 @@ class Do:
|
|||||||
os.remove(join(self.syspath, file))
|
os.remove(join(self.syspath, file))
|
||||||
|
|
||||||
|
|
||||||
netaddr_dict = {}
|
|
||||||
for netif in os.scandir('/sys/class/net'):
|
for netif in os.scandir('/sys/class/net'):
|
||||||
if netif.name != 'lo': # do not consider loopback interface
|
if netif.name != 'lo': # do not consider loopback interface
|
||||||
with open(os.path.join(netif.path, 'address')) as f:
|
with open(os.path.join(netif.path, 'address')) as f:
|
||||||
netaddr_dict[netif.name] = netaddr = f.read().strip().lower()
|
addr = f.read().strip().lower()
|
||||||
|
net_addr[netif.name] = addr
|
||||||
|
|
||||||
|
sorted_if = sorted(net_addr)
|
||||||
|
|
||||||
|
apuid = int(''.join(net_addr[sorted_if[0]].split(':')[-3:]), 16) & 0xffffff
|
||||||
|
|
||||||
|
|
||||||
def handle_config():
|
def handle_config():
|
||||||
cfgfile = None
|
cfgfile = None
|
||||||
cfgfiles = []
|
cfgfiles = []
|
||||||
shortids = {}
|
for file in glob(CFGPATH % ('*', apuid)):
|
||||||
for netif, addr in netaddr_dict.items():
|
cfgfiles.append(file)
|
||||||
shortid = int(''.join(addr.split(':')[-3:]), 16) & 0xffffff
|
|
||||||
cfgfiles += glob(CFGPATH % ('*', shortid))
|
|
||||||
shortids[netif] = shortid
|
|
||||||
with open('/etc/hostname') as f:
|
with open('/etc/hostname') as f:
|
||||||
hostname = f.read().strip()
|
hostname = f.read().strip()
|
||||||
|
newhostname = hostname
|
||||||
if not cfgfiles:
|
if not cfgfiles:
|
||||||
disp = serial.Serial('/dev/ttyS1', baudrate=115200, timeout=1)
|
disp = serial.Serial('/dev/ttyS1', baudrate=115200, timeout=1)
|
||||||
disp.write(b'\x1b\x1b\x01\xf3')
|
disp.write(b'\x1b\x1b\x01\xf3')
|
||||||
display_available = disp.read(8)[0:4] == b'\x1b\x1b\x05\xf3'
|
display_available = disp.read(8)[0:4] == b'\x1b\x1b\x05\xf3'
|
||||||
ids = sorted(shortids)
|
|
||||||
if display_available:
|
if display_available:
|
||||||
# leftmost interface labelled 'eth0'
|
# leftmost interface labelled 'eth0'
|
||||||
apuid = shortids[ids[0]]
|
wan_if = sorted_if[0]
|
||||||
typ = 'controlbox'
|
typ = 'controlbox'
|
||||||
template = CONTROLBOX_TEMPLATE
|
template = CONTROLBOX_TEMPLATE
|
||||||
else:
|
else:
|
||||||
# rightmost interface
|
# rightmost interface
|
||||||
apuid = shortid[idx[-1]]
|
wan_id = sorted_if[-1]
|
||||||
typ = 'bare apu'
|
typ = 'bare apu'
|
||||||
template = CONFIG_TEMPLATE
|
template = CONFIG_TEMPLATE
|
||||||
print('no cfg file found for this', typ, f'with id {apuid:%6.6x} (hostname={hostname})')
|
print('no cfg file found for this', typ, f'with id {apuid:%6.6x} (hostname={hostname})')
|
||||||
newname = input('enter host name: ')
|
newhostname = input('enter host name: ')
|
||||||
if not newname:
|
if not newhostname:
|
||||||
print('no hostname given')
|
print('no hostname given')
|
||||||
return False
|
return False
|
||||||
cfgfile = CFGPATH % (newname, apuid)
|
cfgfile = CFGPATH % (newhostname, apuid)
|
||||||
with open(cfgfile, 'w') as f:
|
with open(cfgfile, 'w') as f:
|
||||||
f.write(template)
|
f.write(template)
|
||||||
elif len(cfgfiles) > 1:
|
elif len(cfgfiles) > 1:
|
||||||
print('ERROR: ambiguous cfg files: %s' % ', '.join(cfgfiles))
|
print('ERROR: ambiguous cfg files: %s' % ', '.join(cfgfiles))
|
||||||
else:
|
else:
|
||||||
cfgfile = cfgfiles[0]
|
cfgfile = cfgfiles[0]
|
||||||
apuid = int(cfgfile.split('_')[-1].split('.')[0], 16)
|
wan_if = None
|
||||||
if cfgfile != CFGPATH % (hostname, apuid):
|
if cfgfile != CFGPATH % (hostname, apuid):
|
||||||
|
if cfgfile:
|
||||||
|
newhostname = basename(cfgfile).rpartition('_')[0]
|
||||||
if doit:
|
if doit:
|
||||||
os.system('sh ../sethostname.sh')
|
os.system('sh sethostname.sh')
|
||||||
else:
|
else:
|
||||||
if cfgfile:
|
if cfgfile:
|
||||||
print('replace host name %r by %r' % (hostname, basename(cfgfile).rpartition('_')[0]))
|
print('replace host name %r by %r' % (hostname, newhostname))
|
||||||
show.dirty = True
|
show.dirty = True
|
||||||
|
main_info['hostname'] = newhostname
|
||||||
if cfgfile is None:
|
if cfgfile is None:
|
||||||
return False
|
return False
|
||||||
to_start = {}
|
to_start = {}
|
||||||
ifname = ''
|
ifname = ''
|
||||||
parser = ConfigParser()
|
parser = ConfigParser()
|
||||||
dhcp_server_cfg = []
|
|
||||||
try:
|
try:
|
||||||
parser.read(cfgfile)
|
parser.read(cfgfile)
|
||||||
network = dict(parser['NETWORK'])
|
network = dict(parser['NETWORK'])
|
||||||
for ifname, addr in netaddr_dict.items():
|
for ifname in net_addr:
|
||||||
content = create_if(ifname, network.pop(ifname, 'off'), addr, dhcp_server_cfg)
|
content = create_if(ifname, network.pop(ifname, 'off'))
|
||||||
content = '\n'.join('%s=%s' % kv for kv in content.items())
|
content = '\n'.join('%s=%s' % kv for kv in content.items())
|
||||||
todo = write_when_new('/etc/sysconfig/network-scripts/ifcfg-%s' % ifname, content)
|
todo = write_when_new('/etc/sysconfig/network-scripts/ifcfg-%s' % ifname, content)
|
||||||
if todo and more_info == 'NONE':
|
if todo and more_info == 'NONE':
|
||||||
@ -434,7 +482,10 @@ def handle_config():
|
|||||||
dirty = True
|
dirty = True
|
||||||
content.append('[%s]' % section)
|
content.append('[%s]' % section)
|
||||||
content.append(COMMENT)
|
content.append(COMMENT)
|
||||||
for key, value in parser[section].items():
|
section_dict = dict(parser[section].items())
|
||||||
|
if section == 'DISPLAY':
|
||||||
|
display_update(section_dict)
|
||||||
|
for key, value in section_dict.items():
|
||||||
content.append('%s=%s' % (key, value))
|
content.append('%s=%s' % (key, value))
|
||||||
content.append('')
|
content.append('')
|
||||||
if dirty:
|
if dirty:
|
||||||
@ -446,12 +497,12 @@ def handle_config():
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
reload_systemd = False
|
reload_systemd = False
|
||||||
for service, template_func in SERVICES.items():
|
for service, service_func in SERVICES.items():
|
||||||
section = service.upper()
|
section = service.upper()
|
||||||
if parser.has_section(section):
|
if parser.has_section(section):
|
||||||
template = template_func(**dict(parser[section]))
|
servicecfg = service_func(**dict(parser[section]))
|
||||||
else:
|
else:
|
||||||
template = None
|
servicecfg = None
|
||||||
result = unix_cmd('systemctl show -p WantedBy -p ActiveState %s' % service, True)
|
result = unix_cmd('systemctl show -p WantedBy -p ActiveState %s' % service, True)
|
||||||
active = False
|
active = False
|
||||||
enabled = False
|
enabled = False
|
||||||
@ -460,7 +511,7 @@ def handle_config():
|
|||||||
enabled = True
|
enabled = True
|
||||||
elif line.strip() == 'ActiveState=active':
|
elif line.strip() == 'ActiveState=active':
|
||||||
active = True
|
active = True
|
||||||
if template is None:
|
if servicecfg is None:
|
||||||
if active:
|
if active:
|
||||||
unix_cmd('systemctl stop %s' % service)
|
unix_cmd('systemctl stop %s' % service)
|
||||||
show.dirty = True
|
show.dirty = True
|
||||||
@ -472,10 +523,10 @@ def handle_config():
|
|||||||
to_start[service] = 'enable'
|
to_start[service] = 'enable'
|
||||||
elif not active:
|
elif not active:
|
||||||
to_start[service] = 'restart'
|
to_start[service] = 'restart'
|
||||||
if write_when_new('/etc/systemd/system/%s.service' % service, template):
|
if write_when_new('/etc/systemd/system/%s.service' % service, servicecfg):
|
||||||
show.dirty = True
|
show.dirty = True
|
||||||
reload_systemd = True
|
reload_systemd = True
|
||||||
if template and to_start.get('service') is None:
|
if servicecfg and to_start.get('service') is None:
|
||||||
to_start[service] = 'restart'
|
to_start[service] = 'restart'
|
||||||
|
|
||||||
pip()
|
pip()
|
||||||
|
@ -7,3 +7,6 @@ enp4s0=192.168.3.3
|
|||||||
|
|
||||||
[DISPLAY]
|
[DISPLAY]
|
||||||
; please refer to README.md for help
|
; please refer to README.md for help
|
||||||
|
line0=startup...
|
||||||
|
line1=HOST: linse-box1
|
||||||
|
line2=ADDR: 00:0d:b9:5b:26:5c
|
||||||
|
Reference in New Issue
Block a user