Profile cover photo
Profile photo
Jerome Jahnke

This Friday will be my last day at the B of A. I joined in 2002 intent on weathering the dot bomb. I figured I would be back at an internet company in 2004 or 2005 at the latest. But the problems the bank had me working on were really challenging and the people I worked with were friendly and supportive. So 2 years turned into 13.

Early this year Jeri and I decided it was time to leave the bank. The job market is good for people with my skill set and Groupon managed to attract me with their Green Track Jackets and Kitty Cat mascot; oh and they have an interesting strategy to become like Amazon by providing tools for local commerce.

I want to thank everyone I have ever worked with at the B of A you helped make me who I am today. On Friday Apr 3 I am going to leave work around 4:00pm and go to the Berghoff Bar where I will be hanging out until about 6. If you are in the Loop in Chicago and interested in catching up please stop by.
Add a comment...

I haven't been paying attention to the provisioning space. And I decided to change that. First up was Vagrant (and making it work with AWS.)
Add a comment...

Okay this turned out to be way harder than it needed to be. I wanted to  use a Raspberry PI to control an Arduino simple one would think because using these two together just makes sense if you are getting a computer for someone who isn't perhaps 'adult' enough to have a real computer. But as it turns out there is one simple trick that if you don't do it won't work.

First off get a newish version of Raspberian on an SD Card.

This BTW takes for fscking EVER. Like 15 mins to format the damn card, 20 mins to download the file (although in retrospect it might a gone faster had I used the torrent link.)

Okay you got that? Great let me brush off the pumpkin pie crumbs and consult my notes. Okay easy peasy.

sudo apt-get update
sudo apt-get upgrade
sudo reboot
sudo apt-get install arduino

So here is what is ironic, my Arduino shows up in DMESG until I run the Arduino install... WTF? Let me brush off the pecan pie crumbs here and look into this closer... Huh it has defaulted to COM1 and the serial port tool menu is grey... WTH.

Oh yea I promised a once simple trick thing. Turns out for some reason something in all this turns on the serial console (which is used by EVERYONE using the Raspberry Pi) and that hoses talking to the thing that people actually WANT to use the damn thing for which is talk to a microcontroller.

So clearly at some point it might be important to turn on the serial console so I found this. Which is a utility that lets me toggle this.

sudo wget -O /usr/bin/rpi-serial-console && sudo chmod +x /usr/bin/rpi-serial-console
sudo rpi-serial-console disable
sudo reboot

And boom the menu item is no longer grey so I select ttyAMA0 and we are off to the races.

BTW the apt-get installs an OLD version of Arduino 1.01. I am not going to upgrade it, either my nephew will really like this and he and I can work through upgrading it together or her won't and I will continue to do my development on a real laptop.

Oh yea.. One more thing the guys in the Raspberry Pi forums are real gold plated assholes. One interaction I saw went like this.

NOOB: I want to install Ardunio IDE on my Raspberry Pi
GPAH: sudo get-apt install arduino
NOOB: Okay I did that but my serial menu is greyed out
GPAH: Well you didn't say you wanted to use Arduino IDE you just wanted it installed.
NOOB: Okay but how do I use it now
GPAH: <crickets>
Add a comment...

Okay today I needed to start EC2 spot instances... So here is that script.

#!/usr/bin/env python

import boto
import optparse
import os

class QuitException(Exception):

class Menu(object):
  def _init_(self, items):
    self._menu = {}
    count = 1
    for i in items:
      self._menu[str(count)] = i
      count += 1

  def displayMenu(self, display):
    for k,v in sorted(self._menu.iteritems()):
      print '{0} - {1}'.format(k,display(v))

  def returnChoice(self, choice):
    if 'q' in choice:
      raise QuitException('quit')
      retVal = []
      items = choice.split(',')
      for i in items:
        c = self._menu.get(i, None)
        if c:

      return tuple(retVal)

  def chooseMultiple(self, prompt='Choose: ', display=lambda x:x):
    if len(self._menu) == 0:
      print 'No elements exist'
      raise QuitException('quit')

    if len(self._menu) == 1:
      return (self._menu[self._menu.keys()[0]],)

    while True:
      choice = self.returnChoice( raw_input(prompt) )
      if choice:
        return choice

  def choose(self, prompt='Choose: ', display=lambda x:x):
    return self.chooseMultiple(prompt=prompt, display=display)[0]

def getPrice( price ):
  if price is None:
    price = '0.005'
  return price

conn = boto.connect_ec2()

