Our neutron plugin quark accepts many drivers and will use however many that are configured at the same time. Quark currently has no default working configuration in which it can be tested.

This setup will create a neutron server that really doesn’t do anything, but it will not require any other services to run! It also assumes that you have a mysql server configured. If you don’t want to use mysql you can change the sqlalchemy connection string in the neutron.conf provided at the end of the post.

Installing the Packages

First thing we need to do is download the code somewhere and install it. The things we really need to install are:

Create a directory somewhere. This will be where we install all the packages. We will be using virtualenv because we’re good python developers, aren’t we?

cd my_directory_of_choice
virtualenv --prompt='(quark)' .venv
source .venv/bin/activate

Your shell prompt should, at least if you’re using bash, have (quark) in front now.

The rest of this is pretty easy. Since we’re looking to develop quark/neutron we will need source and not packages.

git clone git@github.com:openstack/neutron && cd neutron && python setup.py develop
git clone git@github.com:rackerlabs/quark && cd quark && python setup.py develop

If you run pip freeze you should see some references to neutron and quark in there. There will most likely be a bunch of other packages installed that are dependencies for neutron or quark.

Configuration Details

Make a configuration directory. I call mine etc for giggles. See the full file at the end of this to copy-pasta.

My default testing configuration uses our unmanaged driver. This driver is essentially a noop driver and doesn’t require any extra software to be installed to use quark. Caveat: because it is noop you will have no connectivity if placed into an environment.

Put the following configuration into your neutron.conf (I usually put it at the bottom so the config grouping doesn’t get confused).

[QUARK]
net_driver=quark.drivers.unmanaged.UnmanagedDriver
default_network_type=UNMANAGED

  • set the core_plugin value in the neutron.conf to quark.plugin.Plugin.
  • setting the auth_strategy to noauth is very helpful especially if you are using wafflehaus.try_context to fake out DB connections

Creating the Database

You’ll need to setup a database (probably mysql). Then modify your neutron.conf with the appropriate connection string (see this). To create the initial quark database you need to run:

quark-db-manage --config-file <path-to>neutron.conf upgrade head

Creating the Default Network Artifacts

This resty call will create the mac address ranges for this simple setup:

POST /v2.0/mac_address_ranges.json -d '{"mac_address_range": {"cidr" : "AA:BB:CC", "tenant_id": "provider"}}'

And thisresty call will create the public network:

POST /v2.0/networks -d '{"network": {"id": "00000000-0000-0000-0000-000000000000", "tenant_id": "provider", "name": "public"}}'

Finally you will need to make this resty call to make a subnet.

POST /v2.0/subnets -d '{"subnet": {"network_id": "00000000-0000-0000-0000-000000000000", "segment_id": "blah", "cidr": "10.0.0.0/16", "tenant_id": "derp", "ip_version": "4"}}'

Isolated (tenant owned) networks are currently not supported in this configuration. A more operative driver is necessary. There is an NVP/NSX driver included with quark but it requires standing up a NVP/NSX Controller. Doing such a thing is well beyond the scope of this post.

Running Neutron

Then to run the neutron server locally you run the command (preferably in a virtualenv):

neutron-server --config-dir /home/jhammond/quark_server/etc

Usage and Initial Smoke Test

Some useful tidbits of information about how we’ve changed how things work in quark:

  • to support cells we had to add segment_id to subnets on provider networks
  • ports created on provider networks require a segment_id as well
  • during testing this value can be anything as long as they match

This script uses resty because I dislike curl. Note the segment id in the POST subnets and POST ports.

#!/bin/bash
endpoint="http://localhost:9696/v2.0"
tenant='random'
net_name='test_network'
source ~/bin/resty/resty -W $endpoint -H "Content-type: application/json"
net_id='00000000-0000-0000-0000-000000000000'

subnet=`POST /subnets -d '{"subnet": {"network_id": "'$net_id'", "tenant_id": "'$tenant'", "cidr": "192.168.7.1/24", "ip_version": 4, "segment_id":
"test"}}'`

subnet_id=`echo $subnet | python -c 'import sys, json; print json.load(sys.stdin)["subnet"]["id"]'`
echo "Made subnet $subnet_id"

port=`POST /ports -d '{"port": {"tenant_id": "'$tenant'", "name": "weeble", "network_id": "'$net_id'", "segment_id": "test", "fixed_ips": [{"ip_address":
"192.168.7.50", "subnet_id": "'$subnet_id'"}]}}'`

port_id=`echo $port | python -c 'import sys, json; print json.load(sys.stdin)["port"]["id"]'`
echo "Made port $port_id"

# CLEAN-UP
DELETE /ports/$port_id
DELETE /subnets/$subnet_id
GET /networks

My etc Contents

api-paste.ini
dhcp_agent.ini
fwaas_driver.ini
init.d/
l3_agent.ini
lbaas_agent.ini
metadata_agent.ini
metering_agent.ini
neutron/
neutron.conf
policy.json
rootwrap.conf
services.conf
vpn_agent.ini

Full neutron.conf

Fill out the database connection info. If you remove the database info completely sqlalchemy will attempt to connect to a mysql server with the following connection string:

mysql://root:password@127.0.0.1/neutron?charset=utf8

That may work for you, but you should probably change it.

[DEFAULT]
lock_path = $state_path/lock
core_plugin = quark.plugin.Plugin
auth_strategy = noauth
fake_rabbit = true
rpc_backend = fake

[DATABASE]
connection = mysql://db_user:db_password@127.0.0.1/neutron?charset=utf8
reconnect_interval = 5
auto_create_schema = False
min_pool_size = 100
max_pool_size = 500
max_overflow = 500

[QUARK]
net_driver=quark.drivers.unmanaged.UnmanagedDriver
default_net_strategy='{"00000000-0000-0000-0000-000000000000": {"bridge": "publicnet"}, "11111111-1111-1111-1111-111111111111": {"bridge": "servicenet"}}'
default_network_type=UNMANAGED
# IPAM recycling interval, in seconds
ipam_reuse_after= 300
ipam_retry=1
show_subnet_ip_policy_id = False
show_allocation_pools = True
pessimistic_connection_pooling = True
environment_capabilities = ""

Troubleshooting

TypeError: %d format: a number is required, not NoneType

This is caused by oslo_messaging and rpc functions I do not use. Ensure you have the config variable rpc_backend = fake. This will disable that feature.

Running the Quark Unit Tests

We use tox to run the unit tests. A gotcha with quark is that it has assumed configurations for local mysql DB testing (tox -e mysql). If your local DB doesn’t match these assumptions they will fail.

The following will allow those to work:

QUARK_MYSQL_TESTS_URL="mysql://user:password@localhost/quark_functional_tests" tox -e mysql

This will produce a lot of sqlalchemy output. I use this little snippet to keep the output to something sane:

QUARK_MYSQL_TESTS_URL=&quot;mysql://user:password@localhost/quark_functional_tests&quot; tox -e mysql 2&gt;&amp;1 &gt;/dev/null | grep -B 25 'end captured stdout'Getting OpenStack neutron+quark Working Locally