Ryu is an OpenFlow Controller, written in Python. Amongst other users it has been adopted for use in OpenStack.
Ryu can be installed with pip (pip install ryu
) or directly from the
GitHub source, but either of those
installation methods will result in downloading quite a few Python
dependencies from the network at install time.
Since I prefer to install applications and dependencies from operating
system packages where possible (to benefit from the operating system
security maintenance; an approach that François Marier also
adopts,
and others call "DebOps"),
I wanted to install as many of Ryu's dependencies from the operating
system packages as possible. This blog post lists the dependencies
that can be installed from Ubuntu 14.04 LTS (eg, into the Mininet
test
VM).
It also shows how a way to build Ryu itself into .deb
packages
to be installed . (A similar approach is possible with earlier
Ubuntu releases, but more and more packages have to be backported.)
Ryu has a new release approximately every month, and the number of dependencies -- and the minimum version of those dependencies required -- gradually increases. This was last tested with Ryu 3.12, released near the start of August 2014. However something similar to these instructions should work for later versions.
OS packaged Ryu Python dependencies
The versions packaged in Ubuntu 14.04 LTS of these packages are suitable for use with Ryu:
sudo apt-get install python-pbr python-py python-six python-oslo.config \
python-eventlet python-lxml python-netaddr python-paramiko \
python-routes python-webob python-sphinx python-pip
(In theory python-pip shouldn't be needed, because we are providing all the
Python dependencies outside of PIP, but the Ryu package setup wants to use
PIP to check, and so it depends on python-pip
-- hence we install it.)
python-msgpack 0.4
Ryu uses python-msgpack
,
which is a Python API to use the msgpack
binary
protocol (sort of a binary JSON).
The version of python-msgpack
required by Ryu (0.4.x) is newer
than the one packaged in even Ubuntu 14.04 LTS (0.3.0), so it needs
to be installed separately. To maintain the Debian dependencies a
new Debian package is built from the msgpack-python
source, using
the Debian-style package name (python-msgpack
) adopted by later
versions of Ubuntu. This allows reverting to an operating system
provided package later if a later version becomes available.
python-msgpack
0.4.2 was the current release at the time of writing
so that is what is described as built and installed below; in theory
these instructions should work for any reasonably similar version with
just the substitution of the version number and expected MD5 checksum.
Building the package needs the python-stdeb
helper, suitable compiler
and packaging tools, as well as python-all-dev
because the stdeb
created package source wants to build for all supported Python
versions:
sudo apt-get install build-essential python-stdeb python-all-dev
Once those are installed, we can build our own python-msgpack
0.4.2 package
with:
cd /usr/local/src
sudo mkdir python-msgpack
sudo chown ${USER}:${USER} python-msgpack
cd python-msgpack
wget -O msgpack-python_0.4.2.orig.tar.gz \
https://pypi.python.org/packages/source/m/msgpack-python/msgpack-python-0.4.2.tar.gz
echo 'e3a0fdfd864c72c958bb501d39b39caf msgpack-python_0.4.2.orig.tar.gz' |
md5sum -c
tar -xzf msgpack-python_0.4.2.orig.tar.gz
cd msgpack-python-0.4.2
python setup.py --command-packages=stdeb.command debianize
perl -pn -i -e 's/^(Package: python-msgpack).*$/$1/;' debian/control
dpkg-buildpackage
And then install it with:
cd /usr/local/src/python-msgpack
sudo dpkg --install python-msgpack_0.4.2-*.deb
Note that we need to fix up the package name generated by default
(python-msgpack-python
) before building, because msgpack-python
conflicts with the expected Debian/Ubuntu package names, and Debian/Ubuntu
eventually settled on forcing the name to python-msgpack
, so we do the
same thing.
The md5sum
check is against a copy of the MD5 checksum provided
by the PyPi listing,
which unfortunately is not as easily automated (because the "show
md5" action appears to require already knowing the MD5 checksum...).
Use of a configuration automation tool like
Salt that automates verification against
manually stored md5sum
s is recommended.
In older versions of Ubuntu it was also necessary to explicitly exclude
the msgpack_python.egg-info
directory from the diff or ensure that it
got cleaned up before the diff, otherwise the package built would fail. Eg,
cd /usr/local/src/python-msgpack/msgpack-python-0.4.2
echo 'msgpack_python.egg-info/*' | tee debian/clean
or:
cd /usr/local/src/python-msgpack/msgpack-python-0.4.2
echo 'extend-diff-ignore="^[^/]+\.egg-info/"' | tee debian/source/options
but the packaging tools in Ubuntu 14.04 LTS automatically generate that second ignore line so we do not have to do it manually any longer.
TinyRPC
Ryu also needs tinyrpc
, a
very thin RPC wrapper around a variety of transports. This is not
packaged at all in Ubuntu 14.04 LTS, so we need to build it from
source like the above.
tinyrpc
0.5 was the latest version at the time of writing so that
is what has been built and installed.
Assuming the same Python package build helpers are installed as above:
sudo apt-get install build-essential python-stdeb python-all-dev
it can be built with:
cd /usr/local/src
sudo mkdir tinyrpc
sudo chown ${USER}:${USER} tinyrpc
cd tinyrpc
wget -O tinyrpc_0.5.orig.tar.gz \
https://pypi.python.org/packages/source/t/tinyrpc/tinyrpc-0.5.tar.gz
echo '4bb9ed559bcccc4bf91a7843da781d28 tinyrpc_0.5.orig.tar.gz' |
md5sum -c
tar -xzf tinyrpc_0.5.orig.tar.gz
cd tinyrpc-0.5
python setup.py --command-packages=stdeb.command debianize
dpkg-buildpackage
and then installed with:
cd /usr/local/src/tinyrpc
sudo dpkg --install python-tinyrpc_0.5-1_all.deb
Ryu 3.12
At the time of writing Ryu 3.12 was the latest tagged release. New releases are made approximately every month at present. These instructions should work for newer releases with a change of version number, give or take changes in the dependencies required.
This release is built by using git to download the source, building a source distribution from that, and then building that source. This approach allows for quicker updates to later versions (since git can just download the source changes). The source distribution is built off a specific tag to ensure that it is reproducible; this results in a git "detached HEAD" state, but because we are only building a source distribution from it -- and not making any changes -- this does not cause any practical problem.
Using git requires:
sudo apt-get install git
then we can download and build with:
RYU_VERSION=3.12
cd /usr/local/src
sudo mkdir ryu
sudo chown ${USER}:${USER} ryu
cd ryu
git clone https://github.com/osrg/ryu.git ryu-github --branch=v${RYU_VERSION}
cd ryu-github
python setup.py sdist
mv dist/ryu-${RYU_VERSION}.tar.gz ../ryu_${RYU_VERSION}.orig.tar.gz
rm -f ChangeLog AUTHORS # Remove "sdist" generated files
cd ..
tar -xzf ryu_${RYU_VERSION}.orig.tar.gz
cd ryu-${RYU_VERSION}
mv debian/changelog debian/changelog-3.10
(MYNAME="$(getent passwd ${USER} | cut -f 5 -d : | cut -f 1 -d ,)";
DOMAIN="${DOMAIN:-$(hostname --fqdn)}";
NOW="$(date '+%a, %d %b %Y %H:%M:%S %z')";
echo "ryu (${RYU_VERSION}-1) trusty; urgency=low";
echo ""
echo " * Manually built Ryu ${RYU_VERSION} package"
echo ""
echo " -- ${MYNAME} <${USER}@${DOMAIN}> ${NOW}"
echo "") | tee debian/changelog
cat debian/changelog-3.10 | tee -a debian/changelog
rm debian/changelog-3.10
dpkg-buildpackage
Apparently with Ryu 3.10, Ryu started trying to include a debian
directory in their source distribution, so the python-stdeb
step
is not required. Unfortunately it appears not to have been updated
since Ryu 3.10 so building later versions without making changes
fails due to the missing source file version -- hence the need to
edit debian/changelog
to match the correct version. (It is
surprisingly difficult to generate a correctly formatted Debian changelog
entry by hand, and yet more difficult to prepend it to the file, in
order to ensure that it is seen as the latest version.)
Once built the package can be installed with:
cd /usr/local/src/ryu
sudo dpkg --install python-ryu_${RYU_VERSION}*deb ryu-bin_${RYU_VERSION}*deb
Optionally the generated (HTML) documentation can also be installed:
cd /usr/local/src/ryu
sudo dpkg --install python-ryu-doc_${RYU_VERSION}*deb
Once installed, a couple of trivial tests can be run to ensure that Ryu can be found:
ryu-manager --version
ryu-manager --help
Actually using Ryu, especially with Mininet, is beyond the scope of this blog post. However Ryu do provide an entire book in a variety of formats, including online in HTML. That book is a good introduction to Ryu, OpenFlow and Software Defined Networking. It also provides Mininet example networks to go with several of the examples shown.