Adding support for an unsupported power controller in Emulab

As a continuation of sorts to my previous post, I thought I would also do a short description of adding support for an unsupported power controller. The IBM Bladecenter is more or less unsupported by Emulab in all respects, the switches and the integrated power controller are unsupported and even the blade servers grudgingly resist running any vanilla FreeBSD images that come with the Emulab source.

Note: This set of steps is very similar to my post about adding switch support

Create a new case

Add a case to /usr/testbed/bin/power to include a new power type, I'll use "mynewpower" in this example. Edit this file and include the perl module you will be putting your code in by adding this to the top:
use power_mynewpower;   ##Assuming your module is called power_mynewpower.pm
Somewhere around line 332 you'll find the beginning of the IF you'll need to add your case to:
#

# Finally, we look at the controller type and construct the proper type

# of object

#

my $errors = 0;
if ($type eq "APC") {
my $device = new snmpit_apc($IP,$verbose);
if (!defined $device) {
    warn "Unable to contact controller for $nodestr. Skipping...\n";
    next;
} else {
    print "Calling device-<power($op,@outlets)\n"
	if $verbose > 1;
    if ($device-<power($op,@outlets)) {
	print "Control of $nodestr failed.\n";
	$errors++;
    }
}
} elsif ($type =~ "RPC") {
if (rpc27ctrl($op,$power_id,@outlets)) {
    print "Control of $nodestr failed.\n"; $exitval++;
}
} elsif (($class eq "sg") || ($type eq "garcia")) {
# XXX: 'garcia' is temporary until stargates are subnodes of

# garcias

if (sgmotectrl($op,@nodes)) {
    print "Control of $nodestr failed.\n"; $exitval++;
    $errors++;
}
} elsif ($type =~ /whol-(\w+)/) {
my $iface = $1;
if (wholctrl($op,$iface,@nodes)) {
    print "Control of $nodestr failed.\n"; $exitval++;
    $errors++;
}
} elsif ($type =~ /rmcp-(\w+)/) {
if (rmcpctrl($1,$op,@nodes)) {
    print "Control of $nodestr failed.\n"; ++$exitval;
    ++$errors;
}
} elsif ($type eq 'ilo2' || $type eq 'ilo') {
if (iloctrl($type,$op,@nodes)) {
    print "Control of $nodestr failed.\n"; ++$exitval;
        ++$errors;
    }
} elsif ($type eq "mail") {
if (mailctrl($op,@nodes)) {
    print "Control of $nodestr failed.\n"; $exitval++;
    $errors++;
}
$sendevent = 0; # power_mail sends this itself.

#------------------------------------------------------------------------

# This calls mynewpower_nodectrl() inside power_mynewpower.pm when

# it encounters our new power type

#------------------------------------------------------------------------

} elsif ($type eq "mynewpower") {
   if (mynewpower_nodectrl($1,$op,@nodes)) {
	print "Control of $nodestr failed.\n"; $exitval++;
	$errors++;
   }
}
#------------------------------------------------------------------------

else {
print "power: Unknown power type '$type'\n";
$errors++;
}

Implement the code

Now just create a perl package power_mynewpower.pm and implement the mynewpower_nodectrl($type,$cmd,@nodes) subroutine.  As far as I can tell, the $cmd value that is most important for experimental nodes is the "cycle" command. Here is a sample file:
#!/usr/bin/perl -wT

#


package power_mynewpower;

use Exporter;
@ISA = ("Exporter");
@EXPORT = qw( mynewpower_nodectrl );

use lib "/usr/testbed/lib";
use libdb;

sub mynewpower_nodectrl($$@) {
    my ($type,$cmd,@nodes) = @_;
    my $exitval = 0;
    print "mynewpower_nodectrl called with $type,$cmd,(" . join(',',@nodes) . ")\n";

    if($cmd eq "cycle"){
        ##Do something here

    }
    return $exitval;	
}
In our case, this routine executes a bash script which logs in and reboots the specified node from the bladecenter.

Add the type to the database

Add a new row into the 'node_types' table:
class type
power mynewpower
Now just follow the instructions on the Emulab Wiki for adding nodes that use the power type. Emulab will automatically find your implemented perl module and run the specified subroutine when it attempts to perform a power operation on a node which has a "mynewpower" power manager. You should be good to go! Feedback is very welcome.