From 1e9c095c6faa07a6a7696a8dceccd6eada859b2f Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Mon, 16 Apr 2018 17:53:25 -0300 Subject: [PATCH 01/21] docker: add support for running inside container Based on the original @cfra idea of running topotest on docker. Signed-off-by: Rafael Zalamena --- tests/topotests/docker/Dockerfile | 55 ++++++++++++++ tests/topotests/docker/README.md | 23 ++++++ tests/topotests/docker/compile_frr.sh | 99 +++++++++++++++++++++++++ tests/topotests/docker/docker.sh | 49 ++++++++++++ tests/topotests/docker/entrypoint.sh | 75 +++++++++++++++++++ tests/topotests/docker/funcs.sh | 70 +++++++++++++++++ tests/topotests/docker/motd.txt | 20 +++++ tests/topotests/docker/topotests_run.sh | 51 +++++++++++++ tests/topotests/pytest.ini | 2 +- 9 files changed, 443 insertions(+), 1 deletion(-) create mode 100644 tests/topotests/docker/Dockerfile create mode 100644 tests/topotests/docker/README.md create mode 100755 tests/topotests/docker/compile_frr.sh create mode 100755 tests/topotests/docker/docker.sh create mode 100755 tests/topotests/docker/entrypoint.sh create mode 100755 tests/topotests/docker/funcs.sh create mode 100644 tests/topotests/docker/motd.txt create mode 100755 tests/topotests/docker/topotests_run.sh diff --git a/tests/topotests/docker/Dockerfile b/tests/topotests/docker/Dockerfile new file mode 100644 index 0000000000..eff9623f82 --- /dev/null +++ b/tests/topotests/docker/Dockerfile @@ -0,0 +1,55 @@ +FROM ubuntu:18.04 + +# Update system repos +RUN DEBIAN_FRONTEND=noninteractive apt update + +# Install FRR dependencies +RUN DEBIAN_FRONTEND=noninteractive apt install -y \ + autoconf binutils bison flex libtool libjson-c-dev \ + libpython-dev libreadline-dev libc-ares-dev python-sphinx \ + install-info pkg-config texinfo + +# Install useful tools for debugging +RUN DEBIAN_FRONTEND=noninteractive apt install -y \ + gdb inetutils-ping iproute2 valgrind + +# Install mininet dependencies +RUN DEBIAN_FRONTEND=noninteractive apt install -y \ + mininet python-pip && \ + pip install ipaddr pytest exabgp==3.4.17 + +# Install user utilities +RUN DEBIAN_FRONTEND=noninteractive apt install -y \ + x11-xserver-utils xterm tmux vim tcpdump less man rsync + +# Configure FRR users +RUN groupadd -r -g 92 frr && \ + groupadd -r -g 85 frrvty && \ + useradd -c "FRRouting suite" -d /var/run/frr -g frr -G frrvty \ + -r -s /sbin/nologin frr + +# Configure exabgp user. +RUN useradd -d /var/run/exabgp/ -s /bin/false exabgp + +# Configure coredumps. +RUN echo "" >> /etc/security/limits.conf; \ + echo "* soft core unlimited" >> /etc/security/limits.conf; \ + echo "root soft core unlimited" >> /etc/security/limits.conf; \ + echo "* hard core unlimited" >> /etc/security/limits.conf; \ + echo "root hard core unlimited" >> /etc/security/limits.conf + +# Copy run scripts to facilitate users wanting to run the tests +COPY . /opt/topotests +WORKDIR /root + +RUN echo "cat /opt/topotests/motd.txt" >> /root/.profile && \ + echo "export PS1='(topotests) $PS1'" >> /root/.profile + +# Configure volumes +VOLUME [ "/root/frr", "/root/topotests" ] + +# Add topotests script directory to path +ENV PATH "$PATH:/opt/topotests" + +# Use our custom entrypoint script +ENTRYPOINT [ "bash", "/opt/topotests/entrypoint.sh" ] diff --git a/tests/topotests/docker/README.md b/tests/topotests/docker/README.md new file mode 100644 index 0000000000..d126ca4559 --- /dev/null +++ b/tests/topotests/docker/README.md @@ -0,0 +1,23 @@ +# Topotests in Docker + +This is folder contains auxiliary scripts to automate or help deploying +topology tests under Docker on a standardized Ubuntu environment. + +Files description: + +* _funcs.sh_: shared bash code +* _docker.sh_: builds docker image to run topotests +* _compile_frr.sh_: compile FRR sources (should be used by `topotests_run.sh`) +* _topotests_run.sh_: runs topotest image with the selected command + +## Running Topotests in Docker + +All you need to run topotests in Docker is: + +* Have Docker installed (tested against docker-ce[1]) +* Build the topotest images +* Have the FRR/Topotest sources cloned in your machine + +Review and configure your sources folder in `topotests_run.sh`. + +[1]: https://docs.docker.com/install/linux/docker-ce/ubuntu/ diff --git a/tests/topotests/docker/compile_frr.sh b/tests/topotests/docker/compile_frr.sh new file mode 100755 index 0000000000..44b87405ea --- /dev/null +++ b/tests/topotests/docker/compile_frr.sh @@ -0,0 +1,99 @@ +#!/bin/bash +# +# Copyright 2018 Network Device Education Foundation, Inc. ("NetDEF") +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# Load shared functions +CDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +. $CDIR/funcs.sh + +# +# Script begin +# +if [ ! -f .sync_source -o $SYNC_SOURCE -ne 0 ]; then + log_info "Syncing FRR source with host..." + mkdir -p $FRR_BUILD_DIR >/dev/null 2>&1 + rsync -a --info=progress2 --chown root:root $FRR_DIR/. $FRR_BUILD_DIR/ + touch .sync_source +fi + +log_info "Building FRR..." + +cd $FRR_BUILD_DIR || \ + log_fatal "failed to find frr directory" + +if [ $CLEAN -ne 0 ]; then + make distclean >/dev/null 2>&1 + rm -f Makefile configure +fi + +if [ ! -f configure ]; then + bash bootstrap.sh || \ + log_fatal "failed to bootstrap configuration" +fi + +if [ $DOC -ne 0 ]; then + EXTRA_CONFIGURE+=" --enable-doc " +else + EXTRA_CONFIGURE+=" --disable-doc " +fi + +if [ ! -f Makefile ]; then + if [ $SANITIZER -ne 0 ]; then + export CC="gcc" + export CFLAGS="-O1 -g -fsanitize=address -fno-omit-frame-pointer" + export LD="gcc" + export LDFLAGS="-g -fsanitize=address -ldl" + EXTRA_CONFIGURE+=" --enable-shared=no " + touch .address_sanitizer + else + rm -f .address_sanitizer + fi + + bash configure >/dev/null \ + --enable-multipath=64 \ + --prefix=/usr \ + --localstatedir=/var/run/frr \ + --sbindir=/usr/lib/frr \ + --sysconfdir=/etc/frr \ + $EXTRA_CONFIGURE \ + --with-pkg-extra-version=-topotests \ + || log_fatal "failed to configure the sources" +fi + +# if '.address_sanitizer' file exists it means we are using address sanitizer. +if [ -f .address_sanitizer ]; then + make -C lib CFLAGS="-g -O2" LDFLAGS="-g" clippy +fi + +if [ $VERBOSE -ne 0 ]; then + make -j$(cpu_count) || \ + log_fatal "failed to build the sources" +else + make -j$(cpu_count) >/dev/null || \ + log_fatal "failed to build the sources" +fi + +make install >/dev/null || \ + log_fatal "failed to install frr" + +exit 0 diff --git a/tests/topotests/docker/docker.sh b/tests/topotests/docker/docker.sh new file mode 100755 index 0000000000..c312e58206 --- /dev/null +++ b/tests/topotests/docker/docker.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# +# Copyright 2018 Network Device Education Foundation, Inc. ("NetDEF") +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# Load shared functions +CDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +. $CDIR/funcs.sh + +# +# Script begin +# + +OLD_IMAGE_SHA=$( \ + docker images | \ + egrep "^topotests" | \ + sed -r "s/( )+/ /g" | \ + cut -d " " -f 3 \ +) + +docker build --force-rm --pull --compress -t topotests . || \ + log_fatal "failed to generate topotest docker image" + +if [ ! -z "$OLD_IMAGE_SHA" ]; then + log_info "Removing old topotest image" + docker rmi $OLD_IMAGE_SHA || \ + log_warning "failed to remove old image" +fi + +exit 0 diff --git a/tests/topotests/docker/entrypoint.sh b/tests/topotests/docker/entrypoint.sh new file mode 100755 index 0000000000..f62fa41b88 --- /dev/null +++ b/tests/topotests/docker/entrypoint.sh @@ -0,0 +1,75 @@ +#!/bin/bash +# +# Copyright 2018 Network Device Education Foundation, Inc. ("NetDEF") +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# Load shared functions +CDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +. $CDIR/funcs.sh + +# +# Script begin +# +log_info "Configuring OpenvSwitch...." + +# Configure OpenvSwitch so we are able to run mininet +mkdir -p /var/run/openvswitch +ovsdb-tool create /etc/openvswitch/conf.db \ + /usr/share/openvswitch/vswitch.ovsschema +ovsdb-server /etc/openvswitch/conf.db \ + --remote=punix:/var/run/openvswitch/db.sock \ + --remote=ptcp:6640 --pidfile=ovsdb-server.pid >/dev/null 2>/dev/null & \ + disown +ovs-vswitchd >/dev/null 2>/dev/null & disown + +sleep 2 + +ovs-vsctl --no-wait -- init +ovs_version=$(ovs-vsctl -V | grep ovs-vsctl | awk '{print $4}') +ovs_db_version=$(\ + ovsdb-tool schema-version /usr/share/openvswitch/vswitch.ovsschema) +ovs-vsctl --no-wait -- set Open_vSwitch . db-version="${ovs_db_version}" +ovs-vsctl --no-wait -- set Open_vSwitch . ovs-version="${ovs_version}" +ovs-vsctl --no-wait -- set Open_vSwitch . system-type="docker-ovs" +ovs-vsctl --no-wait -- set Open_vSwitch . system-version="0.1" +ovs-vsctl --no-wait -- \ + set Open_vSwitch . external-ids:system-id=`cat /proc/sys/kernel/random/uuid` +ovs-vsctl --no-wait -- set-manager ptcp:6640 +ovs-appctl -t ovsdb-server \ + ovsdb-server/add-remote db:Open_vSwitch,Open_vSwitch,manager_options + +# Build FRR +env \ + CLEAN=1 \ + VERBOSE=0 \ + bash /opt/topotests/compile_frr.sh + +log_info "Setting permissions on /tmp so we can generate logs" +chmod -v 1777 /tmp + +log_info "Starting bash shell to interact with topotests" +echo '' + +tmux + +log_info "Stopping OpenvSwitch" +service openvswitch-switch stop diff --git a/tests/topotests/docker/funcs.sh b/tests/topotests/docker/funcs.sh new file mode 100755 index 0000000000..8c46c8dcb2 --- /dev/null +++ b/tests/topotests/docker/funcs.sh @@ -0,0 +1,70 @@ +#!/bin/bash +# +# Copyright 2018 Network Device Education Foundation, Inc. ("NetDEF") +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +FRR_DIR=/root/frr +FRR_BUILD_DIR=/root/frr-build +TOPOTESTS_DIR=/root/topotests + +[ -z $CLEAN ] && CLEAN=0 +[ -z $VERBOSE ] && VERBOSE=1 +[ -z $DOC ] && DOC=0 +[ -z $SANITIZER ] && SANITIZER=1 +[ -z $SYNC_SOURCE ] && SYNC_SOURCE=0 + +log_info() { + local msg=$1 + + echo -e "=> $msg" +} + +log_error() { + local msg=$1 + + echo -e "E: $msg" 2>&1 +} + +log_warning() { + local msg=$1 + + echo -e "W: $msg" 2>&1 +} + +log_fatal() { + local msg=$1 + + echo -e "F: $msg" 2>&1 + + exit 1 +} + +cpu_count() { + local cpu_count + + cpu_count=$(cat /proc/cpuinfo | grep -w processor | wc -l) + if [ $? -eq 0 ]; then + echo -n $cpu_count + else + echo -n 2 + fi +} diff --git a/tests/topotests/docker/motd.txt b/tests/topotests/docker/motd.txt new file mode 100644 index 0000000000..1427fafcff --- /dev/null +++ b/tests/topotests/docker/motd.txt @@ -0,0 +1,20 @@ +Welcome to the topotests container. + +Here are some useful tips: +* After changing the FRR/Topotests sources, you may rebuild them + using the command `compile_frr.sh`. The build command has the + following environment variables: + - CLEAN: whether we should distclean or not (disabled by default) + - VERBOSE: show build messages (enabled by default) + - DOC: whether we should build docs or not (disabled by default) + - SANITIZER: whether we should use the address sanitizer (enabled by default) + - SYNC_SOURCE: copy new changes from host FRR sources (disabled by default) + + Usage example: env CLEAN=1 SYNC_SOURCE=1 DOC=1 compile_frr.sh + +* The topotests log directory can be found on your host machine on + `/tmp/topotests_logs`. + +* You may open an `xterm` inside the container. We do our best to detect + the X session on your host machine + diff --git a/tests/topotests/docker/topotests_run.sh b/tests/topotests/docker/topotests_run.sh new file mode 100755 index 0000000000..07e9f28b2f --- /dev/null +++ b/tests/topotests/docker/topotests_run.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# +# Copyright 2018 Network Device Education Foundation, Inc. ("NetDEF") +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +# Source folders +FRR_DIR=$HOME/src/frr +TOPOTESTS_DIR=$HOME/src/topotests + + +# +# Script begin +# +CMD=$1 +if [ -z $1 ]; then + CMD=bash +fi + +docker run --rm -ti \ + -v "/lib/modules:/lib/modules" \ + -v "/tmp/topotests_logs:/tmp" \ + -v "$FRR_DIR:/root/frr:ro" \ + -v "$TOPOTESTS_DIR:/root/topotests:ro" \ + -v "/tmp/.X11-unix:/tmp/.X11-unix" \ + -v "$HOME/.Xauthority:/root/.Xauthority" \ + -e DISPLAY=$DISPLAY \ + --net=host \ + --privileged \ + topotests + +exit 0 diff --git a/tests/topotests/pytest.ini b/tests/topotests/pytest.ini index 7362fae0c4..119ab93857 100644 --- a/tests/topotests/pytest.ini +++ b/tests/topotests/pytest.ini @@ -1,6 +1,6 @@ # Skip pytests example directory [pytest] -norecursedirs = .git example-test lib +norecursedirs = .git example-test lib docker [topogen] # Default configuration values From e425ee635718b2e29c9ed06ce172b82a24e651fb Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Wed, 17 Oct 2018 18:27:35 +0200 Subject: [PATCH 02/21] Dockerfile: Move to project root and combine RUNs According to https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#run `apt-get update` should always be combined with `apt-get install` in the same `RUN` statement, to avoid installation of outdated packages. Also, combine some more `RUN`s together as to avoid fewer layers. Finally, remove some comments which are superflous. Comments shouldn't describe what is done, especially when it's obvious. They should explain why something is done. Signed-off-by: Christian Franke --- tests/topotests/Dockerfile | 66 +++++++++++++++++++++++++++++++ tests/topotests/docker/Dockerfile | 55 -------------------------- 2 files changed, 66 insertions(+), 55 deletions(-) create mode 100644 tests/topotests/Dockerfile delete mode 100644 tests/topotests/docker/Dockerfile diff --git a/tests/topotests/Dockerfile b/tests/topotests/Dockerfile new file mode 100644 index 0000000000..8cd98c43a7 --- /dev/null +++ b/tests/topotests/Dockerfile @@ -0,0 +1,66 @@ +FROM ubuntu:18.04 + +RUN export DEBIAN_FRONTEND=noninteractive \ + && apt-get update \ + && apt-get install -y \ + autoconf \ + binutils \ + bison \ + flex \ + gdb \ + inetutils-ping \ + install-info \ + iproute2 \ + less \ + libtool \ + libjson-c-dev \ + libpython-dev \ + libreadline-dev \ + libc-ares-dev \ + man \ + mininet \ + pkg-config \ + python-pip \ + python-sphinx \ + rsync \ + tcpdump \ + texinfo \ + tmux \ + valgrind \ + vim \ + x11-xserver-utils \ + xterm \ + && pip install \ + exabgp==3.4.17 \ + ipaddr \ + pytest + +RUN groupadd -r -g 92 frr \ + && groupadd -r -g 85 frrvty \ + && useradd -c "FRRouting suite" \ + -d /var/run/frr \ + -g frr \ + -G frrvty \ + -r \ + -s /sbin/nologin \ + frr \ + && useradd -d /var/run/exabgp/ \ + -s /bin/false \ + exabgp + +# Configure coredumps +RUN echo "" >> /etc/security/limits.conf; \ + echo "* soft core unlimited" >> /etc/security/limits.conf; \ + echo "root soft core unlimited" >> /etc/security/limits.conf; \ + echo "* hard core unlimited" >> /etc/security/limits.conf; \ + echo "root hard core unlimited" >> /etc/security/limits.conf + +# Copy run scripts to facilitate users wanting to run the tests +COPY docker/ /opt/topotests +WORKDIR /root +ENV PATH "$PATH:/opt/topotests" + +RUN echo "cat /opt/topotests/motd.txt" >> /root/.profile && \ + echo "export PS1='(topotests) $PS1'" >> /root/.profile + +ENTRYPOINT [ "bash", "/opt/topotests/entrypoint.sh" ] diff --git a/tests/topotests/docker/Dockerfile b/tests/topotests/docker/Dockerfile deleted file mode 100644 index eff9623f82..0000000000 --- a/tests/topotests/docker/Dockerfile +++ /dev/null @@ -1,55 +0,0 @@ -FROM ubuntu:18.04 - -# Update system repos -RUN DEBIAN_FRONTEND=noninteractive apt update - -# Install FRR dependencies -RUN DEBIAN_FRONTEND=noninteractive apt install -y \ - autoconf binutils bison flex libtool libjson-c-dev \ - libpython-dev libreadline-dev libc-ares-dev python-sphinx \ - install-info pkg-config texinfo - -# Install useful tools for debugging -RUN DEBIAN_FRONTEND=noninteractive apt install -y \ - gdb inetutils-ping iproute2 valgrind - -# Install mininet dependencies -RUN DEBIAN_FRONTEND=noninteractive apt install -y \ - mininet python-pip && \ - pip install ipaddr pytest exabgp==3.4.17 - -# Install user utilities -RUN DEBIAN_FRONTEND=noninteractive apt install -y \ - x11-xserver-utils xterm tmux vim tcpdump less man rsync - -# Configure FRR users -RUN groupadd -r -g 92 frr && \ - groupadd -r -g 85 frrvty && \ - useradd -c "FRRouting suite" -d /var/run/frr -g frr -G frrvty \ - -r -s /sbin/nologin frr - -# Configure exabgp user. -RUN useradd -d /var/run/exabgp/ -s /bin/false exabgp - -# Configure coredumps. -RUN echo "" >> /etc/security/limits.conf; \ - echo "* soft core unlimited" >> /etc/security/limits.conf; \ - echo "root soft core unlimited" >> /etc/security/limits.conf; \ - echo "* hard core unlimited" >> /etc/security/limits.conf; \ - echo "root hard core unlimited" >> /etc/security/limits.conf - -# Copy run scripts to facilitate users wanting to run the tests -COPY . /opt/topotests -WORKDIR /root - -RUN echo "cat /opt/topotests/motd.txt" >> /root/.profile && \ - echo "export PS1='(topotests) $PS1'" >> /root/.profile - -# Configure volumes -VOLUME [ "/root/frr", "/root/topotests" ] - -# Add topotests script directory to path -ENV PATH "$PATH:/opt/topotests" - -# Use our custom entrypoint script -ENTRYPOINT [ "bash", "/opt/topotests/entrypoint.sh" ] From c12ec8557e6416415766f5e09b0abcade85f3e84 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Wed, 17 Oct 2018 19:35:15 +0200 Subject: [PATCH 03/21] docker: Run container with its own network namespace For normal operation, there is no need for the container to run in the host network environment or to have access to the users X Session. To accomodate usecases which need this, there is now a `TOPOTEST_OPTIONS` environment variable to provide additional options to the docker run command. Signed-off-by: Christian Franke --- tests/topotests/docker/motd.txt | 4 - tests/topotests/docker/topotests_run.sh | 125 ++++++++++++++++++++---- 2 files changed, 104 insertions(+), 25 deletions(-) diff --git a/tests/topotests/docker/motd.txt b/tests/topotests/docker/motd.txt index 1427fafcff..cb02540f5c 100644 --- a/tests/topotests/docker/motd.txt +++ b/tests/topotests/docker/motd.txt @@ -14,7 +14,3 @@ Here are some useful tips: * The topotests log directory can be found on your host machine on `/tmp/topotests_logs`. - -* You may open an `xterm` inside the container. We do our best to detect - the X session on your host machine - diff --git a/tests/topotests/docker/topotests_run.sh b/tests/topotests/docker/topotests_run.sh index 07e9f28b2f..8bca756b89 100755 --- a/tests/topotests/docker/topotests_run.sh +++ b/tests/topotests/docker/topotests_run.sh @@ -22,30 +22,113 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +set -e -# Source folders -FRR_DIR=$HOME/src/frr -TOPOTESTS_DIR=$HOME/src/topotests +if [[ "$1" = "-h" ]] || [[ "$1" = "--help" ]]; then + cat >&2 <<-EOF + This script runs the FRRouting topotests on the FRR tree + in the current working directory. -# -# Script begin -# -CMD=$1 -if [ -z $1 ]; then - CMD=bash + Usage: $0 [args...] + + Its behavior can be modified by the following environment variables: + + TOPOTEST_AUTOLOAD If set to 1, the script will try to load necessary + kernel modules without asking for confirmation first. + + TOPOTEST_BUILDCACHE Docker volume used for caching multiple FRR builds + over container runs. By default a + \`topotest-buildcache\` volume will be created for + that purpose. + + TOPOTEST_FRR If set, don't test the FRR in the current working + directory, but the one at the given path. + + TOPOTEST_LOGS If set, don't use \`/tmp/topotest_logs\` directory + but use the provided path instead. + + TOPOTEST_OPTIONS These options are appended to the docker-run + command for starting the tests. + + TOPOTEST_PATH If set, don't use the tests built into the image + but the ones at the given path. + + To get information about the commands available inside of the container, + run \`$0 help\`. + EOF + exit 1 fi -docker run --rm -ti \ - -v "/lib/modules:/lib/modules" \ - -v "/tmp/topotests_logs:/tmp" \ - -v "$FRR_DIR:/root/frr:ro" \ - -v "$TOPOTESTS_DIR:/root/topotests:ro" \ - -v "/tmp/.X11-unix:/tmp/.X11-unix" \ - -v "$HOME/.Xauthority:/root/.Xauthority" \ - -e DISPLAY=$DISPLAY \ - --net=host \ - --privileged \ - topotests +# +# These two modules are needed to run the MPLS tests. +# They are often not automatically loaded. +# +# We cannot load them from the container since we don't +# have host kernel modules available there. If we load +# them from the host however, they can be used just fine. +# -exit 0 +for module in mpls-router mpls-iptunnel; do + if modprobe -n $module 2> /dev/null; then + : + else + # If the module doesn't exist, we cannot do anything about it + continue + fi + + if [ $(grep -c ${module/-/_} /proc/modules) -ne 0 ]; then + # If the module is loaded, we don't have to do anything + continue + fi + + if [ "$TOPOTEST_AUTOLOAD" != "1" ]; then + echo "To run all the possible tests, we need to load $module." + echo -n "Do you want to proceed? [y/n] " + read answer + if [ x"$answer" != x"y" ]; then + echo "Not loading." + continue + fi + fi + + if [ x"$(whoami)" = x"root" ]; then + modprobe $module + else + sudo modprobe $module + fi +done + +if [ -z "$TOPOTEST_LOGS" ]; then + mkdir -p /tmp/topotest_logs + TOPOTEST_LOGS="/tmp/topotest_logs" +fi + +if [ -z "$TOPOTEST_FRR" ]; then + TOPOTEST_FRR="$(pwd)" +fi + +if [ -z "$TOPOTEST_BUILDCACHE" ]; then + TOPOTEST_BUILDCACHE=topotest-buildcache + docker volume inspect "${TOPOTEST_BUILDCACHE}" &> /dev/null \ + || docker volume create "${TOPOTEST_BUILDCACHE}" +fi + +if [ -z "$TOPOTEST_PATH" ]; then + docker run --rm -ti \ + -v "$TOPOTEST_LOGS:/tmp" \ + -v "$TOPOTEST_FRR:/root/frr:ro" \ + -v "$TOPOTEST_BUILDCACHE:/root/frr-build" \ + --privileged \ + $TOPOTEST_OPTIONS \ + frrouting/topotests "$@" +else + docker run --rm -ti \ + -v "$TOPOTEST_LOGS:/tmp" \ + -v "$TOPOTEST_FRR:/root/frr:ro" \ + -v "$TOPOTEST_BUILDCACHE:/root/frr-build" \ + -v "$TOPOTEST_PATH:/root/topotests:ro" \ + --privileged \ + $TOPOTEST_OPTIONS \ + frrouting/topotests "$@" +fi From 04c63c05b5ab1b81e10f9a3cf94742558913f95a Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Wed, 17 Oct 2018 19:56:26 +0200 Subject: [PATCH 04/21] docker: reindent shell scripts Signed-off-by: Christian Franke --- tests/topotests/docker/compile_frr.sh | 72 +++++++++++++-------------- tests/topotests/docker/docker.sh | 16 +++--- tests/topotests/docker/entrypoint.sh | 20 ++++---- tests/topotests/docker/funcs.sh | 32 ++++++------ 4 files changed, 70 insertions(+), 70 deletions(-) diff --git a/tests/topotests/docker/compile_frr.sh b/tests/topotests/docker/compile_frr.sh index 44b87405ea..d9d27b670e 100755 --- a/tests/topotests/docker/compile_frr.sh +++ b/tests/topotests/docker/compile_frr.sh @@ -30,70 +30,70 @@ CDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Script begin # if [ ! -f .sync_source -o $SYNC_SOURCE -ne 0 ]; then - log_info "Syncing FRR source with host..." - mkdir -p $FRR_BUILD_DIR >/dev/null 2>&1 - rsync -a --info=progress2 --chown root:root $FRR_DIR/. $FRR_BUILD_DIR/ - touch .sync_source + log_info "Syncing FRR source with host..." + mkdir -p $FRR_BUILD_DIR >/dev/null 2>&1 + rsync -a --info=progress2 --chown root:root $FRR_DIR/. $FRR_BUILD_DIR/ + touch .sync_source fi log_info "Building FRR..." cd $FRR_BUILD_DIR || \ - log_fatal "failed to find frr directory" + log_fatal "failed to find frr directory" if [ $CLEAN -ne 0 ]; then - make distclean >/dev/null 2>&1 - rm -f Makefile configure + make distclean >/dev/null 2>&1 + rm -f Makefile configure fi if [ ! -f configure ]; then - bash bootstrap.sh || \ - log_fatal "failed to bootstrap configuration" + bash bootstrap.sh || \ + log_fatal "failed to bootstrap configuration" fi if [ $DOC -ne 0 ]; then - EXTRA_CONFIGURE+=" --enable-doc " + EXTRA_CONFIGURE+=" --enable-doc " else - EXTRA_CONFIGURE+=" --disable-doc " + EXTRA_CONFIGURE+=" --disable-doc " fi if [ ! -f Makefile ]; then - if [ $SANITIZER -ne 0 ]; then - export CC="gcc" - export CFLAGS="-O1 -g -fsanitize=address -fno-omit-frame-pointer" - export LD="gcc" - export LDFLAGS="-g -fsanitize=address -ldl" - EXTRA_CONFIGURE+=" --enable-shared=no " - touch .address_sanitizer - else - rm -f .address_sanitizer - fi + if [ $SANITIZER -ne 0 ]; then + export CC="gcc" + export CFLAGS="-O1 -g -fsanitize=address -fno-omit-frame-pointer" + export LD="gcc" + export LDFLAGS="-g -fsanitize=address -ldl" + EXTRA_CONFIGURE+=" --enable-shared=no " + touch .address_sanitizer + else + rm -f .address_sanitizer + fi - bash configure >/dev/null \ - --enable-multipath=64 \ - --prefix=/usr \ - --localstatedir=/var/run/frr \ - --sbindir=/usr/lib/frr \ - --sysconfdir=/etc/frr \ - $EXTRA_CONFIGURE \ - --with-pkg-extra-version=-topotests \ - || log_fatal "failed to configure the sources" + bash configure >/dev/null \ + --enable-multipath=64 \ + --prefix=/usr \ + --localstatedir=/var/run/frr \ + --sbindir=/usr/lib/frr \ + --sysconfdir=/etc/frr \ + $EXTRA_CONFIGURE \ + --with-pkg-extra-version=-topotests \ + || log_fatal "failed to configure the sources" fi # if '.address_sanitizer' file exists it means we are using address sanitizer. if [ -f .address_sanitizer ]; then - make -C lib CFLAGS="-g -O2" LDFLAGS="-g" clippy + make -C lib CFLAGS="-g -O2" LDFLAGS="-g" clippy fi if [ $VERBOSE -ne 0 ]; then - make -j$(cpu_count) || \ - log_fatal "failed to build the sources" + make -j$(cpu_count) || \ + log_fatal "failed to build the sources" else - make -j$(cpu_count) >/dev/null || \ - log_fatal "failed to build the sources" + make -j$(cpu_count) >/dev/null || \ + log_fatal "failed to build the sources" fi make install >/dev/null || \ - log_fatal "failed to install frr" + log_fatal "failed to install frr" exit 0 diff --git a/tests/topotests/docker/docker.sh b/tests/topotests/docker/docker.sh index c312e58206..ac40e6c5af 100755 --- a/tests/topotests/docker/docker.sh +++ b/tests/topotests/docker/docker.sh @@ -31,19 +31,19 @@ CDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # OLD_IMAGE_SHA=$( \ - docker images | \ - egrep "^topotests" | \ - sed -r "s/( )+/ /g" | \ - cut -d " " -f 3 \ + docker images | \ + egrep "^topotests" | \ + sed -r "s/( )+/ /g" | \ + cut -d " " -f 3 \ ) docker build --force-rm --pull --compress -t topotests . || \ - log_fatal "failed to generate topotest docker image" + log_fatal "failed to generate topotest docker image" if [ ! -z "$OLD_IMAGE_SHA" ]; then - log_info "Removing old topotest image" - docker rmi $OLD_IMAGE_SHA || \ - log_warning "failed to remove old image" + log_info "Removing old topotest image" + docker rmi $OLD_IMAGE_SHA || \ + log_warning "failed to remove old image" fi exit 0 diff --git a/tests/topotests/docker/entrypoint.sh b/tests/topotests/docker/entrypoint.sh index f62fa41b88..d9defb424e 100755 --- a/tests/topotests/docker/entrypoint.sh +++ b/tests/topotests/docker/entrypoint.sh @@ -34,11 +34,11 @@ log_info "Configuring OpenvSwitch...." # Configure OpenvSwitch so we are able to run mininet mkdir -p /var/run/openvswitch ovsdb-tool create /etc/openvswitch/conf.db \ - /usr/share/openvswitch/vswitch.ovsschema + /usr/share/openvswitch/vswitch.ovsschema ovsdb-server /etc/openvswitch/conf.db \ - --remote=punix:/var/run/openvswitch/db.sock \ - --remote=ptcp:6640 --pidfile=ovsdb-server.pid >/dev/null 2>/dev/null & \ - disown + --remote=punix:/var/run/openvswitch/db.sock \ + --remote=ptcp:6640 --pidfile=ovsdb-server.pid >/dev/null 2>/dev/null & \ + disown ovs-vswitchd >/dev/null 2>/dev/null & disown sleep 2 @@ -46,22 +46,22 @@ sleep 2 ovs-vsctl --no-wait -- init ovs_version=$(ovs-vsctl -V | grep ovs-vsctl | awk '{print $4}') ovs_db_version=$(\ - ovsdb-tool schema-version /usr/share/openvswitch/vswitch.ovsschema) + ovsdb-tool schema-version /usr/share/openvswitch/vswitch.ovsschema) ovs-vsctl --no-wait -- set Open_vSwitch . db-version="${ovs_db_version}" ovs-vsctl --no-wait -- set Open_vSwitch . ovs-version="${ovs_version}" ovs-vsctl --no-wait -- set Open_vSwitch . system-type="docker-ovs" ovs-vsctl --no-wait -- set Open_vSwitch . system-version="0.1" ovs-vsctl --no-wait -- \ - set Open_vSwitch . external-ids:system-id=`cat /proc/sys/kernel/random/uuid` + set Open_vSwitch . external-ids:system-id=`cat /proc/sys/kernel/random/uuid` ovs-vsctl --no-wait -- set-manager ptcp:6640 ovs-appctl -t ovsdb-server \ - ovsdb-server/add-remote db:Open_vSwitch,Open_vSwitch,manager_options + ovsdb-server/add-remote db:Open_vSwitch,Open_vSwitch,manager_options # Build FRR env \ - CLEAN=1 \ - VERBOSE=0 \ - bash /opt/topotests/compile_frr.sh + CLEAN=1 \ + VERBOSE=0 \ + bash /opt/topotests/compile_frr.sh log_info "Setting permissions on /tmp so we can generate logs" chmod -v 1777 /tmp diff --git a/tests/topotests/docker/funcs.sh b/tests/topotests/docker/funcs.sh index 8c46c8dcb2..78640d3244 100755 --- a/tests/topotests/docker/funcs.sh +++ b/tests/topotests/docker/funcs.sh @@ -33,38 +33,38 @@ TOPOTESTS_DIR=/root/topotests [ -z $SYNC_SOURCE ] && SYNC_SOURCE=0 log_info() { - local msg=$1 + local msg=$1 - echo -e "=> $msg" + echo -e "=> $msg" } log_error() { - local msg=$1 + local msg=$1 - echo -e "E: $msg" 2>&1 + echo -e "E: $msg" 2>&1 } log_warning() { - local msg=$1 + local msg=$1 - echo -e "W: $msg" 2>&1 + echo -e "W: $msg" 2>&1 } log_fatal() { - local msg=$1 + local msg=$1 - echo -e "F: $msg" 2>&1 + echo -e "F: $msg" 2>&1 - exit 1 + exit 1 } cpu_count() { - local cpu_count + local cpu_count - cpu_count=$(cat /proc/cpuinfo | grep -w processor | wc -l) - if [ $? -eq 0 ]; then - echo -n $cpu_count - else - echo -n 2 - fi + cpu_count=$(cat /proc/cpuinfo | grep -w processor | wc -l) + if [ $? -eq 0 ]; then + echo -n $cpu_count + else + echo -n 2 + fi } From ca64604f47a8d9f4753b53b9fa4354eb18e4c511 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Wed, 17 Oct 2018 20:31:52 +0200 Subject: [PATCH 05/21] docker: Install topotests into image Also: Change directory layout so we can do an indempotent sync from host later. Signed-off-by: Christian Franke --- tests/topotests/Dockerfile | 8 ++++---- tests/topotests/docker/compile_frr.sh | 2 +- tests/topotests/docker/entrypoint.sh | 2 +- tests/topotests/docker/funcs.sh | 8 ++++++-- tests/topotests/docker/topotests_run.sh | 8 ++++---- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/tests/topotests/Dockerfile b/tests/topotests/Dockerfile index 8cd98c43a7..ecc91bc543 100644 --- a/tests/topotests/Dockerfile +++ b/tests/topotests/Dockerfile @@ -56,11 +56,11 @@ RUN echo "" >> /etc/security/limits.conf; \ echo "root hard core unlimited" >> /etc/security/limits.conf # Copy run scripts to facilitate users wanting to run the tests -COPY docker/ /opt/topotests +COPY . /root/topotests WORKDIR /root -ENV PATH "$PATH:/opt/topotests" +ENV PATH "$PATH:/root/topotests/docker" -RUN echo "cat /opt/topotests/motd.txt" >> /root/.profile && \ +RUN echo "cat /root/topotests/docker/motd.txt" >> /root/.profile && \ echo "export PS1='(topotests) $PS1'" >> /root/.profile -ENTRYPOINT [ "bash", "/opt/topotests/entrypoint.sh" ] +ENTRYPOINT [ "bash", "/root/topotests/docker/entrypoint.sh" ] diff --git a/tests/topotests/docker/compile_frr.sh b/tests/topotests/docker/compile_frr.sh index d9d27b670e..55046f9edb 100755 --- a/tests/topotests/docker/compile_frr.sh +++ b/tests/topotests/docker/compile_frr.sh @@ -32,7 +32,7 @@ CDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" if [ ! -f .sync_source -o $SYNC_SOURCE -ne 0 ]; then log_info "Syncing FRR source with host..." mkdir -p $FRR_BUILD_DIR >/dev/null 2>&1 - rsync -a --info=progress2 --chown root:root $FRR_DIR/. $FRR_BUILD_DIR/ + rsync -a --info=progress2 --chown root:root $FRR_HOST_DIR/. $FRR_BUILD_DIR/ touch .sync_source fi diff --git a/tests/topotests/docker/entrypoint.sh b/tests/topotests/docker/entrypoint.sh index d9defb424e..e227029586 100755 --- a/tests/topotests/docker/entrypoint.sh +++ b/tests/topotests/docker/entrypoint.sh @@ -61,7 +61,7 @@ ovs-appctl -t ovsdb-server \ env \ CLEAN=1 \ VERBOSE=0 \ - bash /opt/topotests/compile_frr.sh + bash "${CDIR}/compile_frr.sh" log_info "Setting permissions on /tmp so we can generate logs" chmod -v 1777 /tmp diff --git a/tests/topotests/docker/funcs.sh b/tests/topotests/docker/funcs.sh index 78640d3244..dae71de329 100755 --- a/tests/topotests/docker/funcs.sh +++ b/tests/topotests/docker/funcs.sh @@ -22,10 +22,14 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -FRR_DIR=/root/frr -FRR_BUILD_DIR=/root/frr-build +FRR_HOST_DIR=/root/host-frr +FRR_BUILD_DIR=/root/persist/frr-build TOPOTESTS_DIR=/root/topotests +if [ ! -L "/root/frr" ]; then + ln -s $FRR_BUILD_DIR /root/frr +fi + [ -z $CLEAN ] && CLEAN=0 [ -z $VERBOSE ] && VERBOSE=1 [ -z $DOC ] && DOC=0 diff --git a/tests/topotests/docker/topotests_run.sh b/tests/topotests/docker/topotests_run.sh index 8bca756b89..a68896789a 100755 --- a/tests/topotests/docker/topotests_run.sh +++ b/tests/topotests/docker/topotests_run.sh @@ -117,16 +117,16 @@ fi if [ -z "$TOPOTEST_PATH" ]; then docker run --rm -ti \ -v "$TOPOTEST_LOGS:/tmp" \ - -v "$TOPOTEST_FRR:/root/frr:ro" \ - -v "$TOPOTEST_BUILDCACHE:/root/frr-build" \ + -v "$TOPOTEST_FRR:/root/host-frr:ro" \ + -v "$TOPOTEST_BUILDCACHE:/root/persist" \ --privileged \ $TOPOTEST_OPTIONS \ frrouting/topotests "$@" else docker run --rm -ti \ -v "$TOPOTEST_LOGS:/tmp" \ - -v "$TOPOTEST_FRR:/root/frr:ro" \ - -v "$TOPOTEST_BUILDCACHE:/root/frr-build" \ + -v "$TOPOTEST_FRR:/root/host-frr:ro" \ + -v "$TOPOTEST_BUILDCACHE:/root/persist" \ -v "$TOPOTEST_PATH:/root/topotests:ro" \ --privileged \ $TOPOTEST_OPTIONS \ From 7b75f8cce379485a95cbb36597b2bb2ffd6998cd Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Thu, 18 Oct 2018 11:31:20 +0200 Subject: [PATCH 06/21] Docker: Update buildscripts to be more efficient Signed-off-by: Christian Franke --- tests/topotests/Dockerfile | 1 + tests/topotests/docker/compile_frr.sh | 64 ++++++++++++++----------- tests/topotests/docker/entrypoint.sh | 11 +---- tests/topotests/docker/funcs.sh | 11 ++--- tests/topotests/docker/motd.txt | 11 ++--- tests/topotests/docker/topotests_run.sh | 33 +++++++------ 6 files changed, 64 insertions(+), 67 deletions(-) diff --git a/tests/topotests/Dockerfile b/tests/topotests/Dockerfile index ecc91bc543..d6a395a948 100644 --- a/tests/topotests/Dockerfile +++ b/tests/topotests/Dockerfile @@ -8,6 +8,7 @@ RUN export DEBIAN_FRONTEND=noninteractive \ bison \ flex \ gdb \ + git \ inetutils-ping \ install-info \ iproute2 \ diff --git a/tests/topotests/docker/compile_frr.sh b/tests/topotests/docker/compile_frr.sh index 55046f9edb..6b64f79d60 100755 --- a/tests/topotests/docker/compile_frr.sh +++ b/tests/topotests/docker/compile_frr.sh @@ -22,6 +22,8 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +set -e + # Load shared functions CDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" . $CDIR/funcs.sh @@ -29,36 +31,47 @@ CDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # # Script begin # -if [ ! -f .sync_source -o $SYNC_SOURCE -ne 0 ]; then - log_info "Syncing FRR source with host..." - mkdir -p $FRR_BUILD_DIR >/dev/null 2>&1 - rsync -a --info=progress2 --chown root:root $FRR_HOST_DIR/. $FRR_BUILD_DIR/ - touch .sync_source + +log_info "Syncing FRR source with host..." +mkdir -p $FRR_SYNC_DIR +rsync -a --info=progress2 \ + --exclude '*.o' \ + --exclude '*.lo'\ + --chown root:root \ + $FRR_HOST_DIR/. $FRR_SYNC_DIR/ +(cd $FRR_SYNC_DIR && git clean -xdf > /dev/null) +mkdir -p $FRR_BUILD_DIR +rsync -a --info=progress2 --chown root:root $FRR_SYNC_DIR/. $FRR_BUILD_DIR/ + +cd "$FRR_BUILD_DIR" || \ + log_fatal "failed to find frr directory" + +if [ "${TOPOTEST_VERBOSE}" != "0" ]; then + exec 3>&1 +else + exec 3>/dev/null +fi + +if [ "${TOPOTEST_CLEAN}" != "0" ]; then + log_info "Cleaning FRR builddir..." + git clean -xdf > /dev/null fi log_info "Building FRR..." -cd $FRR_BUILD_DIR || \ - log_fatal "failed to find frr directory" - -if [ $CLEAN -ne 0 ]; then - make distclean >/dev/null 2>&1 - rm -f Makefile configure -fi - -if [ ! -f configure ]; then - bash bootstrap.sh || \ +if [ ! -e configure ]; then + bash bootstrap.sh >&3 || \ log_fatal "failed to bootstrap configuration" fi -if [ $DOC -ne 0 ]; then +if [ "${TOPOTEST_DOC}" != "0" ]; then EXTRA_CONFIGURE+=" --enable-doc " else EXTRA_CONFIGURE+=" --disable-doc " fi -if [ ! -f Makefile ]; then - if [ $SANITIZER -ne 0 ]; then +if [ ! -e Makefile ]; then + if [ "${TOPOTEST_SANITIZER}" != "0" ]; then export CC="gcc" export CFLAGS="-O1 -g -fsanitize=address -fno-omit-frame-pointer" export LD="gcc" @@ -69,7 +82,7 @@ if [ ! -f Makefile ]; then rm -f .address_sanitizer fi - bash configure >/dev/null \ + bash configure >&3 \ --enable-multipath=64 \ --prefix=/usr \ --localstatedir=/var/run/frr \ @@ -82,18 +95,11 @@ fi # if '.address_sanitizer' file exists it means we are using address sanitizer. if [ -f .address_sanitizer ]; then - make -C lib CFLAGS="-g -O2" LDFLAGS="-g" clippy + make -C lib CFLAGS="-g -O2" LDFLAGS="-g" clippy >&3 fi -if [ $VERBOSE -ne 0 ]; then - make -j$(cpu_count) || \ - log_fatal "failed to build the sources" -else - make -j$(cpu_count) >/dev/null || \ - log_fatal "failed to build the sources" -fi +make -j$(cpu_count) >&3 || \ + log_fatal "failed to build the sources" make install >/dev/null || \ log_fatal "failed to install frr" - -exit 0 diff --git a/tests/topotests/docker/entrypoint.sh b/tests/topotests/docker/entrypoint.sh index e227029586..707c521888 100755 --- a/tests/topotests/docker/entrypoint.sh +++ b/tests/topotests/docker/entrypoint.sh @@ -57,11 +57,7 @@ ovs-vsctl --no-wait -- set-manager ptcp:6640 ovs-appctl -t ovsdb-server \ ovsdb-server/add-remote db:Open_vSwitch,Open_vSwitch,manager_options -# Build FRR -env \ - CLEAN=1 \ - VERBOSE=0 \ - bash "${CDIR}/compile_frr.sh" +bash "${CDIR}/compile_frr.sh" log_info "Setting permissions on /tmp so we can generate logs" chmod -v 1777 /tmp @@ -69,7 +65,4 @@ chmod -v 1777 /tmp log_info "Starting bash shell to interact with topotests" echo '' -tmux - -log_info "Stopping OpenvSwitch" -service openvswitch-switch stop +exec bash diff --git a/tests/topotests/docker/funcs.sh b/tests/topotests/docker/funcs.sh index dae71de329..acb8b55e97 100755 --- a/tests/topotests/docker/funcs.sh +++ b/tests/topotests/docker/funcs.sh @@ -23,18 +23,17 @@ # SOFTWARE. FRR_HOST_DIR=/root/host-frr +FRR_SYNC_DIR=/root/persist/frr-sync FRR_BUILD_DIR=/root/persist/frr-build -TOPOTESTS_DIR=/root/topotests if [ ! -L "/root/frr" ]; then ln -s $FRR_BUILD_DIR /root/frr fi -[ -z $CLEAN ] && CLEAN=0 -[ -z $VERBOSE ] && VERBOSE=1 -[ -z $DOC ] && DOC=0 -[ -z $SANITIZER ] && SANITIZER=1 -[ -z $SYNC_SOURCE ] && SYNC_SOURCE=0 +[ -z $TOPOTEST_CLEAN ] && TOPOTEST_CLEAN=0 +[ -z $TOPOTEST_VERBOSE ] && TOPOTEST_VERBOSE=1 +[ -z $TOPOTEST_DOC ] && TOPOTEST_DOC=0 +[ -z $TOPOTEST_SANITIZER ] && TOPOTEST_SANITIZER=1 log_info() { local msg=$1 diff --git a/tests/topotests/docker/motd.txt b/tests/topotests/docker/motd.txt index cb02540f5c..1e2f34f8fb 100644 --- a/tests/topotests/docker/motd.txt +++ b/tests/topotests/docker/motd.txt @@ -4,13 +4,12 @@ Here are some useful tips: * After changing the FRR/Topotests sources, you may rebuild them using the command `compile_frr.sh`. The build command has the following environment variables: - - CLEAN: whether we should distclean or not (disabled by default) - - VERBOSE: show build messages (enabled by default) - - DOC: whether we should build docs or not (disabled by default) - - SANITIZER: whether we should use the address sanitizer (enabled by default) - - SYNC_SOURCE: copy new changes from host FRR sources (disabled by default) + - TOPOTEST_CLEAN: whether we should distclean or not (disabled by default) + - TOPOTEST_VERBOSE: show build messages (enabled by default) + - TOPOTEST_DOC: whether we should build docs or not (disabled by default) + - TOPOTEST_SANITIZER: whether we should use the address sanitizer (enabled by default) - Usage example: env CLEAN=1 SYNC_SOURCE=1 DOC=1 compile_frr.sh + Usage example: env TOPOTEST_CLEAN=1 compile_frr.sh * The topotests log directory can be found on your host machine on `/tmp/topotests_logs`. diff --git a/tests/topotests/docker/topotests_run.sh b/tests/topotests/docker/topotests_run.sh index a68896789a..e5e91156a5 100755 --- a/tests/topotests/docker/topotests_run.sh +++ b/tests/topotests/docker/topotests_run.sh @@ -114,21 +114,20 @@ if [ -z "$TOPOTEST_BUILDCACHE" ]; then || docker volume create "${TOPOTEST_BUILDCACHE}" fi -if [ -z "$TOPOTEST_PATH" ]; then - docker run --rm -ti \ - -v "$TOPOTEST_LOGS:/tmp" \ - -v "$TOPOTEST_FRR:/root/host-frr:ro" \ - -v "$TOPOTEST_BUILDCACHE:/root/persist" \ - --privileged \ - $TOPOTEST_OPTIONS \ - frrouting/topotests "$@" -else - docker run --rm -ti \ - -v "$TOPOTEST_LOGS:/tmp" \ - -v "$TOPOTEST_FRR:/root/host-frr:ro" \ - -v "$TOPOTEST_BUILDCACHE:/root/persist" \ - -v "$TOPOTEST_PATH:/root/topotests:ro" \ - --privileged \ - $TOPOTEST_OPTIONS \ - frrouting/topotests "$@" +set -- --rm -ti \ + -v "$TOPOTEST_LOGS:/tmp" \ + -v "$TOPOTEST_FRR:/root/host-frr:ro" \ + -v "$TOPOTEST_BUILDCACHE:/root/persist" \ + -e "TOPOTEST_CLEAN=$TOPOTEST_CLEAN" \ + -e "TOPOTEST_VERBOSE=$TOPOTEST_VERBOSE" \ + -e "TOPOTEST_DOC=$TOPOTEST_DOC" \ + -e "TOPOTEST_SANITIZER=$TOPOTEST_SANITIZER" \ + --privileged \ + $TOPOTEST_OPTIONS \ + frrouting/topotests "$@" + +if [ -n "TOPOTEST_PATH" ]; then + set -- -v "$TOPOTEST_PATH:/root/topotests:ro" "$@" fi + +exec docker run "$@" From 8e6f0d80f6c591763b99028b2d991aafa5e02b07 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Thu, 18 Oct 2018 11:32:00 +0200 Subject: [PATCH 07/21] Dockerfile: Use iputils-ping instead of inetutils-ping, install strace Signed-off-by: Christian Franke --- tests/topotests/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/topotests/Dockerfile b/tests/topotests/Dockerfile index d6a395a948..d7b2cae354 100644 --- a/tests/topotests/Dockerfile +++ b/tests/topotests/Dockerfile @@ -9,8 +9,8 @@ RUN export DEBIAN_FRONTEND=noninteractive \ flex \ gdb \ git \ - inetutils-ping \ install-info \ + iputils-ping \ iproute2 \ less \ libtool \ @@ -24,6 +24,7 @@ RUN export DEBIAN_FRONTEND=noninteractive \ python-pip \ python-sphinx \ rsync \ + strace \ tcpdump \ texinfo \ tmux \ From d9e887de2a24635677672a9d57c9da3ccd1acc65 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Thu, 18 Oct 2018 11:56:20 +0200 Subject: [PATCH 08/21] Docker: Call the run script frr-topotests.sh Signed-off-by: Christian Franke --- tests/topotests/docker/README.md | 30 +++++++++---------- .../{topotests_run.sh => frr-topotests.sh} | 0 2 files changed, 14 insertions(+), 16 deletions(-) rename tests/topotests/docker/{topotests_run.sh => frr-topotests.sh} (100%) diff --git a/tests/topotests/docker/README.md b/tests/topotests/docker/README.md index d126ca4559..b506fd6fb1 100644 --- a/tests/topotests/docker/README.md +++ b/tests/topotests/docker/README.md @@ -1,23 +1,21 @@ # Topotests in Docker -This is folder contains auxiliary scripts to automate or help deploying -topology tests under Docker on a standardized Ubuntu environment. +## Usage -Files description: +If you have Docker installed, you can run the topotests in Docker. +The easiest way to do this, is to use the `frr-topotests.sh` script +from this repository: -* _funcs.sh_: shared bash code -* _docker.sh_: builds docker image to run topotests -* _compile_frr.sh_: compile FRR sources (should be used by `topotests_run.sh`) -* _topotests_run.sh_: runs topotest image with the selected command +```console +wget -O /usr/local/bin/frr-topotests \ + https://raw.githubusercontent.com/frrouting/topotests/master/docker/frr-topotests.sh +chmod +x /usr/local/bin/frr-topotests +``` -## Running Topotests in Docker +Once this script is in place, simply run it while you are inside your FRR repository: -All you need to run topotests in Docker is: +``` +frr-topotests +``` -* Have Docker installed (tested against docker-ce[1]) -* Build the topotest images -* Have the FRR/Topotest sources cloned in your machine - -Review and configure your sources folder in `topotests_run.sh`. - -[1]: https://docs.docker.com/install/linux/docker-ce/ubuntu/ +It should build FRR inside of the container and run the topotests on it. diff --git a/tests/topotests/docker/topotests_run.sh b/tests/topotests/docker/frr-topotests.sh similarity index 100% rename from tests/topotests/docker/topotests_run.sh rename to tests/topotests/docker/frr-topotests.sh From f1c0836f6700bff9743f08ecbbd99325c3b1d6ae Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Thu, 18 Oct 2018 12:07:24 +0200 Subject: [PATCH 09/21] Docker: Update buildscript not to delete old images Signed-off-by: Christian Franke --- tests/topotests/docker/docker.sh | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/tests/topotests/docker/docker.sh b/tests/topotests/docker/docker.sh index ac40e6c5af..4dcee218c9 100755 --- a/tests/topotests/docker/docker.sh +++ b/tests/topotests/docker/docker.sh @@ -30,20 +30,7 @@ CDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Script begin # -OLD_IMAGE_SHA=$( \ - docker images | \ - egrep "^topotests" | \ - sed -r "s/( )+/ /g" | \ - cut -d " " -f 3 \ -) - -docker build --force-rm --pull --compress -t topotests . || \ - log_fatal "failed to generate topotest docker image" - -if [ ! -z "$OLD_IMAGE_SHA" ]; then - log_info "Removing old topotest image" - docker rmi $OLD_IMAGE_SHA || \ - log_warning "failed to remove old image" -fi - -exit 0 +exec docker build --pull \ + --compress \ + -t frrrouting/topotests \ + . From 1ab13617bfdf6f15a307345d3ceb3533aaca72bd Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Thu, 18 Oct 2018 12:27:16 +0200 Subject: [PATCH 10/21] Docker: really cleanup when TOPOTEST_CLEAN is specified Signed-off-by: Christian Franke --- tests/topotests/docker/compile_frr.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/topotests/docker/compile_frr.sh b/tests/topotests/docker/compile_frr.sh index 6b64f79d60..579994f83d 100755 --- a/tests/topotests/docker/compile_frr.sh +++ b/tests/topotests/docker/compile_frr.sh @@ -32,6 +32,11 @@ CDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Script begin # +if [ "${TOPOTEST_CLEAN}" != "0" ]; then + log_info "Cleaning FRR builddir..." + rm -rf $FRR_SYNC_DIR $FRR_BUILD_DIR &> /dev/null +fi + log_info "Syncing FRR source with host..." mkdir -p $FRR_SYNC_DIR rsync -a --info=progress2 \ @@ -52,11 +57,6 @@ else exec 3>/dev/null fi -if [ "${TOPOTEST_CLEAN}" != "0" ]; then - log_info "Cleaning FRR builddir..." - git clean -xdf > /dev/null -fi - log_info "Building FRR..." if [ ! -e configure ]; then From 3311145d703424dd346d3defa8ad4f0f892db2be Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Thu, 18 Oct 2018 12:27:37 +0200 Subject: [PATCH 11/21] Docker: Allow executing topotests while in subdir of FRR repo Signed-off-by: Christian Franke --- tests/topotests/Dockerfile | 10 ++++++---- tests/topotests/docker/{docker.sh => build.sh} | 10 +--------- tests/topotests/docker/frr-topotests.sh | 7 ++++++- tests/topotests/docker/{ => inner}/compile_frr.sh | 0 tests/topotests/docker/{ => inner}/entrypoint.sh | 0 tests/topotests/docker/{ => inner}/funcs.sh | 0 tests/topotests/docker/{ => inner}/motd.txt | 0 7 files changed, 13 insertions(+), 14 deletions(-) rename tests/topotests/docker/{docker.sh => build.sh} (89%) rename tests/topotests/docker/{ => inner}/compile_frr.sh (100%) rename tests/topotests/docker/{ => inner}/entrypoint.sh (100%) rename tests/topotests/docker/{ => inner}/funcs.sh (100%) rename tests/topotests/docker/{ => inner}/motd.txt (100%) diff --git a/tests/topotests/Dockerfile b/tests/topotests/Dockerfile index d7b2cae354..4f418b3acb 100644 --- a/tests/topotests/Dockerfile +++ b/tests/topotests/Dockerfile @@ -58,11 +58,13 @@ RUN echo "" >> /etc/security/limits.conf; \ echo "root hard core unlimited" >> /etc/security/limits.conf # Copy run scripts to facilitate users wanting to run the tests +COPY docker/inner /opt/topotests COPY . /root/topotests -WORKDIR /root -ENV PATH "$PATH:/root/topotests/docker" -RUN echo "cat /root/topotests/docker/motd.txt" >> /root/.profile && \ +WORKDIR /root/topotests +ENV PATH "$PATH:/opt/topotests" + +RUN echo "cat /opt/topotests/motd.txt" >> /root/.profile && \ echo "export PS1='(topotests) $PS1'" >> /root/.profile -ENTRYPOINT [ "bash", "/root/topotests/docker/entrypoint.sh" ] +ENTRYPOINT [ "bash", "/opt/topotests/entrypoint.sh" ] diff --git a/tests/topotests/docker/docker.sh b/tests/topotests/docker/build.sh similarity index 89% rename from tests/topotests/docker/docker.sh rename to tests/topotests/docker/build.sh index 4dcee218c9..47b14df0b0 100755 --- a/tests/topotests/docker/docker.sh +++ b/tests/topotests/docker/build.sh @@ -22,15 +22,7 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -# Load shared functions -CDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -. $CDIR/funcs.sh - -# -# Script begin -# - exec docker build --pull \ --compress \ - -t frrrouting/topotests \ + -t frrouting/topotests \ . diff --git a/tests/topotests/docker/frr-topotests.sh b/tests/topotests/docker/frr-topotests.sh index e5e91156a5..3df31c5d63 100755 --- a/tests/topotests/docker/frr-topotests.sh +++ b/tests/topotests/docker/frr-topotests.sh @@ -105,7 +105,12 @@ if [ -z "$TOPOTEST_LOGS" ]; then fi if [ -z "$TOPOTEST_FRR" ]; then - TOPOTEST_FRR="$(pwd)" + TOPOTEST_FRR="$(git rev-parse --show-toplevel || true)" + if [ -z "$TOPOTEST_FRR" ]; then + echo "Could not determine base of FRR tree." >&2 + echo "frr-topotests only works if you have your tree in git." >&2 + exit 1 + fi fi if [ -z "$TOPOTEST_BUILDCACHE" ]; then diff --git a/tests/topotests/docker/compile_frr.sh b/tests/topotests/docker/inner/compile_frr.sh similarity index 100% rename from tests/topotests/docker/compile_frr.sh rename to tests/topotests/docker/inner/compile_frr.sh diff --git a/tests/topotests/docker/entrypoint.sh b/tests/topotests/docker/inner/entrypoint.sh similarity index 100% rename from tests/topotests/docker/entrypoint.sh rename to tests/topotests/docker/inner/entrypoint.sh diff --git a/tests/topotests/docker/funcs.sh b/tests/topotests/docker/inner/funcs.sh similarity index 100% rename from tests/topotests/docker/funcs.sh rename to tests/topotests/docker/inner/funcs.sh diff --git a/tests/topotests/docker/motd.txt b/tests/topotests/docker/inner/motd.txt similarity index 100% rename from tests/topotests/docker/motd.txt rename to tests/topotests/docker/inner/motd.txt From 31eae3e3b0eb024dfde9b3fb592f94488ad73f7e Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Thu, 18 Oct 2018 13:04:01 +0200 Subject: [PATCH 12/21] Docker: move openvswitch setup to separate script Signed-off-by: Christian Franke --- tests/topotests/docker/inner/entrypoint.sh | 31 +---------- tests/topotests/docker/inner/openvswitch.sh | 59 +++++++++++++++++++++ 2 files changed, 61 insertions(+), 29 deletions(-) create mode 100755 tests/topotests/docker/inner/openvswitch.sh diff --git a/tests/topotests/docker/inner/entrypoint.sh b/tests/topotests/docker/inner/entrypoint.sh index 707c521888..dd329619f8 100755 --- a/tests/topotests/docker/inner/entrypoint.sh +++ b/tests/topotests/docker/inner/entrypoint.sh @@ -29,35 +29,8 @@ CDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # # Script begin # -log_info "Configuring OpenvSwitch...." - -# Configure OpenvSwitch so we are able to run mininet -mkdir -p /var/run/openvswitch -ovsdb-tool create /etc/openvswitch/conf.db \ - /usr/share/openvswitch/vswitch.ovsschema -ovsdb-server /etc/openvswitch/conf.db \ - --remote=punix:/var/run/openvswitch/db.sock \ - --remote=ptcp:6640 --pidfile=ovsdb-server.pid >/dev/null 2>/dev/null & \ - disown -ovs-vswitchd >/dev/null 2>/dev/null & disown - -sleep 2 - -ovs-vsctl --no-wait -- init -ovs_version=$(ovs-vsctl -V | grep ovs-vsctl | awk '{print $4}') -ovs_db_version=$(\ - ovsdb-tool schema-version /usr/share/openvswitch/vswitch.ovsschema) -ovs-vsctl --no-wait -- set Open_vSwitch . db-version="${ovs_db_version}" -ovs-vsctl --no-wait -- set Open_vSwitch . ovs-version="${ovs_version}" -ovs-vsctl --no-wait -- set Open_vSwitch . system-type="docker-ovs" -ovs-vsctl --no-wait -- set Open_vSwitch . system-version="0.1" -ovs-vsctl --no-wait -- \ - set Open_vSwitch . external-ids:system-id=`cat /proc/sys/kernel/random/uuid` -ovs-vsctl --no-wait -- set-manager ptcp:6640 -ovs-appctl -t ovsdb-server \ - ovsdb-server/add-remote db:Open_vSwitch,Open_vSwitch,manager_options - -bash "${CDIR}/compile_frr.sh" +"${CDIR}/compile_frr.sh" +"${CDIR}/openvswitch.sh" log_info "Setting permissions on /tmp so we can generate logs" chmod -v 1777 /tmp diff --git a/tests/topotests/docker/inner/openvswitch.sh b/tests/topotests/docker/inner/openvswitch.sh new file mode 100755 index 0000000000..67142f04ce --- /dev/null +++ b/tests/topotests/docker/inner/openvswitch.sh @@ -0,0 +1,59 @@ +#!/bin/bash +# +# Copyright 2018 Network Device Education Foundation, Inc. ("NetDEF") +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# Load shared functions +CDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +. $CDIR/funcs.sh + +# +# Script begin +# + +log_info "Configuring OpenvSwitch...." + +# Configure OpenvSwitch so we are able to run mininet +mkdir -p /var/run/openvswitch +ovsdb-tool create /etc/openvswitch/conf.db \ + /usr/share/openvswitch/vswitch.ovsschema +ovsdb-server /etc/openvswitch/conf.db \ + --remote=punix:/var/run/openvswitch/db.sock \ + --remote=ptcp:6640 --pidfile=ovsdb-server.pid >/dev/null 2>/dev/null & \ + disown +ovs-vswitchd >/dev/null 2>/dev/null & disown + +sleep 2 + +ovs-vsctl --no-wait -- init +ovs_version=$(ovs-vsctl -V | grep ovs-vsctl | awk '{print $4}') +ovs_db_version=$(\ + ovsdb-tool schema-version /usr/share/openvswitch/vswitch.ovsschema) +ovs-vsctl --no-wait -- set Open_vSwitch . db-version="${ovs_db_version}" +ovs-vsctl --no-wait -- set Open_vSwitch . ovs-version="${ovs_version}" +ovs-vsctl --no-wait -- set Open_vSwitch . system-type="docker-ovs" +ovs-vsctl --no-wait -- set Open_vSwitch . system-version="0.1" +ovs-vsctl --no-wait -- \ + set Open_vSwitch . external-ids:system-id=`cat /proc/sys/kernel/random/uuid` +ovs-vsctl --no-wait -- set-manager ptcp:6640 +ovs-appctl -t ovsdb-server \ + ovsdb-server/add-remote db:Open_vSwitch,Open_vSwitch,manager_options From 4242d6e2ae668ea6761db039f9f06e56f7416107 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Thu, 18 Oct 2018 13:48:55 +0200 Subject: [PATCH 13/21] Docker: Use pytest as default command Signed-off-by: Christian Franke --- tests/topotests/README.md | 4 +++ tests/topotests/docker/README.md | 33 +++++++++++++++++++-- tests/topotests/docker/inner/compile_frr.sh | 6 +++- tests/topotests/docker/inner/entrypoint.sh | 11 ++++--- 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/tests/topotests/README.md b/tests/topotests/README.md index 47668f4bba..3f1323c218 100644 --- a/tests/topotests/README.md +++ b/tests/topotests/README.md @@ -11,6 +11,10 @@ that does what you need. If nothing is similar, then you may create a new topology, preferably, using the newest [template](example-test/test_template.py). +## Running tests with docker + +There is a docker image which allows to run topotests. Instructions can be +found [here](docker/README.md). ## Installation of Mininet for running tests Only tested with Ubuntu 16.04 and Ubuntu 18.04 (which uses Mininet 2.2.x) diff --git a/tests/topotests/docker/README.md b/tests/topotests/docker/README.md index b506fd6fb1..25b18da7dc 100644 --- a/tests/topotests/docker/README.md +++ b/tests/topotests/docker/README.md @@ -1,6 +1,6 @@ # Topotests in Docker -## Usage +## Quickstart If you have Docker installed, you can run the topotests in Docker. The easiest way to do this, is to use the `frr-topotests.sh` script @@ -14,8 +14,35 @@ chmod +x /usr/local/bin/frr-topotests Once this script is in place, simply run it while you are inside your FRR repository: -``` +```console frr-topotests ``` -It should build FRR inside of the container and run the topotests on it. +## Advanced Usage + +There are several environtment variables which can be used to modify the behavior of +the image. Those can be listed using `frr-topotests -h`. + +For example, a volume is used to cache build artifacts between multiple runs +of the image. If you need to force a complete recompile, you can set `TOPOTEST_CLEAN`: + +```console +TOPOTEST_CLEAN=1 frr-topotests +``` + +By default, `frr-topotests` will execute pytest without any arguments. If you append an +arguments with the first one starting with `/` or `./`, they will replace the call to +pytest. If the appended arguments do not match this patttern, they will be provided to +pytest as arguments. + +So, to run a specific test with more verbose logging: + +```console +frr-topotests -vv -s all-protocol-startup/test_all_protocol_startup.py +``` + +And to compile FRR but drop into a shell instead of running pytest: + +```console +frr-topotests /bin/bash +``` diff --git a/tests/topotests/docker/inner/compile_frr.sh b/tests/topotests/docker/inner/compile_frr.sh index 579994f83d..896514b5d5 100755 --- a/tests/topotests/docker/inner/compile_frr.sh +++ b/tests/topotests/docker/inner/compile_frr.sh @@ -83,11 +83,15 @@ if [ ! -e Makefile ]; then fi bash configure >&3 \ - --enable-multipath=64 \ + --enable-static-bin \ + --with-moduledir=/usr/lib/frr/modules \ --prefix=/usr \ --localstatedir=/var/run/frr \ --sbindir=/usr/lib/frr \ --sysconfdir=/etc/frr \ + --enable-multipath=0 \ + --enable-fpm \ + --enable-sharpd \ $EXTRA_CONFIGURE \ --with-pkg-extra-version=-topotests \ || log_fatal "failed to configure the sources" diff --git a/tests/topotests/docker/inner/entrypoint.sh b/tests/topotests/docker/inner/entrypoint.sh index dd329619f8..37c5b75bf7 100755 --- a/tests/topotests/docker/inner/entrypoint.sh +++ b/tests/topotests/docker/inner/entrypoint.sh @@ -33,9 +33,12 @@ CDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" "${CDIR}/openvswitch.sh" log_info "Setting permissions on /tmp so we can generate logs" -chmod -v 1777 /tmp +chmod 1777 /tmp -log_info "Starting bash shell to interact with topotests" -echo '' +if [ $# -eq 0 ] || ([[ "$1" != /* ]] && [[ "$1" != ./* ]]); then + export TOPOTESTS_CHECK_MEMLEAK=/tmp/memleak_ + export TOPOTESTS_CHECK_STDERR=Yes + set -- pytest --junitxml /tmp/topotests.xml "$@" +fi -exec bash +exec "$@" From 877d4e3642248ac995b41ad036c1a5e3e821fd19 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Tue, 30 Oct 2018 18:26:38 +0100 Subject: [PATCH 14/21] Docker: Document additional environment variables Signed-off-by: Christian Franke --- tests/topotests/docker/frr-topotests.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/topotests/docker/frr-topotests.sh b/tests/topotests/docker/frr-topotests.sh index 3df31c5d63..90f1668451 100755 --- a/tests/topotests/docker/frr-topotests.sh +++ b/tests/topotests/docker/frr-topotests.sh @@ -42,6 +42,12 @@ if [[ "$1" = "-h" ]] || [[ "$1" = "--help" ]]; then \`topotest-buildcache\` volume will be created for that purpose. + TOPOTEST_CLEAN Clean all previous build artifacts prior to + building. Disabled by default, set to 1 to enable. + + TOPOTEST_DOC Build the documentation associated with FRR. + Disabled by default, set to 1 to enable. + TOPOTEST_FRR If set, don't test the FRR in the current working directory, but the one at the given path. @@ -54,6 +60,12 @@ if [[ "$1" = "-h" ]] || [[ "$1" = "--help" ]]; then TOPOTEST_PATH If set, don't use the tests built into the image but the ones at the given path. + TOPOTEST_SANITIZER Controls whether to use the address sanitizer. + Enabled by default, set to 0 to disable. + + TOPOTEST_VERBOSE Show detailed build output. + Enabled by default, set to 0 to disable. + To get information about the commands available inside of the container, run \`$0 help\`. EOF From 6926d304a816b6570b4c81e261f5c4d806e89a14 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Thu, 1 Nov 2018 18:14:23 +0100 Subject: [PATCH 15/21] Docker: Fail if compilation is unsucessful Signed-off-by: Christian Franke --- tests/topotests/docker/inner/entrypoint.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/topotests/docker/inner/entrypoint.sh b/tests/topotests/docker/inner/entrypoint.sh index 37c5b75bf7..f491d15f79 100755 --- a/tests/topotests/docker/inner/entrypoint.sh +++ b/tests/topotests/docker/inner/entrypoint.sh @@ -26,6 +26,8 @@ CDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" . $CDIR/funcs.sh +set -e + # # Script begin # From 7996f1975dc42854b9a3e3df0ea18d21b5d2bac0 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Mon, 5 Nov 2018 17:23:37 +0100 Subject: [PATCH 16/21] Dockerfile: Install libyang Recent versions of FRR require libyang to build. So install it from the FRR CI servers. Signed-off-by: Christian Franke --- tests/topotests/Dockerfile | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/topotests/Dockerfile b/tests/topotests/Dockerfile index 4f418b3acb..4a07336a19 100644 --- a/tests/topotests/Dockerfile +++ b/tests/topotests/Dockerfile @@ -15,6 +15,7 @@ RUN export DEBIAN_FRONTEND=noninteractive \ less \ libtool \ libjson-c-dev \ + libpcre3-dev \ libpython-dev \ libreadline-dev \ libc-ares-dev \ @@ -30,6 +31,7 @@ RUN export DEBIAN_FRONTEND=noninteractive \ tmux \ valgrind \ vim \ + wget \ x11-xserver-utils \ xterm \ && pip install \ @@ -37,6 +39,16 @@ RUN export DEBIAN_FRONTEND=noninteractive \ ipaddr \ pytest +RUN cd /tmp \ + && wget -q https://ci1.netdef.org/artifact/LIBYANG-YANGRELEASE/shared/build-1/Ubuntu-18.04-x86_64-Packages/libyang-dev_0.16.46_amd64.deb \ + -O libyang-dev.deb \ + && wget -q https://ci1.netdef.org/artifact/LIBYANG-YANGRELEASE/shared/build-1/Ubuntu-18.04-x86_64-Packages/libyang_0.16.46_amd64.deb \ + -O libyang.deb \ + && echo "039252cc66eb254a97e160b1c325af669470cde8a02d73ec9f7b920ed3c7997c libyang.deb" | sha256sum -c - \ + && echo "e7e2d5bfc7b33b3218df8bef404432970f9b4ad10d6dbbdcb0e0be2babbb68e9 libyang-dev.deb" | sha256sum -c - \ + && dpkg -i libyang*.deb \ + && rm libyang*.deb + RUN groupadd -r -g 92 frr \ && groupadd -r -g 85 frrvty \ && useradd -c "FRRouting suite" \ From 9b5470a84351b0a0bd5db441240c362737210ac9 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Mon, 5 Nov 2018 17:44:18 +0100 Subject: [PATCH 17/21] docker: Improve README and frr-topotests usage Signed-off-by: Christian Franke --- tests/topotests/docker/README.md | 4 ++-- tests/topotests/docker/frr-topotests.sh | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/topotests/docker/README.md b/tests/topotests/docker/README.md index 25b18da7dc..918594e6a3 100644 --- a/tests/topotests/docker/README.md +++ b/tests/topotests/docker/README.md @@ -30,8 +30,8 @@ of the image. If you need to force a complete recompile, you can set `TOPOTEST_C TOPOTEST_CLEAN=1 frr-topotests ``` -By default, `frr-topotests` will execute pytest without any arguments. If you append an -arguments with the first one starting with `/` or `./`, they will replace the call to +By default, `frr-topotests` will build frr and run pytest. If you append +arguments and the first one starts with `/` or `./`, they will replace the call to pytest. If the appended arguments do not match this patttern, they will be provided to pytest as arguments. diff --git a/tests/topotests/docker/frr-topotests.sh b/tests/topotests/docker/frr-topotests.sh index 90f1668451..435649c32f 100755 --- a/tests/topotests/docker/frr-topotests.sh +++ b/tests/topotests/docker/frr-topotests.sh @@ -32,7 +32,11 @@ if [[ "$1" = "-h" ]] || [[ "$1" = "--help" ]]; then Usage: $0 [args...] - Its behavior can be modified by the following environment variables: + If any arguments are provided and the first argument starts with / or ./ + the arguments are interpreted as command and will be executed instead + of pytest. + + Behavior can be further modified by the following environment variables: TOPOTEST_AUTOLOAD If set to 1, the script will try to load necessary kernel modules without asking for confirmation first. @@ -66,8 +70,6 @@ if [[ "$1" = "-h" ]] || [[ "$1" = "--help" ]]; then TOPOTEST_VERBOSE Show detailed build output. Enabled by default, set to 0 to disable. - To get information about the commands available inside of the container, - run \`$0 help\`. EOF exit 1 fi From 937e5dab6a352e22363b5bee7e504b92d964d45e Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Fri, 9 Nov 2018 15:42:10 +0100 Subject: [PATCH 18/21] docker/compile_frr: Don't build with disable shared With libyang, we need to build the frr_user_types.so libyang plugin for FRR to work. This means we cannot build with disable shared. Signed-off-by: Christian Franke --- tests/topotests/docker/inner/compile_frr.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/topotests/docker/inner/compile_frr.sh b/tests/topotests/docker/inner/compile_frr.sh index 896514b5d5..2d72082c1e 100755 --- a/tests/topotests/docker/inner/compile_frr.sh +++ b/tests/topotests/docker/inner/compile_frr.sh @@ -74,9 +74,7 @@ if [ ! -e Makefile ]; then if [ "${TOPOTEST_SANITIZER}" != "0" ]; then export CC="gcc" export CFLAGS="-O1 -g -fsanitize=address -fno-omit-frame-pointer" - export LD="gcc" export LDFLAGS="-g -fsanitize=address -ldl" - EXTRA_CONFIGURE+=" --enable-shared=no " touch .address_sanitizer else rm -f .address_sanitizer @@ -84,6 +82,8 @@ if [ ! -e Makefile ]; then bash configure >&3 \ --enable-static-bin \ + --enable-static \ + --enable-shared \ --with-moduledir=/usr/lib/frr/modules \ --prefix=/usr \ --localstatedir=/var/run/frr \ From f509ad97856959d1670886b836f50077ca043b0b Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Tue, 20 Nov 2018 16:32:09 +0100 Subject: [PATCH 19/21] docker/frr-topotests: Fix missing $ in if check Signed-off-by: Christian Franke --- tests/topotests/docker/frr-topotests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/topotests/docker/frr-topotests.sh b/tests/topotests/docker/frr-topotests.sh index 435649c32f..6ddfdc9484 100755 --- a/tests/topotests/docker/frr-topotests.sh +++ b/tests/topotests/docker/frr-topotests.sh @@ -145,7 +145,7 @@ set -- --rm -ti \ $TOPOTEST_OPTIONS \ frrouting/topotests "$@" -if [ -n "TOPOTEST_PATH" ]; then +if [ -n "$TOPOTEST_PATH" ]; then set -- -v "$TOPOTEST_PATH:/root/topotests:ro" "$@" fi From ff37641ba2e8272ed4f58a88a9f837d5ff9bb560 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Thu, 29 Nov 2018 15:22:23 +0100 Subject: [PATCH 20/21] topotests: Adapt docker changes for integrated tests Signed-off-by: Christian Franke --- Makefile.am | 1 + tests/topotests/Dockerfile | 1 - tests/topotests/docker/build.sh | 4 +++- tests/topotests/docker/frr-topotests.sh | 10 ++-------- tests/topotests/subdir.am | 7 +++++++ 5 files changed, 13 insertions(+), 10 deletions(-) create mode 100644 tests/topotests/subdir.am diff --git a/Makefile.am b/Makefile.am index d12d452645..c56a551aa5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -149,6 +149,7 @@ include yang/libyang_plugins/subdir.am include vtysh/subdir.am include tests/subdir.am +include tests/topotests/subdir.am if PKGSRC rcdir=@pkgsrcrcdir@ diff --git a/tests/topotests/Dockerfile b/tests/topotests/Dockerfile index 4a07336a19..72a876ed83 100644 --- a/tests/topotests/Dockerfile +++ b/tests/topotests/Dockerfile @@ -71,7 +71,6 @@ RUN echo "" >> /etc/security/limits.conf; \ # Copy run scripts to facilitate users wanting to run the tests COPY docker/inner /opt/topotests -COPY . /root/topotests WORKDIR /root/topotests ENV PATH "$PATH:/opt/topotests" diff --git a/tests/topotests/docker/build.sh b/tests/topotests/docker/build.sh index 47b14df0b0..344fb2ffcb 100755 --- a/tests/topotests/docker/build.sh +++ b/tests/topotests/docker/build.sh @@ -22,7 +22,9 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +cd "$(dirname "$0")"/.. + exec docker build --pull \ --compress \ - -t frrouting/topotests \ + -t frrouting/frr:topotests-latest \ . diff --git a/tests/topotests/docker/frr-topotests.sh b/tests/topotests/docker/frr-topotests.sh index 6ddfdc9484..9a157c49a8 100755 --- a/tests/topotests/docker/frr-topotests.sh +++ b/tests/topotests/docker/frr-topotests.sh @@ -61,9 +61,6 @@ if [[ "$1" = "-h" ]] || [[ "$1" = "--help" ]]; then TOPOTEST_OPTIONS These options are appended to the docker-run command for starting the tests. - TOPOTEST_PATH If set, don't use the tests built into the image - but the ones at the given path. - TOPOTEST_SANITIZER Controls whether to use the address sanitizer. Enabled by default, set to 0 to disable. @@ -136,6 +133,7 @@ fi set -- --rm -ti \ -v "$TOPOTEST_LOGS:/tmp" \ -v "$TOPOTEST_FRR:/root/host-frr:ro" \ + -v "$TOPOTEST_FRR/tests/topotests:/root/topotests:ro" \ -v "$TOPOTEST_BUILDCACHE:/root/persist" \ -e "TOPOTEST_CLEAN=$TOPOTEST_CLEAN" \ -e "TOPOTEST_VERBOSE=$TOPOTEST_VERBOSE" \ @@ -143,10 +141,6 @@ set -- --rm -ti \ -e "TOPOTEST_SANITIZER=$TOPOTEST_SANITIZER" \ --privileged \ $TOPOTEST_OPTIONS \ - frrouting/topotests "$@" - -if [ -n "$TOPOTEST_PATH" ]; then - set -- -v "$TOPOTEST_PATH:/root/topotests:ro" "$@" -fi + frrouting/frr:topotests-latest "$@" exec docker run "$@" diff --git a/tests/topotests/subdir.am b/tests/topotests/subdir.am new file mode 100644 index 0000000000..e489f92bfa --- /dev/null +++ b/tests/topotests/subdir.am @@ -0,0 +1,7 @@ +TOPOTESTS_DIR = tests/topotests + +topotests-build: ## Builds docker images for topotests + $(TOPOTESTS_DIR)/docker/build.sh + +topotests: ## Runs topotests + $(TOPOTESTS_DIR)/docker/frr-topotests.sh From 5f1ac6d6692228eeb516de6e3a79aa8fe576cfed Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Thu, 29 Nov 2018 16:05:44 +0100 Subject: [PATCH 21/21] topotests: Only set -t when input is a terminal Signed-off-by: Christian Franke --- tests/topotests/docker/frr-topotests.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/topotests/docker/frr-topotests.sh b/tests/topotests/docker/frr-topotests.sh index 9a157c49a8..673354f5da 100755 --- a/tests/topotests/docker/frr-topotests.sh +++ b/tests/topotests/docker/frr-topotests.sh @@ -130,7 +130,7 @@ if [ -z "$TOPOTEST_BUILDCACHE" ]; then || docker volume create "${TOPOTEST_BUILDCACHE}" fi -set -- --rm -ti \ +set -- --rm -i \ -v "$TOPOTEST_LOGS:/tmp" \ -v "$TOPOTEST_FRR:/root/host-frr:ro" \ -v "$TOPOTEST_FRR/tests/topotests:/root/topotests:ro" \ @@ -143,4 +143,8 @@ set -- --rm -ti \ $TOPOTEST_OPTIONS \ frrouting/frr:topotests-latest "$@" +if [ -t 0 ]; then + set -- -t "$@" +fi + exec docker run "$@"