From 47be8af5754d51d469dc8f381a870b0e94054f26 Mon Sep 17 00:00:00 2001 From: Lukas Vogel Date: Wed, 22 Jul 2020 13:20:37 +0200 Subject: [PATCH] topogen: allocate ipv4 subnets for docker If we just specify an IPv6 subnet in a docker network, docker-compose chooses an IPv4 subnet which might overlap with another IPv4 network that we allocated. This will make the topology fail able to start. This commit prevents this and should fix a few CI errors. Also remove the `--in-docker` flag and supporting code, because it is no longer needed. Also add extra_hosts entry for jaeger tracing. --- acceptance/common.sh | 7 -- go/integration/BUILD.bazel | 1 + go/integration/common.go | 11 ++++ integration/common.sh | 4 -- integration/integration_test.sh | 10 +-- python/topology/common.py | 34 +++++----- python/topology/config.py | 36 +++++++--- python/topology/docker.py | 36 ++++++++-- python/topology/docker_utils.py | 15 +++-- python/topology/generator.py | 2 - python/topology/go.py | 8 ++- python/topology/jaeger.py | 2 +- python/topology/net.py | 113 ++++++++++++++++---------------- python/topology/prometheus.py | 12 ++-- python/topology/sig.py | 2 +- python/topology/topo.py | 29 ++++++-- scion.sh | 5 -- tools/dc | 5 -- 18 files changed, 192 insertions(+), 140 deletions(-) diff --git a/acceptance/common.sh b/acceptance/common.sh index 64f894a9c1..f63ee36ef2 100644 --- a/acceptance/common.sh +++ b/acceptance/common.sh @@ -51,13 +51,6 @@ fail() { exit 1 } -####################################### -# Returns whether this script is running in docker -####################################### -is_running_in_docker() { - cut -d: -f 3 /proc/1/cgroup | grep -q '^/docker/' -} - ####################################### # Return the ip of the container # Arguments: diff --git a/go/integration/BUILD.bazel b/go/integration/BUILD.bazel index e2739c485c..23860e7739 100644 --- a/go/integration/BUILD.bazel +++ b/go/integration/BUILD.bazel @@ -15,5 +15,6 @@ go_library( "//go/lib/snet:go_default_library", "//go/lib/sock/reliable:go_default_library", "@com_github_opentracing_opentracing_go//:go_default_library", + "@com_github_uber_jaeger_client_go//:go_default_library", ], ) diff --git a/go/integration/common.go b/go/integration/common.go index 7b343a1dbc..70d746e7d3 100644 --- a/go/integration/common.go +++ b/go/integration/common.go @@ -19,10 +19,12 @@ import ( "context" "flag" "fmt" + "net" "os" "time" "github.com/opentracing/opentracing-go" + "github.com/uber/jaeger-client-go" "github.com/scionproto/scion/go/lib/addr" "github.com/scionproto/scion/go/lib/env" @@ -67,9 +69,18 @@ func addFlags() { // InitTracer initializes the global tracer and returns a closer function. func InitTracer(name string) (func(), error) { + agent := fmt.Sprintf("jaeger:%d", jaeger.DefaultUDPSpanServerPort) + c, err := net.DialTimeout("udp", agent, 100*time.Millisecond) + if err != nil { + log.Debug("Jaeger tracer not found, using default", "err", err) + agent = "" + } else if c != nil { + c.Close() + } cfg := &env.Tracing{ Enabled: true, Debug: true, + Agent: agent, } cfg.InitDefaults() tr, closer, err := cfg.NewTracer(name) diff --git a/integration/common.sh b/integration/common.sh index 9c8e76e6b2..2d55d9c6eb 100755 --- a/integration/common.sh +++ b/integration/common.sh @@ -39,10 +39,6 @@ is_docker_be() { [ -f gen/scion-dc.yml ] } -is_running_in_docker() { - cut -d: -f 3 /proc/1/cgroup | grep -q '^/docker/' -} - usage() { echo "Usage: $0: [-b brs]" exit 1 diff --git a/integration/integration_test.sh b/integration/integration_test.sh index 1bcbce8d4d..1c32dcce4d 100755 --- a/integration/integration_test.sh +++ b/integration/integration_test.sh @@ -33,13 +33,9 @@ shutdown() { fi } -if is_running_in_docker; then - log "Starting scion (without building)" - ./scion.sh run nobuild | grep -v "started" || exit 1 -else - log "Starting scion" - ./scion.sh run | grep -v "started" || exit 1 -fi +log "Starting scion" +./scion.sh run | grep -v "started" || exit 1 + log "Scion status:" ./scion.sh status || exit 1 if is_docker_be; then diff --git a/python/topology/common.py b/python/topology/common.py index 0b830c2b91..6705771225 100644 --- a/python/topology/common.py +++ b/python/topology/common.py @@ -13,15 +13,15 @@ # limitations under the License. # Stdlib -import ipaddress +from ipaddress import ip_address, ip_network import os import subprocess -import sys from urllib.parse import urlsplit +from typing import Mapping # SCION from python.lib.scion_addr import ISD_AS -from python.topology.net import AddressProxy +from python.topology.net import AddressProxy, NetworkDescription COMMON_DIR = 'endhost' @@ -109,21 +109,23 @@ def split_host_port(addr: str) -> (str, int): def join_host_port(host: str, port: int) -> str: - ip = ipaddress.ip_address(host) + ip = ip_address(host) if ip.version == 4: return '{}:{}'.format(host, port) return '[{}]:{}'.format(host, port) -def sciond_ip(docker, topo_id, networks): - for i, net in enumerate(networks): - for prog, ip_net in networks[net].items(): +def sciond_ip(docker, topo_id, networks: Mapping[ip_network, NetworkDescription]): + for net_desc in networks.values(): + for prog, ip_net in net_desc.ip_net.items(): if prog == 'sd%s' % topo_id.file_fmt(): return ip_net.ip return None -def prom_addr_dispatcher(docker, topo_id, networks, port, name): +def prom_addr_dispatcher(docker, topo_id, + networks: Mapping[ip_network, NetworkDescription], + port, name): if not docker: return "[127.0.0.1]:%s" % port target_name = '' @@ -133,9 +135,9 @@ def prom_addr_dispatcher(docker, topo_id, networks, port, name): target_name = 'sig%s' % topo_id.file_fmt() else: target_name = 'disp%s' % topo_id.file_fmt() - for _, net in enumerate(networks): - if target_name in networks[net]: - return '[%s]:%s' % (networks[net][target_name].ip, port) + for net_desc in networks.values(): + if target_name in net_desc.ip_net: + return '[%s]:%s' % (net_desc.ip_net[target_name].ip, port) return None @@ -159,14 +161,8 @@ def docker_image(args, image): return image -def docker_host(in_docker, docker, addr=None): - if in_docker: - # If in-docker we need to know the DOCKER0 IP - addr = os.getenv('DOCKER0', None) - if not addr: - print('DOCKER0 env variable required! Exiting!') - sys.exit(1) - elif docker or not addr: +def docker_host(docker, addr=None): + if docker or not addr: # Using docker topology or there is no default addr, # we directly get the DOCKER0 IP addr = docker_ip() diff --git a/python/topology/config.py b/python/topology/config.py index 61e2a9a47f..3bfcae72b9 100755 --- a/python/topology/config.py +++ b/python/topology/config.py @@ -23,6 +23,8 @@ import os import sys from io import StringIO +from ipaddress import ip_network +from typing import Mapping # SCION from python.lib.defines import ( @@ -41,6 +43,7 @@ from python.topology.go import GoGenArgs, GoGenerator from python.topology.jaeger import JaegerGenArgs, JaegerGenerator from python.topology.net import ( + NetworkDescription, SubnetGenerator, DEFAULT_NETWORK, ) @@ -81,8 +84,8 @@ def _read_defaults(self, network): Configure default network. """ defaults = self.topo_config.get("defaults", {}) - self.subnet_gen4 = SubnetGenerator(DEFAULT_NETWORK, self.args.docker, self.args.in_docker) - self.subnet_gen6 = SubnetGenerator(DEFAULT6_NETWORK, self.args.docker, self.args.in_docker) + self.subnet_gen4 = SubnetGenerator(DEFAULT_NETWORK, self.args.docker) + self.subnet_gen6 = SubnetGenerator(DEFAULT6_NETWORK, self.args.docker) self.default_mtu = defaults.get("mtu", DEFAULT_MTU) def generate_all(self): @@ -90,7 +93,8 @@ def generate_all(self): Generate all needed files. """ self._ensure_uniq_ases() - topo_dicts, self.networks = self._generate_topology() + topo_dicts, self.all_networks = self._generate_topology() + self.networks = remove_v4_nets(self.all_networks) self._generate_with_topo(topo_dicts) self._write_networks_conf(self.networks, NETWORKS_FILE) self._write_sciond_conf(self.networks, SCIOND_ADDRESSES_FILE) @@ -160,7 +164,7 @@ def _generate_docker(self, topo_dicts): docker_gen.generate() def _docker_args(self, topo_dicts): - return DockerGenArgs(self.args, topo_dicts, self.networks) + return DockerGenArgs(self.args, topo_dicts, self.all_networks) def _generate_prom_conf(self, topo_dicts): args = self._prometheus_args(topo_dicts) @@ -179,23 +183,35 @@ def _write_ca_files(self, topo_dicts, ca_files): for path, value in ca_files[int(isd)].items(): write_file(os.path.join(base, path), value.decode()) - def _write_networks_conf(self, networks, out_file): + def _write_networks_conf(self, + networks: Mapping[ip_network, NetworkDescription], + out_file: str): config = configparser.ConfigParser(interpolation=None) - for i, net in enumerate(networks): + for net, net_desc in networks.items(): sub_conf = {} - for prog, ip_net in networks[net].items(): + for prog, ip_net in net_desc.ip_net.items(): sub_conf[prog] = ip_net.ip config[net] = sub_conf text = StringIO() config.write(text) write_file(os.path.join(self.args.output_dir, out_file), text.getvalue()) - def _write_sciond_conf(self, networks, out_file): + def _write_sciond_conf(self, networks: Mapping[ip_network, NetworkDescription], out_file: str): d = dict() - for i, net in enumerate(networks): - for prog, ip_net in networks[net].items(): + for net_desc in networks.values(): + for prog, ip_net in net_desc.ip_net.items(): if prog.startswith("sd"): ia = prog[2:].replace("_", ":") d[ia] = str(ip_net.ip) with open(os.path.join(self.args.output_dir, out_file), mode="w") as f: json.dump(d, f, sort_keys=True, indent=4) + + +def remove_v4_nets(nets: Mapping[ip_network, NetworkDescription] + ) -> Mapping[ip_network, NetworkDescription]: + res = {} + for net, net_desc in nets.items(): + if net_desc.name.endswith('_v4'): + continue + res[net] = net_desc + return res diff --git a/python/topology/docker.py b/python/topology/docker.py index 00d4e4dcf7..2eb9627e89 100644 --- a/python/topology/docker.py +++ b/python/topology/docker.py @@ -15,6 +15,8 @@ # Stdlib import copy import os +from ipaddress import ip_network +from typing import Mapping # External packages import yaml # SCION @@ -24,18 +26,20 @@ ) from python.topology.common import ( ArgsTopoDicts, + docker_host, docker_image, DOCKER_USR_VOL, sciond_svc_name ) from python.topology.docker_utils import DockerUtilsGenArgs, DockerUtilsGenerator +from python.topology.net import NetworkDescription from python.topology.sig import SIGGenArgs, SIGGenerator DOCKER_CONF = 'scion-dc.yml' class DockerGenArgs(ArgsTopoDicts): - def __init__(self, args, topo_dicts, networks): + def __init__(self, args, topo_dicts, networks: Mapping[ip_network, NetworkDescription]): """ :param object args: Contains the passed command line arguments as named attributes. :param dict topo_dicts: The generated topo dicts from TopoGenerator. @@ -57,7 +61,7 @@ def __init__(self, args): self.bridges = {} self.output_base = os.environ.get('SCION_OUTPUT_BASE', os.getcwd()) self.user_spec = os.environ.get('SCION_USERSPEC', '$LOGNAME') - self.prefix = 'scion_docker_' if self.args.in_docker else 'scion_' + self.prefix = 'scion_' def generate(self): self._create_networks() @@ -89,19 +93,32 @@ def _gen_sig(self): self.dc_conf = sig_gen.generate() def _create_networks(self): - for network in self.args.networks: - for elem in self.args.networks[network]: + # first find v4 allocations, those networks don't need to be generated. + v4nets = {} + ignore_nets = [] + for network, net_desc in self.args.networks.items(): + if network.version == 6: + continue + if net_desc.name.endswith('_v4'): + v4nets[net_desc.name[:-3]] = network + ignore_nets.append(network) + + for network, net_desc in self.args.networks.items(): + if network in ignore_nets: + continue + for elem in net_desc.ip_net: if elem not in self.elem_networks: self.elem_networks[elem] = [] ipv = 'ipv4' - if self.args.networks[network][elem].ip.version == 6: + ip = net_desc.ip_net[elem].ip + if ip.version == 6: ipv = 'ipv6' self.elem_networks[elem].append({ 'net': str(network), - ipv: self.args.networks[network][elem].ip + ipv: ip }) # Create docker networks - prefix = 'scnd_' if self.args.in_docker else 'scn_' + prefix = 'scn_' net_name = "%s%03d" % (prefix, len(self.bridges)) self.bridges[str(network)] = net_name self.dc_conf['networks'][net_name] = { @@ -113,6 +130,9 @@ def _create_networks(self): 'com.docker.network.bridge.name': net_name } } + if net_desc.name in v4nets: + v4_net = v4nets[net_desc.name] + self.dc_conf['networks'][net_name]['ipam']['config'].append({'subnet': str(v4_net)}) if network.version == 6: self.dc_conf['networks'][net_name]['enable_ipv6'] = True @@ -178,6 +198,7 @@ def _control_service_conf(self, topo_id, topo, base): def _dispatcher_conf(self, topo_id, topo, base): image = 'dispatcher' base_entry = { + 'extra_hosts': ['jaeger:%s' % docker_host(self.args.docker)], 'image': docker_image(self.args, image), 'environment': { 'SU_EXEC_USERSPEC': self.user_spec, @@ -216,6 +237,7 @@ def _sciond_conf(self, topo_id, base): ip = str(net[ipv]) disp_id = 'cs%s-1' % topo_id.file_fmt() entry = { + 'extra_hosts': ['jaeger:%s' % docker_host(self.args.docker)], 'image': docker_image(self.args, 'sciond'), 'container_name': '%ssd%s' % (self.prefix, topo_id.file_fmt()), 'depends_on': [ diff --git a/python/topology/docker_utils.py b/python/topology/docker_utils.py index ec4f7a1a36..0018a237ae 100644 --- a/python/topology/docker_utils.py +++ b/python/topology/docker_utils.py @@ -17,7 +17,12 @@ import os # SCION from python.lib.util import write_file -from python.topology.common import ArgsBase, docker_image, remote_nets +from python.topology.common import ( + ArgsBase, + docker_host, + docker_image, + remote_nets, +) class DockerUtilsGenArgs(ArgsBase): @@ -55,6 +60,7 @@ def generate(self): def _utils_conf(self): entry_chown = { 'image': 'busybox', + 'network_mode': 'none', 'volumes': [ '/etc/passwd:/etc/passwd:ro', '/etc/group:/etc/group:ro' @@ -63,6 +69,7 @@ def _utils_conf(self): } entry_clean = { 'image': 'busybox', + 'network_mode': 'none', 'volumes': [], 'command': 'sh -c "find /mnt/volumes -type s -print0 | xargs -r0 rm -v"' } @@ -73,17 +80,17 @@ def _utils_conf(self): self.dc_conf['services']['utils_cleaner'] = entry_clean def _test_conf(self, topo_id): - docker = 'docker_' if self.args.in_docker else '' cntr_base = '/share' name = 'tester_%s' % topo_id.file_fmt() entry = { + 'extra_hosts': ['jaeger:%s' % docker_host(self.args.docker)], 'image': docker_image(self.args, 'tester'), - 'container_name': 'tester_%s%s' % (docker, topo_id.file_fmt()), + 'container_name': 'tester_%s' % topo_id.file_fmt(), 'privileged': True, 'entrypoint': 'sh tester.sh', 'environment': {}, 'volumes': [ - 'vol_scion_%sdisp_cs%s-1:/run/shm/dispatcher:rw' % (docker, topo_id.file_fmt()), + 'vol_scion_disp_cs%s-1:/run/shm/dispatcher:rw' % topo_id.file_fmt(), self.output_base + '/logs:' + cntr_base + '/logs:rw', self.output_base + '/gen:' + cntr_base + '/gen:rw', self.output_base + '/gen-certs:' + cntr_base + '/gen-certs:rw' diff --git a/python/topology/generator.py b/python/topology/generator.py index a4333ea403..a5c36e4e56 100755 --- a/python/topology/generator.py +++ b/python/topology/generator.py @@ -45,8 +45,6 @@ def add_arguments(parser): available timeout') parser.add_argument('--random-ifids', action='store_true', help='Generate random IFIDs') - parser.add_argument('--in-docker', action='store_true', - help='Set if running in a docker container') parser.add_argument('--docker-registry', help='Specify docker registry to pull images from') parser.add_argument('--image-tag', help='Docker image tag') parser.add_argument('--sig', action='store_true', diff --git a/python/topology/go.py b/python/topology/go.py index 177ba358e3..89921e9301 100755 --- a/python/topology/go.py +++ b/python/topology/go.py @@ -20,6 +20,8 @@ import os import toml import yaml +from ipaddress import ip_network +from typing import Mapping # SCION from python.lib.util import write_file @@ -41,7 +43,7 @@ CO_CONFIG_NAME, ) -from python.topology.net import socket_address_str +from python.topology.net import socket_address_str, NetworkDescription from python.topology.prometheus import ( CS_PROM_PORT, @@ -57,7 +59,7 @@ class GoGenArgs(ArgsTopoDicts): - def __init__(self, args, topo_dicts, networks): + def __init__(self, args, topo_dicts, networks: Mapping[ip_network, NetworkDescription]): super().__init__(args, topo_dicts) self.networks = networks @@ -298,7 +300,7 @@ def _build_disp_conf(self, name, topo_id=None): } def _tracing_entry(self): - docker_ip = docker_host(self.args.in_docker, self.args.docker) + docker_ip = docker_host(self.args.docker) entry = { 'enabled': True, 'debug': True, diff --git a/python/topology/jaeger.py b/python/topology/jaeger.py index 369e25e779..e401dd62fe 100644 --- a/python/topology/jaeger.py +++ b/python/topology/jaeger.py @@ -43,7 +43,7 @@ def generate(self): yaml.dump(dc_conf, default_flow_style=False)) def _generate_dc(self): - name = 'jaeger-docker' if self.args.in_docker else 'jaeger' + name = 'jaeger' entry = { 'version': '2', 'services': { diff --git a/python/topology/net.py b/python/topology/net.py index 503aeb90ea..26bb6869a0 100755 --- a/python/topology/net.py +++ b/python/topology/net.py @@ -22,6 +22,7 @@ import sys from collections import defaultdict from ipaddress import ip_interface, ip_network +from typing import Mapping # External packages import yaml @@ -32,17 +33,62 @@ DEFAULT_NETWORK = "127.0.0.0/8" DEFAULT_PRIV_NETWORK = "192.168.0.0/16" DEFAULT_SCN_DC_NETWORK = "172.20.0.0/20" -DEFAULT_SCN_IN_D_NETWORK = "172.20.16.0/20" + + +class NetworkDescription(object): + def __init__(self, name: str, ip_net: Mapping[str, ip_interface]): + self.name = name + self.ip_net = ip_net + + +class AddressProxy(yaml.YAMLObject): + yaml_tag = "" + + def __init__(self): + self._intf = None + self.ip = None + + def set_intf(self, intf): + self._intf = intf + self.ip = self._intf.ip + + def __str__(self): + return str(self._intf) + + @classmethod + def to_yaml(cls, dumper, inst): + return dumper.represent_scalar('tag:yaml.org,2002:str', str(inst.ip)) + + +class AddressGenerator(object): + def __init__(self, docker): + self._addrs = defaultdict(lambda: AddressProxy()) + self.docker = docker + + def register(self, id_: str) -> AddressProxy: + return self._addrs[id_] + + def alloc_addrs(self, subnet) -> Mapping[str, ip_interface]: + hosts = subnet.hosts() + interfaces = {} + # With the docker backend, docker itself claims the first ip of every network + if self.docker: + next(hosts) + for elem, proxy in sorted(self._addrs.items()): + intf = ip_interface("%s/%s" % (next(hosts), subnet.prefixlen)) + interfaces[elem] = intf + proxy.set_intf(intf) + return interfaces + + def __len__(self): + return len(self._addrs) class SubnetGenerator(object): - def __init__(self, network, docker, in_docker): + def __init__(self, network: str, docker: bool): self.docker = docker if self.docker and network == DEFAULT_NETWORK: - if in_docker: - network = DEFAULT_SCN_IN_D_NETWORK - else: - network = DEFAULT_SCN_DC_NETWORK + network = DEFAULT_SCN_DC_NETWORK if "/" not in network: logging.critical("No prefix length specified for network '%s'", network) @@ -70,10 +116,10 @@ def __init__(self, network, docker, in_docker): self._allocations[self._net.prefixlen].append(self._net) - def register(self, location): + def register(self, location: str) -> AddressGenerator: return self._subnets[location] - def alloc_subnets(self): + def alloc_subnets(self) -> Mapping[ip_network, NetworkDescription]: max_prefix = self._net.max_prefixlen networks = {} for topo, subnet in sorted(self._subnets.items(), key=lambda x: str(x)): @@ -101,7 +147,7 @@ def alloc_subnets(self): new_net = _workaround_ip_network_hosts_py35(new_net) logging.debug("Allocating %s from %s for subnet size %d" % (new_net, alloc, len(subnet))) - networks[new_net] = subnet.alloc_addrs(new_net) + networks[new_net] = NetworkDescription(topo, subnet.alloc_addrs(new_net)) # Repopulate the allocations list with the left-over space self._exclude_net(alloc, new_net) break @@ -115,68 +161,25 @@ def _exclude_net(self, alloc, net): self._allocations[net.prefixlen].append(net) -class AddressGenerator(object): - def __init__(self, docker): - self._addrs = defaultdict(lambda: AddressProxy()) - self.docker = docker - - def register(self, id_): - return self._addrs[id_] - - def alloc_addrs(self, subnet): - hosts = subnet.hosts() - interfaces = {} - # With the docker backend, docker itself claims the first ip of every network - if self.docker: - next(hosts) - for elem, proxy in sorted(self._addrs.items()): - intf = ip_interface("%s/%s" % (next(hosts), subnet.prefixlen)) - interfaces[elem] = intf - proxy.set_intf(intf) - return interfaces - - def __len__(self): - return len(self._addrs) - - -class AddressProxy(yaml.YAMLObject): - yaml_tag = "" - - def __init__(self): - self._intf = None - self.ip = None - - def set_intf(self, intf): - self._intf = intf - self.ip = self._intf.ip - - def __str__(self): - return str(self._intf) - - @classmethod - def to_yaml(cls, dumper, inst): - return dumper.represent_scalar('tag:yaml.org,2002:str', str(inst.ip)) - - class PortGenerator(object): def __init__(self): self.iter = iter(range(31000, 35000)) self._ports = defaultdict(lambda: next(self.iter)) - def register(self, id_): + def register(self, id_: str) -> int: p = self._ports[id_] # reserve a quic port self._ports[id_+"quic"] return p -def socket_address_str(ip, port): +def socket_address_str(ip: str, port: int) -> str: if ip.version == 4: return "%s:%d" % (ip, port) return "[%s]:%d" % (ip, port) -def _workaround_ip_network_hosts_py35(net): +def _workaround_ip_network_hosts_py35(net: ip_network) -> ip_network: """ Returns an _identical_ ipaddress.ip_network for which hosts() which will work as it should. diff --git a/python/topology/prometheus.py b/python/topology/prometheus.py index f4e750f96a..e87de67b49 100755 --- a/python/topology/prometheus.py +++ b/python/topology/prometheus.py @@ -19,6 +19,8 @@ # Stdlib import os from collections import defaultdict +from ipaddress import ip_network +from typing import Mapping # External packages import yaml @@ -32,6 +34,9 @@ prom_addr_dispatcher, sciond_ip, ) +from python.topology.net import ( + NetworkDescription +) CS_PROM_PORT = 30452 SCIOND_PROM_PORT = 30455 @@ -44,7 +49,7 @@ class PrometheusGenArgs(ArgsTopoDicts): - def __init__(self, args, topo_dicts, networks): + def __init__(self, args, topo_dicts, networks: Mapping[ip_network, NetworkDescription]): super().__init__(args, topo_dicts) self.networks = networks @@ -145,12 +150,11 @@ def _write_disp_file(self): write_file(targets_path, yaml.dump(target_config, default_flow_style=False)) def _write_dc_file(self): - name_prefix = 'prometheus' - name = '%s_docker' % name_prefix if self.args.in_docker else name_prefix + name = 'prometheus' prom_dc = { 'version': DOCKER_COMPOSE_CONFIG_VERSION, 'services': { - name_prefix: { + name: { 'image': 'prom/prometheus:v2.6.0', 'container_name': name, 'network_mode': 'host', diff --git a/python/topology/sig.py b/python/topology/sig.py index bbfce9e472..5d1e78078f 100644 --- a/python/topology/sig.py +++ b/python/topology/sig.py @@ -56,7 +56,7 @@ def __init__(self, args): self.dc_conf = args.dc_conf self.user_spec = os.environ.get('SCION_USERSPEC', '$LOGNAME') self.output_base = os.environ.get('SCION_OUTPUT_BASE', os.getcwd()) - self.prefix = 'docker_' if self.args.in_docker else '' + self.prefix = '' def generate(self): for topo_id, topo in self.args.topo_dicts.items(): diff --git a/python/topology/topo.py b/python/topology/topo.py index 4fe1ccf89f..09d753c0a9 100755 --- a/python/topology/topo.py +++ b/python/topology/topo.py @@ -30,7 +30,6 @@ # SCION from python.lib.defines import ( AS_LIST_FILE, - DEFAULT_MTU, IFIDS_FILE, SCION_MIN_MTU, SCION_ROUTER_PORT, @@ -46,7 +45,10 @@ srv_iter, TopoID ) -from python.topology.net import PortGenerator +from python.topology.net import ( + PortGenerator, + SubnetGenerator +) DEFAULT_LINK_BW = 1000 @@ -63,7 +65,12 @@ class TopoGenArgs(ArgsBase): - def __init__(self, args, topo_config, subnet_gen4, subnet_gen6, default_mtu): + def __init__(self, + args: ArgsBase, + topo_config, + subnet_gen4: SubnetGenerator, + subnet_gen6: SubnetGenerator, + default_mtu: int): """ :param ArgsBase args: Contains the passed command line arguments. :param dict topo_config: The parsed topology config. @@ -94,14 +101,24 @@ def __init__(self, args): self.links = defaultdict(list) self.ifid_map = {} - def _reg_addr(self, topo_id, elem_id, addr_type): - subnet = self.args.subnet_gen[addr_type].register(topo_id) + def _reg_addr(self, topo_id: TopoID, elem_id, addr_type): + subnet = self.args.subnet_gen[addr_type].register(str(topo_id)) + if self.args.docker and addr_type == ADDR_TYPE_6: + # for docker also allocate an IPv4 address so that we have ipv4 + # range allocated for the network. + v4subnet = self.args.subnet_gen[ADDR_TYPE_4].register(str(topo_id) + '_v4') + v4subnet.register(elem_id + '_v4') return subnet.register(elem_id) def _reg_link_addrs(self, local_br, remote_br, local_ifid, remote_ifid, addr_type): link_name = str(sorted((local_br, remote_br))) link_name += str(sorted((local_ifid, remote_ifid))) subnet = self.args.subnet_gen[addr_type].register(link_name) + if self.args.docker and addr_type == ADDR_TYPE_6: + # for docker also allocate an IPv4 address so that we have ipv4 + # range allocated for the network. + v4subnet = self.args.subnet_gen[ADDR_TYPE_4].register(link_name + '_v4') + v4subnet.register(local_br + '_v4') return subnet.register(local_br), subnet.register(remote_br) def _iterate(self, f): @@ -323,7 +340,7 @@ def _gen_br_intf(self, remote, public_addr, remote_addr, attrs, remote_type): 'bandwidth': attrs.get('bw', DEFAULT_LINK_BW), 'isd_as': str(remote), 'link_to': LinkType.to_str(remote_type.lower()), - 'mtu': attrs.get('mtu', DEFAULT_MTU) + 'mtu': attrs.get('mtu', self.args.default_mtu) } def _gen_sig_entries(self, topo_id, as_conf): diff --git a/scion.sh b/scion.sh index 94151499fb..be8ceecf1d 100755 --- a/scion.sh +++ b/scion.sh @@ -30,7 +30,6 @@ cmd_topology() { tar --overwrite -xf bazel-bin/scion-topo.tar -C bin echo "Create topology, configuration, and execution files." - is_running_in_docker && set -- "$@" --in-docker python/topology/generator.py "$@" if is_docker_be; then ./tools/quiet ./tools/dc run utils_chowner @@ -222,10 +221,6 @@ is_supervisor() { [ -f gen/dispatcher/supervisord.conf ] } -is_running_in_docker() { - cut -d: -f 3 /proc/1/cgroup | grep -q '^/docker/' -} - cmd_test(){ local ret=0 case "$1" in diff --git a/tools/dc b/tools/dc index 4343d9824d..92004e04fc 100755 --- a/tools/dc +++ b/tools/dc @@ -85,7 +85,6 @@ dc() { local project="$1" local dc_file="gen/$1-dc.yml" shift - is_running_in_docker && project="${project}_docker" COMPOSE_FILE="$dc_file" docker-compose -p "$project" --no-ansi "$@" } @@ -133,10 +132,6 @@ service_running() { [ -n "$cntr" ] && [ -n "$(docker ps -q --no-trunc | grep $cntr)" ] } -is_running_in_docker() { - cut -d: -f 3 /proc/1/cgroup | grep -q '^/docker/' -} - PROGRAM="${0##*/}" COMMAND="$1" shift