summaryrefslogtreecommitdiffstats
path: root/docker
diff options
context:
space:
mode:
Diffstat (limited to 'docker')
-rw-r--r--docker/.gitignore1
-rw-r--r--docker/alpine/Dockerfile72
-rw-r--r--docker/alpine/Dockerfile-coverage12
-rwxr-xr-xdocker/alpine/build.sh48
-rwxr-xr-xdocker/alpine/docker-start18
-rw-r--r--docker/alpine/libyang/10-remove-non-standard-headers.patch298
-rw-r--r--docker/alpine/libyang/11-utest-dont-parse-dlerror.patch40
-rwxr-xr-xdocker/alpine/libyang/APKBUILD40
-rw-r--r--docker/centos-7/Dockerfile57
-rwxr-xr-xdocker/centos-7/build.sh31
-rwxr-xr-xdocker/centos-7/docker-start4
-rw-r--r--docker/centos-8/Dockerfile66
-rwxr-xr-xdocker/centos-8/build.sh31
-rwxr-xr-xdocker/centos-8/docker-start4
-rw-r--r--docker/debian/Dockerfile28
-rw-r--r--docker/debian/README.md20
-rwxr-xr-xdocker/debian/docker-start4
-rw-r--r--docker/ubi-8/Dockerfile83
-rwxr-xr-xdocker/ubi-8/build.sh46
-rwxr-xr-xdocker/ubi-8/docker-start4
-rw-r--r--docker/ubuntu18-ci/Dockerfile73
-rw-r--r--docker/ubuntu18-ci/README.md44
-rwxr-xr-xdocker/ubuntu18-ci/docker-start8
-rw-r--r--docker/ubuntu20-ci/Dockerfile78
-rw-r--r--docker/ubuntu20-ci/README.md45
-rwxr-xr-xdocker/ubuntu20-ci/docker-start8
26 files changed, 1163 insertions, 0 deletions
diff --git a/docker/.gitignore b/docker/.gitignore
new file mode 100644
index 0000000..6f91eb5
--- /dev/null
+++ b/docker/.gitignore
@@ -0,0 +1 @@
+pkgs/
diff --git a/docker/alpine/Dockerfile b/docker/alpine/Dockerfile
new file mode 100644
index 0000000..b9278db
--- /dev/null
+++ b/docker/alpine/Dockerfile
@@ -0,0 +1,72 @@
+# syntax=docker/dockerfile:1
+
+# Create a basic stage set up to build APKs
+FROM alpine:3.15 as alpine-builder
+RUN apk add \
+ --update-cache \
+ abuild \
+ alpine-conf \
+ alpine-sdk \
+ && setup-apkcache /var/cache/apk \
+ && mkdir -p /pkgs/apk \
+ && echo 'builder ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
+RUN adduser -D -G abuild builder && su builder -c 'abuild-keygen -a -n'
+
+# This stage builds a dist tarball from the source
+FROM alpine:3.15 as source-builder
+
+RUN mkdir -p /src/alpine
+COPY alpine/APKBUILD.in /src/alpine
+RUN source /src/alpine/APKBUILD.in \
+ && apk add \
+ --no-cache \
+ --update-cache \
+ $makedepends \
+ gzip \
+ py-pip \
+ rtrlib \
+ && pip install pytest
+RUN mkdir -p /pkgs/apk
+COPY . /src
+ARG PKGVER
+RUN cd /src \
+ && ./bootstrap.sh \
+ && ./configure \
+ --enable-numeric-version \
+ --with-pkg-extra-version="_git$PKGVER" \
+ && make dist
+
+# This stage builds an APK from the dist tarball
+FROM alpine-builder as alpine-apk-builder
+COPY --from=source-builder /src/frr-*.tar.gz /src/alpine/* /dist/
+RUN find /pkgs/apk -type f -name APKINDEX.tar.gz -delete
+RUN chown -R builder /dist /pkgs
+USER builder
+RUN cd /dist \
+ && abuild checksum \
+ && git init \
+ && abuild -r -P /pkgs/apk
+
+# This stage installs frr from the apk
+FROM alpine:3.15
+RUN mkdir -p /pkgs/apk
+COPY --from=alpine-apk-builder /pkgs/apk/ /pkgs/apk/
+RUN apk add \
+ --no-cache \
+ --update-cache \
+ tini \
+ && apk add \
+ --no-cache \
+ --allow-untrusted /pkgs/apk/*/*.apk \
+ && rm -rf /pkgs
+
+# Own the config / PID files
+RUN mkdir -p /var/run/frr
+RUN chown -R frr:frr /etc/frr /var/run/frr
+
+# Simple init manager for reaping processes and forwarding signals
+ENTRYPOINT ["/sbin/tini", "--"]
+
+# Default CMD starts watchfrr
+COPY docker/alpine/docker-start /usr/lib/frr/docker-start
+CMD ["/usr/lib/frr/docker-start"]
diff --git a/docker/alpine/Dockerfile-coverage b/docker/alpine/Dockerfile-coverage
new file mode 100644
index 0000000..5fdb117
--- /dev/null
+++ b/docker/alpine/Dockerfile-coverage
@@ -0,0 +1,12 @@
+FROM alpine:3.7
+ARG commit
+ARG token
+ENV COMMIT=${commit}
+ENV TOKEN=${token}
+ADD . /src
+RUN cd /src && \
+ source alpine/APKBUILD.in && \
+ apk add --no-cache alpine-sdk $makedepends $checkdepends && \
+ ./bootstrap.sh && \
+ ./configure --enable-gcov
+ENTRYPOINT [ "/bin/sh", "-c", "cd /src && make && make -j 1 check-coverage" ]
diff --git a/docker/alpine/build.sh b/docker/alpine/build.sh
new file mode 100755
index 0000000..80ee81c
--- /dev/null
+++ b/docker/alpine/build.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+set -e
+set -x
+
+##
+# Package version needs to be decimal
+##
+
+##
+# Set GITREV=0 or similar in ENV if you want the tag to just be updated to -0
+# everytime for automation usage/scripts/etc locally.
+#
+# Ex) GITREV=0 ./build.sh
+##
+
+GITREV="${GITREV:=$(git rev-parse --short=10 HEAD)}"
+PKGVER="$(printf '%u\n' 0x$GITREV)"
+
+docker build \
+ --pull \
+ --file=docker/alpine/Dockerfile \
+ --build-arg="PKGVER=$PKGVER" \
+ --tag="frr:alpine-builder-$GITREV" \
+ --target=alpine-builder \
+ .
+
+# Keep .apk files for debugging purposes, docker image as well.
+docker build \
+ --pull \
+ --file=docker/alpine/Dockerfile \
+ --build-arg="PKGVER=$PKGVER" \
+ --tag="frr:alpine-apk-builder-$GITREV" \
+ --target=alpine-apk-builder \
+ .
+
+CONTAINER_ID="$(docker create "frr:alpine-apk-builder-$GITREV")"
+docker cp "${CONTAINER_ID}:/pkgs/" docker/alpine
+docker rm "${CONTAINER_ID}"
+
+docker build \
+ --file=docker/alpine/Dockerfile \
+ --build-arg="PKGVER=$PKGVER" \
+ --tag="frr:alpine-$GITREV" \
+ .
+
+docker rmi "frr:alpine-builder-$GITREV"
+docker rmi "frr:alpine-apk-builder-$GITREV"
diff --git a/docker/alpine/docker-start b/docker/alpine/docker-start
new file mode 100755
index 0000000..995cea4
--- /dev/null
+++ b/docker/alpine/docker-start
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+if [ -r "/lib/lsb/init-functions" ]; then
+ . /lib/lsb/init-functions
+else
+ log_success_msg() {
+ echo "$@"
+ }
+ log_warning_msg() {
+ echo "$@" >&2
+ }
+ log_failure_msg() {
+ echo "$@" >&2
+ }
+fi
+
+source /usr/lib/frr/frrcommon.sh
+/usr/lib/frr/watchfrr $(daemon_list)
diff --git a/docker/alpine/libyang/10-remove-non-standard-headers.patch b/docker/alpine/libyang/10-remove-non-standard-headers.patch
new file mode 100644
index 0000000..18812b5
--- /dev/null
+++ b/docker/alpine/libyang/10-remove-non-standard-headers.patch
@@ -0,0 +1,298 @@
+From 8f4907590afbe3eafabcf5b461c0ae51b65c3a37 Mon Sep 17 00:00:00 2001
+From: Michal Vasko <mvasko@cesnet.cz>
+Date: Thu, 10 Jun 2021 15:07:02 +0200
+Subject: [PATCH] libyang BUGFIX do not include non-standard headers
+
+Fixes #1614
+---
+ src/context.c | 1 -
+ src/diff.c | 1 -
+ src/log.c | 1 -
+ src/out.c | 1 -
+ src/plugins_types.c | 1 -
+ src/plugins_types/bits.c | 1 -
+ src/plugins_types/date_and_time.c | 1 -
+ src/plugins_types/identityref.c | 1 -
+ src/plugins_types/integer.c | 1 -
+ src/plugins_types/ipv4_address.c | 1 -
+ src/plugins_types/ipv4_address_no_zone.c | 1 -
+ src/plugins_types/ipv4_prefix.c | 1 -
+ src/plugins_types/ipv6_address.c | 1 -
+ src/plugins_types/ipv6_address_no_zone.c | 1 -
+ src/plugins_types/ipv6_prefix.c | 1 -
+ src/plugins_types/union.c | 1 -
+ src/schema_compile_node.c | 1 -
+ src/tree_data_helpers.c | 1 -
+ src/tree_schema.c | 1 -
+ src/validation.c | 1 -
+ src/xpath.c | 1 -
+ tools/re/main.c | 1 -
+ 22 files changed, 22 deletions(-)
+
+diff --git a/src/context.c b/src/context.c
+index eb671255..ac62cac5 100644
+--- a/src/context.c
++++ b/src/context.c
+@@ -17,7 +17,6 @@
+ #define _XOPEN_SOURCE 1
+ #define _XOPEN_SOURCE_EXTENDED 1
+ #endif
+-#include <sys/cdefs.h>
+
+ #include "context.h"
+
+diff --git a/src/diff.c b/src/diff.c
+index b40dd73a..4971c6fe 100644
+--- a/src/diff.c
++++ b/src/diff.c
+@@ -12,7 +12,6 @@
+ * https://opensource.org/licenses/BSD-3-Clause
+ */
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include "diff.h"
+
+diff --git a/src/log.c b/src/log.c
+index 97c7b283..9cd5fd0d 100644
+--- a/src/log.c
++++ b/src/log.c
+@@ -13,7 +13,6 @@
+ */
+
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include "log.h"
+
+diff --git a/src/out.c b/src/out.c
+index 37beb696..898d663a 100644
+--- a/src/out.c
++++ b/src/out.c
+@@ -13,7 +13,6 @@
+ */
+
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include "out.h"
+ #include "out_internal.h"
+diff --git a/src/plugins_types.c b/src/plugins_types.c
+index 26bac210..a2cf0f38 100644
+--- a/src/plugins_types.c
++++ b/src/plugins_types.c
+@@ -13,7 +13,6 @@
+ */
+
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include "plugins_types.h"
+
+diff --git a/src/plugins_types/bits.c b/src/plugins_types/bits.c
+index 9d086ffb..ef87691b 100644
+--- a/src/plugins_types/bits.c
++++ b/src/plugins_types/bits.c
+@@ -13,7 +13,6 @@
+ */
+
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include "plugins_types.h"
+
+diff --git a/src/plugins_types/date_and_time.c b/src/plugins_types/date_and_time.c
+index 0d52dbb1..a23caaa9 100644
+--- a/src/plugins_types/date_and_time.c
++++ b/src/plugins_types/date_and_time.c
+@@ -13,7 +13,6 @@
+ */
+
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include "plugins_types.h"
+
+diff --git a/src/plugins_types/identityref.c b/src/plugins_types/identityref.c
+index 90546d69..91ddbde2 100644
+--- a/src/plugins_types/identityref.c
++++ b/src/plugins_types/identityref.c
+@@ -13,7 +13,6 @@
+ */
+
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include "plugins_types.h"
+
+diff --git a/src/plugins_types/integer.c b/src/plugins_types/integer.c
+index 44e87f99..bf2b7812 100644
+--- a/src/plugins_types/integer.c
++++ b/src/plugins_types/integer.c
+@@ -13,7 +13,6 @@
+ */
+
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include "plugins_types.h"
+
+diff --git a/src/plugins_types/ipv4_address.c b/src/plugins_types/ipv4_address.c
+index a95752ea..a7369d6b 100644
+--- a/src/plugins_types/ipv4_address.c
++++ b/src/plugins_types/ipv4_address.c
+@@ -13,7 +13,6 @@
+ */
+
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include "plugins_types.h"
+
+diff --git a/src/plugins_types/ipv4_address_no_zone.c b/src/plugins_types/ipv4_address_no_zone.c
+index a17a7efe..1fb34b06 100644
+--- a/src/plugins_types/ipv4_address_no_zone.c
++++ b/src/plugins_types/ipv4_address_no_zone.c
+@@ -13,7 +13,6 @@
+ */
+
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include "plugins_types.h"
+
+diff --git a/src/plugins_types/ipv4_prefix.c b/src/plugins_types/ipv4_prefix.c
+index 3108b2c5..6fb93390 100644
+--- a/src/plugins_types/ipv4_prefix.c
++++ b/src/plugins_types/ipv4_prefix.c
+@@ -13,7 +13,6 @@
+ */
+
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include "plugins_types.h"
+
+diff --git a/src/plugins_types/ipv6_address.c b/src/plugins_types/ipv6_address.c
+index c0d20fa4..d09425b3 100644
+--- a/src/plugins_types/ipv6_address.c
++++ b/src/plugins_types/ipv6_address.c
+@@ -13,7 +13,6 @@
+ */
+
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include "plugins_types.h"
+
+diff --git a/src/plugins_types/ipv6_address_no_zone.c b/src/plugins_types/ipv6_address_no_zone.c
+index c612b663..06bd1891 100644
+--- a/src/plugins_types/ipv6_address_no_zone.c
++++ b/src/plugins_types/ipv6_address_no_zone.c
+@@ -13,7 +13,6 @@
+ */
+
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include "plugins_types.h"
+
+diff --git a/src/plugins_types/ipv6_prefix.c b/src/plugins_types/ipv6_prefix.c
+index b3ad34b6..91431fef 100644
+--- a/src/plugins_types/ipv6_prefix.c
++++ b/src/plugins_types/ipv6_prefix.c
+@@ -13,7 +13,6 @@
+ */
+
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include "plugins_types.h"
+
+diff --git a/src/plugins_types/union.c b/src/plugins_types/union.c
+index a8ec43b3..89e81c7a 100644
+--- a/src/plugins_types/union.c
++++ b/src/plugins_types/union.c
+@@ -13,7 +13,6 @@
+ */
+
+ #define _GNU_SOURCE /* strdup */
+-#include <sys/cdefs.h>
+
+ #include "plugins_types.h"
+
+diff --git a/src/schema_compile_node.c b/src/schema_compile_node.c
+index 424b7f8f..273023de 100644
+--- a/src/schema_compile_node.c
++++ b/src/schema_compile_node.c
+@@ -13,7 +13,6 @@
+ */
+
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include "schema_compile_node.h"
+
+diff --git a/src/tree_data_helpers.c b/src/tree_data_helpers.c
+index 488efbbb..2d9ba624 100644
+--- a/src/tree_data_helpers.c
++++ b/src/tree_data_helpers.c
+@@ -13,7 +13,6 @@
+ */
+
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include <assert.h>
+ #include <ctype.h>
+diff --git a/src/tree_schema.c b/src/tree_schema.c
+index 93f29796..4a57cc47 100644
+--- a/src/tree_schema.c
++++ b/src/tree_schema.c
+@@ -13,7 +13,6 @@
+ */
+
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include "tree_schema.h"
+
+diff --git a/src/validation.c b/src/validation.c
+index b9eda810..e2062256 100644
+--- a/src/validation.c
++++ b/src/validation.c
+@@ -12,7 +12,6 @@
+ * https://opensource.org/licenses/BSD-3-Clause
+ */
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include "validation.h"
+
+diff --git a/src/xpath.c b/src/xpath.c
+index b68a76b8..ea1cdfc9 100644
+--- a/src/xpath.c
++++ b/src/xpath.c
+@@ -12,7 +12,6 @@
+ * https://opensource.org/licenses/BSD-3-Clause
+ */
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include "xpath.h"
+
+diff --git a/tools/re/main.c b/tools/re/main.c
+index b512ad80..4d8aa99c 100644
+--- a/tools/re/main.c
++++ b/tools/re/main.c
+@@ -13,7 +13,6 @@
+ */
+
+ #define _GNU_SOURCE /* asprintf, strdup */
+-#include <sys/cdefs.h>
+
+ #include <errno.h>
+ #include <getopt.h>
+--
+2.31.1
+
diff --git a/docker/alpine/libyang/11-utest-dont-parse-dlerror.patch b/docker/alpine/libyang/11-utest-dont-parse-dlerror.patch
new file mode 100644
index 0000000..054862f
--- /dev/null
+++ b/docker/alpine/libyang/11-utest-dont-parse-dlerror.patch
@@ -0,0 +1,40 @@
+From 2054431ea3024b177083f09c66c1bb4c3d08b048 Mon Sep 17 00:00:00 2001
+From: Wesley Coakley <w@wesleycoakley.com>
+Date: Wed, 16 Jun 2021 00:30:50 -0400
+Subject: [PATCH] don't attempt to parse dlerror() in utests
+
+---
+ tests/utests/basic/test_plugins.c | 17 -----------------
+ 1 file changed, 17 deletions(-)
+
+diff --git a/tests/utests/basic/test_plugins.c b/tests/utests/basic/test_plugins.c
+index fd9e6130..662fd9b4 100644
+--- a/tests/utests/basic/test_plugins.c
++++ b/tests/utests/basic/test_plugins.c
+@@ -36,23 +36,6 @@ static void
+ test_add_invalid(void **state)
+ {
+ assert_int_equal(LY_ESYS, lyplg_add(TESTS_BIN "/plugins/plugin_does_not_exist" LYPLG_SUFFIX));
+-
+-#ifdef __APPLE__
+- CHECK_LOG("Loading \""TESTS_BIN "/plugins/plugin_does_not_exist" LYPLG_SUFFIX "\" as a plugin failed "
+- "(dlopen("TESTS_BIN "/plugins/plugin_does_not_exist" LYPLG_SUFFIX ", 2): image not found).", NULL);
+-#else
+- CHECK_LOG("Loading \""TESTS_BIN "/plugins/plugin_does_not_exist" LYPLG_SUFFIX "\" as a plugin failed "
+- "("TESTS_BIN "/plugins/plugin_does_not_exist" LYPLG_SUFFIX ": cannot open shared object file: "
+- "No such file or directory).", NULL);
+-#endif
+-
+- assert_int_equal(LY_EINVAL, lyplg_add(TESTS_BIN "/plugins/plugin_invalid" LYPLG_SUFFIX));
+-#ifndef __APPLE__
+- /* OS X prints address of the symbol being searched and cmocka doesn't support wildcards in string checking assert */
+- CHECK_LOG("Processing user type plugin \""TESTS_BIN "/plugins/plugin_invalid"LYPLG_SUFFIX "\" failed, "
+- "missing type plugins information ("TESTS_BIN "/plugins/plugin_invalid"LYPLG_SUFFIX ": "
+- "undefined symbol: plugins_types__).", NULL);
+-#endif
+ }
+
+ static void
+--
+2.31.1
+
diff --git a/docker/alpine/libyang/APKBUILD b/docker/alpine/libyang/APKBUILD
new file mode 100755
index 0000000..aa792e7
--- /dev/null
+++ b/docker/alpine/libyang/APKBUILD
@@ -0,0 +1,40 @@
+# Contributor: Sören Tempel <soeren+alpine@soeren-tempel.net>
+# Maintainer: Christian Franke <nobody@nowhere.ws>
+pkgname=libyang
+pkgver=2.0.194
+pkgrel=0
+pkgdesc="YANG data modelling language parser and toolkit"
+url="https://github.com/CESNET/libyang"
+arch="all"
+license="BSD-3-Clause-Clear"
+makedepends="bison cmake cmocka-dev flex pcre2-dev"
+checkdepends="expect grep shunit2"
+subpackages="$pkgname-dev $pkgname-doc"
+source="$pkgname-$pkgver.tar.gz::https://github.com/CESNET/libyang/archive/v$pkgver.tar.gz"
+
+# secfixes:
+# 1.0.215-r1:
+# - CVE-2021-28902
+# - CVE-2021-28903
+# - CVE-2021-28904
+# - CVE-2021-28905
+# - CVE-2021-28906
+
+build() {
+ if [ "$CBUILD" != "$CHOST" ]; then
+ CMAKE_CROSSOPTS="-DCMAKE_SYSTEM_NAME=Linux -DCMAKE_HOST_SYSTEM_NAME=Linux"
+ fi
+ cmake -B build \
+ -DCMAKE_BUILD_TYPE=None \
+ -DCMAKE_INSTALL_PREFIX=/usr \
+ -DCMAKE_INSTALL_LIBDIR=lib \
+ -DBUILD_SHARED_LIBS=True \
+ -DCMAKE_C_FLAGS="$CFLAGS" \
+ -DENABLE_BUILD_TESTS=ON \
+ "$CMAKE_CROSSOPTS"
+ make -C build
+}
+
+package() {
+ make -C build DESTDIR="$pkgdir" install
+}
diff --git a/docker/centos-7/Dockerfile b/docker/centos-7/Dockerfile
new file mode 100644
index 0000000..2d1ee9e
--- /dev/null
+++ b/docker/centos-7/Dockerfile
@@ -0,0 +1,57 @@
+# This stage builds an rpm from the source
+FROM centos:centos7 as centos-7-builder
+RUN yum install -y epel-release
+RUN yum install -y rpm-build autoconf automake libtool make \
+ readline-devel texinfo net-snmp-devel groff pkgconfig \
+ json-c-devel pam-devel bison flex pytest c-ares-devel \
+ python3-devel python3-sphinx libcap-devel systemd-devel \
+ https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-7-x86_64-Packages/libyang2-2.0.0.10.g2eb910e4-1.el7.x86_64.rpm \
+ https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-7-x86_64-Packages/libyang2-devel-2.0.0.10.g2eb910e4-1.el7.x86_64.rpm \
+ https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-00146/CentOS-7-x86_64-Packages/librtr-0.8.0-1.el7.x86_64.rpm \
+ https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-00146/CentOS-7-x86_64-Packages/librtr-devel-0.8.0-1.el7.x86_64.rpm
+
+COPY . /src
+ARG PKGVER
+
+RUN echo '%_smp_mflags %( echo "-j$(/usr/bin/getconf _NPROCESSORS_ONLN)"; )' >> /root/.rpmmacros \
+ && cd /src \
+ && ./bootstrap.sh \
+ && ./configure \
+ --enable-rpki \
+ --enable-numeric-version \
+ --with-pkg-extra-version="_git$PKGVER" \
+ && make dist \
+ && cd / \
+ && mkdir -p /rpmbuild/{SOURCES,SPECS} \
+ && cp /src/frr*.tar.gz /rpmbuild/SOURCES \
+ && cp /src/redhat/frr.spec /rpmbuild/SPECS \
+ && rpmbuild \
+ --define "_topdir /rpmbuild" \
+ -ba /rpmbuild/SPECS/frr.spec
+
+# This stage installs frr from the rpm
+FROM centos:centos7
+RUN mkdir -p /pkgs/rpm \
+ && yum install -y https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-7-x86_64-Packages/libyang2-2.0.0.10.g2eb910e4-1.el7.x86_64.rpm \
+ https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-00146/CentOS-7-x86_64-Packages/librtr-0.8.0-1.el7.x86_64.rpm
+
+COPY --from=centos-7-builder /rpmbuild/RPMS/ /pkgs/rpm/
+
+RUN yum install -y /pkgs/rpm/*/*.rpm \
+ && rm -rf /pkgs
+
+# Own the config / PID files
+RUN mkdir -p /var/run/frr
+RUN chown -R frr:frr /etc/frr /var/run/frr
+
+# Add tini because no CentOS7 package
+ENV TINI_VERSION v0.19.0
+ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /sbin/tini
+RUN chmod +x /sbin/tini
+
+# Simple init manager for reaping processes and forwarding signals
+ENTRYPOINT ["/sbin/tini", "--"]
+
+# Default CMD starts watchfrr
+COPY docker/centos-7/docker-start /usr/lib/frr/docker-start
+CMD ["/usr/lib/frr/docker-start"]
diff --git a/docker/centos-7/build.sh b/docker/centos-7/build.sh
new file mode 100755
index 0000000..b3022d7
--- /dev/null
+++ b/docker/centos-7/build.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+set -e
+
+##
+# Package version needs to be decimal
+##
+GITREV="$(git rev-parse --short=10 HEAD)"
+PKGVER="$(printf '%u\n' 0x$GITREV)"
+
+mkdir -p docker/centos-7/pkgs
+docker build \
+ --file=docker/centos-7/Dockerfile \
+ --build-arg="PKGVER=$PKGVER" \
+ --tag="frr:centos-7-builder-$GITREV" \
+ --target=centos-7-builder \
+ .
+
+# Copy RPM package from container to host
+CONTAINER_ID="$(docker create "frr:centos-7-builder-$GITREV")"
+docker cp "${CONTAINER_ID}:/rpmbuild/RPMS/x86_64/" docker/centos-7/pkgs
+docker rm "${CONTAINER_ID}"
+
+docker build \
+ --cache-from="frr:centos-7-builder-$GITREV" \
+ --file=docker/centos-7/Dockerfile \
+ --build-arg="PKGVER=$PKGVER" \
+ --tag="frr:centos-7-$GITREV" \
+ .
+
+docker rmi "frr:centos-7-builder-$GITREV"
diff --git a/docker/centos-7/docker-start b/docker/centos-7/docker-start
new file mode 100755
index 0000000..d954142
--- /dev/null
+++ b/docker/centos-7/docker-start
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+source /usr/lib/frr/frrcommon.sh
+/usr/lib/frr/watchfrr $(daemon_list)
diff --git a/docker/centos-8/Dockerfile b/docker/centos-8/Dockerfile
new file mode 100644
index 0000000..df772b8
--- /dev/null
+++ b/docker/centos-8/Dockerfile
@@ -0,0 +1,66 @@
+# This stage builds an rpm from the source
+FROM centos:centos8 as centos-8-builder
+
+RUN sed -i -e "s|mirrorlist=|#mirrorlist=|g" /etc/yum.repos.d/CentOS-*
+RUN sed -i -e "s|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g" /etc/yum.repos.d/CentOS-*
+
+RUN dnf install --enablerepo=powertools -y rpm-build git autoconf pcre-devel \
+ systemd-devel \
+ automake libtool make readline-devel texinfo net-snmp-devel pkgconfig \
+ groff pkgconfig json-c-devel pam-devel bison flex python3-pytest \
+ c-ares-devel python3-devel python3-sphinx libcap-devel platform-python-devel \
+ https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-8-x86_64-Packages/libyang2-2.0.0.10.g2eb910e4-1.el8.x86_64.rpm \
+ https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-8-x86_64-Packages/libyang2-devel-2.0.0.10.g2eb910e4-1.el8.x86_64.rpm \
+ https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-00146/CentOS-7-x86_64-Packages/librtr-0.8.0-1.el7.x86_64.rpm \
+ https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-00146/CentOS-7-x86_64-Packages/librtr-devel-0.8.0-1.el7.x86_64.rpm
+
+COPY . /src
+
+ARG PKGVER
+
+RUN echo '%_smp_mflags %( echo "-j$(/usr/bin/getconf _NPROCESSORS_ONLN)"; )' >> /root/.rpmmacros \
+ && cd /src \
+ && ./bootstrap.sh \
+ && ./configure \
+ --enable-rpki \
+ --enable-numeric-version \
+ --with-pkg-extra-version="_git$PKGVER" \
+ && make dist \
+ && cd / \
+ && mkdir -p /rpmbuild/{SOURCES,SPECS} \
+ && cp /src/frr*.tar.gz /rpmbuild/SOURCES \
+ && cp /src/redhat/frr.spec /rpmbuild/SPECS \
+ && rpmbuild \
+ --define "_topdir /rpmbuild" \
+ -ba /rpmbuild/SPECS/frr.spec
+
+# This stage installs frr from the rpm
+FROM centos:centos8
+
+RUN sed -i -e "s|mirrorlist=|#mirrorlist=|g" /etc/yum.repos.d/CentOS-* \
+ && sed -i -e "s|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g" /etc/yum.repos.d/CentOS-*
+
+RUN mkdir -p /pkgs/rpm \
+ && yum install -y https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-8-x86_64-Packages/libyang2-2.0.0.10.g2eb910e4-1.el8.x86_64.rpm \
+ https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-00146/CentOS-7-x86_64-Packages/librtr-0.8.0-1.el7.x86_64.rpm
+
+COPY --from=centos-8-builder /rpmbuild/RPMS/ /pkgs/rpm/
+
+RUN yum install -y /pkgs/rpm/*/*.rpm \
+ && rm -rf /pkgs
+
+# Own the config / PID files
+RUN mkdir -p /var/run/frr
+RUN chown -R frr:frr /etc/frr /var/run/frr
+
+# Add tini because no CentOS8 package
+ENV TINI_VERSION v0.19.0
+ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /sbin/tini
+RUN chmod +x /sbin/tini
+
+# Simple init manager for reaping processes and forwarding signals
+ENTRYPOINT ["/sbin/tini", "--"]
+
+# Default CMD starts watchfrr
+COPY docker/centos-8/docker-start /usr/lib/frr/docker-start
+CMD ["/usr/lib/frr/docker-start"]
diff --git a/docker/centos-8/build.sh b/docker/centos-8/build.sh
new file mode 100755
index 0000000..4a99184
--- /dev/null
+++ b/docker/centos-8/build.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+set -e
+
+##
+# Package version needs to be decimal
+##
+GITREV="$(git rev-parse --short=10 HEAD)"
+PKGVER="$(printf '%u\n' 0x$GITREV)"
+
+mkdir -p docker/centos-8/pkgs
+docker build \
+ --file=docker/centos-8/Dockerfile \
+ --build-arg="PKGVER=$PKGVER" \
+ --tag="frr:centos-8-builder-$GITREV" \
+ --target=centos-8-builder \
+ .
+
+# Copy RPM package from container to host
+CONTAINER_ID="$(docker create "frr:centos-8-builder-$GITREV")"
+docker cp "${CONTAINER_ID}:/rpmbuild/RPMS/x86_64/" docker/centos-8/pkgs
+docker rm "${CONTAINER_ID}"
+
+docker build \
+ --cache-from="frr:centos-8-builder-$GITREV" \
+ --file=docker/centos-8/Dockerfile \
+ --build-arg="PKGVER=$PKGVER" \
+ --tag="frr:centos-8-$GITREV" \
+ .
+
+docker rmi "frr:centos-8-builder-$GITREV"
diff --git a/docker/centos-8/docker-start b/docker/centos-8/docker-start
new file mode 100755
index 0000000..d954142
--- /dev/null
+++ b/docker/centos-8/docker-start
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+source /usr/lib/frr/frrcommon.sh
+/usr/lib/frr/watchfrr $(daemon_list)
diff --git a/docker/debian/Dockerfile b/docker/debian/Dockerfile
new file mode 100644
index 0000000..7476e5f
--- /dev/null
+++ b/docker/debian/Dockerfile
@@ -0,0 +1,28 @@
+FROM debian:buster
+MAINTAINER Rob Gil (rob@rem5.com)
+
+ENV DEBIAN_FRONTEND noninteractive
+ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
+
+RUN apt-get update && \
+ apt-get install -y libpcre3-dev apt-transport-https ca-certificates curl wget logrotate \
+ libc-ares2 libjson-c3 vim procps libreadline7 gnupg2 lsb-release apt-utils \
+ tini && rm -rf /var/lib/apt/lists/*
+
+RUN curl -s https://deb.frrouting.org/frr/keys.asc | apt-key add -
+RUN echo deb https://deb.frrouting.org/frr $(lsb_release -s -c) frr-stable | tee -a /etc/apt/sources.list.d/frr.list
+
+RUN apt-get update && \
+ apt-get install -y frr frr-pythontools && \
+ rm -rf /var/lib/apt/lists/*
+
+# Own the config / PID files
+RUN mkdir -p /var/run/frr
+RUN chown -R frr:frr /etc/frr /var/run/frr
+
+# Simple init manager for reaping processes and forwarding signals
+ENTRYPOINT ["/usr/bin/tini", "--"]
+
+# Default CMD starts watchfrr
+COPY docker-start /usr/lib/frr/docker-start
+CMD ["/usr/lib/frr/docker-start"]
diff --git a/docker/debian/README.md b/docker/debian/README.md
new file mode 100644
index 0000000..3c1209b
--- /dev/null
+++ b/docker/debian/README.md
@@ -0,0 +1,20 @@
+# Debian 10 Docker
+
+This is a binary docker container build of Debian 10 (buster) with FRR.
+
+# Build
+
+```
+docker build -t frr-debian:latest .
+```
+
+# Running
+
+```
+docker run -itd --privileged --name frr frr-debian:latest
+```
+
+vtysh
+```
+docker exec -it frr vtysh
+```
diff --git a/docker/debian/docker-start b/docker/debian/docker-start
new file mode 100755
index 0000000..d954142
--- /dev/null
+++ b/docker/debian/docker-start
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+source /usr/lib/frr/frrcommon.sh
+/usr/lib/frr/watchfrr $(daemon_list)
diff --git a/docker/ubi-8/Dockerfile b/docker/ubi-8/Dockerfile
new file mode 100644
index 0000000..1d1e8bd
--- /dev/null
+++ b/docker/ubi-8/Dockerfile
@@ -0,0 +1,83 @@
+# This stage builds an rpm from the source
+FROM registry.access.redhat.com/ubi8/ubi:8.5 as ubi-8-builder
+
+RUN dnf -y update-minimal --security --sec-severity=Important --sec-severity=Critical
+
+RUN rpm --import https://www.centos.org/keys/RPM-GPG-KEY-CentOS-Official \
+ && dnf config-manager --disableplugin subscription-manager --add-repo http://mirror.centos.org/centos/8-stream/BaseOS/x86_64/os \
+ && dnf config-manager --disableplugin subscription-manager --add-repo http://mirror.centos.org/centos/8-stream/AppStream/x86_64/os \
+ && dnf config-manager --disableplugin subscription-manager --add-repo http://mirror.centos.org/centos/8-stream/PowerTools/x86_64/os
+
+RUN dnf install -qy https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm \
+ && dnf install --enablerepo=* -qy rpm-build git autoconf pcre-devel \
+ systemd-devel automake libtool make readline-devel texinfo \
+ net-snmp-devel pkgconfig groff pkgconfig json-c-devel pam-devel \
+ bison flex python3-pytest c-ares-devel python3-devel python3-sphinx \
+ libcap-devel platform-python-devel \
+ https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-8-x86_64-Packages/libyang2-2.0.0.10.g2eb910e4-1.el8.x86_64.rpm \
+ https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-8-x86_64-Packages/libyang2-devel-2.0.0.10.g2eb910e4-1.el8.x86_64.rpm \
+ https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-00146/CentOS-7-x86_64-Packages/librtr-0.8.0-1.el7.x86_64.rpm \
+ https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-00146/CentOS-7-x86_64-Packages/librtr-devel-0.8.0-1.el7.x86_64.rpm
+
+
+COPY . /src
+
+ARG PKGVER
+
+RUN echo '%_smp_mflags %( echo "-j$(/usr/bin/getconf _NPROCESSORS_ONLN)"; )' >> /root/.rpmmacros \
+ && cd /src \
+ && ./bootstrap.sh \
+ && ./configure \
+ --enable-rpki \
+ --enable-snmp=agentx \
+ --enable-numeric-version \
+ --with-pkg-extra-version="_palmetto_git$PKGVER" \
+ && make dist \
+ && cd / \
+ && mkdir -p /rpmbuild/{SOURCES,SPECS} \
+ && cp /src/frr*.tar.gz /rpmbuild/SOURCES \
+ && cp /src/redhat/frr.spec /rpmbuild/SPECS \
+ && rpmbuild \
+ --define "_topdir /rpmbuild" \
+ -ba /rpmbuild/SPECS/frr.spec
+
+# This stage installs frr from the rpm
+FROM registry.access.redhat.com/ubi8/ubi:8.5
+RUN dnf -y update-minimal --security --sec-severity=Important --sec-severity=Critical
+ARG FRR_IMAGE_TAG
+ARG FRR_RELEASE
+ARG FRR_NAME
+ARG FRR_VENDOR
+LABEL name=$FRR_NAME \
+ vendor=$FRR_VENDOR \
+ version=$FRR_IMAGE_TAG \
+ release=$FRR_RELEASE
+
+RUN rpm --import https://www.centos.org/keys/RPM-GPG-KEY-CentOS-Official \
+ && dnf config-manager --disableplugin subscription-manager --add-repo http://mirror.centos.org/centos/8-stream/BaseOS/x86_64/os \
+ && dnf config-manager --disableplugin subscription-manager --add-repo http://mirror.centos.org/centos/8-stream/AppStream/x86_64/os
+
+RUN dnf install -qy https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm \
+ && mkdir -p /pkgs/rpm \
+ && dnf install --enablerepo=* -qy https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-8-x86_64-Packages/libyang2-2.0.0.10.g2eb910e4-1.el8.x86_64.rpm \
+ https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-00146/CentOS-7-x86_64-Packages/librtr-0.8.0-1.el7.x86_64.rpm
+
+COPY --from=ubi-8-builder /rpmbuild/RPMS/ /pkgs/rpm/
+
+RUN dnf install -qy /pkgs/rpm/*/*.rpm \
+ && rm -rf /pkgs \
+# Own the config / PID files
+ && mkdir -p /var/run/frr \
+ && chown -R frr:frr /etc/frr /var/run/frr
+
+# Add tini because no CentOS8 package
+ENV TINI_VERSION v0.19.0
+ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /sbin/tini
+RUN chmod +x /sbin/tini
+
+# Simple init manager for reaping processes and forwarding signals
+ENTRYPOINT ["/sbin/tini", "--"]
+
+# Default CMD starts watchfrr
+COPY docker/ubi-8/docker-start /usr/lib/frr/docker-start
+CMD ["/usr/lib/frr/docker-start"]
diff --git a/docker/ubi-8/build.sh b/docker/ubi-8/build.sh
new file mode 100755
index 0000000..0216636
--- /dev/null
+++ b/docker/ubi-8/build.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+set -e
+
+##
+# Package version needs to be decimal
+##
+DISTRO=ubi-8
+
+GITREV="$2"
+if [ -z "$GITREV" ];then
+ GITREV="$(git rev-parse --short=10 HEAD)"
+fi
+
+FRR_IMAGE_TAG="$1"
+if [ -z $FRR_IMAGE_TAG ];then
+ FRR_IMAGE_TAG="frr:ubi-8-$GITREV"
+fi
+PKGVER="$(printf '%u\n' 0x$GITREV)"
+
+FRR_RELEASE="$3"
+if [ -z $FRR_RELEASE ];then
+ FRR_RELEASE=$(git describe --tags --abbrev=0)
+fi
+
+FRR_NAME=$4
+if [ -z $FRR_NAME ];then
+ FRR_NAME=frr
+fi
+
+FRR_VENDOR=$5
+if [ -z $FRR_VENDOR ];then
+ FRR_VENDOR=frr
+fi
+
+docker build \
+ --cache-from="frr:$DISTRO-builder-$GITREV" \
+ --file=docker/$DISTRO/Dockerfile \
+ --build-arg="PKGVER=$PKGVER" \
+ --build-arg="FRR_IMAGE_TAG=$FRR_IMAGE_TAG" \
+ --build-arg="FRR_RELEASE=$FRR_RELEASE" \
+ --build-arg="FRR_NAME=$FRR_NAME" \
+ --build-arg="FRR_VENDOR=$FRR_VENDOR" \
+ --tag="$FRR_IMAGE_TAG" \
+ .
+
diff --git a/docker/ubi-8/docker-start b/docker/ubi-8/docker-start
new file mode 100755
index 0000000..d954142
--- /dev/null
+++ b/docker/ubi-8/docker-start
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+source /usr/lib/frr/frrcommon.sh
+/usr/lib/frr/watchfrr $(daemon_list)
diff --git a/docker/ubuntu18-ci/Dockerfile b/docker/ubuntu18-ci/Dockerfile
new file mode 100644
index 0000000..07a5a2f
--- /dev/null
+++ b/docker/ubuntu18-ci/Dockerfile
@@ -0,0 +1,73 @@
+FROM ubuntu:18.04
+
+ARG DEBIAN_FRONTEND=noninteractive
+ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
+# Update Ubuntu Software repository
+RUN apt update && \
+ apt-get install -y \
+ git autoconf automake libtool make libreadline-dev texinfo \
+ pkg-config libpam0g-dev libjson-c-dev bison flex python3-pip \
+ libc-ares-dev python3-dev python3-sphinx \
+ install-info build-essential libsnmp-dev perl libcap-dev \
+ libelf-dev \
+ sudo gdb iputils-ping time \
+ python-pip net-tools iproute2 && \
+ python3 -m pip install wheel && \
+ python3 -m pip install pytest && \
+ python3 -m pip install pytest-xdist && \
+ python3 -m pip install "scapy>=2.4.2" && \
+ python3 -m pip install xmltodict && \
+ python2 -m pip install 'exabgp<4.0.0'
+
+RUN groupadd -r -g 92 frr && \
+ groupadd -r -g 85 frrvty && \
+ adduser --system --ingroup frr --home /home/frr \
+ --gecos "FRR suite" --shell /bin/bash frr && \
+ usermod -a -G frrvty frr && \
+ useradd -d /var/run/exabgp/ -s /bin/false exabgp && \
+ echo 'frr ALL = NOPASSWD: ALL' | tee /etc/sudoers.d/frr && \
+ mkdir -p /home/frr && chown frr.frr /home/frr
+
+#for libyang 2
+RUN apt-get install -y cmake libpcre2-dev
+
+USER frr:frr
+
+# build and install libyang2
+RUN cd && pwd && ls -al && \
+ git clone https://github.com/CESNET/libyang.git && \
+ cd libyang && \
+ git checkout v2.0.0 && \
+ mkdir build; cd build && \
+ cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr \
+ -DCMAKE_BUILD_TYPE:String="Release" .. && \
+ make -j $(nproc) && \
+ sudo make install
+
+COPY --chown=frr:frr . /home/frr/frr/
+
+RUN cd && ls -al && ls -al frr
+
+RUN cd ~/frr && \
+ ./bootstrap.sh && \
+ ./configure \
+ --prefix=/usr \
+ --localstatedir=/var/run/frr \
+ --sbindir=/usr/lib/frr \
+ --sysconfdir=/etc/frr \
+ --enable-vtysh \
+ --enable-pimd \
+ --enable-sharpd \
+ --enable-multipath=64 \
+ --enable-user=frr \
+ --enable-group=frr \
+ --enable-vty-group=frrvty \
+ --enable-snmp=agentx \
+ --with-pkg-extra-version=-my-manual-build && \
+ make -j $(nproc) && \
+ sudo make install
+
+RUN cd ~/frr && make check || true
+
+COPY docker/ubuntu18-ci/docker-start /usr/sbin/docker-start
+CMD ["/usr/sbin/docker-start"]
diff --git a/docker/ubuntu18-ci/README.md b/docker/ubuntu18-ci/README.md
new file mode 100644
index 0000000..4e8ab89
--- /dev/null
+++ b/docker/ubuntu18-ci/README.md
@@ -0,0 +1,44 @@
+# Ubuntu 18.04
+
+This builds an ubuntu 18.04 container for dev / test
+
+# Build
+
+```
+docker build -t frr-ubuntu18:latest -f docker/ubuntu18-ci/Dockerfile .
+```
+
+# Running
+
+```
+docker run -d --privileged --name frr-ubuntu18 --mount type=bind,source=/lib/modules,target=/lib/modules frr-ubuntu18:latest
+```
+
+# make check
+
+```
+docker exec frr-ubuntu18 bash -c 'cd ~/frr ; make check'
+```
+
+# interactive bash
+```
+docker exec -it frr-ubuntu18 bash
+```
+
+# topotest -- when Host O/S is Ubuntu only
+
+```
+docker exec frr-ubuntu18 bash -c 'cd ~/frr/tests/topotests/ospf-topo1 ; sudo pytest test_ospf_topo1.py'
+```
+
+# stop & remove container
+
+```
+docker stop frr-ubuntu18 ; docker rm frr-ubuntu18
+```
+
+# remove image
+
+```
+docker rmi frr-ubuntu18:latest
+```
diff --git a/docker/ubuntu18-ci/docker-start b/docker/ubuntu18-ci/docker-start
new file mode 100755
index 0000000..9a45c72
--- /dev/null
+++ b/docker/ubuntu18-ci/docker-start
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+if [ $(uname -a | grep -ci Ubuntu) -ge 1 ]; then
+ #for topotests under ubuntu host
+ sudo modprobe mpls-router mpls-iptunnel
+ sudo /etc/init.d/openvswitch-switch start
+fi
+while true ; do sleep 365d ; done
diff --git a/docker/ubuntu20-ci/Dockerfile b/docker/ubuntu20-ci/Dockerfile
new file mode 100644
index 0000000..b9fe385
--- /dev/null
+++ b/docker/ubuntu20-ci/Dockerfile
@@ -0,0 +1,78 @@
+FROM ubuntu:20.04
+
+ARG DEBIAN_FRONTEND=noninteractive
+ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
+# Update Ubuntu Software repository
+RUN apt update && \
+ apt-get install -y \
+ git autoconf automake libtool make libreadline-dev texinfo \
+ pkg-config libpam0g-dev libjson-c-dev bison flex python3-pip \
+ libc-ares-dev python3-dev python3-sphinx \
+ install-info build-essential libsnmp-dev perl \
+ libcap-dev python2 libelf-dev \
+ sudo gdb curl iputils-ping time \
+ lua5.3 liblua5.3-dev \
+ net-tools iproute2 && \
+ curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output /tmp/get-pip.py && \
+ python2 /tmp/get-pip.py && \
+ rm -f /tmp/get-pip.py && \
+ python3 -m pip install wheel && \
+ python3 -m pip install pytest && \
+ python3 -m pip install pytest-xdist && \
+ python3 -m pip install "scapy>=2.4.2" && \
+ python3 -m pip install xmltodict && \
+ python2 -m pip install 'exabgp<4.0.0'
+
+RUN groupadd -r -g 92 frr && \
+ groupadd -r -g 85 frrvty && \
+ adduser --system --ingroup frr --home /home/frr \
+ --gecos "FRR suite" --shell /bin/bash frr && \
+ usermod -a -G frrvty frr && \
+ useradd -d /var/run/exabgp/ -s /bin/false exabgp && \
+ echo 'frr ALL = NOPASSWD: ALL' | tee /etc/sudoers.d/frr && \
+ mkdir -p /home/frr && chown frr.frr /home/frr
+
+#for libyang 2
+RUN apt-get install -y cmake libpcre2-dev
+
+USER frr:frr
+
+# build and install libyang2
+RUN cd && pwd && ls -al && \
+ git clone https://github.com/CESNET/libyang.git && \
+ cd libyang && \
+ git checkout v2.0.0 && \
+ mkdir build; cd build && \
+ cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr \
+ -DCMAKE_BUILD_TYPE:String="Release" .. && \
+ make -j $(nproc) && \
+ sudo make install
+
+COPY --chown=frr:frr . /home/frr/frr/
+
+RUN cd && ls -al && ls -al frr
+
+RUN cd ~/frr && \
+ ./bootstrap.sh && \
+ ./configure \
+ --prefix=/usr \
+ --localstatedir=/var/run/frr \
+ --sbindir=/usr/lib/frr \
+ --sysconfdir=/etc/frr \
+ --enable-vtysh \
+ --enable-pimd \
+ --enable-sharpd \
+ --enable-multipath=64 \
+ --enable-user=frr \
+ --enable-group=frr \
+ --enable-vty-group=frrvty \
+ --enable-snmp=agentx \
+ --enable-scripting \
+ --with-pkg-extra-version=-my-manual-build && \
+ make -j $(nproc) && \
+ sudo make install
+
+RUN cd ~/frr && make check || true
+
+COPY docker/ubuntu20-ci/docker-start /usr/sbin/docker-start
+CMD ["/usr/sbin/docker-start"]
diff --git a/docker/ubuntu20-ci/README.md b/docker/ubuntu20-ci/README.md
new file mode 100644
index 0000000..11138c6
--- /dev/null
+++ b/docker/ubuntu20-ci/README.md
@@ -0,0 +1,45 @@
+# Ubuntu 20.04
+
+This builds an ubuntu 20.04 container for dev / test
+
+# Build
+
+```
+docker build -t frr-ubuntu20:latest -f docker/ubuntu20-ci/Dockerfile .
+```
+
+# Running
+
+```
+docker run -d --privileged --name frr-ubuntu20 --mount type=bind,source=/lib/modules,target=/lib/modules frr-ubuntu20:latest
+```
+
+# make check
+
+```
+docker exec frr-ubuntu20 bash -c 'cd ~/frr ; make check'
+```
+
+# interactive bash
+
+```
+docker exec -it frr-ubuntu20 bash
+```
+
+# topotest -- when Host O/S is Ubuntu only
+
+```
+docker exec frr-ubuntu20 bash -c 'cd ~/frr/tests/topotests/ospf-topo1 ; sudo pytest test_ospf_topo1.py'
+```
+
+# stop & remove container
+
+```
+docker stop frr-ubuntu20 ; docker rm frr-ubuntu18
+```
+
+# remove image
+
+```
+docker rmi frr-ubuntu20:latest
+```
diff --git a/docker/ubuntu20-ci/docker-start b/docker/ubuntu20-ci/docker-start
new file mode 100755
index 0000000..9a45c72
--- /dev/null
+++ b/docker/ubuntu20-ci/docker-start
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+if [ $(uname -a | grep -ci Ubuntu) -ge 1 ]; then
+ #for topotests under ubuntu host
+ sudo modprobe mpls-router mpls-iptunnel
+ sudo /etc/init.d/openvswitch-switch start
+fi
+while true ; do sleep 365d ; done