Repository: scionproto/scion
Pull request #3627 (2020-01-21 12:57:22)

ci: Add dockerized integration tests
Re-enables the dockerized tests that we had in the old CI pipeline.
Also add support for ipv6 to the docker generator

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/scionproto/scion/3627)
<!-- Reviewable:end -->



Patch:
diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml
index 8a74feb03..5c862718e 100644
--- a/.buildkite/pipeline.yml
+++ b/.buildkite/pipeline.yml
@@ -82,7 +82,7 @@ steps:
     - ./scion.sh topology -t
     - ./scion.sh run && sleep 10
     - ./bin/cert_req_integration -log.console warn
-    - ./bin/pp_integration  -log.console warn
+    - ./bin/pp_integration -log.console warn
     - ./bin/scmp_integration -log.console warn
     - ./bin/end2end_integration -log.console warn
     artifact_paths:
@@ -93,6 +93,25 @@ steps:
       automatic:
         - exit_status: -1  # Agent was lost
         - exit_status: 255 # Forced agent shutdown
+  - label: ":docker: Integration: end2end_integration"
+    command:
+    - bazel run //docker/perapp:prod
+    - ./scion.sh topology -t -d -c topology/Tiny.topo
+    - ./scion.sh run
+    - docker-compose -f gen/scion-dc.yml -p scion up -d $(docker-compose -f gen/scion-dc.yml config --services | grep tester)
+    - sleep 5
+    - ./bin/cert_req_integration -d -log.console warn
+    - ./bin/pp_integration -d -log.console warn
+    - ./bin/scmp_integration -d -log.console warn
+    - ./bin/end2end_integration -d -log.console warn
+    artifact_paths:
+      - "artifacts.out/**/*"
+    timeout_in_minutes: 10
+    key: docker_integration_tests
+    retry:
+      automatic:
+        - exit_status: -1  # Agent was lost
+        - exit_status: 255 # Forced agent shutdown
   - label: "Integration: end2end_integration"
     command:
     - bazel build //:scion //:scion-ci >/dev/null 2>&1
diff --git a/acceptance/common.sh b/acceptance/common.sh
index 4e82ed147..70b3a51f7 100644
--- a/acceptance/common.sh
+++ b/acceptance/common.sh
@@ -70,6 +70,8 @@ docker_status() {
 #######################################
 test_teardown() {
     docker_status
+    mkdir -p logs/docker
+    ./tools/dc collect_logs logs/docker
     ./tools/dc down
 }
 
diff --git a/acceptance/discovery_util/util.sh b/acceptance/discovery_util/util.sh
index 2a8f9ed47..8bffa78ef 100644
--- a/acceptance/discovery_util/util.sh
+++ b/acceptance/discovery_util/util.sh
@@ -8,7 +8,7 @@ AS_FILE="$(as_file $IA)"
 TOPO="gen/ISD1/AS$AS_FILE/br$IA_FILE-1/topology.json"
 
 UTIL_PATH="acceptance/discovery_util"
-TEST_TOPOLOGY="topology/Tiny.topo"
+TEST_TOPOLOGY="topology/Tiny4.topo"
 
 HTTP_DIR="gen/discovery_acceptance"
 STATIC_DIR="$HTTP_DIR/discovery/v1/static"
diff --git a/acceptance/sigutil/common.sh b/acceptance/sigutil/common.sh
index 1319d2f11..cd066de2b 100755
--- a/acceptance/sigutil/common.sh
+++ b/acceptance/sigutil/common.sh
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-TEST_TOPOLOGY=${TEST_TOPOLOGY:-topology/Tiny.topo}
+TEST_TOPOLOGY=${TEST_TOPOLOGY:-topology/Tiny4.topo}
 SRC_IA=${SRC_IA:-1-ff00:0:111}
 DST_IA=${DST_IA:-1-ff00:0:112}
 
diff --git a/python/topology/docker.py b/python/topology/docker.py
index 944ea4021..58841692f 100644
--- a/python/topology/docker.py
+++ b/python/topology/docker.py
@@ -104,8 +104,13 @@ class DockerGenerator(object):
             for elem in self.args.networks[network]:
                 if elem not in self.elem_networks:
                     self.elem_networks[elem] = []
-                self.elem_networks[elem].append(
-                    {'net': str(network), 'ipv4': self.args.networks[network][elem].ip})
+                ipv = 'ipv4'
+                if self.args.networks[network][elem].ip.version == 6:
+                    ipv = 'ipv6'
+                self.elem_networks[elem].append({
+                    'net': str(network),
+                    ipv: self.args.networks[network][elem].ip
+                })
             # Create docker networks
             prefix = 'scnd_' if self.args.in_docker else 'scn_'
             net_name = "%s%03d" % (prefix, len(self.bridges))
@@ -119,6 +124,8 @@ class DockerGenerator(object):
                     'com.docker.network.bridge.name': net_name
                 }
             }
