diff mbox series

[ovs-dev] add ovn-kubernetes job to github actions

Message ID 20210701183552.2157890-1-numans@ovn.org
State Accepted
Headers show
Series [ovs-dev] add ovn-kubernetes job to github actions | expand

Checks

Context Check Description
ovsrobot/apply-robot warning apply and check: warning
ovsrobot/github-robot-_Build_and_Test success github build: passed
ovsrobot/github-robot-_ovn-kubernetes fail github build: failed

Commit Message

Numan Siddique July 1, 2021, 6:35 p.m. UTC
From: Antonio Ojea <antonio.ojea.garcia@gmail.com>

It allows to specify the ovn-kubernetes commits to test against.

Submitted-at: https://github.com/ovn-org/ovn/pull/61
Signed-off-by: Antonio Ojea <antonio.ojea.garcia@gmail.com>
---
 .ci/ovn-kubernetes/Dockerfile        |  81 +++++++++++++
 .github/workflows/ovn-kubernetes.yml | 170 +++++++++++++++++++++++++++
 Makefile.am                          |   2 +
 3 files changed, 253 insertions(+)
 create mode 100644 .ci/ovn-kubernetes/Dockerfile
 create mode 100644 .github/workflows/ovn-kubernetes.yml

Comments

0-day Robot July 1, 2021, 6:41 p.m. UTC | #1
Bleep bloop.  Greetings Numan Siddique, I am a robot and I have tried out your patch.
Thanks for your contribution.

I encountered some error that I wasn't expecting.  See the details below.


checkpatch:
WARNING: Line is 83 characters long (recommended limit is 79)
#34 FILE: .ci/ovn-kubernetes/Dockerfile:11:
    python3-pyyaml bind-utils procps-ng openssl numactl-libs firewalld-filesystem \

WARNING: Line is 82 characters long (recommended limit is 79)
#64 FILE: .ci/ovn-kubernetes/Dockerfile:41:
# Clone OVN Kubernetes and build the binary based on the commit passed as argument

WARNING: Line is 94 characters long (recommended limit is 79)
#88 FILE: .ci/ovn-kubernetes/Dockerfile:65:
COPY --from=ovnkubebuilder /root/ovn-kubernetes/go-controller/_output/go/bin/ovnkube /usr/bin/

WARNING: Line is 100 characters long (recommended limit is 79)
#89 FILE: .ci/ovn-kubernetes/Dockerfile:66:
COPY --from=ovnkubebuilder /root/ovn-kubernetes/go-controller/_output/go/bin/ovn-kube-util /usr/bin/

WARNING: Line is 99 characters long (recommended limit is 79)
#90 FILE: .ci/ovn-kubernetes/Dockerfile:67:
COPY --from=ovnkubebuilder /root/ovn-kubernetes/go-controller/_output/go/bin/ovndbchecker /usr/bin/

WARNING: Line is 133 characters long (recommended limit is 79)
#91 FILE: .ci/ovn-kubernetes/Dockerfile:68:
COPY --from=ovnkubebuilder /root/ovn-kubernetes/go-controller/_output/go/bin/ovn-k8s-cni-overlay /usr/libexec/cni/ovn-k8s-cni-overlay

WARNING: Line is 90 characters long (recommended limit is 79)
#96 FILE: .ci/ovn-kubernetes/Dockerfile:73:
COPY --from=ovnkubebuilder /root/ovn-kubernetes/dist/images/ovndb-raft-functions.sh /root/

WARNING: Line is 87 characters long (recommended limit is 79)
#97 FILE: .ci/ovn-kubernetes/Dockerfile:74:
COPY --from=ovnkubebuilder /root/ovn-kubernetes/dist/images/iptables-scripts /usr/sbin/

WARNING: Line is 106 characters long (recommended limit is 79)
#100 FILE: .ci/ovn-kubernetes/Dockerfile:77:
    io.k8s.description="This is a Kubernetes network plugin that provides an overlay network using OVN." \

