cube-vrf: Introduce the cube-vrf container

Move the OpenVSwitch 'br-int' bridge from -essential to a new
container (cube-vrf) along with updates to the network hooks to push
the container veth ends that would have previously existed in
-essential into the new cube-vrf container.

These changes go along with changes to the install scripts which
establish cube-vrf as a pflask container which will be run at startup
via the essential-autostart.service. Since 'c' in 'cube-vrf' comes
before 'd' in 'dom0' the cube-vrf container will be the first to start
at bootup. This ensures that 'dom0' veth interface will be able to be
moved into the cube-vrf container.

With these changes applied the system will look much as it did before,
with the following changes:
 * br-int in -essential will only have the br-int port and IP
 * the cube-vrf will be listed in machinectl and c3
 * the cube-vrf hosts a new br-int OVS bridge where all
   container veth interfaces are now attached

Signed-off-by: Mark Asselstine <mark.asselstine@windriver.com>
Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
This commit is contained in:
Mark Asselstine
2018-04-25 16:43:07 -04:00
committed by Bruce Ashfield
parent 4f2b8bacc9
commit ad749f0c06
7 changed files with 144 additions and 9 deletions

View File

@@ -0,0 +1,22 @@
SUMMARY = "System Virtual Routing & Forwarding (VRF) container"
DESCRIPTION = "In an effort to keep cube-essential small while \
ensuring cube-dom0 remains focused on container management system \
routing functions are managed by this container."
HOMEPAGE = "http://www.windriver.com"
require recipes-core/images/c3-app-container.inc
IMAGE_INSTALL += " \
openvswitch \
iproute2 \
vrf-init \
bash \
"
ROOTFS_POSTPROCESS_COMMAND += "create_cube_mount_dirs; "
create_cube_mount_dirs () {
mkdir -p ${IMAGE_ROOTFS}/opt/container
mkdir -p ${IMAGE_ROOTFS}/var/lib/cube
}

View File

@@ -50,6 +50,36 @@ interface_exists() {
return 0
}
# Get the cube-vrf 'init' PID
get_cube_vrf_pid() {
cube_vrf_ppid=$(ps -ef|grep "pflask.*cube-vrf"|grep -v grep|awk '{print $2}')
echo $(ps -ef|grep -E "[0-9]+\ +${cube_vrf_ppid}\ +"|grep -v grep|awk '{print $2}')
}
#
# Useful for containers with no interfaces but which still have
# a netns created which we want to access with 'ip netns'
#
# Create the netns link in /var/run/netns
#
if [ "${action}" = "nslinkup" ]; then
cname=$(echo ${cubename} | cut -c1-13)
# create the netns symlink
mkdir -p /var/run/netns
ln -sfT /proc/${pid}/ns/net /var/run/netns/${cname}
exit 0
fi
#
# Delete the link from /var/run/netns
#
if [ "${action}" = "nslinkdown" ]; then
cname=$(echo ${cubename} | cut -c1-13)
# cleans up the netns symlink
ip netns delete ${cname} 2> /dev/null
exit 0
fi
if [ "${action}" = "down" ]; then
if [ -f .cube.veth ]; then
veth_name=$(cat .cube.veth)
@@ -147,21 +177,26 @@ if [ "${action}" = "up" ]; then
nsenter -t ${pid} -m sh -c "echo \"${nm_unmanaged}\" >> /etc/NetworkManager/NetworkManager.conf"
fi
fi
#
# Add the veth that stays in essential to the ovs-bridge. This gets us
# connectivity to the network prime, and hence the outside world
ovs-vsctl --may-exist add-port br-int ${veth_name}
#
cube_vrf_pid=$(get_cube_vrf_pid)
# push the container veth endpoint into the container network namespace
# NOTE: also done by pflask
if [ -n "${pflask}" ]; then
# if we are pflask, rename the veth to the one we generated above
ip link set ${veth_pflask} name ${veth_name}
ip link set ${veth_name} up
ip link set ${veth_name} netns cube-vrf
nsenter -t ${cube_vrf_pid} -m -n -p -u /usr/bin/vrf-iface-add ${veth_name}
nsenter -t ${pid} -n ip link set ${veth_pflask} name ${veth_name}
else
# if we are NOT pflask, then we have to push the veth into the namespace
# and then rename it.
ip link set ${veth_name} netns cube-vrf
nsenter -t ${cube_vrf_pid} -m -n -p -u /usr/bin/vrf-iface-add ${veth_name}
ip link set veth-br-int netns ${pid}
nsenter -t ${pid} -n ip link set veth-br-int name ${veth_name}
fi
@@ -336,12 +371,8 @@ if [ "${action}" = "up" ]; then
fi
if [ "${action}" = "down" ]; then
ovs-vsctl --if-exists del-port br-int ${veth_name}
interface_exists ${veth_name}
if [ $? -eq 1 ]; then
ip link del dev ${veth_name}
fi
cube_vrf_pid=$(get_cube_vrf_pid)
nsenter -t ${cube_vrf_pid} -m -n -p -u /usr/bin/vrf-iface-del ${veth_name}
cname=$(basename ${cubedir})

