ovs-docker is a helper script to add network interfaces to docker containers and to attach them as ports to OVS bridge.
This script can be further enhanced as we understand different use cases. Signed-off-by: Gurucharan Shetty <gshe...@nicira.com> --- NEWS | 2 + debian/openvswitch-common.install | 1 + rhel/openvswitch-fedora.spec.in | 1 + rhel/openvswitch.spec.in | 1 + utilities/automake.mk | 4 +- utilities/ovs-docker | 203 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 211 insertions(+), 1 deletion(-) create mode 100755 utilities/ovs-docker diff --git a/NEWS b/NEWS index 74984a7..7851f6e 100644 --- a/NEWS +++ b/NEWS @@ -36,6 +36,8 @@ Post-v2.3.0 still needed, so this should not be enabled on production environments. - Stats are no longer updated on fake bond interface. - Keep active bond slave selection across OVS restart. + - A simple wrapper script, 'ovs-docker', to integrate OVS with Docker + containers. v2.3.0 - 14 Aug 2014 diff --git a/debian/openvswitch-common.install b/debian/openvswitch-common.install index f2a0d48..11bb596 100644 --- a/debian/openvswitch-common.install +++ b/debian/openvswitch-common.install @@ -1,5 +1,6 @@ usr/bin/ovs-appctl usr/bin/ovs-benchmark +usr/bin/ovs-docker usr/bin/ovs-ofctl usr/bin/ovs-parse-backtrace usr/bin/ovs-pki diff --git a/rhel/openvswitch-fedora.spec.in b/rhel/openvswitch-fedora.spec.in index c5e99ef..d3b0ecb 100644 --- a/rhel/openvswitch-fedora.spec.in +++ b/rhel/openvswitch-fedora.spec.in @@ -173,6 +173,7 @@ systemctl start openvswitch.service /usr/sbin/ovs-vswitchd /usr/sbin/ovsdb-server /usr/bin/ovs-appctl +/usr/bin/ovs-docker /usr/bin/ovs-dpctl /usr/bin/ovs-dpctl-top /usr/bin/ovs-ofctl diff --git a/rhel/openvswitch.spec.in b/rhel/openvswitch.spec.in index 5e99ccb..5d26d59 100644 --- a/rhel/openvswitch.spec.in +++ b/rhel/openvswitch.spec.in @@ -130,6 +130,7 @@ exit 0 /usr/bin/ovs-benchmark /usr/bin/ovs-dpctl /usr/bin/ovs-dpctl-top +/usr/bin/ovs-docker /usr/bin/ovs-ofctl /usr/bin/ovs-parse-backtrace /usr/bin/ovs-pcap diff --git a/utilities/automake.mk b/utilities/automake.mk index 87ccb98..9ddbbe2 100644 --- a/utilities/automake.mk +++ b/utilities/automake.mk @@ -4,7 +4,8 @@ bin_PROGRAMS += \ utilities/ovs-dpctl \ utilities/ovs-ofctl \ utilities/ovs-vsctl -bin_SCRIPTS += utilities/ovs-pki +bin_SCRIPTS += utilities/ovs-docker \ + utilities/ovs-pki if HAVE_PYTHON bin_SCRIPTS += \ utilities/ovs-dpctl-top \ @@ -27,6 +28,7 @@ EXTRA_DIST += \ utilities/ovs-check-dead-ifs.in \ utilities/ovs-ctl.in \ utilities/ovs-dev.py \ + utilities/ovs-docker \ utilities/ovs-dpctl-top.in \ utilities/ovs-l3ping.in \ utilities/ovs-lib.in \ diff --git a/utilities/ovs-docker b/utilities/ovs-docker new file mode 100755 index 0000000..a798eb7 --- /dev/null +++ b/utilities/ovs-docker @@ -0,0 +1,203 @@ +#!/bin/bash +# Copyright (C) 2014 Nicira, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if (ovs-vsctl --version) > /dev/null 2>&1; then :; else + echo "missing ovs-vsctl, cannot proceed" + exit 1 +fi + +if (ip netns) > /dev/null 2>&1; then :; else + echo "ip utility not found (or it does not support netns), cannot proceed" + exit 1 +fi + +if (docker --version) > /dev/null 2>&1; then :; else + echo "docker utility not found, cannot proceed" + exit 1 +fi + +ovs_vsctl () { + ovs-vsctl --timeout=5 "$@" +} + +create_netns_link () { + mkdir -p /var/run/netns + if [ ! -e /var/run/netns/"$PID" ]; then + ln -s /proc/"$PID"/ns/net /var/run/netns/"$PID" + NETNS_LINK="true" + fi +} + +delete_netns_link () { + if [ "$NETNS_LINK" = "true" ]; then + rm -f /var/run/netns/"$PID" + fi +} + +add_port () { + BRIDGE="$1" + INTERFACE="$2" + CONTAINER="$3" + ADDRESS="$4" + + if [ "$#" -lt 3 ]; then + usage + exit 1 + fi + + if (ovs_vsctl --may-exist add-br "$BRIDGE"); then :; else + echo "Failed to create bridge $BRIDGE" + exit 1 + fi + + if PID=`docker inspect -f '{{.State.Pid}}' "$CONTAINER"`; then :; else + echo "Failed to get the PID of the container" + exit 1 + fi + + create_netns_link + + # Create a veth pair. + PORTNAME="${CONTAINER:0:8}${INTERFACE:0:5}" + ip link add "${PORTNAME}_l" type veth peer name "${PORTNAME}_c" + + # Add one end of veth to OVS bridge. + if (ovs_vsctl --may-exist add-port "$BRIDGE" "${PORTNAME}_l" \ + -- set interface "${PORTNAME}_l" \ + external_ids:container_id="$CONTAINER" \ + external_ids:container_iface="$INTERFACE"); then :; else + echo "Failed to add "${PORTNAME}_l" port to bridge $BRIDGE" + ip link delete "${PORTNAME}_l" + delete_netns_link + exit 1 + fi + + ip link set "${PORTNAME}_l" up + + # Move "${PORTNAME}_c" inside the container and changes its name. + ip link set "${PORTNAME}_c" netns $PID + ip netns exec "$PID" ip link set dev "${PORTNAME}_c" name "${INTERFACE}" + ip netns exec "$PID" ip link set "${INTERFACE}" up + + if [ -n "$ADDRESS" ]; then + ip netns exec $PID ip addr add "$ADDRESS" dev "${INTERFACE}" + fi + + delete_netns_link +} + +del_port () { + BRIDGE="$1" + INTERFACE="$2" + CONTAINER="$3" + + if [ "$#" -lt 3 ]; then + usage + exit 1 + fi + + PORT=`ovs_vsctl --columns=name find interface \ + external_ids:container_id="$CONTAINER" \ + external_ids:container_iface="$INTERFACE" \ + | awk -F '"' '{print $2}'` + if [ -z "$PORT" ]; then + echo "Failed to find any attached port in $BRIDGE" \ + "for CONTAINER=$CONTAINER and INTERFACE=$INTERFACE" + exit 1 + fi + + ovs_vsctl --if-exists del-port "$PORT" + + ip link delete "$PORT" +} + +del_ports () { + BRIDGE="$1" + CONTAINER="$2" + if [ "$#" -lt 2 ]; then + usage + exit 1 + fi + + PORTS=`ovs_vsctl --columns=name find interface \ + external_ids:container_id="$CONTAINER" | awk -F '"' '{print $2}'` + if [ -z "$PORTS" ]; then + exit 0 + fi + + for PORT in $PORTS; do + ovs_vsctl --if-exists del-port "$PORT" + ip link delete "$PORT" + done +} + +usage() { + UTIL=$(basename $0) + cat << EOF +${UTIL}: Performs integration of Open vSwitch with Docker. +usage: ${UTIL} COMMAND + +Commands: + add-port BRIDGE INTERFACE CONTAINER [ADDRESS] + Adds INTERFACE inside CONTAINER and connects it as a port + in Open vSwitch BRIDGE. Optionally, sets ADDRESS on + INTERFACE. ADDRESS can include a '/' to represent network + prefix length. + ${UTIL} add-port br-int eth1 c474a0e2830e 192.168.1.2/24 + del-port BRIDGE INTERFACE CONTAINER + Deletes INTERFACE inside CONTAINER and removes its + connection to Open vSwitch BRIDGE. e.g: + ${UTIL} del-port br-int eth1 c474a0e2830e + del-ports BRIDGE CONTAINER + Removes all Open vSwitch interfaces from CONTAINER. e.g: + ${UTIL} del-ports br-int c474a0e2830e +Options: + -h, --help display this help message. +EOF +} + +if [ $# -eq 0 ]; then + usage + exit 0 +fi + +while [ $# -ne 0 ] +do + case $1 in + "add-port") + shift + add_port "$@" + exit 0 + ;; + "del-port") + shift + del_port "$@" + exit 0 + ;; + "del-ports") + shift + del_ports "$@" + exit 0 + ;; + -h | --help) + usage + exit 0 + ;; + *) + echo >&2 "$0: unknown command \"$1\" (use --help for help)" + exit 1 + ;; + esac +done -- 1.9.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev