121 lines
3.1 KiB
Python
Executable file
121 lines
3.1 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
|
|
from lxc_net import parse_network, libvirt_error, util
|
|
import signal
|
|
import libvirt
|
|
import argparse
|
|
import logging
|
|
import sys
|
|
|
|
|
|
def parse_args():
|
|
parser = argparse.ArgumentParser(description="Spawns a network of LXC containers.")
|
|
parser.add_argument("topology", help="A YAML file defining the network topology")
|
|
|
|
args = parser.parse_args()
|
|
return args
|
|
|
|
|
|
def handle_dom(topology, cmd, sudo_drop=True):
|
|
if not cmd:
|
|
print("Missing argument.")
|
|
return
|
|
|
|
if cmd[0] in ["up", "down"]:
|
|
dom_id = None
|
|
if len(cmd) > 1:
|
|
try:
|
|
dom_id = [int(x) for x in cmd[1:]]
|
|
except ValueError:
|
|
print("Bad id: {}".format(cmd[1]))
|
|
return
|
|
state = cmd[0] == "up"
|
|
|
|
util.ensure_sudo_rights()
|
|
if dom_id:
|
|
for dom in dom_id:
|
|
topology.dom_setstate_single(dom, state, verbose=True)
|
|
else:
|
|
topology.dom_setstate(state, verbose=True)
|
|
if sudo_drop:
|
|
util.drop_sudo_rights()
|
|
elif cmd[0] == "restart":
|
|
handle_dom(topology, ["down"] + cmd[1:], sudo_drop=False)
|
|
handle_dom(topology, ["up"] + cmd[1:])
|
|
elif cmd[0] == "help":
|
|
print("Available commands: up, down, restart, help")
|
|
else:
|
|
print("Bad command.")
|
|
|
|
|
|
def main_loop(topology):
|
|
actions = {
|
|
"dom": handle_dom,
|
|
"exit": "_exit",
|
|
"help": "_help",
|
|
}
|
|
|
|
while True:
|
|
print(">> ", end="")
|
|
sys.stdout.flush()
|
|
|
|
try:
|
|
line = input().strip().split()
|
|
if not line: # Empty line
|
|
continue
|
|
|
|
action = actions.get(line[0], "_bad")
|
|
if isinstance(action, str):
|
|
if action == "_bad":
|
|
print("Unknown command: {}.".format(line[0]))
|
|
if action in ["_help", "_bad"]:
|
|
print("Available commands: dom, exit, help")
|
|
elif action == "_exit":
|
|
return
|
|
else:
|
|
print("Unknown action.")
|
|
else:
|
|
action(topology, line[1:])
|
|
except Exception as exn:
|
|
print(exn)
|
|
|
|
|
|
def main():
|
|
args = parse_args()
|
|
|
|
received_sigint = False
|
|
|
|
def handle_sigint(signum, frame):
|
|
""" Called upon SIGINT (^C) """
|
|
nonlocal received_sigint
|
|
|
|
print(" >> Received SIGINT, stopping network...")
|
|
received_sigint = True
|
|
|
|
signal.signal(signal.SIGINT, handle_sigint)
|
|
|
|
logging.basicConfig(level=logging.WARNING)
|
|
libvirt.registerErrorHandler(libvirt_error.libvirt_error_handler, None)
|
|
|
|
conn = libvirt.open("lxc:///")
|
|
|
|
topology = parse_network.YamlTopology(args.topology, conn)
|
|
|
|
util.ensure_sudo_rights()
|
|
topology.net_start(verbose=True)
|
|
topology.dom_start(verbose=True)
|
|
util.drop_sudo_rights()
|
|
|
|
print("Network running. Press ^C to terminate.")
|
|
|
|
main_loop(topology)
|
|
|
|
util.ensure_sudo_rights()
|
|
topology.dom_stop(verbose=True)
|
|
topology.net_stop(verbose=True)
|
|
util.drop_sudo_rights()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|