From 0916f6ba160b4aeddaaa2b3df5e006e24c343ef2 Mon Sep 17 00:00:00 2001 From: Jake Hillion Date: Wed, 4 Nov 2020 22:53:36 +0000 Subject: [PATCH 1/3] functional runner --- evaluation.ipynb | 80 ++++++++++---------- runners/runners.py | 167 +++++++++++++++++++++++++++++++++++++---- structure/__init__.py | 2 +- structure/structure.py | 162 +++++++++++++++++++++++++++++++++++---- 4 files changed, 343 insertions(+), 68 deletions(-) diff --git a/evaluation.ipynb b/evaluation.ipynb index de9a267..11ceeb5 100644 --- a/evaluation.ipynb +++ b/evaluation.ipynb @@ -13,7 +13,7 @@ "\n", "import runners\n", "from structure import Bridge\n", - "from structure import SpeedTestServer, RemoteServer, LocalServer\n", + "from structure import RemotePortal, LocalPortal\n", "from structure import Interface, IpMethod\n", "\n", "%load_ext dotenv\n", @@ -28,19 +28,7 @@ "name": "#%%\n" } }, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'runners' is not defined", - "output_type": "error", - "traceback": [ - "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", - "\u001B[0;31mNameError\u001B[0m Traceback (most recent call last)", - "\u001B[0;32m\u001B[0m in \u001B[0;36m\u001B[0;34m\u001B[0m\n\u001B[0;32m----> 1\u001B[0;31m runner = runners.ProxmoxRunner(\n\u001B[0m\u001B[1;32m 2\u001B[0m \u001B[0mhost\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mos\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mgetenv\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m'PROXMOX_HOST'\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 3\u001B[0m \u001B[0mnode\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mos\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mgetenv\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m'PROXMOX_NODE'\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 4\u001B[0m \u001B[0muser\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mos\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mgetenv\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m'PROXMOX_USER'\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 5\u001B[0m \u001B[0mtoken_name\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mos\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mgetenv\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m'PROXMOX_TOKEN_NAME'\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;31mNameError\u001B[0m: name 'runners' is not defined" - ] - } - ], + "outputs": [], "source": [ "runner = runners.ProxmoxRunner(\n", " host=os.getenv('PROXMOX_HOST'),\n", @@ -52,47 +40,63 @@ " template_id=9000,\n", " initial_vm_id=21002,\n", "\n", - " internet_bridge='vmbr2',\n", + " internet_bridge=os.getenv('INTERNET_BRIDGE'),\n", "\n", - " management_bridge='vmbr4',\n", - " management_initial_ip=ipaddress.ip_address('10.21.12.2'),\n", - ")" + " management_bridge=os.getenv('MANAGEMENT_BRIDGE'),\n", + " management_gateway=ipaddress.ip_address(os.getenv('MANAGEMENT_GATEWAY')),\n", + " management_initial_ip=ipaddress.ip_address(os.getenv('MANAGEMENT_INITIAL_IP')),\n", + ")\n", + "\n", + "setup_params = {\n", + " 'access_key': os.getenv('S3_ACCESS_KEY'),\n", + " 'secret_key': os.getenv('S3_SECRET_KEY'),\n", + " 'branch': os.getenv('TARGET_BRANCH'),\n", + "}" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "metadata": { "pycharm": { "name": "#%%\n" } }, - "outputs": [], + "outputs": [ + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", + "\u001B[0;31mKeyboardInterrupt\u001B[0m Traceback (most recent call last)", + "\u001B[0;32m\u001B[0m in \u001B[0;36m\u001B[0;34m\u001B[0m\n\u001B[1;32m 12\u001B[0m \u001B[0;34m*\u001B[0m\u001B[0mlp\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mget_interfaces\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;36m0\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;36m2\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 13\u001B[0m ])\n\u001B[0;32m---> 14\u001B[0;31m \u001B[0mrunner\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mbuild\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mtop_level_bridge\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 15\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/sync/school/exercises/paper-0/dissertation/3-evaluation/runners/runners.py\u001B[0m in \u001B[0;36mbuild\u001B[0;34m(self, bridge)\u001B[0m\n\u001B[1;32m 137\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_build_bridges\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 138\u001B[0m \u001B[0;32mfor\u001B[0m \u001B[0mnode\u001B[0m \u001B[0;32min\u001B[0m \u001B[0mnodes\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 139\u001B[0;31m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_build_node\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mnode\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 140\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 141\u001B[0m \u001B[0;32mdef\u001B[0m \u001B[0m_await_task\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mself\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mupid\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mtimeout\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0;36m10\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/sync/school/exercises/paper-0/dissertation/3-evaluation/runners/runners.py\u001B[0m in \u001B[0;36m_build_node\u001B[0;34m(self, node)\u001B[0m\n\u001B[1;32m 262\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_await_task\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mstart_task\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 263\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 264\u001B[0;31m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_open_ssh\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mnode\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 265\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mssh\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mnode\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mnode\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mget_internet_setup\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 266\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_close_ssh\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mnode\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/sync/school/exercises/paper-0/dissertation/3-evaluation/runners/runners.py\u001B[0m in \u001B[0;36m_open_ssh\u001B[0;34m(self, node, interface)\u001B[0m\n\u001B[1;32m 206\u001B[0m \u001B[0;32mwhile\u001B[0m \u001B[0;34m(\u001B[0m\u001B[0mdatetime\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mnow\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m)\u001B[0m \u001B[0;34m-\u001B[0m \u001B[0mt1\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mseconds\u001B[0m \u001B[0;34m<\u001B[0m \u001B[0mProxmoxRunner\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mssh_timeout\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 207\u001B[0m \u001B[0;32mtry\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 208\u001B[0;31m client.connect(\n\u001B[0m\u001B[1;32m 209\u001B[0m \u001B[0mhostname\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mstr\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0minterface\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mget_address\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 210\u001B[0m \u001B[0musername\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0;34m'python'\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/sync/school/exercises/paper-0/dissertation/3-evaluation/venv/lib/python3.8/site-packages/paramiko/client.py\u001B[0m in \u001B[0;36mconnect\u001B[0;34m(self, hostname, port, username, password, pkey, key_filename, timeout, allow_agent, look_for_keys, compress, sock, gss_auth, gss_kex, gss_deleg_creds, gss_host, banner_timeout, auth_timeout, gss_trust_dns, passphrase, disabled_algorithms)\u001B[0m\n\u001B[1;32m 347\u001B[0m \u001B[0;32mexcept\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 348\u001B[0m \u001B[0;32mpass\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 349\u001B[0;31m \u001B[0mretry_on_signal\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;32mlambda\u001B[0m\u001B[0;34m:\u001B[0m \u001B[0msock\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mconnect\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0maddr\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 350\u001B[0m \u001B[0;31m# Break out of the loop on success\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 351\u001B[0m \u001B[0;32mbreak\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/sync/school/exercises/paper-0/dissertation/3-evaluation/venv/lib/python3.8/site-packages/paramiko/util.py\u001B[0m in \u001B[0;36mretry_on_signal\u001B[0;34m(function)\u001B[0m\n\u001B[1;32m 281\u001B[0m \u001B[0;32mwhile\u001B[0m \u001B[0;32mTrue\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 282\u001B[0m \u001B[0;32mtry\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 283\u001B[0;31m \u001B[0;32mreturn\u001B[0m \u001B[0mfunction\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 284\u001B[0m \u001B[0;32mexcept\u001B[0m \u001B[0mEnvironmentError\u001B[0m \u001B[0;32mas\u001B[0m \u001B[0me\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 285\u001B[0m \u001B[0;32mif\u001B[0m \u001B[0me\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0merrno\u001B[0m \u001B[0;34m!=\u001B[0m \u001B[0merrno\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mEINTR\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/sync/school/exercises/paper-0/dissertation/3-evaluation/venv/lib/python3.8/site-packages/paramiko/client.py\u001B[0m in \u001B[0;36m\u001B[0;34m()\u001B[0m\n\u001B[1;32m 347\u001B[0m \u001B[0;32mexcept\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 348\u001B[0m \u001B[0;32mpass\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 349\u001B[0;31m \u001B[0mretry_on_signal\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;32mlambda\u001B[0m\u001B[0;34m:\u001B[0m \u001B[0msock\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mconnect\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0maddr\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 350\u001B[0m \u001B[0;31m# Break out of the loop on success\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 351\u001B[0m \u001B[0;32mbreak\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;31mKeyboardInterrupt\u001B[0m: " + ] + } + ], "source": [ - "g_st = SpeedTestServer([Interface(IpMethod.Auto4)])\n", - "l_st = SpeedTestServer([Interface(IpMethod.Dhcp4)])\n", + "rp = RemotePortal([Interface(IpMethod.Auto4)], setup_params=setup_params)\n", + "lp = LocalPortal([\n", + " Interface(IpMethod.Auto4, limit=1),\n", + " Interface(IpMethod.Auto4, limit=1),\n", + "], None, setup_params=setup_params)\n", "\n", - "rs = RemoteServer([Interface(IpMethod.Auto4)])\n", - "ls = LocalServer([\n", - " Interface(IpMethod.Auto4, limit=1),\n", - " Interface(IpMethod.Auto4, limit=1),\n", - "], l_st)\n", + "rp.set_local_portal(lp)\n", + "lp.set_remote_portal(rp)\n", "\n", "top_level_bridge = Bridge(*[\n", - " g_st.get_interfaces()[0],\n", - " rs.get_interfaces()[0],\n", - " *ls.get_interfaces()[0:2],\n", + " rp.get_interfaces()[0],\n", + " *lp.get_interfaces()[0:2],\n", "])\n", "runner.build(top_level_bridge)\n", "\n", - "# Test from the client to the global network via the proxy\n", - "g_st.server()\n", - "l_st.client(rs.get_interfaces()[0])\n", - "\n", - "# Test from the global network to the client via the proxy\n", - "g_st.server()\n", - "l_st.client(rs.get_interfaces()[0])\n", - "\n", "# Clean up\n", "runner.teardown()" ] diff --git a/runners/runners.py b/runners/runners.py index bd19170..21e319f 100644 --- a/runners/runners.py +++ b/runners/runners.py @@ -1,9 +1,12 @@ import ipaddress import os +import time from datetime import datetime from typing import Callable, List, Tuple +from urllib.parse import quote import proxmoxer +import paramiko import structure @@ -15,7 +18,7 @@ def check_env(*names: str) -> bool: return True -def bridge_node_dfs( +def bridge_node_search( first: structure.Bridge, bridge_name_generator: Callable[[structure.Bridge], str], node_id_generator: Callable[[structure.Node], int], @@ -59,7 +62,7 @@ class PrintRunner: self._last_node_id = 0 def build(self, bridge: structure.Bridge): - bridges, nodes = bridge_node_dfs(bridge, lambda _: self.name_bridge(), lambda _: self.id_node()) + bridges, nodes = bridge_node_search(bridge, lambda _: self.name_bridge(), lambda _: self.id_node()) print(bridges) print(nodes) @@ -77,6 +80,8 @@ class PrintRunner: class ProxmoxRunner: + ssh_timeout = 300 + def __init__( self, host: str, @@ -92,6 +97,7 @@ class ProxmoxRunner: management_bridge: str, management_initial_ip: ipaddress, + management_gateway: ipaddress, verify_ssl: bool = False, ): @@ -111,20 +117,33 @@ class ProxmoxRunner: self._proxmox_node = node self._template_id = template_id - self._initial_vm_id = initial_vm_id - 1 + self._initial_vm_id = initial_vm_id - self._internet_bridge = internet_bridge + self._internet_bridge = structure.Bridge() + self._internet_bridge.set_name(internet_bridge) - self._management_bridge = management_bridge + self._management_bridge = structure.Bridge() + self._management_bridge.set_name(management_bridge) self._management_initial_ip = management_initial_ip + self._management_gateway = management_gateway + + # generate a single use SSH key (we can use any with Proxmox) + self._private_key = paramiko.RSAKey.generate(3072) + self._client = paramiko.SSHClient() def build(self, bridge: structure.Bridge): - bridges, nodes = bridge_node_dfs(bridge, lambda x: self._create_bridge(x), lambda x: self._create_node(x)) + bridges, nodes = bridge_node_search(bridge, lambda x: self._create_bridge(x), lambda x: self._create_node(x)) self._build_bridges() + for node in nodes: self._build_node(node) + # guarantee that setup is not called until all of the nodes are built + # this means that all will have their final IPs by this point + for node in nodes: + self._setup_node(node) + def _await_task(self, upid, timeout=10): t1 = datetime.now() while (datetime.now() - t1).seconds < timeout: @@ -133,8 +152,6 @@ class ProxmoxRunner: raise TimeoutError def _create_bridge(self, bridge: structure.Bridge) -> str: - self._last_bridge += 1 - while True: try: self._proxmox.nodes(self._proxmox_node).network.post( @@ -143,6 +160,7 @@ class ProxmoxRunner: autostart=1, comments='Automatically created by Python evaluation', ) + self._last_bridge += 1 break except proxmoxer.core.ResourceException as e: if 'interface already exists' in str(e): @@ -150,7 +168,7 @@ class ProxmoxRunner: else: raise e - bridge_name = 'vmbr{}'.format(self._last_bridge) + bridge_name = 'vmbr{}'.format(self._last_bridge - 1) self._created_bridges.append(bridge_name) return bridge_name @@ -159,14 +177,13 @@ class ProxmoxRunner: self._await_task(network_task) def _create_node(self, node: structure.Node) -> int: - self._last_node_id += 1 - while True: try: clone_task = self._proxmox.nodes(self._proxmox_node).qemu(self._template_id).clone.post( newid=self._initial_vm_id + self._last_node_id, name='Diss-{}-Testing'.format(node.__class__.__name__), ) + self._last_node_id += 1 break except proxmoxer.core.ResourceException as e: if 'config file already exists' in str(e): @@ -176,13 +193,130 @@ class ProxmoxRunner: self._await_task(clone_task) new_id = self._initial_vm_id + self._last_node_id - self._created_nodes.append(new_id) - return new_id + self._created_nodes.append(new_id - 1) + return new_id - 1 + + def _open_ssh(self, node: structure.Node, interface: structure.Interface = None): + if interface is None: + for iface in node.get_interfaces(): + if iface.get_method() == structure.IpMethod.Management: + interface = iface + break + if interface is None: + raise RuntimeError('no management interface available') + + client = paramiko.SSHClient() + client.set_missing_host_key_policy(paramiko.AutoAddPolicy) + + t1 = datetime.now() + while (datetime.now() - t1).seconds < ProxmoxRunner.ssh_timeout: + try: + client.connect( + hostname=str(interface.get_address()), + username='python', + pkey=self._private_key, + banner_timeout=15, + ) + client.set_missing_host_key_policy(paramiko.RejectPolicy) + break + except (paramiko.ssh_exception.AuthenticationException, paramiko.ssh_exception.NoValidConnectionsError): + time.sleep(10) + + node.client = client + + def _close_ssh(self, node: structure.Node): + node.client.close() + del node.client + + def ssh(self, node: structure.Node, command: str, error_stderr=False, error_stdout=False) -> int: + chan = node.client.get_transport().open_session() + + chan.exec_command(command) + exit_status = chan.recv_exit_status() + + if exit_status != 0: + if error_stderr and error_stdout: + raise Exception( + 'stdout:\n{}\n\nstderr:\n{}\n'.format(chan.recv(2048).decode(), chan.recv_stderr(2048).decode())) + if error_stderr: + raise Exception(chan.recv_stderr(2048).decode()) + if error_stdout: + raise Exception(chan.recv(2048).decode()) + + return exit_status def _build_node(self, node: structure.Node): - # Step 1: connect to Internet bridge with DHCP to install packages - # Step 2: connect to management bridge for correct setup - pass + # Step 1: Configure access + self._proxmox.nodes(self._proxmox_node).qemu(node.get_id()).config.put( + ciuser='python', + sshkeys=quote('ssh-rsa ' + self._private_key.get_base64(), ''), + cores=node.get_core_count(), + sockets=1, + memory=node.get_memory_mb(), + ) + + # Step 2: connect to Internet bridge with DHCP to install packages + if node.get_internet_setup() is not None: + interfaces = node.get_interfaces() + internet_interface = structure.Interface(structure.IpMethod.Dhcp4) + internet_interface.set_bridge(self._internet_bridge) + temp_interfaces = [internet_interface, interfaces[len(interfaces)-1]] + + self._setup_node_interfaces(node, temp_interfaces) + + start_task = self._proxmox.nodes(self._proxmox_node).qemu(node.get_id()).status.start.post() + self._await_task(start_task) + + self._open_ssh(node) + self.ssh(node, node.get_internet_setup(), error_stdout=True, error_stderr=True) + self._close_ssh(node) + + stop_task = self._proxmox.nodes(self._proxmox_node).qemu(node.get_id()).status.shutdown.post() + self._await_task(stop_task) + + # Step 3: connect to management bridge for final setup + self._setup_node_interfaces(node) + + start_task = self._proxmox.nodes(self._proxmox_node).qemu(node.get_id()).status.start.post() + self._await_task(start_task) + + self._open_ssh(node) + + def _setup_node_interfaces(self, node: structure.Node, interfaces: List[structure.Interface] = None): + if interfaces is None: + interfaces = node.get_interfaces() + + kwargs = dict() + for i in range(len(interfaces)): + interface = interfaces[i] + method = interface.get_method() + + if method == structure.IpMethod.Manual: + pass + elif method == structure.IpMethod.Management: + interface.set_bridge(self._management_bridge) + addr = self._management_initial_ip + node.get_id() - self._initial_vm_id + + kwargs['ipconfig{}'.format(i)] = 'ip={}/24,gw={}'.format(addr, self._management_gateway) + interface.set_address(addr) + elif method == structure.IpMethod.Auto4: + bridge = interface.get_bridge() + addr = bridge.get_ip_address() + + kwargs['ipconfig{}'.format(i)] = 'ip={}/{}'.format(addr, bridge.netmask) + interface.set_address(addr) + elif method == structure.IpMethod.Dhcp4: + kwargs['ipconfig{}'.format(i)] = 'ip=dhcp' + else: + raise RuntimeError('not implemented') + + kwargs['net{}'.format(i)] = 'model=virtio,bridge={}'.format(interface.get_bridge().get_name()) + + self._proxmox.nodes(self._proxmox_node).qemu(node.get_id()).config.put(**kwargs) + + def _setup_node(self, node: structure.Node): + if node.get_setup() is not None: + self.ssh(node, node.get_setup(), error_stdout=True, error_stderr=True) def teardown(self): for node in self._created_nodes: @@ -193,6 +327,7 @@ class ProxmoxRunner: for bridge in self._created_bridges: self._proxmox.nodes(self._proxmox_node).network(bridge).delete() + network_task = self._proxmox.nodes(self._proxmox_node).network.put() self._await_task(network_task) diff --git a/structure/__init__.py b/structure/__init__.py index 3f37154..d8de3bf 100644 --- a/structure/__init__.py +++ b/structure/__init__.py @@ -2,4 +2,4 @@ from .structure import Node from .structure import IpMethod, Interface, Bridge -from .structure import SpeedTestServer, LocalServer, RemoteServer +from .structure import SpeedTestServer, LocalPortal, RemotePortal diff --git a/structure/structure.py b/structure/structure.py index 0ae04fb..27c69bf 100644 --- a/structure/structure.py +++ b/structure/structure.py @@ -1,8 +1,10 @@ +import ipaddress +import textwrap from enum import Enum -from typing import List, Optional, Union +import random +from typing import List, Optional, Union, Dict -# Enums class IpMethod(Enum): Manual = 0 Management = 1 @@ -22,6 +24,7 @@ class Interface: self._method = method self._limit = limit + self._address: ipaddress.ip_address = None def get_method(self): return self._method @@ -38,6 +41,12 @@ class Interface: def get_bridge(self): return self._bridge + def set_address(self, addr: ipaddress.ip_address): + self._address = addr + + def get_address(self) -> ipaddress.ip_address: + return self._address + class Bridge: def __init__(self, *interfaces: Interface): @@ -48,6 +57,11 @@ class Bridge: self._interfaces.append(interface) interface.set_bridge(self) + # Generate a random class c private range by default (10.0.0.0) + self.netmask = 24 + self._addr: ipaddress.ip_address = ipaddress.ip_address('10.0.0.0') + random.randint(0, 16777216) + self._network_iterator = ipaddress.ip_network('{}/{}'.format(self._addr, self.netmask), False).hosts() + def get_interfaces(self) -> List[Interface]: return self._interfaces @@ -57,9 +71,16 @@ class Bridge: def get_name(self) -> str: return self._name + def set_netmask(self, mask: int): + self.netmask = mask + self._network_iterator = ipaddress.ip_network('{}/{}'.format(self._addr, self.netmask), False).hosts() + + def get_ip_address(self) -> ipaddress.ip_address: + return next(self._network_iterator) + class Node: - def __init__(self, interfaces: List[Interface]): + def __init__(self, interfaces: List[Interface], setup_params: Dict = None): self._id: Union[int, None] = None self._interfaces: List[Interface] = interfaces self._interfaces.append(Interface(IpMethod.Management)) @@ -67,6 +88,8 @@ class Node: for interface in self._interfaces: interface.set_node(self) + self.setup_params = {} if setup_params is None else setup_params + def get_interfaces(self): return self._interfaces @@ -76,22 +99,135 @@ class Node: def get_id(self): return self._id + def get_core_count(self) -> int: + return 2 + + def get_memory_mb(self) -> int: + return 2048 + + def get_internet_setup(self) -> Optional[str]: + return None + + def get_setup(self) -> Optional[str]: + return None + class SpeedTestServer(Node): - def server(self): - pass - def client(self, server: Interface): pass + # Entry method for running the serve with `with speedtest:` + def __enter__(self): + pass -class RemoteServer(Node): - pass + def __exit__(self, exc_type, exc_val, exc_tb): + pass -class LocalServer(Node): - def __init__(self, wan_interfaces: List[Interface], child: Node): - lan_interface = Interface(IpMethod.Manual) - super().__init__([*wan_interfaces, lan_interface]) +class RemotePortal(Node): + def __init__(self, interfaces, **kwargs): + super(RemotePortal, self).__init__(interfaces, **kwargs) - Bridge(lan_interface, child.get_interfaces()[0]) + self.local_portal = None + + def set_local_portal(self, local_portal): + self.local_portal = local_portal + + def get_internet_setup(self) -> Optional[str]: + return textwrap.dedent(''' + set -e + + wget -q http://10.20.0.11/minio-client + chmod +x minio-client + + ./minio-client alias set s3 http://10.20.0.25:3900 {access_key} {secret_key} || \ + ./minio-client alias set s3 s3.us-west-001.backblazeb2.com {access_key} {secret_key} + ./minio-client cp s3/dissertation/binaries/debian/{branch} mpbl3p + + cloud-init status --wait + sudo apt-get install -y iperf3 + + chmod +x mpbl3p + + ''').format(**self.setup_params) + + def get_setup(self) -> Optional[str]: + return textwrap.dedent(''' + set -e + + cat << EOF > config.ini + [Host] + PrivateKey = INVALID + + [Peer] + PublicKey = INVALID + Method = TCP + + LocalHost = {local_host} + LocalPort = 1234 + EOF + ''').format( + local_host=self.get_interfaces()[0].get_address(), + **self.setup_params, + ) + + +class LocalPortal(Node): + def __init__(self, wan_interfaces: List[Interface], child: Optional[Node], **kwargs): + if child is not None: + lan_interface = Interface(IpMethod.Manual) + Bridge(lan_interface, child.get_interfaces()[0]) + super().__init__([*wan_interfaces, lan_interface], **kwargs) + else: + super().__init__(wan_interfaces, **kwargs) + + self.remote_portal = None + + def set_remote_portal(self, remote_portal): + self.remote_portal = remote_portal + + def get_internet_setup(self) -> Optional[str]: + return textwrap.dedent(''' + set -e + + wget -q http://10.20.0.11/minio-client + chmod +x minio-client + + ./minio-client alias set s3 http://10.20.0.25:3900 {access_key} {secret_key} || \ + ./minio-client alias set s3 s3.us-west-001.backblazeb2.com {access_key} {secret_key} + ./minio-client cp s3/dissertation/binaries/debian/{branch} mpbl3p + + cloud-init status --wait + sudo apt-get install -y iperf3 + + chmod +x mpbl3p + + ''').format(**self.setup_params) + + def get_setup(self) -> str: + peer_string = textwrap.dedent(''' + [Peer] + PublicKey = INVALID + Method = TCP + + LocalHost = {local_host} + + RemoteHost = {remote_host} + RemotePort = 1234 + ''') + + peers = '\n\n'.join([peer_string.format( + local_host=x.get_address(), + remote_host=self.remote_portal.get_interfaces()[0].get_address(), + ) for x in self.get_interfaces()[:-1]]) + + return textwrap.dedent(''' + set -e + + cat << EOF > config.ini + [Host] + PrivateKey = INVALID + + {peers} + EOF + ''').format(**self.setup_params, peers=peers) From c5513d4abac1efcc261e5fe15ad4f6fdaacdf860 Mon Sep 17 00:00:00 2001 From: Jake Hillion Date: Wed, 4 Nov 2020 22:55:03 +0000 Subject: [PATCH 2/3] readme pre-commit --- README.md | 11 +++++- evaluation.ipynb | 96 ++++++++---------------------------------------- 2 files changed, 26 insertions(+), 81 deletions(-) diff --git a/README.md b/README.md index 7f269d0..d3abf29 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,13 @@ # Dissertation Evaluation A Python backing to partially automate producing the graphs for my dissertation using an iPython Notebook and a Proxmox server. - \ No newline at end of file + +# Git +## Hooks +### pre-commit +Clears the output of the Jupyter notebook to avoid Git churn. + + #!/bin/sh + + jupyter nbconvert --ClearOutputPreprocessor.enabled=True --inplace evaluation.ipynb + git add evaluation.ipynb \ No newline at end of file diff --git a/evaluation.ipynb b/evaluation.ipynb index 11ceeb5..be7d65f 100644 --- a/evaluation.ipynb +++ b/evaluation.ipynb @@ -2,10 +2,8 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "import os\n", @@ -22,7 +20,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "pycharm": { "name": "#%%\n" @@ -56,31 +54,13 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "pycharm": { "name": "#%%\n" } }, - "outputs": [ - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", - "\u001B[0;31mKeyboardInterrupt\u001B[0m Traceback (most recent call last)", - "\u001B[0;32m\u001B[0m in \u001B[0;36m\u001B[0;34m\u001B[0m\n\u001B[1;32m 12\u001B[0m \u001B[0;34m*\u001B[0m\u001B[0mlp\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mget_interfaces\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;36m0\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;36m2\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 13\u001B[0m ])\n\u001B[0;32m---> 14\u001B[0;31m \u001B[0mrunner\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mbuild\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mtop_level_bridge\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 15\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/sync/school/exercises/paper-0/dissertation/3-evaluation/runners/runners.py\u001B[0m in \u001B[0;36mbuild\u001B[0;34m(self, bridge)\u001B[0m\n\u001B[1;32m 137\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_build_bridges\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 138\u001B[0m \u001B[0;32mfor\u001B[0m \u001B[0mnode\u001B[0m \u001B[0;32min\u001B[0m \u001B[0mnodes\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 139\u001B[0;31m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_build_node\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mnode\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 140\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 141\u001B[0m \u001B[0;32mdef\u001B[0m \u001B[0m_await_task\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mself\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mupid\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mtimeout\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0;36m10\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/sync/school/exercises/paper-0/dissertation/3-evaluation/runners/runners.py\u001B[0m in \u001B[0;36m_build_node\u001B[0;34m(self, node)\u001B[0m\n\u001B[1;32m 262\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_await_task\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mstart_task\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 263\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 264\u001B[0;31m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_open_ssh\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mnode\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 265\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mssh\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mnode\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mnode\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mget_internet_setup\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 266\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_close_ssh\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mnode\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/sync/school/exercises/paper-0/dissertation/3-evaluation/runners/runners.py\u001B[0m in \u001B[0;36m_open_ssh\u001B[0;34m(self, node, interface)\u001B[0m\n\u001B[1;32m 206\u001B[0m \u001B[0;32mwhile\u001B[0m \u001B[0;34m(\u001B[0m\u001B[0mdatetime\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mnow\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m)\u001B[0m \u001B[0;34m-\u001B[0m \u001B[0mt1\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mseconds\u001B[0m \u001B[0;34m<\u001B[0m \u001B[0mProxmoxRunner\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mssh_timeout\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 207\u001B[0m \u001B[0;32mtry\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 208\u001B[0;31m client.connect(\n\u001B[0m\u001B[1;32m 209\u001B[0m \u001B[0mhostname\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mstr\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0minterface\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mget_address\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 210\u001B[0m \u001B[0musername\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0;34m'python'\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/sync/school/exercises/paper-0/dissertation/3-evaluation/venv/lib/python3.8/site-packages/paramiko/client.py\u001B[0m in \u001B[0;36mconnect\u001B[0;34m(self, hostname, port, username, password, pkey, key_filename, timeout, allow_agent, look_for_keys, compress, sock, gss_auth, gss_kex, gss_deleg_creds, gss_host, banner_timeout, auth_timeout, gss_trust_dns, passphrase, disabled_algorithms)\u001B[0m\n\u001B[1;32m 347\u001B[0m \u001B[0;32mexcept\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 348\u001B[0m \u001B[0;32mpass\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 349\u001B[0;31m \u001B[0mretry_on_signal\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;32mlambda\u001B[0m\u001B[0;34m:\u001B[0m \u001B[0msock\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mconnect\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0maddr\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 350\u001B[0m \u001B[0;31m# Break out of the loop on success\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 351\u001B[0m \u001B[0;32mbreak\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/sync/school/exercises/paper-0/dissertation/3-evaluation/venv/lib/python3.8/site-packages/paramiko/util.py\u001B[0m in \u001B[0;36mretry_on_signal\u001B[0;34m(function)\u001B[0m\n\u001B[1;32m 281\u001B[0m \u001B[0;32mwhile\u001B[0m \u001B[0;32mTrue\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 282\u001B[0m \u001B[0;32mtry\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 283\u001B[0;31m \u001B[0;32mreturn\u001B[0m \u001B[0mfunction\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 284\u001B[0m \u001B[0;32mexcept\u001B[0m \u001B[0mEnvironmentError\u001B[0m \u001B[0;32mas\u001B[0m \u001B[0me\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 285\u001B[0m \u001B[0;32mif\u001B[0m \u001B[0me\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0merrno\u001B[0m \u001B[0;34m!=\u001B[0m \u001B[0merrno\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mEINTR\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;32m~/sync/school/exercises/paper-0/dissertation/3-evaluation/venv/lib/python3.8/site-packages/paramiko/client.py\u001B[0m in \u001B[0;36m\u001B[0;34m()\u001B[0m\n\u001B[1;32m 347\u001B[0m \u001B[0;32mexcept\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 348\u001B[0m \u001B[0;32mpass\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 349\u001B[0;31m \u001B[0mretry_on_signal\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;32mlambda\u001B[0m\u001B[0;34m:\u001B[0m \u001B[0msock\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mconnect\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0maddr\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 350\u001B[0m \u001B[0;31m# Break out of the loop on success\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 351\u001B[0m \u001B[0;32mbreak\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", - "\u001B[0;31mKeyboardInterrupt\u001B[0m: " - ] - } - ], + "outputs": [], "source": [ "rp = RemotePortal([Interface(IpMethod.Auto4)], setup_params=setup_params)\n", "lp = LocalPortal([\n", @@ -103,7 +83,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": { "pycharm": { "name": "#%%\n" @@ -148,7 +128,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { "pycharm": { "name": "#%%\n" @@ -179,24 +159,13 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": { "pycharm": { "name": "#%%\n" } }, - "outputs": [ - { - "data": { - "text/plain": "
", - "image/png": "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pHQpTKwVIZZdu3Zh586dOOGEE9Jqk8GmTZsQa0UZNmwYmjRpgnr16qFnz55Yt24dQqEQhg4dilatWqFWrVoYNWpUOTmJSHT+AZR+nuy8TpgwAV988QXC4XC52bjBzJkz8frrryM7OxtHH300tm/fjpUrV2L27Nm46KKLULNmTbRt2xYnnXRSuf1at26N3377LWX7FUXxBz9mwMcBGA1gIRHlRD67i5lnWD2glZmq2yxcuBBNmzYtZxZMxcCBA7Fw4ULUr1+/tKOOR6tWrdC/f3/89NNPcf3JRqTrJ598gtmzZ+N///sf/vGPf2DhwoVxFXE6GLPImjVrljNvRs8uje+YGZdddhkefvjhcsf43//+Z6sNZttkcMghh1RYehOvvU4RHWncoEGDlNtv374de/fuRWFhIfLz8yvsw8x45plncOqpp5b7fMaM5I9Mfn4+DjnkkDRariiKl/gRBf09MxMzZzFzduRlWflmIu+//z7y8vIwe/Zs3HDDDXHNv4mYOHFiyoCf/fv3Y/78+ejcuTMAoKSkpDRg56233sLgwYNRUlKC9evX48QTT8QjjzyCXbt2Ye/eveWOc/LJJ+PFF18sVT55eXno3r071q5di1WrVgEA3njjjdKZZ7oMGzYM06dPLx2E5OXlYd26dRg0aBBmz55damLPy8sDADRq1Ah79uypcJwmTZqgWbNmpf7ddNvUrVu3uDPjWAYOHIhvv/0W27ZtQ3FxMaZOnVoqp3bt2igsLIy7X7zzH0uy83rNNdfg73//O0aNGlXqd47m1FNPxaRJk0rlr1ixAvv27cOQIUPw9ttvo7i4GJs2bcLXX39dbr8VK1aYjtBXFMV7NBe0DS666CIcc8wxWL58Odq1a4eXX34Z27Ztwx133IGXXnoJ3bp1w/XXX4+bbpJcI08//TTatWuHDRs2ICsrC1deeWWFY55++uk48cQT48obNWoUsrOzMWDAAIwZM6bUt9egQQP8/PPP6N27N7766itMmDABxcXFuOSSS9CnTx/069cPN954I5o2bVrueFdeeSU6dOiArKws9O3bF2+99Rbq1auH//znPzjvvPPQp08f1KhRA9dee62l89OzZ088+OCDOOWUU5CVlYWTTz651Bw8efJknH322ejbt2+pmfaPf/wjPvjgg9IgrGhee+013H777cjKykJOTg4mTJhguh0NGjRA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\n" - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "plot_iperf_results(\n", " {\n", @@ -209,24 +178,13 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": { "pycharm": { "name": "#%%\n" } }, - "outputs": [ - { - "data": { - "text/plain": "
", - "image/png": "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\n" - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "plot_iperf_results(\n", " {\n", @@ -241,24 +199,13 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": { "pycharm": { "name": "#%%\n" } }, - "outputs": [ - { - "data": { - "text/plain": "
", - "image/png": "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TU1NUx/PPvtsfPzxx16fA4Ig2jZt1gvandtvB7Zu1fea6enAc88pO9Zut2PLli2YMmUKoqKi8O677+LCCy/Eiy++iGXLluH3338PeA3GGE466ST8+OOPqKiowNlnn43s7OwWxyxYsAAxMTHYv38/nnvuuSYBXF1djYkTJ+LZZ5/Fww8/jIceeggvvfQSHn/8cWRnZyMmJgbl5eWt2nzjjTdgt9uxdetWREVFoaysDLW1tbj66qvx66+/YtiwYbjyyivx6quv4vbbbwcA9OnTB5s3b8Yrr7yCp556Cm+99RYAYM+ePbDZbKisrMTw4cNx880348CBA/j000+xevVqREdH45ZbbsGSJUswf/58XH/99Vi5ciVSUlJQVlaGXr164aabbkK3bt1w1113ARATAcmVV16JF198EXPmzMEDDzyAhx56CM+5vqDGxkasX78e33//PR566CH88ssveO2113DbbbdhwYIFqK+v96q5rl69Gq+//nrT/3v37sXbb7+NGTNmYNGiRXjllVea+tK7d29s3rwZBQUFmDp1KjZt2oSePXvilFNOwddff43zzjsPX3zxBV5++WUsW7YMDz30EAYMGNA0SQGARx99FHPnzsU777yD8vJyTJ48GSeddBJef/11dOnSBVlZWdi+fXvTxA4Aevbsibq6Ohw5cgS9e/cO+BwRBNF2IA04SKqqqnDBBRfgueeeazJlpqam4oorrsCZZ56Jd955B506dVJ0rUsvvRSffPIJPvnkE1x22WWt9i9ZsgTbt29Hbm4unnrqKeTk5AAAIiIicMkllwAAFi5ciFWrVgEAxowZgwULFuDDDz9EVFTrudYvv/yCG2+8sWlfr169sHfvXqSkpGDYsGEAgKuuugorV65sOuf8888HAEyYMAF2u71p+xlnnIGYmBj06dMH/fr1Q1FREX799Vds2rQJkyZNQnp6On799VccPHgQ69atw+zZs5tCTXr16uX3vlRUVKC8vBxz5sxR3Kdp06bhsccewxNPPIGcnBx07ty51XXLysrQvXv3pv+TkpIwY8aMVvcRQNP93bBhAzIyMtC3b19ERUVhwYIFTX158cUX8e9//xsxMTFev7+ffvoJjz/+ONLT05GRkYHa2lrk5uZi5cqVWLhwIQDxnY0ZM6bFef369UNBQYHfe0QQRNujXWjASjVVvWloaMAFF1yABQsW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\n" - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "plot_iperf_results(\n", " {\n", @@ -272,24 +219,13 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": { "pycharm": { "name": "#%%\n" } }, - "outputs": [ - { - "data": { - "text/plain": "
", - "image/png": "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lZW8Z88ezs3N5V27dvHChQu5S5cuvHnzZmZmvvfee/naa69lZua1a9fyoEGDuKqqisvLy3n48OG8aNEiHjFiRON30tfm8ePHecqUKVxRUcHMzM8991zjfsaNG8cffvghMzPffPPNza6nxYsX8/nnn98ifubgHfCLL77IL774IjMzz57NDDCXlfmz7/p6tb+zzvJnf0L6A3HAyaWgoABXX301zj//fDz22GPo0KFDs8+//e1vY+rUqTj99NObLddu8bnnnsOVV17ZYr/PPPMMVqxYge3bt+Pee+/Ftm2qxGi7du3w1a9+FQBw1VVXYfHixQCAwsJCzJkzB08//TTat1cjzt566y0UFxejuLgYr732Gm644QYUFxfj5JNPjut71dfXo76+HjfddBNOOukkjBo1qtk2GRkZOO200/Dcc8+hqqoK0ZNqDB8+HMuXL8emTZvwwAMP4MYbb2z87Mwzz0SfPn3QuXNnXHLJJVi8eDHGjRuHd955Bz/96U/x0UcfoWfPns32d+TIEezatQsXX3wxADWutEuXLli8eDGuvPJKZGRkYMCAAZg2bRqWLFkCAJg8eTJyc3PRrl07FBcXY6ulA0879okTJzYuf/vtt3H33XejuLgY06dPR3V1NbZv3453330X3/jGNxrPdXQrQjSLFy/GxRdfjK5du6Jbt2645JJL8NFHHwEAhg0b1tgCYj223d/USllZGfr1a173/aKLLkLnzp3Rt29fzJgxA59++mnj99bDfRYvXoyrrroKADB69GgMGTIE69evx4ABA3DXXXdhxowZuO+++1p8p5KSEqxatQpnnnkmiouL8atf/Qo7d+7EwYMHcfDgQUydOhUAcPXVVzfbrn///igtLXU8P0Fx+PBhHD58GAAQaVhAxLQnzLFj6vnIEX/2J7Ru0nYcsJVIy11KsXLlSmRlZaGioqLZ8jvvvBN79uzBww8/3GKbyZMnY+XKlejSpQtGjhwZc9/9+vXDhAkT8N///hdDhgxp8bnOJH3jjTewaNEivP766/j1r3+NlStX4uyzz8bZZ58NQDUjzp07F9OnT0/4e7Vr1w7t2tnfz11xxRW4+OKLcccddzju+8ILL8S1117b4ntY348cORKfffYZ3nzzTfziF7/AzJkzcfvttxvHb0fHjh0bX2dkZKCurq7FZ9blzIwXX3yxxc2Gn0THpJug7f6mViHu3Llzi2E8ducRALp27WoUy8qVK9GnTx9bwWRmFBQU4JNPPmm23C3JrLq6Gp07dzY6fpDoU1VaCowfn/j+tPCKAAsmiAMOgJdeegn79+/HokWL8N3vfrfxx+jRRx/FW2+9hWeffTamWN199934zW9+47j/yspKfP755xg+fDgAoKGhobE/7h//+AdOO+00NDQ0YMeOHZgxYwZ++9vf4tChQzh69Ggg38uN008/Hbfccoutq7eyePHixu8EAO+88w7279+PqqoqvPLKK/jSl76E0tJSdOnSBVdddRV+/OMf47PPPmu2j+7duyM3NxevvPIKAKCmpgaVlZU4/fTT8fzzz6O+vh579uzBokWLMHnyZE/fX3P22WfjD3/4Q2Nf8eeffw5AOfaHH364Uaj3RzoCu3fvjiM2v8inn346XnnlFVRWVuLYsWN4+eWXW7SKWDH5m44ZMwYbN25stuzVV19FdXU19u3bhw8++AAnnXSSbSzPPPMMAGD9+vXYvn07Ro0ahU8//RT/+te/8Pnnn+Pee+/Fli1bmm03atQo7Nmzp1GAa2trsXr1amRlZSErK6uxNUbvW7N+/Xrj0QNB4rcDFgEWvCACnABXXnklpkyZgpKSEuTm5uJvf/sb9u7di5/97Gd49NFHMXLkSHznO9/B97//fQDAN7/5TezevRtTpkxBcXEx7rrrrhb7POeccxqTdaKZM2cOiouLMXHiRMydOxcTJ04EoJzMp59+irFjx+L999/H7bffjvr6elx11VWNSTXf+973kJWVFcj3coOIcPPNN9tWy9q0aVPjMKRbb70Vjz76aONnkydPxqWXXorCwkJceumlmDRpElauXInJkyejuLgYd955J37xi1+02OdTTz2FBx98EIWFhTj11FNRXl6Oiy++GIWFhSgqKsIZZ5yBe+65p3Eoilduu+021NbWorCwEAUFBbjtttsAADfccAMGDx7ceJx//OMfAIAbb7wRs2fPbvF3nTBhAubOnYvJkyfj5JNPxg033IDxDjbM5G86evRoHDp0qJngFxYWYsaMGTjllFNw2223IScnp8W+v/3tb6OhoQHjxo3DV7/6VTzxxBMAgK9//et47LHHkJOTg/vuuw/XXXdds2FlHTp0wAsvvICf/vSnKCoqQnFxMT7++GMAwOOPP46bbroJxcXFzbYBgIULF+K8885zOdPB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\n" - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "plot_iperf_results(\n", " {\n", @@ -334,4 +270,4 @@ }, "nbformat": 4, "nbformat_minor": 1 -} \ No newline at end of file +} From 165bb130d62c862b44f91745092ebda347f2e34a Mon Sep 17 00:00:00 2001 From: Jake Hillion Date: Thu, 5 Nov 2020 17:25:23 +0000 Subject: [PATCH 3/3] functioning automatic testing --- README.md | 2 +- evaluation.ipynb | 324 ++++++++++++++++++++++++++++++++++------- runners/runners.py | 75 ++++++++-- structure/structure.py | 86 +++++++++-- 4 files changed, 411 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index d3abf29..ae82642 100644 --- a/README.md +++ b/README.md @@ -10,4 +10,4 @@ Clears the output of the Jupyter notebook to avoid Git churn. #!/bin/sh jupyter nbconvert --ClearOutputPreprocessor.enabled=True --inplace evaluation.ipynb - git add evaluation.ipynb \ No newline at end of file + git add evaluation.ipynb diff --git a/evaluation.ipynb b/evaluation.ipynb index be7d65f..721c447 100644 --- a/evaluation.ipynb +++ b/evaluation.ipynb @@ -1,5 +1,27 @@ { "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Project Evaluation\n", + "\n", + "This file interfaces with a Proxmox server to automatically generate VM structures and graphs for testing the\n", + "success criteria of my project." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## Setup\n", + "This section sets up the required variables for the Proxmox server." + ] + }, { "cell_type": "code", "execution_count": null, @@ -8,6 +30,7 @@ "source": [ "import os\n", "import ipaddress\n", + "import threading\n", "\n", "import runners\n", "from structure import Bridge\n", @@ -18,6 +41,18 @@ "%dotenv" ] }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## Testing\n", + "This section gathers the required data from the different structures for later graphs." + ] + }, { "cell_type": "code", "execution_count": null, @@ -41,7 +76,6 @@ " internet_bridge=os.getenv('INTERNET_BRIDGE'),\n", "\n", " management_bridge=os.getenv('MANAGEMENT_BRIDGE'),\n", - " management_gateway=ipaddress.ip_address(os.getenv('MANAGEMENT_GATEWAY')),\n", " management_initial_ip=ipaddress.ip_address(os.getenv('MANAGEMENT_INITIAL_IP')),\n", ")\n", "\n", @@ -49,7 +83,10 @@ " 'access_key': os.getenv('S3_ACCESS_KEY'),\n", " 'secret_key': os.getenv('S3_SECRET_KEY'),\n", " 'branch': os.getenv('TARGET_BRANCH'),\n", - "}" + "}\n", + "\n", + "directionInbound = {}\n", + "directionOutbound = {}" ] }, { @@ -64,8 +101,49 @@ "source": [ "rp = RemotePortal([Interface(IpMethod.Auto4)], setup_params=setup_params)\n", "lp = LocalPortal([\n", - " Interface(IpMethod.Auto4, limit=1),\n", - " Interface(IpMethod.Auto4, limit=1),\n", + " Interface(IpMethod.Auto4),\n", + "], None, setup_params=setup_params)\n", + "\n", + "rp.set_local_portal(lp)\n", + "lp.set_remote_portal(rp)\n", + "\n", + "top_level_bridge = Bridge(*[\n", + " rp.get_interfaces()[0],\n", + " lp.get_interfaces()[0],\n", + "])\n", + "\n", + "try:\n", + " runner.build(top_level_bridge)\n", + "\n", + " lp.get_interfaces()[0].set_rate(1)\n", + " lp.speedtest_server()\n", + " directionInbound['One1MBNotProxied'] = rp.speedtest_client(lp.get_interfaces()[0].get_address())\n", + " rp.speedtest_server()\n", + " directionOutbound['One1MBNotProxied'] = lp.speedtest_client(rp.get_interfaces()[0].get_address())\n", + "\n", + " lp.get_interfaces()[0].set_rate(2)\n", + " lp.speedtest_server()\n", + " directionInbound['One2MBNotProxied'] = rp.speedtest_client(lp.get_interfaces()[0].get_address())\n", + " rp.speedtest_server()\n", + " directionOutbound['One2MBNotProxied'] = lp.speedtest_client(rp.get_interfaces()[0].get_address())\n", + "finally:\n", + " runner.teardown()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "rp = RemotePortal([Interface(IpMethod.Auto4)], setup_params=setup_params)\n", + "lp = LocalPortal([\n", + " Interface(IpMethod.Auto4),\n", + " Interface(IpMethod.Auto4),\n", "], None, setup_params=setup_params)\n", "\n", "rp.set_local_portal(lp)\n", @@ -75,10 +153,136 @@ " rp.get_interfaces()[0],\n", " *lp.get_interfaces()[0:2],\n", "])\n", - "runner.build(top_level_bridge)\n", "\n", - "# Clean up\n", - "runner.teardown()" + "try:\n", + " runner.build(top_level_bridge)\n", + "\n", + " lp.get_interfaces()[0].set_rate(1)\n", + " lp.get_interfaces()[1].set_rate(1)\n", + "\n", + " lp.speedtest_server()\n", + " directionInbound['Two1MBProxied'] = rp.speedtest_client('172.19.152.3')\n", + " rp.speedtest_server()\n", + " directionOutbound['Two1MBProxied'] = lp.speedtest_client('172.19.152.2')\n", + "\n", + " lp.get_interfaces()[0].set_rate(2)\n", + " lp.get_interfaces()[1].set_rate(2)\n", + "\n", + " lp.speedtest_server()\n", + " directionInbound['Two2MBProxied'] = rp.speedtest_client('172.19.152.3')\n", + " rp.speedtest_server()\n", + " directionOutbound['Two2MBProxied'] = lp.speedtest_client('172.19.152.2')\n", + "\n", + " lp.get_interfaces()[0].set_rate(1)\n", + " lp.get_interfaces()[1].set_rate(2)\n", + "\n", + " lp.speedtest_server()\n", + " directionInbound['One1MBOne2MBProxied'] = rp.speedtest_client('172.19.152.3')\n", + " rp.speedtest_server()\n", + " directionOutbound['One1MBOne2MBProxied'] = lp.speedtest_client('172.19.152.2')\n", + "\n", + " lp.get_interfaces()[0].set_rate(2)\n", + " lp.get_interfaces()[1].set_rate(2)\n", + "\n", + " lp.speedtest_server()\n", + " threading.Timer(5+15, lambda: lp.get_interfaces()[1].set_rate(1)).start()\n", + " threading.Timer(5+30, lambda: lp.get_interfaces()[1].set_rate(2)).start()\n", + "\n", + " directionInbound['One2MBOneYMBProxiedSlow15Return30'] = rp.speedtest_client('172.19.152.3', time=60)\n", + " rp.speedtest_server()\n", + " directionOutbound['One2MBOneYMBProxiedSlow15Return30'] = lp.speedtest_client('172.19.152.2', time=60)\n", + "finally:\n", + " runner.teardown()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "rp = RemotePortal([Interface(IpMethod.Auto4)], setup_params=setup_params)\n", + "lp = LocalPortal([\n", + " Interface(IpMethod.Auto4),\n", + " Interface(IpMethod.Auto4),\n", + " Interface(IpMethod.Auto4),\n", + "], None, setup_params=setup_params)\n", + "\n", + "rp.set_local_portal(lp)\n", + "lp.set_remote_portal(rp)\n", + "\n", + "top_level_bridge = Bridge(*[\n", + " rp.get_interfaces()[0],\n", + " *lp.get_interfaces()[0:3],\n", + "])\n", + "\n", + "try:\n", + " runner.build(top_level_bridge)\n", + "\n", + " lp.get_interfaces()[0].set_rate(1)\n", + " lp.get_interfaces()[1].set_rate(1)\n", + " lp.get_interfaces()[2].set_rate(1)\n", + "\n", + " lp.speedtest_server()\n", + " directionInbound['Three1MBProxied'] = rp.speedtest_client('172.19.152.3')\n", + " rp.speedtest_server()\n", + " directionOutbound['Three1MBProxied'] = lp.speedtest_client('172.19.152.2')\n", + "finally:\n", + " runner.teardown()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "rp = RemotePortal([Interface(IpMethod.Auto4)], setup_params=setup_params)\n", + "lp = LocalPortal([\n", + " Interface(IpMethod.Auto4),\n", + " Interface(IpMethod.Auto4),\n", + " Interface(IpMethod.Auto4),\n", + " Interface(IpMethod.Auto4),\n", + "], None, setup_params=setup_params)\n", + "\n", + "rp.set_local_portal(lp)\n", + "lp.set_remote_portal(rp)\n", + "\n", + "top_level_bridge = Bridge(*[\n", + " rp.get_interfaces()[0],\n", + " *lp.get_interfaces()[0:4],\n", + "])\n", + "\n", + "try:\n", + " runner.build(top_level_bridge)\n", + "\n", + " lp.get_interfaces()[0].set_rate(1)\n", + " lp.get_interfaces()[1].set_rate(1)\n", + " lp.get_interfaces()[2].set_rate(1)\n", + " lp.get_interfaces()[3].set_rate(1)\n", + "\n", + " lp.speedtest_server()\n", + " directionInbound['Four1MBProxied'] = rp.speedtest_client('172.19.152.3')\n", + " rp.speedtest_server()\n", + " directionOutbound['Four1MBProxied'] = lp.speedtest_client('172.19.152.2')\n", + "finally:\n", + " runner.teardown()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Graphs\n", + "This section produces graphs from the collected data." ] }, { @@ -127,34 +331,15 @@ ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": { "pycharm": { - "name": "#%%\n" + "name": "#%% md\n" } }, - "outputs": [], "source": [ - "# Manual results\n", - "# sudo iperf3 -c X.X.X.X -t 30 -O 5 -J\n", - "\n", - "import json\n", - "\n", - "def load_json_from_file(path):\n", - " with open(path, 'r') as f:\n", - " return json.loads(f.read())\n", - "\n", - "One1MBStraight = load_json_from_file('manual/One1MBStraight.json')\n", - "One2MBStraight = load_json_from_file('manual/One2MBStraight.json')\n", - "\n", - "Two1MBAggregate = load_json_from_file('manual/Two1MBAggregate.json')\n", - "Two2MBAggregate = load_json_from_file('manual/Two2MBAggregate.json')\n", - "\n", - "One1MBOne2MBAggregate = load_json_from_file('manual/One1MBOne2MBAggregate.json')\n", - "\n", - "# A 60 second long test\n", - "Two2MBAggregateKillOneRecoverOne = load_json_from_file('manual/Two2MBAggregateKillOneRecoverOne.json')\n" + "### Equal Connection Scaling\n", + "This section shows equal connections scaling at various speeds and number of connections." ] }, { @@ -169,10 +354,10 @@ "source": [ "plot_iperf_results(\n", " {\n", - " '1x1MBps connection (not proxied)': One1MBStraight,\n", - " '2x1MBps connections (proxied)': Two1MBAggregate,\n", + " '2x1MBps Connections (proxied)': directionInbound['Two1MBProxied'],\n", + " '1x1MBps Connection (not proxied)': directionInbound['One1MBNotProxied'],\n", " },\n", - " 'Proxying adds additional bandwidth',\n", + " 'Two Equal 1MB Connections',\n", ")" ] }, @@ -188,12 +373,10 @@ "source": [ "plot_iperf_results(\n", " {\n", - " '1x1MBps connection (not proxied)': One1MBStraight,\n", - " '2x1MBps connections (proxied)': Two1MBAggregate,\n", - " '1x2MBps connection (not proxied)': One2MBStraight,\n", - " '2x2MBps connections (proxied)': Two2MBAggregate,\n", + " '2x2MBps Connections (proxied)': directionInbound['Two2MBProxied'],\n", + " '1x2MBps Connection (not proxied)': directionInbound['One2MBNotProxied'],\n", " },\n", - " 'Proxing bandwidth scaling/overhead',\n", + " 'Two Equal 2MB Connections',\n", ")" ] }, @@ -209,11 +392,43 @@ "source": [ "plot_iperf_results(\n", " {\n", - " '2x1MBps connections (proxied)': Two1MBAggregate,\n", - " '1x1MBps+1x2MBps connections (proxied)': One1MBOne2MBAggregate,\n", - " '2x2MBps connections (proxied)': Two2MBAggregate,\n", + " '4x1MBps Connections (proxied)': directionInbound['Four1MBProxied'],\n", + " '3x1MBps Connections (proxied)': directionInbound['Three1MBProxied'],\n", + " '2x1MBps Connections (proxied)': directionInbound['Two1MBProxied'],\n", " },\n", - " 'Imbalanced connections add',\n", + " 'More Equal Connections',\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "### Mixed Connections Scaling\n", + "This section shows mixed connections at various speeds with various events." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, + "outputs": [], + "source": [ + "plot_iperf_results(\n", + " {\n", + " '2x2MBps Connections (proxied)': directionInbound['Two2MBProxied'],\n", + " '1x1MBps + 1x2MBps Connections (proxied)': directionInbound['One1MBOne2MBProxied'],\n", + " '2x1MBps Connections (proxied)': directionInbound['Two1MBProxied'],\n", + " },\n", + " 'Mixed Speed Connections',\n", ")" ] }, @@ -229,22 +444,29 @@ "source": [ "plot_iperf_results(\n", " {\n", - " '1x2MBps+1xYMBps connections (proxied)': Two2MBAggregateKillOneRecoverOne,\n", + " '1x2MBps + 1xYMBps Connections (proxied)': directionInbound['One2MBOneYMBProxiedSlow15Return30'],\n", " },\n", - " 'Killed connection',\n", - " events={15: 'Y = 0', 40: 'Y = 2'},\n", - " filename='graph4.png',\n", + " 'Network Slow',\n", + " events={0: 'Y=2', 15: 'Y=1', 30: 'Y=2'}\n", ")" ] }, + { + "cell_type": "markdown", + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, + "source": [ + "## Criteria\n", + "This section automatically verifies some criteria with assertions." + ] + }, { "cell_type": "code", "execution_count": null, - "metadata": { - "pycharm": { - "name": "#%%\n" - } - }, + "metadata": {}, "outputs": [], "source": [] } diff --git a/runners/runners.py b/runners/runners.py index 21e319f..eba29e1 100644 --- a/runners/runners.py +++ b/runners/runners.py @@ -1,8 +1,10 @@ +import concurrent.futures import ipaddress import os +import re import time from datetime import datetime -from typing import Callable, List, Tuple +from typing import Callable, List, Tuple, Optional, Union from urllib.parse import quote import proxmoxer @@ -97,7 +99,7 @@ class ProxmoxRunner: management_bridge: str, management_initial_ip: ipaddress, - management_gateway: ipaddress, + management_netmask: int = 24, verify_ssl: bool = False, ): @@ -125,7 +127,7 @@ class ProxmoxRunner: self._management_bridge = structure.Bridge() self._management_bridge.set_name(management_bridge) self._management_initial_ip = management_initial_ip - self._management_gateway = management_gateway + self._management_netmask = management_netmask # generate a single use SSH key (we can use any with Proxmox) self._private_key = paramiko.RSAKey.generate(3072) @@ -136,13 +138,16 @@ class ProxmoxRunner: self._build_bridges() - for node in nodes: - self._build_node(node) + with concurrent.futures.ThreadPoolExecutor(max_workers=8) as executor: + build_futures = [executor.submit(self._build_node, node) for node in nodes] + for future in build_futures: + future.result() - # guarantee that setup is not called until all of the nodes are built - # this means that all will have their final IPs by this point - for node in nodes: - self._setup_node(node) + # guarantee that setup is not called until all of the nodes are built + # this means that all will have their final IPs by this point + setup_futures = [executor.submit(self._setup_node, node) for node in nodes] + for future in setup_futures: + future.result() def _await_task(self, upid, timeout=10): t1 = datetime.now() @@ -228,7 +233,14 @@ class ProxmoxRunner: node.client.close() del node.client - def ssh(self, node: structure.Node, command: str, error_stderr=False, error_stdout=False) -> int: + def ssh( + self, + node: structure.Node, + command: str, + error_stderr=False, + error_stdout=False, + return_stdout=False, + ) -> Union[int, str]: chan = node.client.get_transport().open_session() chan.exec_command(command) @@ -243,6 +255,12 @@ class ProxmoxRunner: if error_stdout: raise Exception(chan.recv(2048).decode()) + if return_stdout is not False: + if return_stdout is True: + return chan.makefile().read() + else: + return chan.recv(return_stdout).decode() + return exit_status def _build_node(self, node: structure.Node): @@ -260,7 +278,7 @@ class ProxmoxRunner: interfaces = node.get_interfaces() internet_interface = structure.Interface(structure.IpMethod.Dhcp4) internet_interface.set_bridge(self._internet_bridge) - temp_interfaces = [internet_interface, interfaces[len(interfaces)-1]] + temp_interfaces = [internet_interface, interfaces[len(interfaces) - 1]] self._setup_node_interfaces(node, temp_interfaces) @@ -272,7 +290,7 @@ class ProxmoxRunner: self._close_ssh(node) stop_task = self._proxmox.nodes(self._proxmox_node).qemu(node.get_id()).status.shutdown.post() - self._await_task(stop_task) + self._await_task(stop_task, timeout=20) # Step 3: connect to management bridge for final setup self._setup_node_interfaces(node) @@ -281,6 +299,7 @@ class ProxmoxRunner: self._await_task(start_task) self._open_ssh(node) + node.ssh = (lambda n: lambda *args, **kwargs: self.ssh(n, *args, **kwargs))(node) def _setup_node_interfaces(self, node: structure.Node, interfaces: List[structure.Interface] = None): if interfaces is None: @@ -297,7 +316,7 @@ class ProxmoxRunner: interface.set_bridge(self._management_bridge) addr = self._management_initial_ip + node.get_id() - self._initial_vm_id - kwargs['ipconfig{}'.format(i)] = 'ip={}/24,gw={}'.format(addr, self._management_gateway) + kwargs['ipconfig{}'.format(i)] = 'ip={}/{}'.format(addr, self._management_netmask) interface.set_address(addr) elif method == structure.IpMethod.Auto4: bridge = interface.get_bridge() @@ -311,9 +330,39 @@ class ProxmoxRunner: raise RuntimeError('not implemented') kwargs['net{}'.format(i)] = 'model=virtio,bridge={}'.format(interface.get_bridge().get_name()) + if interface.get_rate() is not None: + kwargs['net{}'.format(i)] += ',rate={}'.format(interface.get_rate()) + + def interface_set_rate(iface): + def new_set_rate(rate: Optional[int]): + structure.Interface.set_rate(iface, rate) + self._update_node_interfaces(node) + + return new_set_rate + + interface.set_rate = interface_set_rate(interface) self._proxmox.nodes(self._proxmox_node).qemu(node.get_id()).config.put(**kwargs) + def _update_node_interfaces(self, node: structure.Node): + interfaces = node.get_interfaces() + + old_config = self._proxmox.nodes(self._proxmox_node).qemu(node.get_id()).config.get() + old_digest = old_config['digest'] + old_config = {k: v for (k, v) in old_config.items() if k[:3] == 'net'} + + rate_regex = re.compile(r',rate=(\d+(?:\.\d+)?)') + + new_config = {'digest': old_digest} + for k, v in old_config.items(): + index = int(k[3:]) + iface = interfaces[index] + new_config[k] = rate_regex.sub('', v) + if iface.get_rate() is not None: + new_config[k] += ',rate={}'.format(iface.get_rate()) + + self._proxmox.nodes(self._proxmox_node).qemu(node.get_id()).config.put(**new_config) + def _setup_node(self, node: structure.Node): if node.get_setup() is not None: self.ssh(node, node.get_setup(), error_stdout=True, error_stderr=True) diff --git a/structure/structure.py b/structure/structure.py index 27c69bf..335e05c 100644 --- a/structure/structure.py +++ b/structure/structure.py @@ -1,4 +1,5 @@ import ipaddress +import json import textwrap from enum import Enum import random @@ -15,15 +16,15 @@ class IpMethod(Enum): class Interface: - def __init__(self, method: IpMethod, limit: Optional[int] = None): + def __init__(self, method: IpMethod, rate: Optional[int] = None): self._method: IpMethod self._node: Optional[Node] = None - self._limit: Optional[int] = None + self._rate: Optional[int] = None self._bridge: Optional[Bridge] = None self._method = method - self._limit = limit + self._rate = rate self._address: ipaddress.ip_address = None def get_method(self): @@ -47,6 +48,12 @@ class Interface: def get_address(self) -> ipaddress.ip_address: return self._address + def get_rate(self) -> Optional[int]: + return self._rate + + def set_rate(self, rate: Optional[int]): + self._rate = rate + class Bridge: def __init__(self, *interfaces: Interface): @@ -78,6 +85,9 @@ class Bridge: def get_ip_address(self) -> ipaddress.ip_address: return next(self._network_iterator) + def get_network(self) -> str: + return str(ipaddress.ip_network('{}/{}'.format(self._addr, self.netmask), False)) + class Node: def __init__(self, interfaces: List[Interface], setup_params: Dict = None): @@ -111,6 +121,9 @@ class Node: def get_setup(self) -> Optional[str]: return None + def ssh(self, *args, **kwargs): + raise RuntimeError('ssh not implemented') + class SpeedTestServer(Node): def client(self, server: Interface): @@ -144,17 +157,19 @@ class RemotePortal(Node): ./minio-client alias set s3 s3.us-west-001.backblazeb2.com {access_key} {secret_key} ./minio-client cp s3/dissertation/binaries/debian/{branch} mpbl3p - cloud-init status --wait - sudo apt-get install -y iperf3 - chmod +x mpbl3p + cloud-init status --wait || cloud-init status --long + sudo apt-get install -y iperf3 ''').format(**self.setup_params) def get_setup(self) -> Optional[str]: return textwrap.dedent(''' set -e + sudo sysctl -w net.ipv4.conf.all.arp_announce=1 + sudo sysctl -w net.ipv4.conf.all.arp_ignore=2 + cat << EOF > config.ini [Host] PrivateKey = INVALID @@ -166,11 +181,27 @@ class RemotePortal(Node): LocalHost = {local_host} LocalPort = 1234 EOF + + (nohup sudo ./mpbl3p > mpbl3p.log 2>&1 & echo $! > mpbl3p.pid) + + sleep 1 + sudo ip link set up nc0 + sudo ip addr add 172.19.152.2/31 dev nc0 + + ps $(cat mpbl3p.pid) ''').format( local_host=self.get_interfaces()[0].get_address(), **self.setup_params, ) + def speedtest_server(self): + self.ssh('iperf3 -s -1 -D', error_stdout=True, error_stderr=True) + + def speedtest_client(self, target, time=30): + command = 'iperf3 -c {target} -t {time} -O 5 -J'.format(target=target, time=time) + out = self.ssh(command, error_stdout=True, error_stderr=True, return_stdout=True) + return json.loads(out) + class LocalPortal(Node): def __init__(self, wan_interfaces: List[Interface], child: Optional[Node], **kwargs): @@ -196,12 +227,11 @@ class LocalPortal(Node): ./minio-client alias set s3 http://10.20.0.25:3900 {access_key} {secret_key} || \ ./minio-client alias set s3 s3.us-west-001.backblazeb2.com {access_key} {secret_key} ./minio-client cp s3/dissertation/binaries/debian/{branch} mpbl3p - - cloud-init status --wait - sudo apt-get install -y iperf3 - + chmod +x mpbl3p + cloud-init status --wait || cloud-init status --long + sudo apt-get install -y iperf3 ''').format(**self.setup_params) def get_setup(self) -> str: @@ -221,8 +251,26 @@ class LocalPortal(Node): remote_host=self.remote_portal.get_interfaces()[0].get_address(), ) for x in self.get_interfaces()[:-1]]) + policy_routing_string = textwrap.dedent(''' + sudo ip route flush {table_number} + sudo ip route add table {table_number} to {network} dev {device} + sudo ip rule add from {local_address} table {table_number} priority {table_number} + ''') + + policy_routing = '\n\n'.join([policy_routing_string.format( + table_number=i+10, + device='eth{}'.format(i), + network=iface.get_bridge().get_network(), + local_address=iface.get_address(), + ) for i, iface in enumerate(self.get_interfaces()[:-1])]) + return textwrap.dedent(''' set -e + + sudo sysctl -w net.ipv4.conf.all.arp_announce=1 + sudo sysctl -w net.ipv4.conf.all.arp_ignore=2 + + {policy_routing} cat << EOF > config.ini [Host] @@ -230,4 +278,20 @@ class LocalPortal(Node): {peers} EOF - ''').format(**self.setup_params, peers=peers) + + (nohup sudo ./mpbl3p > mpbl3p.log 2>&1 & echo $! > mpbl3p.pid) + + sleep 1 + sudo ip link set up nc0 + sudo ip addr add 172.19.152.3/31 dev nc0 + + ps $(cat mpbl3p.pid) + ''').format(**self.setup_params, peers=peers, policy_routing=policy_routing) + + def speedtest_server(self): + self.ssh('iperf3 -s -1 -D', error_stdout=True, error_stderr=True) + + def speedtest_client(self, target, time=30): + command = 'iperf3 -c {target} -t {time} -O 5 -J'.format(target=target, time=time) + out = self.ssh(command, error_stdout=True, error_stderr=True, return_stdout=True) + return json.loads(out)