예제 #1
0
def add_link(args):
    """Add a link to the topology."""
    topo = Topology.load(args.workdir.joinpath(CONFIG_DATA_FILE))
    link = _get_link_from_args(topo, args)

    if link is not None:
        ixp, as_a, as_b = link
        open_log_file(args.workdir)
        log.debug("Command: add_link")

        try:
            links.add_link(topo=topo,
                           workdir=args.workdir,
                           dc=docker.from_env(),
                           ixp=ixp,
                           a=(args.as_a, as_a),
                           b=(args.as_b, as_b),
                           link_properties={
                               "type": args.type,
                               "mtu": args.mtu,
                               "bandwidth": args.bandwidth
                           })
        finally:
            topo.close_host_connections()
            topo.save(args.workdir.joinpath(CONFIG_DATA_FILE))
예제 #2
0
def modify_link(args):
    """Modify an existing link."""
    topo = Topology.load(args.workdir.joinpath(CONFIG_DATA_FILE))
    link = _get_link_from_args(topo, args)

    if link is not None:
        ixp, as_a, as_b = link
        properties = {}
        arg_dict = vars(args)

        for key in ['type', 'mtu', 'bandwidth']:
            if key in arg_dict:
                properties[key] = arg_dict[key]

        open_log_file(args.workdir)
        log.debug("Command: modify_link")

        try:
            links.modify_link(topo=topo,
                              workdir=args.workdir,
                              dc=docker.from_env(),
                              ixp=ixp,
                              a=(args.as_a, as_a),
                              b=(args.as_b, as_b),
                              link_properties=properties)
        finally:
            topo.close_host_connections()
            topo.save(args.workdir.joinpath(CONFIG_DATA_FILE))
예제 #3
0
def stats(args):
    """Measure the average CPU utilization of SCION ASes and services."""
    open_log_file(args.workdir)
    log.debug("Command: stats")
    topo = Topology.load(args.workdir.joinpath(CONFIG_DATA_FILE))
    try:
        measurements = Measurements()
        # Read existing measurements.
        try:
            with open(args.output_file) as file:
                measurements.data = json.load(file)
        except FileNotFoundError:
            pass  # No existing data to read in.

        # Take new measurements and merge with existing data.
        measurements.experiment = args.experiment
        measure_perf_stats(topo,
                           measurements,
                           as_pattern=args.as_pattern,
                           services=set(args.services),
                           interval=args.interval,
                           count=args.count)

        # Write merged data back to disk.
        with open(args.output_file, 'w') as file:
            json.dump(measurements.data, file)

    finally:
        topo.close_host_connections()
예제 #4
0
def update(args):
    """Fetch the AS configuration files from the coordinator."""
    open_log_file(args.workdir)
    log.debug("Command: update")
    topo = Topology.load(args.workdir.joinpath(CONFIG_DATA_FILE))
    try:
        if topo.coordinator is None:
            log.error("Topology has no coordinator.")
        else:
            if args.as_list is None:
                fetch_config(topo,
                             as_selector=args.as_pattern,
                             detach=args.detach,
                             force=args.force,
                             no_restart=args.no_restart,
                             rate=args.rate)
            else:
                as_list = []
                with open(args.as_list) as file:
                    for line in file.readlines():
                        as_list.append(ISD_AS(line))
                fetch_config(topo,
                             as_selector=as_list,
                             detach=args.detach,
                             force=args.force,
                             no_restart=args.no_restart,
                             rate=args.rate)
    finally:
        topo.close_host_connections()
예제 #5
0
def stop_cntrs(args):
    """Stop all containers."""
    open_log_file(args.workdir)
    log.debug("Command: stop_cntrs")
    topo = Topology.load(args.workdir.joinpath(CONFIG_DATA_FILE))

    try:
        topo.stop_containers()
        topo.remove_bridges()
    finally:
        topo.close_host_connections()
        topo.save(args.workdir.joinpath(CONFIG_DATA_FILE))
예제 #6
0
def exec(args):
    """Run a command in one or multiple containers."""
    open_log_file(args.workdir)
    log.debug("Command: exec")
    topo = Topology.load(args.workdir.joinpath(CONFIG_DATA_FILE))
    try:
        run_in_cntrs(topo,
                     as_selector=args.as_pattern,
                     cmd_template=args.command,
                     user=args.user,
                     detach=args.detach,
                     dry_run=args.dry_run)
    finally:
        topo.close_host_connections()
