Commit 91f0b2aa authored by Simon Redman's avatar Simon Redman

Enough ospf configurator to launch the daemon

parent a7babc72
......@@ -27,6 +27,7 @@ import ssh_helper
......@@ -36,9 +37,14 @@ def generate_repo_clone_command(repo: str, branch: str, path: str) -> str:
return "git clone -b {branch} --single-branch -- {repo} {path}".format(repo=repo, branch=branch, path=path)
def generate_repo_update_command(path: str) -> str:
return "pushd {path}; git pull; popd".format(path=path)
def generate_start_command(path:str=DEFAULT_CLONE_PATH,
executable: str=DEFAULT_EXECUTABLE,
controller: str=DEFAULT_CONTROLLER,
logfile: str=DEFAULT_LOGFILE,
pidfile: str=DEFAULT_PIDFILE,
) -> str:
......@@ -46,16 +52,18 @@ def generate_start_command(path:str=DEFAULT_CLONE_PATH,
Does not do any initialization, such as downloading the sniffer
:param path: Path into which the sniffer was cloned
:param path: Path into which the sniffer was cloned
:param executable: Filename of the sniffer daemon from the repository root
:param controller: Hostname or IP address to which sniffer reports should be sent
:param pidfile: File to which the PID will be written
:param logfile: File to which output from the sniffer should be written
:param pidfile: File to which the PID will be written
return "{path}/{executable} --controller={controller} & echo $! > {pidfile} && disown".format(
return "{path}/{executable} --controller={controller} 1> {logfile} & echo $! > {pidfile} && disown".format(
......@@ -85,6 +93,7 @@ def clone_repo_on_network(graph: networkx.Graph,
# If we try to clone into an existing directory, git will return an error
# (Obviously this will get messed up on a non-English system. Sorry.)
allowed_exception = ".*fatal: destination path \S+ already exists and is not an empty directory"
sessions_needing_updating = []
outputs = ssh_helper.run_commands_on_many_hosts(sessions, commands)
except ssh_helper.SSHCommandErrorError as e:
......@@ -92,10 +101,16 @@ def clone_repo_on_network(graph: networkx.Graph,
output = str.join('', e.output.splitlines()) # Get rid of linebreaks (otherwise we get one every 80 characters)
if re.match(allowed_exception, output):
# No problem: Hopefully we tried to re-clone the repository
e =
# Update anything which needed updating
commands = [generate_repo_update_command(path)] * len(sessions_needing_updating)
outputs = ssh_helper.run_commands_on_many_hosts(sessions_needing_updating, commands)
def start_sniffer_on_network(graph: networkx.Graph,
......@@ -120,7 +135,22 @@ def start_sniffer_on_network(graph: networkx.Graph,
commands = [command for host in hosts]
sessions = [graph._node[host]['session'] for host in hosts]
outputs = ssh_helper.run_commands_on_many_hosts(sessions, commands)
# Since this command puts the sniffer in the background, the naïve default error checking does not work
# First the command is echoed
echos = ssh_helper.unchecked_run_commands_on_many_hosts(sessions, commands)
# Next we check for potential outputs
outputs = list(map(lambda s: ssh_helper.get_output(s, timeout=1), sessions))
# Some real basic error checking
errors = None
for index in range(0, len(outputs)):
# The only good output from a backgrounded script with stdout being redirected to a file is silence
if not len(outputs[index]) == 0:
errors = ssh_helper.SSHCommandErrorError(sessions[index],
if errors is not None: raise errors
def stop_sniffer_on_network(graph: networkx.Graph, pidfile: str=DEFAULT_PIDFILE) -> Optional[str]:
......@@ -139,6 +169,8 @@ if __name__ == "__main__":
help="Regex used to determine which nodes, if any, should be ignored (Default: \".*ovs.*\")")
parser.add_argument("--pid-file", action='store', type=str, default=DEFAULT_PIDFILE,
help="File to write sniffer's PID (Default: {default})".format(default=DEFAULT_PIDFILE))
parser.add_argument("--log-file", action='store', type=str, default=DEFAULT_LOGFILE,
help="File to write sniffer's output (Default: {default})".format(default=DEFAULT_LOGFILE))
parser.add_argument("--controller-name", action='store', type=str, default=DEFAULT_CONTROLLER,
help="Hostname or IP of the node which is listening to the OSPF reports (Default: {default})".format(default=DEFAULT_CONTROLLER))
parser.add_argument("--repo-path", action='store', type=str, default=DEFAULT_REPO_URL,
......@@ -146,7 +178,7 @@ if __name__ == "__main__":
parser.add_argument("--repo-branch", action='store', type=str, default=DEFAULT_REPO_BRANCH,
help="Name of the branch in the repository to check out (Default: {default})".format(default=DEFAULT_REPO_BRANCH))
parser.add_argument("--clone-path", action='store', type=str, default=DEFAULT_CLONE_PATH,
help="Location where the repository should be downloaded (Default: {default})".format(default=DEFAULT_CLONE_PATH))
help="Directory where the repository should be downloaded (Default: {default})".format(default=DEFAULT_CLONE_PATH))
args = parser.parse_args()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment