Burst.NET Windows VPS && SolusVM API

Fri 23 September 2011
By mute

Burst.NET will give you any sort of Windows server VPS on Xen-HVM for under $8 in Miami. I got one because a friend had a Linux VPS and couldn't install modules. I said, that's because they use OpenVZ. Of course, with a Windows VPS they must use full virtualization. So I installed GRUB in boot.ini and tried to install linux in there... It didn't work out so well with my usual Debian. PV-on-HVM driver never showed ethernet correctly. :( A different kernel unaware of the VM would have worked. The problem was probably due to version differences in the PV drivers, I don't recall..

FreeBSD worked fine, of course, since it didn't try to use PV drivers, it just used the virtual hardware like it was real.. There is a performance hit, but whatever.

So I tried to put Windows 2008 R2 32-bit on there and it wasn't working out. Thought I killed the node and for some reason the VPS control panel stopped responding... Oddly, only to Chrome. So while I was poking around in the VPS control panel in Firefox I activated the API. It allows you to check status and do boot/reboot/shutdown.

So I found SolusVM Client API wiki page and tried it out. Turns out that the sample doesn't work. It uses POST. GET method worked out. I edited the script and quickly made this to show a nice status output:

[mute@geek ~/burst]$ ./status
Virtual Machine: burst.scottn.us
 Main interface:

 Harddisk Usage: 0 B of 20 GB (0%)
   Memory Usage: 0 B of 0 B (0%)
Bandwidth Usage: 835.96 MB of 1000 GB (0%)

         Status: ONLINE

Read full story to see source below:

#!/usr/bin/php-cgi -q

// Specify the key, hash and action

$postfields["key"] = "xxxxx-xxxxx-xxxxx";
$postfields["hash"] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

$postfields["action"] = "status"; // reboot, shutdown, boot, status
$postfields["ipaddr"] = "true";
$postfields["hdd"] = "true";
$postfields["mem"] = "true";
$postfields["bw"] = "true";

// Url to the client API

$url = "";

// Send the query to the solusvm master

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url . "?"
            . http_build_query($postfields));
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);

// Parse the returned data and build an array
preg_match_all('/<(.*?)>([^<]+)<\/\\1>/i', $data, $match);
$result = array();
foreach ($match[1] as $x => $y)
        $result[$y] = $match[2][$x];

// TODO: Error checking ...
// Do something useful with it.

$hdd = explode(",", $result["hdd"]);
$mem = explode(",", $result["mem"]);
$bw  = explode(",", $result["bw"]);

printf("Virtual Machine: %s\n", $result["hostname"]);
printf(" Main interface: %s\n", $result["ipaddress"]);
printf("            IPs: %s\n\n",
        str_replace(",", "\n                 ", $result["ipaddr"]));

printf(" Harddisk Usage: %s of %s (%d%%)\n", formatSize($hdd[1]),
       formatSize($hdd[0]), $hdd[3]);
printf("   Memory Usage: %s of %s (%d%%)\n", formatSize($mem[1]),
       formatSize($mem[0]), $mem[3]);
printf("Bandwidth Usage: %s of %s (%d%%)\n\n", formatSize($bw[1]),
       formatSize($bw[0]), $bw[3]);
printf("         Status: %s\n", strtoupper($result["statusmsg"]));

function formatSize($size)
        $units = array(' B', ' KB', ' MB', ' GB', ' TB');
        for ($i = 0; $size > 1024; $i++) { $size /= 1024; }
        return round($size, 2).$units[$i];