+            if network.version == 6:
+                self.dc_conf['networks'][net_name]['enable_ipv6'] = True
 
     def _br_conf(self, topo_id, topo, base):
         for k, _ in topo.get("BorderRouters", {}).items():
@@ -144,9 +151,19 @@ class DockerGenerator(object):
 
             # Set BR IPs
             in_net = self.elem_networks[k + "_internal"][0]
-            entry['networks'][self.bridges[in_net['net']]] = {'ipv4_address': str(in_net['ipv4'])}
+            ipv = 'ipv4'
+            if ipv not in in_net:
+                ipv = 'ipv6'
+            entry['networks'][self.bridges[in_net['net']]] = {
+                '%s_address' % ipv: str(in_net[ipv])
+            }
             for net in self.elem_networks[k]:
-                entry['networks'][self.bridges[net['net']]] = {'ipv4_address': str(net['ipv4'])}
+                ipv = 'ipv4'
+                if ipv not in net:
+                    ipv = 'ipv6'
+                entry['networks'][self.bridges[net['net']]] = {
+                    '%s_address' % ipv: str(net[ipv])
+                }
             self.dc_conf['services']['scion_%s' % k] = entry
 
     def _cs_conf(self, topo_id, topo, base):
@@ -231,9 +248,12 @@ class DockerGenerator(object):
         for k in topo.get("BorderRouters", {}):
             entry = copy.deepcopy(prep_entry)
             ctrl_net = self.elem_networks[k + "_ctrl"][0]
-            ctrl_ip = str(ctrl_net['ipv4'])
+            ipv = 'ipv4'
+            if ipv not in ctrl_net:
+                ipv = 'ipv6'
+            ctrl_ip = str(ctrl_net[ipv])
             disp_id = '%s%s' % (topo_id.file_fmt(), k[-2:])
-            entry['networks'][self.bridges[ctrl_net['net']]] = {'ipv4_address': ctrl_ip}
+            entry['networks'][self.bridges[ctrl_net['net']]] = {'%s_address' % ipv: ctrl_ip}
             entry['container_name'] = '%sdisp_br_%s' % (self.prefix, disp_id)
             entry['volumes'].append(self._disp_br_vol(disp_id))
             conf = '%s:/share/conf:rw' % os.path.join(base, 'disp_br_%s' % disp_id)
@@ -243,8 +263,11 @@ class DockerGenerator(object):
     def _infra_dispatcher(self, entry, topo_id, base):
         # Create dispatcher for Infra
         net = self.elem_networks["disp" + topo_id.file_fmt()][0]
-        ip = str(net['ipv4'])
-        entry['networks'][self.bridges[net['net']]] = {'ipv4_address': ip}
+        ipv = 'ipv4'
+        if ipv not in net:
+            ipv = 'ipv6'
+        ip = str(net[ipv])
+        entry['networks'][self.bridges[net['net']]] = {'%s_address' % ipv: ip}
         entry['container_name'] = '%sdisp_%s' % (self.prefix, topo_id.file_fmt())
         entry['volumes'].append(self._disp_vol(topo_id))
         conf = '%s:/share/conf:rw' % os.path.join(base, 'disp_%s' % topo_id.file_fmt())
@@ -254,7 +277,10 @@ class DockerGenerator(object):
     def _sciond_conf(self, topo_id, base):
         name = sciond_svc_name(topo_id)
         net = self.elem_networks["sd" + topo_id.file_fmt()][0]