def getImage(name='*tormenta*'):
  filters = {'name':name} if name else {'name':'*tormenta*'}
  menu = Menu( conn.get_all_images(filters=filters) )
  image = menu.choose(display=lambda x: '{0} | {1}'.format(,
  return image

def getSecurity(name=None):
  filters = {'group-name':name} if name else None
  menu = Menu(conn.get_all_security_groups(filters=filters))
  sec = menu.chooseMultiple(display=lambda x: '{0} | {1}'.format(,
  return sec

def getKey(name=None):
  filters = {'key-name':name} if name else None
  menu = Menu(conn.get_all_key_pairs(filters=filters))
  sec = menu.choose(display=lambda x: '{0} | {1}'.format(, x.fingerprint))
  return sec

def main():
  usage = 'usage: %prog [options]'
  parser = optparse.OptionParser(usage)
  parser.add_option('-i', '--image-name', dest='image_name',
                  help='Finds the AMI containing this string')
  parser.add_option('-s', '--security-group', dest='security_group',
                  help='Finds the security group containing this string')
  parser.add_option('-k', '--key', dest='key_name',
                  help='Finds the key containing this string')
  parser.add_option('-p', '--price', dest='image_price',
          help='Finds the resource with this price')
  options, args = parser.parse_args()
  image = getImage(options.image_name)
  security = [ for s in getSecurity(options.security_group)]
  key = getKey(options.key_name)
  price = getPrice(options.image_price)
  print "starting   conn.request_spot_instances( '" + price + "', '" + + "', key_name='" + + "', security_groups=" + str(security) + ", instance_type='t1.micro')"
  #conn.request_spot_instances( str(price),, key_name=, security_groups=security, instance_type='t1.micro')

if _name_ == '__main__':
Add a comment...

On vacation this week. I need to move my hosting from where it is (long story short they restrict me too much charge too much and deliver too little.) So I am gonna go to EC2. I don't need much processing hardware the t1.micro servers are plenty for the minuscule amount of traffic I receive. At spot pricing they are typically less than half a cent per hour which brings my costs in at < 4 bucks a month.

They have a nice web UI but I need to be able to script some stuff. So I have downloaded boto and am starting to write some utility scripts. If you are interested here is the first one. What it does is lists all the running instances and lets me choose which one I want to ssh to.

dandy jahnke [ ~/tools/bin ]$ getawsaddresses
1 - chef-server-10.18.2 2013-04-07T00:15:27.000Z
2 - tormenta-empty-couch-internet-ready 2013-04-08T03:22:48.000Z
Choose a machine: 1
Launching ssh -i /Users/jahnke/ec2-keys/jahnke-gsg-keypair.pem
Welcome to Ubuntu 11.10 (GNU/Linux 3.0.0-26-virtual x86_64)

Da code..
#!/usr/bin/env python

import boto
import optparse
import os

conn = boto.connect_ec2()

def getKey( key ):
  keypath = '/Users/jahnke/ec2-keys'
  k = key or 'jahnke-gsg-keypair'
  return '{0}/{1}.pem'.format(keypath, k)

def buildMenu(user):
  count = 1
  menu = {}
  for reservations in conn.get_all_instances():
    for i in reservations.instances:
      param1 = "-i " + getKey(i.key_name) 
      param2 = '{0}@{1}'.format(user, i.public_dns_name)
      cmd = 'ssh {0} {1}'.format(param1, param2)
        ami = conn.get_all_images( filters={'image-id':i.image_id})[0].name
      except IndexError:
        ami = 'unknown'
      menu[str(count)] = (i.public_dns_name, i.launch_time, ami, i.instance_type, i.state, i.key_name, cmd)
      count += 1
  return menu

def displayMenu(user):
  while True:
    m = buildMenu(user)
    for k,v in m.items():
      print '{0} - {1} {2}'.format(k,v[2],v[1])

    res = raw_input('Choose a machine: ')
    r = m.get(res,None)
    if r:
      return r[-1]

    if res == 'q':
      return None

def main():
  usage = 'usage: %prog [options]'
  parser = optparse.OptionParser(usage)
  parser.add_option('-u', '--user', dest='machine_user',
          help='Log in as this user')
  options, args = parser.parse_args()

  user = options.machine_user or 'ubuntu'
  launch = displayMenu(user)
  if launch:
    print 'Launching {0}'.format(launch)

if _name_ == '__main__':
Add a comment...

Want freeswitch on  your raspberry pi? Got at least a day? Have at it.

sudo apt-get install git autoconf automake libtool libncurses5-dev libjpeg-dev
sudo git clone git://
cd /usr/local/src/freeswitch/
sudo ./ 
sudo ./configure 
sudo make all install cd-sounds-install cd-moh-install
ulimit -s 240
sudo /usr/local/freeswitch/bin/freeswitch 
Add a comment...

Hokay so Raspberry Pi has been frustrating me today. It wasn't working, network was not working reliably nor was keyboard. Which was odd. So I looked onna innernets and they said bad power. I went looking for my multimeter (to prove or disprove the innernets) and that seems to have disappeared somewhere. BUT I did find a different power supply and tried that which seemed to have sorted out the problem.

Now I am compiling freeswitch which I think this is gonna take a while. A very LONG while.
Add a comment...

Holy Crap that was painful... So I have had enough of my hosting provider I want to move to a different one. So step one is set up a business gmail account to start collecting my email. Easily done 3 accounts (me, my wife and a catchall to see what addresses I might need to attach to hers or my address.) All very easy, and now to fix DNS...

So hosting provider doesn't have a way for me to manage my zones file, I guess making it hard for me is gonna make be stay with them. So I go to my name provider and they kinda have a way for me to manage my zones file. I can't do what I want, and somehow I end up at DynDNS and holy crap that site is 90% "Please use our service" and 1% "Here change your zone file" and 9% "Fooled ya you can't actually change your zone file from here." 

So I gave up, my hosting provider is probably gonna mess with me over the next few weeks. But I will just be gone sooner in this case. This should have taken a lot less time than it did. BUT once again Amazon saves the day for $.50 a month I can manage my zone file on a fairly robust backbone. Since I will probably move my hosting here as well it is good enough for me (for now.)
Add a comment...

Post has attachment
I wonder if I should get into ethical hacking. It certainly sounds like a lot of fun.
Add a comment...

Compiling Android ICS, and getting it to run on my pandaboard. Tron is running in the background. It is like it is 1999 all over again.
Add a comment...
Wait while more posts are being loaded