Virtual Surreality

It's too real to be true

Browsing Posts in Operating Systems

A little “remember me later” for conditionally deploying a Rails 3 app running on Ruby 1.9 on Heroku.

$ruby_version = `ruby --version`.split[1].to_f
$heroku = ENV['USER'].match(/^repo\d+/)

source :rubygems
source 'http://gems.github.com'

gem 'rails', '3.0.0.beta4'
# gem 'rails', :git => 'git://github.com/rails/rails.git'

gem 'bson_ext', '~> 1.0.1'
gem 'decent_exposure'
gem 'haml'
gem 'mongoid', '>= 2.0.0.beta.9'

unless $heroku
  if $ruby_version < 1.9
    gem 'ruby-debug'
  else
    gem 'ruby-debug19'
  end

  group :development, :test do
    gem 'rspec-rails', '>= 2.0.0.beta.17'
    gem 'rails3-generators' #for HAML
  end
end

The --without=test option isn’t (yet) being used on Heroku deploys, thus the :test group is in the unheroku block. Update: check if .bundle/config WITHOUT="" works.

Update: Mongoid changed gem versioning for lexicographical sorting (a “dot” between “beta” and the number
Update: Latest mongoid (beta.16 and something after beta.9) requires Rails 3.0.0.rc which doesn’t support Ruby 1.9.1 which isn’t yet on Heroku
Update: Heroku user doesn’t have “repo” in it anymore and USER env var isn’t available – find new mechanism if bundler config WITHOUT option doesn’t work

Also:

  • Only the --colo(u)r and --format options work in the .rspec file
  • use_transactional_fixtures=false in spec_helper.rb (talk to Chelimsky about transactional fixtures in non-ActiveRecord environments)
  • In application.rb:
    • require 'mongoid/railtie'
    • require 'decent_exposure/railtie'
    • g.orm :mongoid
    • g.template-engine :haml
    • g.text_framework :rspec, :fixture => false, :views => false

In response to Dr Nick’s technological feat, Ajey suggested I take on the much more challenging task of running OS X on a PC.

Result!!

Mac on Windows


Also, Mingle 2.0 is released! Another fantastic effort from the ThoughtWorks Studios crew.

After a meeting of the office of the CTO, most of us stayed around in our San Francisco office for a few days to do some podcasts and to participate in a Code Jam for Inveneo, a not-for-profit who provide computers and connectivity to developing countries (especially their schools, hospitals, and poorer villages).

They install a server in, say, a hospital with a few lower-powered, custom desktops (almost iMac in configuration). These, as well as the servers, can run off solar panels for power.

We were presented with a worthwhile problem with a number of interesting constraints:

  • Low-power server running Ubuntu, with two small SATA hard disks in a Linux software RAID-1 array
  • VMWare images of the servers for testing
  • Python, bash, mdadm, and beep as our “programming languages”

When a RAID array fails, we need to alert any (if any) humans who are near the server. This can be interesting as the only things nearby might be the tree it is mounted in with a long-range WiFi, or the goat who uses it as a heat source at night. This means that any alert should be sufficiently frequent and annoying for the locals to contact someone who can let the support technician know. The conflict is that it also might be the nurses in their office at the hospital who have work to do and don’t want to be disturbed.

The solution was to use the PC speaker to beep. We can control the pitch and duration of the beep. Some combinations sounded too much like an ECG machine so that was no good. In the end, we chose a simple rising scale that would sound odd in any environment (except, perhaps, in a Mike Oldfield recording). This is repeated by default every 30 minutes.

We also had to send an email to the support technician. This doesn’t work when the server doesn’t actually have any connectivity (as some are used only as a local communications hub), or when connectivity is unreliable. Even then, many of the technicians are hours or even days away from the servers.

As many of the technicians aren’t particularly technical, we also had help by identifying which of the two disks had failed and allow them to simply change the one labelled “Disk 1″ or “Disk 2″. Serial numbers are good for this but VM hard disks don’t have serial numbers (I think that’s a feature request to both VMWare and Parallels).

We had Jeff Wishnie from Inveneo as the customer, Anda Abramovici as IM, Jonny Leroy as BA, Paul Hammant and Chad Wathington as QA, and the star developer crew of Drew Olson, Sammy Zahabi, Ola Bini, Erik Doernenburg and your’s truly. We quickly learned the following:

  • The skills we needed (and had, just a little rusty) were more along the lines of Unix devices, shell, ASCII control characters, and simulation
  • Python sucks (a bad tradesman blames his tools? perhaps – but it still sucks)

Anyway, we got most of what we wanted done in the time, and given the context, more than we anticipated. But we all would have liked to get a lot more done and would have if we were using our tools of choice (which are chosen for very good reasons).

Nonetheless, we’re doing it for the kids and it was great!

What a buzz. Super Agile. Super Fun. Go Inveneo, you rock!!

I still hate the handling of spaces – especially when you’re throwing in mixed path delimiters using nice GNU tools on DOS/NTFS.

If you ever want to get rid of SVN or CVS folders (or whatever) in a large source tree after someone has zipped it and sent it to you straight from their workspace, and Explorer’s Search window barfs with that many matching folders all over the place, then try this:

  1. Get unxutils
  2. Use the zsh included
  3. Realise zsh has bipolar tendancies when dealing with “DOS backslash to delimit directories in paths” and “UNIX slash to delimit directories in paths” and “UNIX backslash to quote special characters”
  4. Put unxutil’s usr/local/wbin at the front of your PATH (to get the GNU find, not the DOS one)
  5. Unfortunately -exec ls {} \; doesn’t do the trick because ls can’t handle the spaces and/or backslashes and -exec ls “{}” \; doesn’t have any affect
  6. Use the following neat trick (after 30 mins of mucking around with the bipolar tendancies)

  7. find . -name 'CVS' -print | tr '\\' '/' | while read filename
    do
    rm -r "$filename"
    done

  8. The little translate sorts out GNU find -print returning paths with backslashes and the while loop allows you to do lots of things, including removing the directory :-)

It’s slower than -exec or xargs but it works.