blog.jarpy.net

Techno-babble of a Techno-dabbler

AWS Auto Scaling with boto.

The boto library is awesome for Python people who want to automate Amazon Web Services, but I had a minor struggle with the Auto Scaling interface recently.

Amazon deprecated the old “triggers” mechanism for handling dynamic scaling, and replaced it with CloudWatch “alarms”. While boto supports the new mechanism, it’s hard to find working examples on-line.

UPDATE: This example is now improved and merged into the official boto documentation.

Below is my attempt to define the minimal procedure for creating a dynamically scaled cluster of instances with boto. It’s derived from the excellent work of Liam Friel.

import boto
from boto.ec2.autoscale import ScalingPolicy
from boto.ec2.cloudwatch import MetricAlarm

autoscale = boto.connect_autoscale()
cloudwatch = boto.connect_cloudwatch()

# Let's assume you already have an Auto Scaling group.
# Setting one up is well documented elsewhere.
autoscaling_group = 'as_group_0'

# Define some Scaling Policies. These tell Auto Scaling _how_ to scale
# group, but not when to do it. (We'll define that later).

# We need one policy for scaling up...
scale_up_policy = ScalingPolicy(
    name='scale_up', adjustment_type='ChangeInCapacity',
    as_name=autoscaling_group, scaling_adjustment=1, cooldown=180)

#...and one for scaling down again.
scale_down_policy = ScalingPolicy(
    name='scale_down', adjustment_type='ChangeInCapacity',
    as_name=autoscaling_group, scaling_adjustment=-1, cooldown=180)

# The policy objects are now defined locally.
# Let's submit them to AWS.
autoscale.create_scaling_policy(scale_up_policy)
autoscale.create_scaling_policy(scale_down_policy)

# Now that the polices have been digested by AWS, they have extra properties
# that we aren't aware of locally. We need to refresh them by requesting them
# back again. 
# Specifically we'll need the Amazon Resource Name (ARN) of each policy.
scale_up_policy = autoscale.get_all_policies(
    as_group=autoscaling_group, policy_names=['scale_up'])[0]

scale_down_policy = autoscale.get_all_policies(
    as_group=autoscaling_group, policy_names=['scale_down'])[0]

# Now we'll create CloudWatch alarms that will define _when_ to run the
# Auto Scaling policies.

# We want to measure the average CPU usage across the whole Auto Scaling
# group, rather than individual instances. We can define that as a CloudWatch
# "Dimension".
alarm_dimensions = {"AutoScalingGroupName": autoscaling_group}

# One alarm for when to scale up...
scale_up_alarm = MetricAlarm(
        name='scale_up_on_cpu', namespace='AWS/EC2',
        metric='CPUUtilization', statistic='Average',
        comparison='>', threshold='70',
        period='60', evaluation_periods=2,
        alarm_actions=[scale_up_policy.policy_arn],
        dimensions=alarm_dimensions)
cloudwatch.create_alarm(scale_up_alarm)

# ...and one for when to scale down.
scale_down_alarm = MetricAlarm(
        name='scale_down_on_cpu', namespace='AWS/EC2',
        metric='CPUUtilization', statistic='Average',
        comparison='<', threshold='40',
        period='60', evaluation_periods=2,
        alarm_actions=[scale_down_policy.policy_arn],
        dimensions=alarm_dimensions)
cloudwatch.create_alarm(scale_down_alarm)

PCBs – Designing for Hackability

This hack needs help.

Nice board, but it needs a hack

With a heart full of Geek Pride, I recently unwrapped my first commercially fabricated PCB. As a beginner designer, I missed something in the initial design and realised while I was waiting for the board to arrive. Essentially, the board was obsolete by the time it got to me. The new changes would need to be hacked into place on the board. Oh well, no problem…

Hostile Hardware

As soon as I started making modifications, something felt wrong. It felt like I was trying to hack a closed, commercial circuit. It was almost as though I was reverse engineering my own design, just to make a simple change.

Commercial designs are indifferent to hackers at best and are often deliberately hacker-hostile. This board is a prototype for an open-source design. It should actively encourage modification. It should be designed for hackability.

Don’t hide the design

The PCB fabricator, iTeadStudio, offers solder-mask in a range of funky colours. Ordinary transparent green is also an option. Naturally, I just had to have black solder-mask. It looks non-generic, “edgy”, very Death Star chic. Unfortunately, it also makes it very difficult to see the traces on the board, which is not good when you need to cut a trace.

Open hardware should be made to be understood. Black solder mask literally reduces the transparency of the design.

Test-points are hack-points

Inevitably, I brought out the oscilloscope to examine some of the radio frequency signals on the board. A few sensibly placed test points would have been moderately handy here, but I had none in the layout. It would have been extremely handy if the test points had been plated through-holes, then components could have been added to them instead of being haphazardly soldered to already populated holes and IC pins.

Holes are free, dig?