-        ip = str(net['ipv4'])
+        ipv = 'ipv4'
+        if ipv not in net:
+            ipv = 'ipv6'
+        ip = str(net[ipv])
         entry = {
             'image': docker_image(self.args, 'sciond'),
             'container_name': '%ssd%s' % (self.prefix, topo_id.file_fmt()),
@@ -269,7 +295,7 @@ class DockerGenerator(object):
                 '%s:/share/conf:ro' % os.path.join(base, 'endhost'),
             ],
             'networks': {
-                self.bridges[net['net']]: {'ipv4_address': ip}
+                self.bridges[net['net']]: {'%s_address' % ipv: ip}
             }
         }
         self.dc_conf['services'][name] = entry
diff --git a/python/topology/docker_utils.py b/python/topology/docker_utils.py
index 889c43921..b965c0bf9 100644
--- a/python/topology/docker_utils.py
+++ b/python/topology/docker_utils.py
@@ -98,15 +98,22 @@ class DockerUtilsGenerator(object):
             sig_net = self.args.networks['sig%s' % topo_id.file_fmt()][0]
             net = self.args.networks[name][0]
             bridge = self.args.bridges[net['net']]
-            entry['networks'][bridge] = {'ipv4_address': str(net['ipv4'])}
-            entry['environment']['SIG_IP'] = str(sig_net['ipv4'])
+            ipv = 'ipv4'
+            if ipv not in net:
+                ipv = 'ipv6'
+            entry['networks'][bridge] = {'%s_address' % ipv: str(net[ipv])}
+            entry['environment']['SIG_IP'] = str(sig_net[ipv])
             entry['environment']['REMOTE_NETS'] = remote_nets(self.args.networks, topo_id)
         self.dc_conf['services'][name] = entry
 
     def _sig_testing_conf(self):
         text = ''
         for topo_id in self.args.topo_dicts:
-            ip = self.args.networks['tester_%s' % topo_id.file_fmt()][0]['ipv4']
+            net = self.args.networks['tester_%s' % topo_id.file_fmt()][0]
+            ipv = 'ipv4'
+            if ipv not in net:
+                ipv = 'ipv6'
+            ip = net[ipv]
             text += str(topo_id) + ' ' + str(ip) + '\n'
             conf_path = os.path.join(self.args.output_dir, 'sig-testing.conf')
             write_file(conf_path, text)
diff --git a/python/topology/sig.py b/python/topology/sig.py
index f8d192588..811ef9280 100644
--- a/python/topology/sig.py
+++ b/python/topology/sig.py
@@ -86,7 +86,10 @@ class SIGGenerator(object):
         }
 
         net = self.args.networks['sig%s' % topo_id.file_fmt()][0]
-        entry['networks'][self.args.bridges[net['net']]] = {'ipv4_address': str(net['ipv4'])}
+        ipv = 'ipv4'
+        if ipv not in net:
+            ipv = 'ipv6'
+        entry['networks'][self.args.bridges[net['net']]] = {'%s_address' % ipv: str(net[ipv])}
         self.dc_conf['services']['scion_disp_sig_%s' % topo_id.file_fmt()] = entry
         vol_name = 'vol_scion_%sdisp_sig_%s' % (self.prefix, topo_id.file_fmt())
         self.dc_conf['volumes'][vol_name] = None
@@ -134,12 +137,15 @@ class SIGGenerator(object):
         name = 'sig%s' % topo_id.file_fmt()
         net = self.args.networks[name][0]
         log_level = 'trace' if self.args.trace else 'debug'