WARNING: Line is 131 characters long (recommended limit is 79)
#144 FILE: .github/workflows/ovn-kubernetes.yml:34:
        docker build --build-arg OVNKUBE_COMMIT=${{ env.OVNKUBE_COMMIT }} -t ovn-daemonset-f:dev -f .ci/ovn-kubernetes/Dockerfile .

WARNING: Line is 126 characters long (recommended limit is 79)
#184 FILE: .github/workflows/ovn-kubernetes.yml:74:
        # - {"ipfamily": {"ip": ipv4}, "ha": {"enabled": "false"}, "gateway-mode": shared, "target": {"shard": shard-n-other}}

WARNING: Line is 129 characters long (recommended limit is 79)
#202 FILE: .github/workflows/ovn-kubernetes.yml:92:
      run: sudo eatmydata apt-get remove --auto-remove -y aspnetcore-* dotnet-* libmono-* mono-* msbuild php-* php7* ghc-* zulu-*

WARNING: Line is 80 characters long (recommended limit is 79)
#223 FILE: .github/workflows/ovn-kubernetes.yml:113:
      # For IPv6 and Dualstack, ufw (Uncomplicated Firewall) should be disabled.

WARNING: Line is 80 characters long (recommended limit is 79)
#266 FILE: .github/workflows/ovn-kubernetes.yml:156:
        path: 'src/github.com/ovn-org/ovn-kubernetes/test/_artifacts/index.html'

WARNING: Line is 84 characters long (recommended limit is 79)
#272 FILE: .github/workflows/ovn-kubernetes.yml:162:
        kind export logs --name ${KIND_CLUSTER_NAME} --loglevel=debug /tmp/kind/logs

Lines checked: 297, Warnings: 15, Errors: 0


Please check this out.  If you feel there has been an error, please email aconole@redhat.com

Thanks,
0-day Robot
Numan Siddique July 5, 2021, 4:26 p.m. UTC | #2
On Thu, Jul 1, 2021 at 2:36 PM <numans@ovn.org> wrote:
>
> From: Antonio Ojea <antonio.ojea.garcia@gmail.com>
>
> It allows to specify the ovn-kubernetes commits to test against.
>
> Submitted-at: https://github.com/ovn-org/ovn/pull/61
> Signed-off-by: Antonio Ojea <antonio.ojea.garcia@gmail.com>

Thanks for the PR.  I applied this patch to the main branch.

Numan