There are veritable fields of unused space on the board. At least some of that space should have been allocated to a prototyping grid. The fabricator doesn’t charge for holes, so why be parsimonious? More hack-points means more hackability.

Hackabillity is for hackers

Ultimately, this is an open-source design. I don’t expect that anyone will use it, but the design should consider that possibility. It should also consider that the hypothetical user is a hacker and will use the design for something I haven’t thought of. The more hackable the design, the more adaptable it is to unintended applications. We are hackers, we like unintended applications.

I’ll try to design my next board for hackabillity. I owe it to myself and to all the hackers out there.


The board in question is a “Tayloe Detector” for Software Defined Radio using a PC.
https://github.com/jarpy/JarpySDR

Find the service tag of a Dell server from the Linux command line.

Here’s a quick way to get the service tag (serial number) of a Dell server remotely.

root@vmhost:~# dmidecode | grep "Serial Number" | head -n1
        Serial Number: DJ6GH3H

SATA is SATA… unless your BIOS lies

Yesterday I got an emergency call to fix a RHEL5 system that had taken a dive. The system was not booting and the sotware RAID1 containing the root filesystem had split.

I added the failed disk back into the RAID to see if it was really broken, or if it was just a gremlin. (This all happened after a massive storm).

Once the mirror started rebuilding the kernel began to spew out a continuous stream of these:

Mar 11 13:18:07 sparkus kernel: hdc: status timeout: status=0xd0 { Busy }
Mar 11 13:18:07 sparkus kernel: ide: failed opcode was: unknown
Mar 11 13:18:07 sparkus kernel: hdc: no DRQ after issuing MULTWRITE
Mar 11 13:18:07 sparkus kernel: ide1: reset: success

I thought “OK, that disk really is dead”. But I was wrong.

A bit of Googling suggested that “MULTWRITE” is a command unique to IDE disks, but this disk was SATA. It was also suspicious that the disk was mapped as “hdc”, not “sdc” where I would expect a SATA disk to appear on a modern kernel.

It turns out that the BIOS was set to present the SATA disks in “legacy mode”. Translation: “lie to the operating system and tell it the disks are IDE, even though they aren’t“.

I flipped the BIOS to show the disks as native SATA and brought the system back up. The disks mapped to “/dev/sdx“, the mirror started rebuilding with better throughput than before and the kernel errors ceased.

So folks, don’t let your BIOS lie to your kernel… unless you really need to.

Install Windows to a Macintosh USB drive (without Bootcamp).

The Motivation

OSX can do everything I want from day to day, but occasionally I want to play some San Andreas. Bootcamp and Windows should have had me playing Windows games on the Mac. Sadly, Bootcamp refused to partition my internal disk so I was stuck with no Windows and no San Andreas.

A ray of hope was the idea of installing Windows onto a blank external disk. Windows is not supposed to run from an external disk but it has been done before. The brave souls who made this work in the past still needed to re-partition their disk with Bootcamp though, something that wasn’t an option for me.

It turns out that it is possible to install Windows to a USB disk without using Bootcamp at all. Here’s the recipe:

Ingredients

  • An Intel Macintosh – This procedure was tested on a first generation MacBook.
  • A USB2 hard drive – I used a Welland “Sun Bright” chassis with a Samsung IDE disk inside.
  • rEFIt – A boot manager for EFI computers (like Intel Macs).
  • A Windows XP install CD (SP1 or higher).
  • A tool for extracting and editing ISO images. I used MagicISO (a commercial Windows application sadly).
  • The Microsoft CAB SDK.

Procedure

This is the process I used. Step two is a pretty complex sub-procedure. It was produced by some serious Windows Wizards and is the core of what we are doing here. The rest is easy, these guys are good.

  1. Install rEFIt.
  2. Create a modified Windows XP install CD with support for USB installation. This is a long procedure. Follow the link, complete steps 1-9, then come back here.
  3. Power off.
  4. Disconnect your internal hard drive. For a MacBook, use this guide.
  5. Start your Mac, holding “c” to boot from the XP install disc.
  6. Step through the Windows text-mode installer until your system reboots.
  7. Power off.
  8. Replace your internal drive.
  9. Power on.
  10. Tell rEFIt to boot Windows from the USB drive.
  11. Follow the Windows graphical installer. Answer yes to any questions about unsigned drivers. The system will reboot again
  12. Tell rEFIt to boot Windows from the USB drive.

Now you are running Windows from the USB drive.

Macintosh Drivers (and the USB trap)

At this point, I must confess that I cheated. I did install the Bootcamp drivers into my XP install and I believe there is a serious trap here. The Bootcamp driver set contains drivers for the Intel USB controller, which it naturally tries to install. It pops up an uncertified driver warning before installing them. I told it not to install the USB drivers, since the entire operating system was hanging off that device. Replacing the drivers at that point seemed like a very bad idea to me.

Follow

Get every new post delivered to your Inbox.