include creating of frappy and router service
enhance install.py
This commit is contained in:
173
install.py
173
install.py
@ -7,15 +7,18 @@
|
|||||||
|
|
||||||
if bytes == str:
|
if bytes == str:
|
||||||
raise NotImplementedError('python2 not supported')
|
raise NotImplementedError('python2 not supported')
|
||||||
|
import sys
|
||||||
import os
|
import os
|
||||||
import filecmp
|
import filecmp
|
||||||
import shutil
|
import shutil
|
||||||
import time
|
import time
|
||||||
|
from subprocess import Popen, PIPE
|
||||||
from glob import glob
|
from glob import glob
|
||||||
from ipaddress import IPv4Interface
|
from ipaddress import IPv4Interface
|
||||||
from configparser import ConfigParser
|
from configparser import ConfigParser
|
||||||
from os.path import join, getmtime, exists, basename
|
from os.path import join, getmtime, exists, basename
|
||||||
|
|
||||||
|
more_info = sys.argv[1] if len(sys.argv) > 1 else 'NONE'
|
||||||
os.chdir('/root/aputools/to_system')
|
os.chdir('/root/aputools/to_system')
|
||||||
|
|
||||||
DEL = '__to_delete__'
|
DEL = '__to_delete__'
|
||||||
@ -23,7 +26,7 @@ CFGPATH = '/root/aputools/servercfg/%s_%6.6x.cfg'
|
|||||||
|
|
||||||
COMMENT = "; please refer to README.md for help"
|
COMMENT = "; please refer to README.md for help"
|
||||||
|
|
||||||
TEMPLATE_CFG = """[NETWORK]
|
CONFIG_TEMPLATE = """[NETWORK]
|
||||||
%s
|
%s
|
||||||
enp1s0=192.168.127.1/24
|
enp1s0=192.168.127.1/24
|
||||||
enp2s0=192.168.2.1/24
|
enp2s0=192.168.2.1/24
|
||||||
@ -41,22 +44,100 @@ max-lease-time 7200;
|
|||||||
authoritative;
|
authoritative;
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def write_when_new(filename, content, doit):
|
ROUTER_TEMPLATE = """[Unit]
|
||||||
|
Description = Routing to locally connected hardware
|
||||||
|
After = network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart = /usr/bin/python3 /root/aputools/router.py
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy = multi-user.target
|
||||||
|
"""
|
||||||
|
|
||||||
|
FRAPPY_TEMPLATE = """[Unit]
|
||||||
|
Description = Running frappy server
|
||||||
|
After = network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User = l_samenv
|
||||||
|
ExecStart = /usr/bin/python3 /home/l_samenv/frappy/bin/secop-server %s
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy = multi-user.target
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def frappy(cfg=None, port=None, **kwds):
|
||||||
|
if not cfg:
|
||||||
|
return None
|
||||||
|
if port:
|
||||||
|
cfg = '-p %s %s' % (port, cfg)
|
||||||
|
return FRAPPY_TEMPLATE % cfg
|
||||||
|
|
||||||
|
|
||||||
|
def router(**opts):
|
||||||
|
if not opts:
|
||||||
|
return None
|
||||||
|
return ROUTER_TEMPLATE
|
||||||
|
|
||||||
|
|
||||||
|
SERVICES = dict(router=router, frappy=frappy)
|
||||||
|
|
||||||
|
|
||||||
|
def unix_cmd(command, always=False):
|
||||||
|
if doit or always:
|
||||||
|
if not always:
|
||||||
|
print('$ %s' % command)
|
||||||
|
return Popen(command.split(), stdout=PIPE).communicate()[0].decode()
|
||||||
|
else:
|
||||||
|
print('> %s' % command)
|
||||||
|
|
||||||
|
|
||||||
|
def write_when_new(filename, content):
|
||||||
|
if content is None:
|
||||||
|
lines = []
|
||||||
|
else:
|
||||||
if not content.endswith('\n'):
|
if not content.endswith('\n'):
|
||||||
content += '\n'
|
content += '\n'
|
||||||
|
lines = content.split('\n')
|
||||||
|
try:
|
||||||
with open(filename) as fil:
|
with open(filename) as fil:
|
||||||
old = fil.read()
|
old = fil.read()
|
||||||
|
except FileNotFoundError:
|
||||||
|
old = None
|
||||||
if old == content:
|
if old == content:
|
||||||
return False
|
return False
|
||||||
if doit:
|
if doit:
|
||||||
|
if lines:
|
||||||
with open(filename, 'w') as fil:
|
with open(filename, 'w') as fil:
|
||||||
fil.write(content)
|
fil.write(content)
|
||||||
else:
|
else:
|
||||||
print('===')
|
os.remove(filename)
|
||||||
print(old)
|
elif filename.endswith(more_info):
|
||||||
|
print('changes in', filename)
|
||||||
|
old = [] if old is None else old.split('\n')
|
||||||
|
top_lines = 0 # in case of empty loop
|
||||||
|
for top_lines, (ol, ll) in enumerate(zip(old, lines)):
|
||||||
|
if ol != ll:
|
||||||
|
break
|
||||||
|
bottom_lines = 0
|
||||||
|
for bottom_lines, (ol, ll) in enumerate(zip(reversed(old[top_lines:]), reversed(lines[top_lines:]))):
|
||||||
|
if ol != ll:
|
||||||
|
break
|
||||||
|
if bottom_lines == 0:
|
||||||
|
old.append('')
|
||||||
|
lines.append('')
|
||||||
|
bottom_lines += 1
|
||||||
|
print("===")
|
||||||
|
print('\n'.join(old[:top_lines]))
|
||||||
|
print('<<<')
|
||||||
|
print('\n'.join(old[top_lines:-bottom_lines]))
|
||||||
print('---')
|
print('---')
|
||||||
print(content)
|
print('\n'.join(lines[top_lines:-bottom_lines]))
|
||||||
print('===')
|
print('>>>')
|
||||||
|
print('\n'.join(old[-bottom_lines:-1]))
|
||||||
|
print("===")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@ -132,9 +213,22 @@ def walk(action):
|
|||||||
class Show:
|
class Show:
|
||||||
dirty = False
|
dirty = False
|
||||||
|
|
||||||
def show(self, title, files):
|
def diff(self, title, files):
|
||||||
self.dirty = True
|
self.dirty = True
|
||||||
|
if more_info == 'NONE':
|
||||||
print('%s %s:\n %s' % (title, self.syspath, ' '.join(files)))
|
print('%s %s:\n %s' % (title, self.syspath, ' '.join(files)))
|
||||||
|
else:
|
||||||
|
for f in files:
|
||||||
|
if f.endswith(MORE_INFO):
|
||||||
|
print('diff %s %s' % (join(self.dirpath, f), join(self.syspath, f)))
|
||||||
|
|
||||||
|
def show(self, title, dirpath, files):
|
||||||
|
if more_info == 'NONE':
|
||||||
|
print('%s %s:\n %s' % (title, self.syspath, ' '.join(files)))
|
||||||
|
else:
|
||||||
|
for f in files:
|
||||||
|
if f.endswith(MORE_INFO):
|
||||||
|
print('cat %s' % join(dirpath, f))
|
||||||
|
|
||||||
def newer(self, files):
|
def newer(self, files):
|
||||||
self.show('get from', files)
|
self.show('get from', files)
|
||||||
@ -143,10 +237,10 @@ class Show:
|
|||||||
self.show('replace in', files)
|
self.show('replace in', files)
|
||||||
|
|
||||||
def missing(self, files):
|
def missing(self, files):
|
||||||
self.show('install in', files)
|
self.show('install in', self.dirpath, files)
|
||||||
|
|
||||||
def delete(self, files):
|
def delete(self, files):
|
||||||
self.show('remove from', files)
|
self.show('remove from', self.syspath, files)
|
||||||
|
|
||||||
|
|
||||||
class Do:
|
class Do:
|
||||||
@ -169,7 +263,7 @@ class Do:
|
|||||||
IFNAMES = ['enp%ds0' % i for i in range(1,5)]
|
IFNAMES = ['enp%ds0' % i for i in range(1,5)]
|
||||||
|
|
||||||
|
|
||||||
def network(doit):
|
def handle_config():
|
||||||
netaddr_dict = {}
|
netaddr_dict = {}
|
||||||
for ifname in IFNAMES:
|
for ifname in IFNAMES:
|
||||||
with open('/sys/class/net/%s/address' % ifname) as f:
|
with open('/sys/class/net/%s/address' % ifname) as f:
|
||||||
@ -191,7 +285,7 @@ def network(doit):
|
|||||||
return False
|
return False
|
||||||
cfgfile = CFGPATH % (newname, apuid)
|
cfgfile = CFGPATH % (newname, apuid)
|
||||||
with open(cfgfile, 'w') as f:
|
with open(cfgfile, 'w') as f:
|
||||||
f.write(TEMPLATE_CFG)
|
f.write(CONFIG_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:
|
||||||
@ -215,8 +309,8 @@ def network(doit):
|
|||||||
for ifname in IFNAMES:
|
for ifname in IFNAMES:
|
||||||
content = create_if(ifname, network.pop(ifname, 'off'), netaddr_dict[ifname], dhcp_server_cfg)
|
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())
|
content = '\n'.join('%s=%s' % kv for kv in content.items())
|
||||||
todo = write_when_new('/etc/sysconfig/network-scripts/ifcfg-%s' % ifname, content, doit)
|
todo = write_when_new('/etc/sysconfig/network-scripts/ifcfg-%s' % ifname, content)
|
||||||
if todo:
|
if todo and more_info == 'NONE':
|
||||||
print('change', ifname)
|
print('change', ifname)
|
||||||
show.dirty = True
|
show.dirty = True
|
||||||
if dh:
|
if dh:
|
||||||
@ -228,7 +322,7 @@ def network(doit):
|
|||||||
dh.append(' range %s %s;\n' % rng)
|
dh.append(' range %s %s;\n' % rng)
|
||||||
dh.append('}\n')
|
dh.append('}\n')
|
||||||
content = ''.join(content)
|
content = ''.join(content)
|
||||||
todo = write_when_new('/etc/dhcp/dhcpd.conf', content, doit)
|
todo = write_when_new('/etc/dhcp/dhcpd.conf', content)
|
||||||
if todo:
|
if todo:
|
||||||
print('change ', ifname)
|
print('change ', ifname)
|
||||||
show.dirty = True
|
show.dirty = True
|
||||||
@ -249,21 +343,66 @@ def network(doit):
|
|||||||
print('ERROR: can not handle %s %s: %r' % (hostname, ifname, e))
|
print('ERROR: can not handle %s %s: %r' % (hostname, ifname, e))
|
||||||
raise
|
raise
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# pip requirements ?
|
||||||
|
|
||||||
|
actions_dict = {}
|
||||||
|
reload_systemd = False
|
||||||
|
for service, template_func in SERVICES.items():
|
||||||
|
sction = service.upper()
|
||||||
|
if parser.has_section(section):
|
||||||
|
template = template_func(**dict(parser[section]))
|
||||||
|
else:
|
||||||
|
template = None
|
||||||
|
result = unix_cmd('systemctl show -p WantedBy -p ActiveState %s' % service, True)
|
||||||
|
active = False
|
||||||
|
enabled = False
|
||||||
|
for line in result.split('\n'):
|
||||||
|
if line.startswith('WantedBy=m'):
|
||||||
|
enabled = True
|
||||||
|
elif line.strip() == 'ActiveState=active':
|
||||||
|
active = True
|
||||||
|
actions = set()
|
||||||
|
if template is None:
|
||||||
|
if active:
|
||||||
|
actions.add('stop')
|
||||||
|
elif enabled:
|
||||||
|
actions.add('disable')
|
||||||
|
else:
|
||||||
|
if not active:
|
||||||
|
actions.add('restart')
|
||||||
|
if not enabled:
|
||||||
|
actions.add('enable')
|
||||||
|
if write_when_new('/etc/systemd/system/%s.service' % service, template):
|
||||||
|
reload_systemd = True
|
||||||
|
if 'enable' in actions:
|
||||||
|
actions.add('restart')
|
||||||
|
actions_dict[service] = actions
|
||||||
|
|
||||||
|
if reload_systemd:
|
||||||
|
unix_cmd('systemctl daemon-reload')
|
||||||
|
for service in SERVICES:
|
||||||
|
for action in 'stop', 'restart', 'disable', 'enable':
|
||||||
|
if action in actions_dict[service]:
|
||||||
|
show.dirty = True
|
||||||
|
unix_cmd('systemctl %s %s' % (action, service))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
doit = False
|
||||||
print('---')
|
print('---')
|
||||||
show = Show()
|
show = Show()
|
||||||
result = network(False)
|
|
||||||
walk(show)
|
walk(show)
|
||||||
|
result = handle_config()
|
||||||
|
|
||||||
if not result:
|
if not result:
|
||||||
print('fix first above errors')
|
print('fix first above errors')
|
||||||
elif show.dirty:
|
elif show.dirty and more_info == 'NONE':
|
||||||
print('---')
|
print('---')
|
||||||
answer = input('do above? ')
|
answer = input('do above? ')
|
||||||
|
doit = True
|
||||||
if answer.lower().startswith('y'):
|
if answer.lower().startswith('y'):
|
||||||
network(True)
|
handle_config()
|
||||||
walk(Do())
|
walk(Do())
|
||||||
else:
|
else:
|
||||||
print('nothing to do')
|
print('nothing to do')
|
||||||
|
@ -199,10 +199,5 @@ if __name__ == '__main__':
|
|||||||
if len(cfgfiles) != 1:
|
if len(cfgfiles) != 1:
|
||||||
raise ValueError('there must be one and only one single cfgfile %r' % cfgfiles)
|
raise ValueError('there must be one and only one single cfgfile %r' % cfgfiles)
|
||||||
parser.read(cfgfiles[0])
|
parser.read(cfgfiles[0])
|
||||||
if parser.has_section('FRAPPY'):
|
|
||||||
port = parser.get('FRAPPY', 'port')
|
|
||||||
cfg = parser.get('FRAPPY', 'cfg')
|
|
||||||
cmd = ['su', '-', 'l_samenv', '-c', '/home/l_samenv/frappy/bin/secop-server -p %s %s' % (port, cfg)]
|
|
||||||
Popen(cmd, stdout=DEVNULL, stderr=DEVNULL)
|
|
||||||
if parser.has_section('ROUTER'):
|
if parser.has_section('ROUTER'):
|
||||||
AcceptHandler.run(parser['ROUTER'])
|
AcceptHandler.run(parser['ROUTER'])
|
||||||
|
@ -2,11 +2,16 @@
|
|||||||
; please refer to README.md for help
|
; please refer to README.md for help
|
||||||
enp1s0=dhcp
|
enp1s0=dhcp
|
||||||
enp2s0=192.168.2.15
|
enp2s0=192.168.2.15
|
||||||
enp3s0=192.168.3.3/24
|
enp3s0=192.168.3.1/24
|
||||||
enp4s0=192.168.127.4/24
|
enp4s0=192.168.127.4/24
|
||||||
|
|
||||||
[ROUTER]
|
[ROUTER]
|
||||||
; please refer to README.md for help
|
; please refer to README.md for help
|
||||||
3000=/dev/ttyUSB0
|
3000=/dev/ttyUSB0
|
||||||
5900=192.168.2.33
|
5900=192.168.2.32
|
||||||
8080=192.168.127.254:80
|
8080=192.168.127.254:80
|
||||||
|
|
||||||
|
[FRAPPY]
|
||||||
|
; please refer to README.md for help
|
||||||
|
cfg=sim_uniax
|
||||||
|
port=5000
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description = Routing to locally connected hardware
|
|
||||||
After = network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
ExecStart = /usr/bin/python3 /root/aputools/router.py
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy = multi-user.target
|
|
||||||
|
|
Reference in New Issue
Block a user