Uncle Deadly Image

Hi there. Welcome to blog.oddbit.com! I post articles here on a variety of technical topics. Mostly I’m posting for myself (writing things up helps me remember them in the future), but I always hope the content I put here is helpful to someone else. If you find something here useful and want to say thanks, feel free to buy me a coffee!

A unified CLI for OpenStack

The python-openstackclient project, by Dean Troyer and others, is a new command line tool to replace the existing command line clients (including commands such as nova, keystone, cinder, etc).

This tool solves two problems I’ve encountered in the past:

  • Command line options between different command line clients are sometimes inconsistent.

  • The output from the legacy command line tools is not designed to be machine parse-able (and yet people do it anyway).

The new openstack CLI framework is implement using the cliff module for Python, which will help enforce a consistent interface to the various subcommands (because common options can be shared, and just having everything in the same codebase will help tremendously). Cliff also provides flexible table formatters. It includes a number of useful formatters out of the box, and can be extended via setuptools entry points.

[read more]

Automatic maintenance of tag feeds

I recently added some scripts to automatically generate tag feeds for my blog when pushing new content. I’m using GitHub Pages to publish everything, so it seemed easiest to make tag generation part of a pre-push hook (new in Git 1.8.2). This hook is run automatically as part of the git push operation, so it’s the perfect place to insert generated content that must be kept in sync with posts on the blog.

[read more]

Enabled blog comments

I’ve enabled blog comments using Disqus. This is something of an experiment, since (a) I’m not really happy with how Disqus is handling user registration these days and (b) I don’t know that I have the time to moderate anything. But we’ll see.

[read more]

json-tools: cli for generating and filtering json

Interacting with JSON-based APIs from the command line can be difficult, and OpenStack is filled with REST APIs that consume or produce JSON. I’ve just put pair of tools for generating and filtering JSON on the command line, called collectively json-tools.

Both make use of the Python dpath module to populate or filter JSON objects.

The jsong command generates JSON on stdout. You provide /-delimited paths on the command line to represent the JSON structure. For example, if you run:

[read more]

Quantum in Too Much Detail

I originally posted this article on the RDO website.

The players

This document describes the architecture that results from a particular OpenStack configuration, specifically:

  • Quantum networking using GRE tunnels;
  • A dedicated network controller;
  • A single instance running on a compute host

Much of the document will be relevant to other configurations, but details will vary based on your choice of layer 2 connectivity, number of running instances, and so forth.

[read more]

Moving to GitHub

This blog has been hosted on scriptogram for the past year or so. Unfortunately, while I like the publish-via-Dropbox mechanism, there have been enough problems recently that I’ve finally switched over to using GitHub Pages for hosting. I’ve been thinking about doing this for a while, but the things that finally pushed me to make the change were:

  • Sync problems that would prevent new posts from appearing (and that at least once caused posts to disappear).
  • Lack of any response to bug reports by the site maintainers.

A benefit of the publish-via-Dropbox mechanism is, of course, that I already had all the data and didn’t need to go through any sort of export process.

[read more]

A random collection of OpenStack Tools

I’ve been working with OpenStack a lot recently, and I’ve ended up with a small collection of utilities that make my life easier. On the odd chance that they’ll make your life easier, too, I thought I’d hilight them here.

Crux

Crux is a tool for provisioning tenants, users, and roles in keystone. Instead of a sequence of keystone command, you can provision new tenants, users, and roles with a single comand.

[read more]

Why does the Neutron documentation recommend three interfaces?

The documentation for configuring Neutron recommends that a network controller has three physical interfaces:

Before you start, set up a machine to be a dedicated network node. Dedicated network nodes should have the following NICs: the management NIC (called MGMT_INTERFACE), the data NIC (called DATA_INTERFACE), and the external NIC (called EXTERNAL_INTERFACE).

People occasionally ask, “why three interfaces? What if I only have two?”, so I wanted to provide an extended answer that might help people understand what the interfaces are for and what trade-offs are involved in using fewer interfaces.

[read more]

Automatic hostname entries for libvirt domains

Have you ever wished that you could use libvirt domain names as hostnames? So that you could do something like this:

$ virt-install -n anewhost ...
$ ssh clouduser@anewhost

Since this is something that would certainly make my life convenient, I put together a small script called virt-hosts that makes this possible. You can find virt-hosts in my virt-utils GitHub repository:

Run by itself, with no options, virt-hosts will scan through your running domains for interfaces on the libvirt default network, look up those MAC addresses up in the corresponding default.leases file, and then generate a hosts file on stdout like this:

[read more]

Interrupts on the PiFace

I recently acquired both a Raspberry Pi and a PiFace IO board. I had a rough time finding examples of how to read the input ports via interrupts (rather than periodically polling for values), especially for the newer versions of the PiFace python libraries.

After a little research, here’s some simple code that will print out pin names as you press the input buttons. Button 3 will cause the code to exit:

#!/usr/bin/python

import pifacecommon.core
import pifacecommon.interrupts
import os
import time

quit = False

def print_flag(event):
    print 'You pressed button', event.pin_num, '.'

def stop_listening(event):
    global quit
    quit = True

pifacecommon.core.init()

# GPIOB is the input ports, including the four buttons.
port = pifacecommon.core.GPIOB

listener = pifacecommon.interrupts.PortEventListener(port)

# set up listeners for all buttons
listener.register(0, pifacecommon.interrupts.IODIR_ON, print_flag)
listener.register(1, pifacecommon.interrupts.IODIR_ON, print_flag)
listener.register(2, pifacecommon.interrupts.IODIR_ON, print_flag)
listener.register(3, pifacecommon.interrupts.IODIR_ON, stop_listening)

# Start listening for events.  This spawns a new thread.
listener.activate()

# Hang around until someone presses button 3.
while not quit:
    time.sleep(1)

print 'you pressed button 3 (quitting)'
listener.deactivate()
[read more]