View File

@@ -995,6 +995,11 @@ convert_base_config_to_cube()
echo "${netdevs}" >> pflask.config
fi
# cube-vrf doesn't have any externally available interfaces but needs a netns
if [ "${container_name}" = "cube-vrf" ]; then
pflask_args="${pflask_args} --netif"
fi
# hooks ?
poststart_hooks=$(jq -r '.hooks.poststart' config.json)
if [ "${poststart_hooks}" != "null" ]; then

View File

@@ -0,0 +1,22 @@
#!/bin/bash
# Ensure br-int is up. This also acts as a synchronization
# point such that we don't end up in weird situations where
# we expect networking components to be up when they are
# still being initialized.
end=$((SECONDS+10))
while true; do
/usr/bin/ovs-vsctl show | grep -q "Bridge br-int"
if [ $? -eq 0 ] || [ $SECONDS -gt $end ]; then
break
fi
done
if [ $SECONDS -gt $end ]; then
exit 1
fi
/usr/bin/ovs-vsctl --may-exist add-port br-int $1
/sbin/ip link set $1 up

View File

@@ -0,0 +1,7 @@
#!/bin/bash
/sbin/ip link set $1 down >/dev/null 2>&1
/usr/bin/ovs-vsctl --if-exists del-port br-int $1
/sbin/ip link del dev $1 >/dev/null 2>&1

View File

@@ -0,0 +1,20 @@
#!/bin/bash
# Ensure we have some prerequisites in place
mkdir -p /var/run/openvswitch
# Start the db daemon
/usr/share/openvswitch/scripts/ovs-ctl \
--no-ovs-vswitchd --no-monitor --system-id=random \
start
# Start the vswitch daemon
/usr/share/openvswitch/scripts/ovs-ctl \
--no-ovsdb-server --no-monitor --system-id=random \
start
# Create the br-int bridge
/usr/bin/ovs-vsctl add-br br-int
# We can't exit else the container will be destroyed
sleep infinity

View File

@@ -0,0 +1,28 @@
SUMMARY = "cube-vrf / minimal initialization service"
DESCRIPTION = "A tool for the initial cube-vrf setup"
LICENSE = "GPLv2"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6"
RDEPENDS_${PN} = "bash"
SRC_URI = " \
file://vrf-init \
file://vrf-iface-add \
file://vrf-iface-del \
"
do_install() {
install -d ${D}/sbin
install -m 0755 ${WORKDIR}/vrf-init ${D}/sbin/init
install -d ${D}/${prefix}
install -d ${D}/${bindir}
install -m 0755 ${WORKDIR}/vrf-iface-add ${D}/${bindir}/
install -m 0755 ${WORKDIR}/vrf-iface-del ${D}/${bindir}/
}
FILES_${PN} += " \
${sbin} \
${bindir} \
"