Sunday, March 30, 2014

Adding hardware support to MAAS

MAAS and power

MAAS, or Metal as a Service, is a tool for treating physical servers similarly to cloud resources.  It lets you take a pile of hardware and assign workloads to it without worrying about all the support infrastructure underneath.  In effect, you can plug a bunch of systems into a network and have a Hadoop or OpenStack cluster up, running, and properly configured inside of half an hour.  It's really cool stuff.

But MAAS is targeted at enterprise-level hardware.  It expects things like IPMI to be available to control the hardware at a basic level.  (If your tool is going to be installing an operating system onto a computer, it needs to be able to control that computer at a level below the OS.)  I have a stack of older desktops sitting around gathering dust that I wanted to use as a cluster for experimenting at home.  They still function quite well, but being desktops they don't have enterprise features like IPMI.

Fortunately most desktop BIOSes have a setting to control what they do after a power outage.  Crucially, they can be set to turn the system on when electrical power is restored, regardless of whether the system was on or off when power was lost.  This means I could use an externally controlled power switch in place of IPMI to allow MAAS to power my desktops on and off.

Power on after power failure.  (Helpfully hidden under a random submenu in the BIOS rather than under the 'POWER SETTINGS' heading.)


I used the Web Power Switch 7 from Digital Loggers for this project.  (Warning: almost every page on their site has autoplaying audio and/or video.  Ugh.)  I'll be completely honest here -- price was the reason I chose this switch.  It allows control of up to 8 outlets and cost me just under $140 from Amazon.

My shiny new power switch.  (What do you mean, your datacenter doesn't have an oriental rug?)

Power templates


There are a few bits of MAAS that I had to touch to fully enable support for my DLI switch.  The first and most obvious was creating a power control template to tell MAAS how to talk to the switch.

When MAAS is installed, the templates that tell it how to talk to power management systems are put in /etc/maas/templates/power.  These are shell scripts with a bit of Python evaluation and substitution (surrounded by {{double braces}})that MAAS uses at runtime to build a command to control a specific system.  There are several examples to use there already, and these can be modified to suit your environment.  For example, the SeaMicro SM15000 hardware template looks like this:

# -*- mode: shell-script -*-
#
# Control a system via ipmipower, sending the seamicro specific hex codes
#
{{py: power_mode = 1 if power_change == 'on' else 6 }}

{{ipmitool}} -I lanplus \
    -H {{power_address}} -U {{power_user}} \
    -P {{power_pass}} raw 0x2E 1 0x00 0x7d 0xab \
    {{power_mode}} 0 {{system_id}}

I started by simply replacing one of these templates with my own code.  Because the DLI Web Power Switch can be controlled via HTTP, I just needed to build a GET request for the outlet I wanted to control and send it to the switch, like this:

#!/bin/sh
# -*- mode: shell-script -*-
#
# Control a system via the Digital Loggers, Inc. RESTful interface
#
{{py: power_mode = 'ON' if power_change == 'on' else 'OFF' }}

wget --auth-no-challenge -O /dev/null \
    http://{{power_user}}:{{power_pass}}@{{power_address}}/outlet?{{system_id}}={{power_mode}}

Once I had this template replacing the original sm15k template, I was able to control my switch by telling MAAS I had SeaMicro hardware.  Success!

Better integration


I could have stopped there with a working system.  But it bothered me a bit to lie to MAAS about my hardware.  And what if someday I or someone else wanted to mix the DLI switch with actual SeaMicro hardware?  Replacing the sm15k template with my DLI template wouldn't work then.

It turns out that there are two places in the MAAS code that need to be modified to make it aware of a new power switch.  In the MAAS source, these are src/maasserver/power_parameters.py and src/provisioningserver/enum.pypower_parameters.py is where the real definition of a new power switch is; enum.py just needs an entry in two lists to make the UI show the switch as an option.  (There's a comment in enum.py to the effect that adding the switch name in it will not be necessary at some point in the future, but at least as of March 2014 it still is.)

The code needed to add a power switch is straightforward.  Provide the variables the switch will need to operate a system (e.g. outlet number, IP address of the switch, credentials, etc.) and give them names that can be referenced in the power template later.

Success!


The code I added can be seen in Launchpad (click "expand all" to see the diffs).

Once I added the code there, I was able to rebuild MAAS and see my new switch as an option.  It all works, and now my old desktops have new life!