> ---
>  .ci/ovn-kubernetes/Dockerfile        |  81 +++++++++++++
>  .github/workflows/ovn-kubernetes.yml | 170 +++++++++++++++++++++++++++
>  Makefile.am                          |   2 +
>  3 files changed, 253 insertions(+)
>  create mode 100644 .ci/ovn-kubernetes/Dockerfile
>  create mode 100644 .github/workflows/ovn-kubernetes.yml
>
> diff --git a/.ci/ovn-kubernetes/Dockerfile b/.ci/ovn-kubernetes/Dockerfile
> new file mode 100644
> index 0000000000..ba04fb1990
> --- /dev/null
> +++ b/.ci/ovn-kubernetes/Dockerfile
> @@ -0,0 +1,81 @@
> +ARG OVNKUBE_COMMIT=master
> +
> +FROM fedora:33 AS ovnbuilder
> +
> +USER root
> +
> +ENV PYTHONDONTWRITEBYTECODE yes
> +
> +# install needed rpms - openvswitch must be 2.10.4 or higher
> +RUN INSTALL_PKGS=" \
> +    python3-pyyaml bind-utils procps-ng openssl numactl-libs firewalld-filesystem \
> +    libpcap hostname \
> +    python3-openvswitch python3-pyOpenSSL \
> +    autoconf automake libtool g++ gcc fedora-packager rpmdevtools \
> +    unbound unbound-devel groff python3-sphinx graphviz openssl openssl-devel \
> +    checkpolicy libcap-ng-devel selinux-policy-devel" && \
> +    dnf install --best --refresh -y --setopt=tsflags=nodocs $INSTALL_PKGS && \
> +    dnf clean all && rm -rf /var/cache/dnf/*
> +
> +# Build OVS and OVN rpms from current folder
> +RUN mkdir /tmp/ovn
> +COPY . /tmp/ovn
> +WORKDIR /tmp/ovn/ovs
> +
> +RUN ./boot.sh
> +RUN ./configure -v
> +RUN make && make rpm-fedora
> +RUN rm rpm/rpmbuild/RPMS/x86_64/*debug*
> +RUN rm rpm/rpmbuild/RPMS/x86_64/*devel*
> +
> +WORKDIR /tmp/ovn
> +RUN ./boot.sh
> +RUN ./configure
> +RUN make && make rpm-fedora
> +RUN rm rpm/rpmbuild/RPMS/x86_64/*debug*
> +RUN rm rpm/rpmbuild/RPMS/x86_64/*docker*
> +
> +# Build ovn-kubernetes
> +FROM golang:1.16 as ovnkubebuilder
> +ARG OVNKUBE_COMMIT
> +# Clone OVN Kubernetes and build the binary based on the commit passed as argument
> +WORKDIR /root
> +RUN git clone https://github.com/ovn-org/ovn-kubernetes.git
> +WORKDIR /root/ovn-kubernetes/go-controller
> +RUN git checkout ${OVNKUBE_COMMIT} && make
> +
> +# Build the final image
> +FROM fedora:33
> +
> +# install needed dependencies
> +RUN INSTALL_PKGS=" \
> +    iptables iproute iputils hostname unbound-libs kubernetes-client kmod" && \
> +    dnf install --best --refresh -y --setopt=tsflags=nodocs $INSTALL_PKGS && \
> +    dnf clean all && rm -rf /var/cache/dnf/*
> +
> +RUN mkdir -p /var/run/openvswitch
> +
> +# install openvswitch and ovn rpms built in previous stages
> +COPY --from=ovnbuilder /tmp/ovn/rpm/rpmbuild/RPMS/x86_64/*rpm ./
> +COPY --from=ovnbuilder /tmp/ovn/ovs/rpm/rpmbuild/RPMS/x86_64/*rpm ./
> +RUN dnf install -y *.rpm && rm -f *.rpm
> +
> +# install ovn-kubernetes binaries built in previous stage
> +RUN mkdir -p /usr/libexec/cni/
> +COPY --from=ovnkubebuilder /root/ovn-kubernetes/go-controller/_output/go/bin/ovnkube /usr/bin/
> +COPY --from=ovnkubebuilder /root/ovn-kubernetes/go-controller/_output/go/bin/ovn-kube-util /usr/bin/
> +COPY --from=ovnkubebuilder /root/ovn-kubernetes/go-controller/_output/go/bin/ovndbchecker /usr/bin/
> +COPY --from=ovnkubebuilder /root/ovn-kubernetes/go-controller/_output/go/bin/ovn-k8s-cni-overlay /usr/libexec/cni/ovn-k8s-cni-overlay
> +
> +# ovnkube.sh is the entry point. This script examines environment
> +# variables to direct operation and configure ovn
> +COPY --from=ovnkubebuilder /root/ovn-kubernetes/dist/images/ovnkube.sh /root/
> +COPY --from=ovnkubebuilder /root/ovn-kubernetes/dist/images/ovndb-raft-functions.sh /root/
> +COPY --from=ovnkubebuilder /root/ovn-kubernetes/dist/images/iptables-scripts /usr/sbin/
> +
> +LABEL io.k8s.display-name="ovn-kubernetes" \
> +    io.k8s.description="This is a Kubernetes network plugin that provides an overlay network using OVN." \
> +    maintainer="ovn team"
> +
> +WORKDIR /root
> +ENTRYPOINT /root/ovnkube.sh
> diff --git a/.github/workflows/ovn-kubernetes.yml b/.github/workflows/ovn-kubernetes.yml
> new file mode 100644
> index 0000000000..ee77613f65
> --- /dev/null
> +++ b/.github/workflows/ovn-kubernetes.yml
> @@ -0,0 +1,170 @@
> +name: ovn-kubernetes
> +
> +on:
> +  push:
> +  pull_request:
> +  workflow_dispatch:
> +  schedule:
> +  # Run Sunday at midnight
> +  - cron: '0 0 * * 0'
> +
> +env:
> +  GO_VERSION: "1.16.3"
> +  K8S_VERSION: v1.20.2
> +  OVNKUBE_COMMIT: "f669ef6d35c86bf46d7a1055072e48ea1506f88c"
> +  KIND_CLUSTER_NAME: ovn
> +  KIND_INSTALL_INGRESS: true
> +  KIND_ALLOW_SYSTEM_WRITES: true
> +  # This skips tests tagged as Serial
> +  # Current Serial tests are not relevant for OVN
> +  PARALLEL: true
> +
> +jobs:
> +  build:
> +    name: Build
> +    runs-on: ubuntu-20.04
> +    steps:
> +    - name: Check out ovn
> +      uses: actions/checkout@v2
> +      with:
> +        submodules: recursive
> +
> +    - name: Build ovn-kubernetes container
> +      run: |
> +        docker build --build-arg OVNKUBE_COMMIT=${{ env.OVNKUBE_COMMIT }} -t ovn-daemonset-f:dev -f .ci/ovn-kubernetes/Dockerfile .
> +        mkdir /tmp/_output
> +        docker save ovn-daemonset-f:dev > /tmp/_output/image.tar
> +
> +    - uses: actions/upload-artifact@v2
> +      with:
> +        name: test-image
> +        path: /tmp/_output/image.tar
> +
> +  e2e:
> +    name: e2e
> +    if: github.event_name != 'schedule'
> +    runs-on: ubuntu-20.04
> +    timeout-minutes: 120
> +    strategy:
> +      fail-fast: false
> +      matrix:
> +        target:
> +          - shard: shard-conformance
> +            hybrid-overlay: false
> +            multicast-enable: false
> +            emptylb-enable: false
> +          - shard: control-plane
> +            hybrid-overlay: true
> +            multicast-enable: true
> +            emptylb-enable: true
> +        ipfamily:
> +          - ip: ipv4
> +            name: "IPv4"
> +            ipv4: true
> +            ipv6: false
> +          - ip: ipv6
> +            name: "IPv6"
> +            ipv4: false
> +            ipv6: true
> +          - ip: dualstack
> +            name: "Dualstack"
> +            ipv4: true
> +            ipv6: true
> +        # Example of how to exclude a fully qualified test:
> +        # - {"ipfamily": {"ip": ipv4}, "ha": {"enabled": "false"}, "gateway-mode": shared, "target": {"shard": shard-n-other}}
> +        exclude:
> +         # Not currently supported but needs to be.
> +         - {"ipfamily": {"ip": dualstack}, "target": {"shard": control-plane}}
> +         - {"ipfamily": {"ip": ipv6}, "target": {"shard": control-plane}}
> +    needs: [build]
> +    env:
> +      JOB_NAME: "${{ matrix.target.shard }}-${{ matrix.ipfamily.name }}"
> +      OVN_HA: "true"
> +      KIND_IPV4_SUPPORT: "${{ matrix.ipfamily.ipv4 }}"
> +      KIND_IPV6_SUPPORT: "${{ matrix.ipfamily.ipv6 }}"
> +      OVN_HYBRID_OVERLAY_ENABLE: "${{ matrix.target.hybrid-overlay }}"
> +      OVN_GATEWAY_MODE: "shared"
> +      OVN_MULTICAST_ENABLE:  "${{ matrix.target.multicast-enable }}"
> +      OVN_EMPTY_LB_EVENTS: "${{ matrix.target.emptylb-enable }}"
> +    steps:
> +
> +    - name: Free up disk space
> +      run: sudo eatmydata apt-get remove --auto-remove -y aspnetcore-* dotnet-* libmono-* mono-* msbuild php-* php7* ghc-* zulu-*
> +
> +    - name: Set up Go
> +      uses: actions/setup-go@v2
> +      with:
> +        go-version: ${{ env.GO_VERSION }}
> +      id: go
> +
> +    - name: Check out ovn-kubernetes
> +      uses: actions/checkout@v2
> +      with:
> +          path: src/github.com/ovn-org/ovn-kubernetes
> +          repository: ovn-org/ovn-kubernetes
> +
> +    - name: Set up environment
> +      run: |
> +        export GOPATH=$(go env GOPATH)
> +        echo "GOPATH=$GOPATH" >> $GITHUB_ENV
> +        echo "$GOPATH/bin" >> $GITHUB_PATH
> +
> +    - name: Disable ufw
> +      # For IPv6 and Dualstack, ufw (Uncomplicated Firewall) should be disabled.
> +      # Not needed for KIND deployments, so just disable all the time.
> +      run: |
> +        sudo ufw disable
> +
> +    - uses: actions/download-artifact@v2
> +      with:
> +        name: test-image
> +
> +    - name: Load docker image
> +      run: |
> +        docker load --input image.tar
> +
> +    - name: kind setup
> +      run: |
> +        export OVN_IMAGE="ovn-daemonset-f:dev"
> +        make -C test install-kind
> +      working-directory: src/github.com/ovn-org/ovn-kubernetes
> +
> +    - name: Run Tests
> +      run: |
> +        make -C test ${{ matrix.target.shard }}
> +      working-directory: src/github.com/ovn-org/ovn-kubernetes
> +
> +    - name: Upload Junit Reports
> +      if: always()
> +      uses: actions/upload-artifact@v2
> +      with:
> +        name: kind-junit-${{ env.JOB_NAME }}-${{ github.run_id }}
> +        path: 'src/github.com/ovn-org/ovn-kubernetes/test/_artifacts/*.xml'
> +
> +    - name: Generate Test Report
> +      id: xunit-viewer
> +      if: always()
> +      uses: AutoModality/action-xunit-viewer@v1
> +      with:
> +        results: src/github.com/ovn-org/ovn-kubernetes/test/_artifacts/
> +
> +    - name: Upload Test Report
> +      if: always()
> +      uses: actions/upload-artifact@v2
> +      with:
> +        name: test-report-${{ env.JOB_NAME }}-${{ github.run_id }}
> +        path: 'src/github.com/ovn-org/ovn-kubernetes/test/_artifacts/index.html'
> +
> +    - name: Export logs
> +      if: always()
> +      run: |
> +        mkdir -p /tmp/kind/logs
> +        kind export logs --name ${KIND_CLUSTER_NAME} --loglevel=debug /tmp/kind/logs
> +      working-directory: src/github.com/ovn-org/ovn-kubernetes
> +
> +    - name: Upload logs
> +      if: always()
> +      uses: actions/upload-artifact@v2
> +      with:
> +        name: kind-logs-${{ env.JOB_NAME }}-${{ github.run_id }}
> +        path: /tmp/kind/logs
> diff --git a/Makefile.am b/Makefile.am
> index 80247b62d5..0169c96ef8 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -90,7 +90,9 @@ EXTRA_DIST = \
>         .ci/linux-prepare.sh \
>         .ci/osx-build.sh \
>         .ci/osx-prepare.sh \
> +       .ci/ovn-kubernetes/Dockerfile \
>         .github/workflows/test.yml \
> +       .github/workflows/ovn-kubernetes.yml \
>         boot.sh \
>         $(MAN_FRAGMENTS) \
>         $(MAN_ROOTS) \
> --
> 2.31.1
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
diff mbox series

Patch

diff --git a/.ci/ovn-kubernetes/Dockerfile b/.ci/ovn-kubernetes/Dockerfile
new file mode 100644
index 0000000000..ba04fb1990
--- /dev/null
+++ b/.ci/ovn-kubernetes/Dockerfile
@@ -0,0 +1,81 @@ 
+ARG OVNKUBE_COMMIT=master
+
+FROM fedora:33 AS ovnbuilder
+
+USER root
+
+ENV PYTHONDONTWRITEBYTECODE yes
+
+# install needed rpms - openvswitch must be 2.10.4 or higher
+RUN INSTALL_PKGS=" \
+    python3-pyyaml bind-utils procps-ng openssl numactl-libs firewalld-filesystem \
+    libpcap hostname \
+    python3-openvswitch python3-pyOpenSSL \
+    autoconf automake libtool g++ gcc fedora-packager rpmdevtools \
+    unbound unbound-devel groff python3-sphinx graphviz openssl openssl-devel \
+    checkpolicy libcap-ng-devel selinux-policy-devel" && \
+    dnf install --best --refresh -y --setopt=tsflags=nodocs $INSTALL_PKGS && \
+    dnf clean all && rm -rf /var/cache/dnf/*
+
+# Build OVS and OVN rpms from current folder
+RUN mkdir /tmp/ovn
+COPY . /tmp/ovn
+WORKDIR /tmp/ovn/ovs
+
+RUN ./boot.sh
+RUN ./configure -v
+RUN make && make rpm-fedora
+RUN rm rpm/rpmbuild/RPMS/x86_64/*debug*
+RUN rm rpm/rpmbuild/RPMS/x86_64/*devel*
+
+WORKDIR /tmp/ovn
+RUN ./boot.sh
+RUN ./configure
+RUN make && make rpm-fedora
+RUN rm rpm/rpmbuild/RPMS/x86_64/*debug*
+RUN rm rpm/rpmbuild/RPMS/x86_64/*docker*
+
+# Build ovn-kubernetes
+FROM golang:1.16 as ovnkubebuilder
+ARG OVNKUBE_COMMIT
+# Clone OVN Kubernetes and build the binary based on the commit passed as argument
+WORKDIR /root
+RUN git clone https://github.com/ovn-org/ovn-kubernetes.git
+WORKDIR /root/ovn-kubernetes/go-controller
+RUN git checkout ${OVNKUBE_COMMIT} && make
+
+# Build the final image
+FROM fedora:33
+
+# install needed dependencies
+RUN INSTALL_PKGS=" \
+    iptables iproute iputils hostname unbound-libs kubernetes-client kmod" && \
+    dnf install --best --refresh -y --setopt=tsflags=nodocs $INSTALL_PKGS && \
+    dnf clean all && rm -rf /var/cache/dnf/*
+
+RUN mkdir -p /var/run/openvswitch
+
+# install openvswitch and ovn rpms built in previous stages
+COPY --from=ovnbuilder /tmp/ovn/rpm/rpmbuild/RPMS/x86_64/*rpm ./
+COPY --from=ovnbuilder /tmp/ovn/ovs/rpm/rpmbuild/RPMS/x86_64/*rpm ./
+RUN dnf install -y *.rpm && rm -f *.rpm
+
+# install ovn-kubernetes binaries built in previous stage
+RUN mkdir -p /usr/libexec/cni/
+COPY --from=ovnkubebuilder /root/ovn-kubernetes/go-controller/_output/go/bin/ovnkube /usr/bin/
+COPY --from=ovnkubebuilder /root/ovn-kubernetes/go-controller/_output/go/bin/ovn-kube-util /usr/bin/
+COPY --from=ovnkubebuilder /root/ovn-kubernetes/go-controller/_output/go/bin/ovndbchecker /usr/bin/
+COPY --from=ovnkubebuilder /root/ovn-kubernetes/go-controller/_output/go/bin/ovn-k8s-cni-overlay /usr/libexec/cni/ovn-k8s-cni-overlay
+
+# ovnkube.sh is the entry point. This script examines environment
+# variables to direct operation and configure ovn
+COPY --from=ovnkubebuilder /root/ovn-kubernetes/dist/images/ovnkube.sh /root/
+COPY --from=ovnkubebuilder /root/ovn-kubernetes/dist/images/ovndb-raft-functions.sh /root/
+COPY --from=ovnkubebuilder /root/ovn-kubernetes/dist/images/iptables-scripts /usr/sbin/
+
+LABEL io.k8s.display-name="ovn-kubernetes" \
+    io.k8s.description="This is a Kubernetes network plugin that provides an overlay network using OVN." \
+    maintainer="ovn team"
+
+WORKDIR /root
+ENTRYPOINT /root/ovnkube.sh
diff --git a/.github/workflows/ovn-kubernetes.yml b/.github/workflows/ovn-kubernetes.yml
new file mode 100644
index 0000000000..ee77613f65
--- /dev/null
+++ b/.github/workflows/ovn-kubernetes.yml
@@ -0,0 +1,170 @@ 
+name: ovn-kubernetes
+
+on:
+  push:
+  pull_request:
+  workflow_dispatch:
+  schedule:
+  # Run Sunday at midnight
+  - cron: '0 0 * * 0'
+
+env:
+  GO_VERSION: "1.16.3"
+  K8S_VERSION: v1.20.2
+  OVNKUBE_COMMIT: "f669ef6d35c86bf46d7a1055072e48ea1506f88c"
+  KIND_CLUSTER_NAME: ovn
+  KIND_INSTALL_INGRESS: true
+  KIND_ALLOW_SYSTEM_WRITES: true
+  # This skips tests tagged as Serial
+  # Current Serial tests are not relevant for OVN
+  PARALLEL: true
+
+jobs:
+  build:
+    name: Build
+    runs-on: ubuntu-20.04
+    steps:
+    - name: Check out ovn
+      uses: actions/checkout@v2
+      with:
+        submodules: recursive
+
+    - name: Build ovn-kubernetes container
+      run: |
+        docker build --build-arg OVNKUBE_COMMIT=${{ env.OVNKUBE_COMMIT }} -t ovn-daemonset-f:dev -f .ci/ovn-kubernetes/Dockerfile .
+        mkdir /tmp/_output
+        docker save ovn-daemonset-f:dev > /tmp/_output/image.tar
+
+    - uses: actions/upload-artifact@v2
+      with:
+        name: test-image
+        path: /tmp/_output/image.tar
+
+  e2e:
+    name: e2e
+    if: github.event_name != 'schedule'
+    runs-on: ubuntu-20.04
+    timeout-minutes: 120
+    strategy:
+      fail-fast: false
+      matrix:
+        target:
+          - shard: shard-conformance
+            hybrid-overlay: false
+            multicast-enable: false
+            emptylb-enable: false
+          - shard: control-plane
+            hybrid-overlay: true
+            multicast-enable: true
+            emptylb-enable: true
+        ipfamily:
+          - ip: ipv4
+            name: "IPv4"
+            ipv4: true
+            ipv6: false
+          - ip: ipv6
+            name: "IPv6"
+            ipv4: false
+            ipv6: true
+          - ip: dualstack
+            name: "Dualstack"
+            ipv4: true
+            ipv6: true
+        # Example of how to exclude a fully qualified test:
+        # - {"ipfamily": {"ip": ipv4}, "ha": {"enabled": "false"}, "gateway-mode": shared, "target": {"shard": shard-n-other}}
+        exclude:
+         # Not currently supported but needs to be.
+         - {"ipfamily": {"ip": dualstack}, "target": {"shard": control-plane}}
+         - {"ipfamily": {"ip": ipv6}, "target": {"shard": control-plane}}
+    needs: [build]
+    env:
+      JOB_NAME: "${{ matrix.target.shard }}-${{ matrix.ipfamily.name }}"
+      OVN_HA: "true"
+      KIND_IPV4_SUPPORT: "${{ matrix.ipfamily.ipv4 }}"
+      KIND_IPV6_SUPPORT: "${{ matrix.ipfamily.ipv6 }}"
+      OVN_HYBRID_OVERLAY_ENABLE: "${{ matrix.target.hybrid-overlay }}"
+      OVN_GATEWAY_MODE: "shared"
+      OVN_MULTICAST_ENABLE:  "${{ matrix.target.multicast-enable }}"
+      OVN_EMPTY_LB_EVENTS: "${{ matrix.target.emptylb-enable }}"
+    steps:
+
+    - name: Free up disk space
+      run: sudo eatmydata apt-get remove --auto-remove -y aspnetcore-* dotnet-* libmono-* mono-* msbuild php-* php7* ghc-* zulu-*
+
+    - name: Set up Go
+      uses: actions/setup-go@v2
+      with:
+        go-version: ${{ env.GO_VERSION }}
+      id: go
+
+    - name: Check out ovn-kubernetes
+      uses: actions/checkout@v2
+      with:
+          path: src/github.com/ovn-org/ovn-kubernetes
+          repository: ovn-org/ovn-kubernetes
+
+    - name: Set up environment
+      run: |
+        export GOPATH=$(go env GOPATH)
+        echo "GOPATH=$GOPATH" >> $GITHUB_ENV
+        echo "$GOPATH/bin" >> $GITHUB_PATH
+
+    - name: Disable ufw
+      # For IPv6 and Dualstack, ufw (Uncomplicated Firewall) should be disabled.
+      # Not needed for KIND deployments, so just disable all the time.
+      run: |
+        sudo ufw disable
+
+    - uses: actions/download-artifact@v2
+      with:
+        name: test-image
+
+    - name: Load docker image
+      run: |
+        docker load --input image.tar
+
+    - name: kind setup
+      run: |
+        export OVN_IMAGE="ovn-daemonset-f:dev"
+        make -C test install-kind
+      working-directory: src/github.com/ovn-org/ovn-kubernetes
+
+    - name: Run Tests
+      run: |
+        make -C test ${{ matrix.target.shard }}
+      working-directory: src/github.com/ovn-org/ovn-kubernetes
+
+    - name: Upload Junit Reports
+      if: always()
+      uses: actions/upload-artifact@v2
+      with:
+        name: kind-junit-${{ env.JOB_NAME }}-${{ github.run_id }}
+        path: 'src/github.com/ovn-org/ovn-kubernetes/test/_artifacts/*.xml'
+
+    - name: Generate Test Report
+      id: xunit-viewer
+      if: always()
+      uses: AutoModality/action-xunit-viewer@v1
+      with:
+        results: src/github.com/ovn-org/ovn-kubernetes/test/_artifacts/
+
+    - name: Upload Test Report
+      if: always()
+      uses: actions/upload-artifact@v2
+      with:
+        name: test-report-${{ env.JOB_NAME }}-${{ github.run_id }}
+        path: 'src/github.com/ovn-org/ovn-kubernetes/test/_artifacts/index.html'
+
+    - name: Export logs
+      if: always()
+      run: |
+        mkdir -p /tmp/kind/logs
+        kind export logs --name ${KIND_CLUSTER_NAME} --loglevel=debug /tmp/kind/logs
+      working-directory: src/github.com/ovn-org/ovn-kubernetes
+
+    - name: Upload logs
+      if: always()
+      uses: actions/upload-artifact@v2
+      with:
+        name: kind-logs-${{ env.JOB_NAME }}-${{ github.run_id }}
+        path: /tmp/kind/logs
diff --git a/Makefile.am b/Makefile.am
index 80247b62d5..0169c96ef8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -90,7 +90,9 @@  EXTRA_DIST = \
 	.ci/linux-prepare.sh \
 	.ci/osx-build.sh \
 	.ci/osx-prepare.sh \
+	.ci/ovn-kubernetes/Dockerfile \
 	.github/workflows/test.yml \
+	.github/workflows/ovn-kubernetes.yml \
 	boot.sh \
 	$(MAN_FRAGMENTS) \
 	$(MAN_ROOTS) \