예제 #7
0
def start_cntrs(args):
    """Start the containers and the coordinator if applicable."""
    open_log_file(args.workdir)
    log.debug("Command: start_cntrs")
    topo = Topology.load(args.workdir.joinpath(CONFIG_DATA_FILE))

    try:
        topo.create_bridges()
        topo.start_containers(workdir=args.workdir,
                              sc=args.sc,
                              push_images=args.push_images)
    finally:
        topo.close_host_connections()
        topo.save(args.workdir.joinpath(CONFIG_DATA_FILE))
예제 #8
0
def stop(args):
    """Stop SCION, but keep the containers and the coordinator running."""
    open_log_file(args.workdir)
    log.debug("Command: stop")
    topo = Topology.load(args.workdir.joinpath(CONFIG_DATA_FILE))

    try:
        if args.mode == 'sequential':
            topo.stop_scion()
        elif args.mode == 'parallel':
            topo.stop_scion_parallel()
        elif args.mode == 'detach':
            topo.stop_scion_parallel(detach=True)
    finally:
        topo.close_host_connections()
        topo.save(args.workdir.joinpath(CONFIG_DATA_FILE))
예제 #9
0
def remove_link(args):
    """Remove a link from the topology."""
    topo = Topology.load(args.workdir.joinpath(CONFIG_DATA_FILE))
    link = _get_link_from_args(topo, args)

    if link is not None:
        ixp, as_a, as_b = link
        open_log_file(args.workdir)
        log.debug("Command: remove_link")
        try:
            links.remove_link(topo=topo,
                              workdir=args.workdir,
                              dc=docker.from_env(),
                              ixp=ixp,
                              a=(args.as_a, as_a),
                              b=(args.as_b, as_b))
        finally:
            topo.close_host_connections()
            topo.save(args.workdir.joinpath(CONFIG_DATA_FILE))
예제 #10
0
def policy(args):
    """Wrapper around the coordinator's peering policy REST API."""
    open_log_file(args.workdir)
    log.debug("Command: policy %s" % args.action)
    topo = Topology.load(args.workdir.joinpath(CONFIG_DATA_FILE))

    # Parse and validate ISD-AS string.
    try:
        isd_as = ISD_AS(args.isd_as)
    except SCIONParseError:
        log.error("Invalid ISD-AS string.")
        return
    try:
        if not topo.ases[isd_as].is_user_as():
            log.error("'%s' is not a user AS.", isd_as)
            return
    except KeyError:
        log.error("Unknown AS: %s", isd_as)
        return

    try:
        if topo.coordinator is None:
            log.error("Topology has no coordinator.")
        else:
            response = None
            if args.action == "get_peers":
                response = topo.coordinator.get_peers(isd_as, args.ixp)
            elif args.action == "get":
                response = topo.coordinator.get_policies(isd_as, args.ixp)
            elif args.action == "create":
                policies = sys.stdin.read() if args.data is None else args.data
                print(topo.coordinator.create_policies(isd_as, policies))
            elif args.action == "delete":
                policies = sys.stdin.read() if args.data is None else args.data
                print(topo.coordinator.delete_policies(isd_as, policies))

            if response is not None:
                print(json.dumps(response, indent=2))

    finally:
        topo.close_host_connections()
예제 #11
0
def generate_topology(args):
    """Generate a topology."""
    # Make sure the work directory exists and is empty.
    os.makedirs(args.workdir, exist_ok=True)
    if len(os.listdir(args.workdir)) > 0:
        if args.clear_workdir:
            log.info("Clearing work directory.")
            clear_directory(args.workdir)
        else:
            log.error("Work directory is not empty.")
            return

    open_log_file(args.workdir)
    dc = docker.from_env()  # Connect to Docker daemon

    topo = generate(name=args.name,
                    input_file_path=args.topo_file,
                    workdir=args.workdir,
                    sc=args.sc,
                    dc=dc)
    topo.save(args.workdir.joinpath(CONFIG_DATA_FILE))
예제 #12
0
def start(args):
    """Start the containers and SCION."""
    open_log_file(args.workdir)
    log.debug("Command: start")
    topo = Topology.load(args.workdir.joinpath(CONFIG_DATA_FILE))

    try:
        # Make sure the containers are running
        topo.create_bridges()
        topo.start_containers(workdir=args.workdir,
                              sc=args.sc,
                              push_images=args.push_images)
        # Run SCION in containers
        if args.mode == 'sequential':
            topo.run_scion()
        elif args.mode == 'parallel':
            topo.run_scion_parallel()
        elif args.mode == 'detach':
            topo.run_scion_parallel(detach=True)
    finally:
        topo.close_host_connections()
        topo.save(args.workdir.joinpath(CONFIG_DATA_FILE))