2018-06-06 17:03:44 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
import configparser
|
|
|
|
import sys
|
|
|
|
import os
|
|
|
|
|
|
|
|
from xml.etree import ElementTree as etree
|
|
|
|
|
|
|
|
|
2018-06-20 17:45:44 +00:00
|
|
|
def getSetting(s, name, fallback): return name in s and s[name] or fallback
|
|
|
|
|
|
|
|
|
|
|
|
shadowRoot = getSetting(os.environ, "SHADOW_ROOT",
|
|
|
|
os.path.join(os.environ['HOME'], '.shadow'))
|
2018-06-06 17:03:44 +00:00
|
|
|
|
|
|
|
libpath = 'libshadow-plugin-llarp.so'
|
|
|
|
|
2018-06-20 17:45:44 +00:00
|
|
|
|
2018-06-07 16:45:51 +00:00
|
|
|
def nodeconf(conf, baseDir, name, ifname=None, port=None):
|
2018-06-06 17:03:44 +00:00
|
|
|
conf['netdb'] = {'dir': 'tmp-nodes'}
|
2018-06-20 17:45:44 +00:00
|
|
|
conf['router'] = {}
|
|
|
|
conf['router']['contact-file'] = os.path.join(
|
|
|
|
baseDir, '{}.signed'.format(name))
|
|
|
|
conf['router']['ident-privkey'] = os.path.join(
|
|
|
|
baseDir, '{}-ident.key'.format(name))
|
|
|
|
conf['router']['transport-privkey'] = os.path.join(
|
|
|
|
baseDir, '{}-transport.key'.format(name))
|
2018-06-07 16:45:51 +00:00
|
|
|
if ifname and port:
|
|
|
|
conf['bind'] = {ifname: port}
|
|
|
|
conf['connect'] = {}
|
2018-06-06 17:03:44 +00:00
|
|
|
|
2018-06-20 17:45:44 +00:00
|
|
|
|
2018-06-06 17:03:44 +00:00
|
|
|
def addPeer(conf, baseDir, peer):
|
2018-06-07 16:45:51 +00:00
|
|
|
conf['connect'][peer] = os.path.join(baseDir, '{}.signed'.format(peer))
|
2018-06-06 17:03:44 +00:00
|
|
|
|
2018-06-20 17:45:44 +00:00
|
|
|
|
2018-06-06 17:03:44 +00:00
|
|
|
def createNode(pluginName, root, peer):
|
2018-06-07 17:36:17 +00:00
|
|
|
node = etree.SubElement(root, 'node')
|
2018-06-06 17:03:44 +00:00
|
|
|
node.attrib['id'] = peer['name']
|
2018-06-06 21:23:57 +00:00
|
|
|
node.attrib['interfacebuffer'] = '{}'.format(1024 * 1024 * 100)
|
2018-06-06 17:03:44 +00:00
|
|
|
app = etree.SubElement(node, 'process')
|
|
|
|
app.attrib['plugin'] = pluginName
|
|
|
|
app.attrib['time'] = '50'
|
|
|
|
app.attrib['arguments'] = peer['configfile']
|
|
|
|
|
|
|
|
|
|
|
|
def makeBase(settings, name, id):
|
|
|
|
return {
|
|
|
|
'id': id,
|
2018-06-20 17:45:44 +00:00
|
|
|
'name': name,
|
|
|
|
'contact-file': os.path.join(getSetting(settings, 'baseDir', 'tmp'), '{}.signed'.format(name)),
|
|
|
|
'configfile': os.path.join(getSetting(settings, 'baseDir', 'tmp'), '{}.ini'.format(name)),
|
2018-06-06 17:03:44 +00:00
|
|
|
'config': configparser.ConfigParser()
|
|
|
|
}
|
|
|
|
|
2018-06-20 17:45:44 +00:00
|
|
|
|
2018-06-07 16:45:51 +00:00
|
|
|
def makeClient(settings, name, id):
|
2018-06-06 17:03:44 +00:00
|
|
|
peer = makeBase(settings, name, id)
|
2018-06-07 16:45:51 +00:00
|
|
|
nodeconf(peer['config'], getSetting(settings, 'baseDir', 'tmp'), name)
|
2018-06-06 17:03:44 +00:00
|
|
|
return peer
|
|
|
|
|
2018-06-20 17:45:44 +00:00
|
|
|
|
2018-06-06 17:03:44 +00:00
|
|
|
def makeSVCNode(settings, name, id, port):
|
|
|
|
peer = makeBase(settings, name, id)
|
2018-06-20 17:45:44 +00:00
|
|
|
nodeconf(peer['config'], getSetting(
|
|
|
|
settings, 'baseDir', 'tmp'), name, 'eth0', port)
|
2018-06-06 17:03:44 +00:00
|
|
|
return peer
|
|
|
|
|
|
|
|
|
|
|
|
def genconf(settings, outf):
|
|
|
|
root = etree.Element('shadow')
|
|
|
|
topology = etree.SubElement(root, 'topology')
|
2018-06-20 17:45:44 +00:00
|
|
|
topology.attrib['path'] = getSetting(settings, 'topology', os.path.join(
|
|
|
|
shadowRoot, 'share', 'topology.graphml.xml'))
|
2018-06-06 17:03:44 +00:00
|
|
|
|
|
|
|
pluginName = getSetting(settings, 'name', 'llarpd')
|
|
|
|
|
|
|
|
kill = etree.SubElement(root, 'kill')
|
|
|
|
kill.attrib['time'] = getSetting(settings, 'runFor', '600')
|
2018-06-20 17:45:44 +00:00
|
|
|
|
2018-06-06 17:03:44 +00:00
|
|
|
baseDir = getSetting(settings, 'baseDir', 'tmp')
|
|
|
|
|
|
|
|
if not os.path.exists(baseDir):
|
|
|
|
os.mkdir(baseDir)
|
2018-06-20 17:45:44 +00:00
|
|
|
|
2018-06-06 17:03:44 +00:00
|
|
|
plugin = etree.SubElement(root, "plugin")
|
|
|
|
plugin.attrib['id'] = pluginName
|
|
|
|
plugin.attrib['path'] = libpath
|
2018-06-06 21:23:57 +00:00
|
|
|
basePort = getSetting(settings, 'svc-base-port', 19000)
|
2018-06-06 17:03:44 +00:00
|
|
|
svcNodeCount = getSetting(settings, 'service-nodes', 20)
|
|
|
|
peers = list()
|
|
|
|
for nodeid in range(svcNodeCount):
|
2018-06-20 17:45:44 +00:00
|
|
|
peers.append(makeSVCNode(
|
|
|
|
settings, 'svc-node-{}'.format(nodeid), str(nodeid), basePort + 1))
|
2018-06-06 17:03:44 +00:00
|
|
|
basePort += 1
|
|
|
|
|
|
|
|
# make all service nodes know each other
|
|
|
|
for peer in peers:
|
|
|
|
for nodeid in range(svcNodeCount):
|
|
|
|
if str(nodeid) != peer['id']:
|
|
|
|
addPeer(peer['config'], baseDir, 'svc-node-{}'.format(nodeid))
|
2018-06-20 17:45:44 +00:00
|
|
|
|
2018-06-06 17:03:44 +00:00
|
|
|
# add client nodes
|
|
|
|
for nodeid in range(getSetting(settings, 'client-nodes', 200)):
|
2018-06-20 17:45:44 +00:00
|
|
|
peer = makeClient(
|
|
|
|
settings, 'client-node-{}'.format(nodeid), str(nodeid))
|
2018-06-06 17:03:44 +00:00
|
|
|
peers.append(peer)
|
2018-06-20 17:45:44 +00:00
|
|
|
for p in range(getSetting(settings, 'client-connect-to', 10)):
|
|
|
|
addPeer(peer['config'], baseDir,
|
|
|
|
'svc-node-{}'.format((p + nodeid) % svcNodeCount))
|
2018-06-06 17:03:44 +00:00
|
|
|
|
|
|
|
# generate xml and settings files
|
|
|
|
for peer in peers:
|
|
|
|
createNode(pluginName, root, peer)
|
|
|
|
|
|
|
|
with open(peer['configfile'], 'w') as f:
|
|
|
|
peer['config'].write(f)
|
|
|
|
|
|
|
|
# render
|
|
|
|
outf.write(etree.tostring(root).decode('utf-8'))
|
|
|
|
|
2018-06-20 17:45:44 +00:00
|
|
|
|
2018-06-06 17:03:44 +00:00
|
|
|
if __name__ == '__main__':
|
|
|
|
settings = {
|
2018-06-20 17:45:44 +00:00
|
|
|
'topology': os.path.join(shadowRoot, 'share', 'topology.graphml.xml')
|
2018-06-06 17:03:44 +00:00
|
|
|
}
|
|
|
|
with open(sys.argv[1], 'w') as f:
|
|
|
|
genconf(settings, f)
|