+        ipv = 'ipv4'
+        if ipv not in net:
+            ipv = 'ipv6'
         sig_conf = {
             'sig': {
                 'ID': name,
                 'SIGConfig': 'conf/cfg.json',
                 'IA': str(topo_id),
-                'IP': str(net['ipv4']),
+                'IP': str(net[ipv]),
             },
             'sd_client': {
                 'Path': get_default_sciond_path(ISD_AS(topo["ISD_AS"]))
diff --git a/python/topology/topo.py b/python/topology/topo.py
index 0f9275fe8..376c932f8 100755
--- a/python/topology/topo.py
+++ b/python/topology/topo.py
@@ -317,7 +317,7 @@ class TopoGenerator(object):
         }
 
     def _gen_sig_entries(self, topo_id, as_conf):
-        addr_type = addr_type_from_underlay(as_conf.get('underlay', DEFAULT_UNDERLAY))
+        addr_type = addr_type_from_underlay(DEFAULT_UNDERLAY)
         elem_id = "sig" + topo_id.file_fmt()
         reg_id = "sig" + topo_id.file_fmt()
         d = {
diff --git a/scion.sh b/scion.sh
index 9083b2e92..d50efd188 100755
--- a/scion.sh
+++ b/scion.sh
@@ -52,12 +52,8 @@ cmd_run() {
         echo "Compiling..."
         make -s || exit 1
         if is_docker_be; then
-            echo "Build scion_base image"
-            ./tools/quiet ./docker.sh base
-            echo "Build scion image"
-            ./tools/quiet ./docker.sh build
             echo "Build perapp images"
-            ./tools/quiet make -C docker/perapp
+            ./tools/quiet make -C docker/perapp bazel
             echo "Build scion tester"
             ./tools/quiet ./docker.sh tester
         fi
diff --git a/topology/Tiny.topo b/topology/Tiny.topo
index c000e02c4..ce00c5d0a 100644
--- a/topology/Tiny.topo
+++ b/topology/Tiny.topo
@@ -10,9 +10,10 @@ ASes:
     cert_issuer: 1-ff00:0:110
   "1-ff00:0:112": # old 1-13
     cert_issuer: 1-ff00:0:110
+    underlay: UDP/IPv6
 links:
   - {a: "1-ff00:0:110#1", b: "1-ff00:0:111#41", linkAtoB: CHILD, mtu: 1280}
-  - {a: "1-ff00:0:110#2", b: "1-ff00:0:112#1", linkAtoB: CHILD, bw: 500}
+  - {a: "1-ff00:0:110#2", b: "1-ff00:0:112#1", linkAtoB: CHILD, bw: 500, underlay: UDP/IPv6}
 CAs:
   CA1-1:
     ISD: 1
diff --git a/topology/Tiny4.topo b/topology/Tiny4.topo
new file mode 100644
index 000000000..2c1015ca1
--- /dev/null
+++ b/topology/Tiny4.topo
@@ -0,0 +1,19 @@
+--- # Tiny Topology IPv4 only
+ASes:
+  "1-ff00:0:110": # old 1-11
+    core: true
+    voting: true
+    authoritative: true
+    issuing: true
+    mtu: 1400
+  "1-ff00:0:111": # old 1-12
+    cert_issuer: 1-ff00:0:110
+  "1-ff00:0:112": # old 1-13
+    cert_issuer: 1-ff00:0:110
+links:
+  - {a: "1-ff00:0:110#1", b: "1-ff00:0:111#41", linkAtoB: CHILD, mtu: 1280}
+  - {a: "1-ff00:0:110#2", b: "1-ff00:0:112#1", linkAtoB: CHILD, bw: 500}
+CAs:
+  CA1-1:
+    ISD: 1
+    commonName: CA1-1


Test patch:
diff --git a/acceptance/showpaths_status_acceptance/test b/acceptance/showpaths_status_acceptance/test
index 37d51896b..4754ecb71 100755
--- a/acceptance/showpaths_status_acceptance/test
+++ b/acceptance/showpaths_status_acceptance/test
@@ -66,7 +66,11 @@ class TestRun(Base):
         else:
             dcFile = load_yaml_file('gen/scion-dc.yml')
             networks = dcFile['services']['scion_disp_1-ff00_0_112']['networks']
-            local_disp = next(iter(networks.items()))[1]['ipv4_address']
+            disp_net = next(iter(networks.items()))[1]
+            if 'ipv4_address' in disp_net:
+                local_disp = disp_net['ipv4_address']
+            else:
+                local_disp = disp_net['ipv6_address']
             out = self.tools_dc('exec_tester', '1-ff00_0_112', './bin/showpaths',
                                 '-srcIA', '1-ff00:0:112', '-sciondFromIA',
                                 '-dstIA', '1-ff00:0:110', '-p', '-local',