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 md5sums 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.