Newer
Older
#!/usr/bin/env python3
from __future__ import annotations
import os
import string
import random
import argparse
from collections.abc import Sequence
# Generates a random string
def random_string(stringLength=4):
letters = string.ascii_lowercase
return ''.join(random.choice(letters) for i in range(stringLength))
# Generate a list of all ports servers and gateways occupy. Doing this as a
# separate step because their configs need every one listed, and generating them
# once is lighter on CPU cycles. Takes an offset to ensure no port collisions
# occur with existing packages
def create_ports_list(offset, manualOffset=0):
# Array of integers for ports of each server and gateway in the network
gateway_ports = []
node_ports = []
node_regCodes = []
for i in range(nodes):
gateway_ports.append(1000 + 10 * offset + manualOffset + i)
node_ports.append(10000 + 10 * offset + i)
regCode = random_string()
# If this regCode is already in the list, we loop until we get one that
# isn't
while regCode in node_regCodes:
regCode = random_string()
node_regCodes.append(regCode)
permissioningPort = 20000 + 10 * offset
return gateway_ports, node_ports, permissioningPort, udbPort, node_regCodes
# Generate server and gateway configs
def generate_server_side_config(offset: int, newPackage: string):
# Open gateway template
gateway_template = ""
with open("gen/gateway.yaml") as f:
gateway_template = f.read()
# Open network config
network_config = ""
with open("gen/network.config") as f:
network_config = f.read()
# Open no errors template
no_errors = ""
with open("gen/noerrors.txt") as f:
no_errors = f.read()
# Open whitelist template
whitelist = ""
with open("gen/whitelist.txt") as f:
whitelist = f.read()
# Open release template
release_template = ""
with open("gen/release.txt") as f:
release_template = f.read()
# Open mainnet template
mainnet_template = ""
with open("gen/mainnet.txt") as f:
mainnet_template = f.read()
# Open devnet template
devnet_template = ""
with open("gen/devnet.txt") as f:
devnet_template = f.read()
#Open betanet template
betanet_template = ""
with open("gen/betanet.txt") as f:
betanet_template = f.read()
reg_template = ""
with open("gen/permissioning.yaml") as f:
reg_template = f.read()
# Open client-registrar
client_reg_template = ""
with open("gen/client-registrar.yaml") as f:
client_reg_template = f.read()
# Open server template
server_template = ""
with open("gen/server.yaml") as f:
server_template = f.read()
# Open run script template
run_template=""
with open("gen/run.sh") as f:
run_template = f.read()
# Open udb config
udb_config = ""
with open("gen/udb.yaml") as f:
udb_config = f.read()
# Open udb contact
udb_contact = ""
with open("gen/udbContact.bin") as f:
udb_contact = f.read()
reg_json = ""
with open("gen/registration.json") as f:
reg_json = f.read()
# Open udb proto file
udb_proto = ""
with open("gen/udbProto.json") as f:
udb_proto = f.read()
if not os.path.exists(newPackage):
os.makedirs(newPackage)
# Create gold sub-directory
if not os.path.exists("{}/clients.goldoutput/".format(newPackage)):
os.makedirs("{}/clients.goldoutput/".format(newPackage))
gateway_ports, node_ports, perm_port, udbPort, node_regCodes = create_ports_list(offset)
with open("{}/server-{}.yaml".format(newPackage, i+1), 'w') as f:
# Array of strings defining node and gateway IPs and ports
node_addrs = []
node_addrs.append("\"{}\"".format(node_ports[i]))
# Create a new config based on template
s_config = server_template.replace("server-1", "server-" + str(i+1)) \
.replace("gateway-1", "gateway-" + str(i)) \
.replace("{NODE_ADDR}", "\r\n".join(node_addrs)) \
.replace("{DB_ADDR}", "".join(["\"\""])) \
.replace("AAAA", node_regCodes[i]) \
.replace("nodeID-1.json", "nodeID-"+str(i)+".json") \
.replace("errServer-0.txt", "errServer-"+str(i)+".txt") \
.replace("{permissioning_port}", str(perm_port))
with open("{}/gateway-{}.yaml".format(newPackage, i+1), 'w') as f:
# Array of strings defining node and gateway IPs and ports
node_addrs = []
node_addrs.append(" \"0.0.0.0:{}\"".format(node_ports[i]))
# Create a new config based on template
g_config = gateway_template.replace("server-1", "server-" + str(i+1)) \
.replace("gateway-1", "gateway-" + str(i+1)) \
.replace("{GW_ADDR}", str(gateway_ports[i])) \
.replace("{NODE_ADDR}", "\r\n".join(node_addrs)) \
.replace("gatewayIDF-0", "gatewayIDF-" + str(i))
f.write(g_config)
# Generate regCodes file
with open("{}/regCodes.json".format(newPackage), "w") as f:
f.write("[")
for i in range(nodes):
f.write("{\"RegCode\": \"" + node_regCodes[i] + "\", \"Order\": \"" + \
# If not the last element, write a comma
if i is not (nodes - 1):
f.write(",")
f.write("]")
# Generate network config
with open("{}/network.config".format(newPackage), "w") as f:
network_config = network_config.replace("{entry_point}", str(gateway_ports[0]))
f.write(network_config)
with open("{}/permissioning.yaml".format(newPackage), "w") as f:
reg_template = reg_template.replace("{permissioning_port}", str(perm_port)) \
.replace("{udb_port}", str(udbPort))\
.replace("{registration_port}", str(perm_port+1))
f.write(reg_template)
with open("{}/registration.json".format(newPackage), "w") as f:
f.write(reg_json)
with open("{}/client-registrar.yaml".format(newPackage), "w") as f:
client_reg_template = client_reg_template.replace("{registration_port}", str(perm_port+1))
f.write(client_reg_template)
with open("{}/noerrors.txt".format(newPackage), "w") as f:
f.write(no_errors)
if not os.path.exists("{}/run.sh".format(newPackage)):
with open("{}/run.sh".format(newPackage), "w") as f:
run_template = run_template.replace("{entry_point}", str(gateway_ports[0]))
f.write(run_template)
else:
with open("{}/run.sh".format(newPackage), "r") as f:
filedata = f.read()
newdata = re.sub(r"(localhost:)(\d+)", f"localhost:{str(gateway_ports[0])}", filedata)
with open("{}/run.sh".format(newPackage), "w") as f:
f.write(newdata)
# Set the executable permissions on the bash script file
os.chmod("{}/run.sh".format(newPackage), 0o755)
# Write whitelist to package
with open("{}/whitelist.txt".format(newPackage), "w") as f:
f.write(whitelist)
# Write release to package
with open("{}/release.txt".format(newPackage), "w") as f:
f.write(release_template)
# Write mainnet to package
with open("{}/mainnet.txt".format(newPackage), "w") as f:
f.write(mainnet_template)
# Write devnet to package
with open("{}/devnet.txt".format(newPackage), "w") as f:
f.write(devnet_template)
# Write betanet to package
with open("{}/betanet.txt".format(newPackage), "w") as f:
f.write(betanet_template)
# Write udb config
with open("{}/udb.yaml".format(newPackage), "w") as f:
udb_config = udb_config.replace("{permissioning_port}", str(perm_port)) \
.replace("{udb_port}", str(udbPort))
f.write(udb_config)
with open("{}/udbContact.bin".format(newPackage), "w") as f:
f.write(udb_contact)
with open("{}/udbProto.json".format(newPackage), "w") as f:
f.write(udb_proto)
# Count the number of packages previously created by counting
# run.sh files creates
current_dir = os.getcwd()
count = 0
for root, dirs, files in os.walk(current_dir):
for file in files:
count += 1
return count
def main(argv: Sequence[str] | None = None) -> int:
parser = argparse.ArgumentParser(description='Generate or count packages')
subparsers = parser.add_subparsers(title='subcommands', dest='command')
# "generate" subcommand
generate_parser = subparsers.add_parser('generate', help='Generate packages')
generate_parser.add_argument('--package', required=True, help='Name of the package')
generate_parser.add_argument('--offset', type=int, default=0, help='Offset value')
# "count" subcommand
count_parser = subparsers.add_parser('count', help='Count packages')
# parse the arguments
args = parser.parse_args()
print(f"Number of occurrences of run.sh in all subdirectories: {network_count}")
return
elif args.command == "generate":
generate_server_side_config(network_count + args.offset, args.package)