Creating a minimal Ubuntu VirtualBox image
In my last post, I showed you how to build a CloudFoundry mini-cloud on an Ubuntu VirtualBox. Building that base image took some work and sorting through old blog posts, so I thought I’d post the instructions I ended up using.
First, download a copy of the latest Ubuntu LTS (Long-Term-Support) image. This tutorial follows the 10.04 installation, later versions may vary.
At the boot screen, press F4 which will let you select the type of installation to perform. Select “Minimal Virtual Machine”, then hit enter to start the Install.
Keyboard selection won’t matter much, so I just chose USA/USA.
For the system clock, I recommend UTC. This models most of the cloud provider images you’re likely to come across.
Have it use the whole disk and auto-partition.
Use ‘ubuntu’ for the username and password for now. Once the system is set up, you can install your ssh keys and remove the password with sudo passwd -d ubuntu.
Disk encryption and HTTP proxies is your choice, but I didn’t need to use either.
When you get to select packages, do manual package selection and it will put you into the aptitude program. This is a little tricky to navigate, but these commands should be plenty to get the job done:
- use /, enter and n to search similar to less or vi
+ to install the selected package
- search and install as needed
- gg to install packages
You’ll need these packages in order to get the VirtualBox guest tools setup. I recommend installing these since it will enable you to detect the IP of the VM and shut it down without having to SSH into it:
- build-essential
- linux-headers-virtual
- openssh-server
Once it reboots, select “Install Guest Additions” from the Devices menu to mount the VirtuaBox guest additions install image. Then log in and run these commands:
sudo mount /dev/cdrom /mnt
sudo sh /mnt/VBoxLinuxAdditions.run
The last important fix is to remove the MAC address cache that this version of Ubuntu has:
sudo rm /etc/udev/rules.d/70-persistent-net.rules
Note that when you import the image using VBoxManage you should also reset it’s MAC address. You can do this using VBoxManage like this:
VBoxManage modifyvm MyVMName --macaddress1 auto
You may also want to be able to shutdown the machine without logging in, you’ll also need to install ACPI support:
sudo apt-get update
sudo apt-get install acpi-support
This will allow you to use the VBoxManage command to shut down the machine cleanly without using SSH:
VBoxManage controlvm MyVMName acpipowerbutton
If you want passwordless sudo access (also common on cloud images) run:
sudo su -c "echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers"
At this point, disconnect the guest additions and shut down the VM. You should now have a super-minimal Ubuntu image that’s confiured similarly to the Ubuntu images you’ll see on cloud services like EC2.
Running CloudFoundry with VirtualBox on OS X
So you might have seen the “one click” installer for CloudFoundry that my esteemed colleague Trotter Cashion posted yesterday. This is very cool. If you have an Ubuntu server handy you can run that script and you have a cloud. But I like to keep things local so I started working to get it installed on VirtualBox. And here’s the solution, packaged as a script.
To use this script you’ll need:
- A Mac (Linux or Cygwin would need some tweaks, pull requests welcome!)
- VirtualBox
Then run this:
curl -O https://github.com/matschaffer/vcap/raw/vbox-install/setup/vbox_install
curl -O https://github.com/matschaffer/vcap/raw/vbox-install/setup/install
sh vbox_install
Accept the host key (should be 5f:f4:1f:14:4c:b8:5c:ad:11:b1:85:f3:f1:0d:a5:2c) and enter the password “ubuntu” once.
That’s it! This script will import a minimal Ubuntu VM from our S3 bucket, set up bridged networking to your default interface, install your SSH key and kick off Trotter’s install script.
It’ll take an hour or so depending on your internet connection. When it’s done, you’ll get some instructions on updating your hosts file, registering with your new cloud and accessing the VirtualBox image. Follow those and enjoy your new personal cloud!
How to hire a Rails developer
As the co-founder of Mashion and organizer of Philly.rb I get a lot of emails from people looking for Rails developers. To help spread the word and maybe do a little less typing, I decided it was time for a blog post.
Before we get into it you should know that finding a good developer in any technology is difficult. Even in larger developer pools like Java or .Net, isolating the top talent is difficult. The pool of Rails developers is of course smaller, but also contains some extremely high quality developers. Here are some of the key points I’ve settled on when helping people find the right developers for their company.
1. Get involved
There are probably some user groups near your area. Maybe even a Ruby user group. Google them, go to a meeting. This is easier when you know a little programming, since the conversation will be mostly technical. If you have even one developer now, send them. If you’re the only person in your company, just show up anyway. Establishing a presence in the community goes a long way. The more often people see you, the more likely your company will come to mind when people think about changing jobs.
This is a continuation of the first point. Being at the meeting is a great start. Being at the podium is even better. And it’s a bonus if you’re talking about cool technologies or business ideas. If no-one in your company can present on a technical topic, sponsor a meeting. Most groups accept sponsors for food, space, or giveaways. So you can probably find an option that works even if your budget is pretty tight. In exchange you’ll usually get mentions in the meeting promotions or a chance to talk about your company while everyone’s paying attention. This varies between groups, so contact the organizer for info.
3. Don’t talk about your degree
Whether it’s technical or business-related, most of what interests Rails developers doesn’t come from a classroom. People are much more interested in hearing about your experiences in real companies, delivering real products. If you don’t have any experience, that’s okay too. Just be honest about it. Rails developers are very aware that good business ideas can come from anywhere.
4. Have a business plan
How are you going to make money? Knowing your target market and having a marketing plan is best. Having a good shot at a buy out is passable. Selling advertising is unlikely to get anyone’s attention. If you’re profitable today, pitch that. If you’re not profitable yet, emphasize what your company has to offer in technology or lifestyle interest. Having VC backing is fine, but it’s not a big selling point. Same goes for equity offers. Most of us experienced what happened in the dot-com bubble and are not eager to repeat it.
5. Don’t hire a “Rails” developer
The best developers I know don’t classify themselves as “Rails” developers. They might do most of their business in Rails, but they also do JavaScript, Clojure, Erlang, Objective-C and a multitude of other languages. They have side projects using technologies even I haven’t heard of yet. The web development landscape changes rapidly, so you’ll need people who are constantly challenging themselves to learn more.
As with any blog post, these are just some ideas that have helped me. If you have some points of your own, please comment. I welcome the feedback.
Good hunting.
Net::HTTP Mocking during Cucumber Tests
I just finished up an awesome week by speaking at RubyNation. Hats off to the organizers and the sponsors for throwing a great conference! During my twilio talk I mentioned how we had problems running Artifice during our @javascript Cucumber features. Here’s how that goes down.
If you’re trying to use any sort of global Net::HTTP mocking tool during your Cucumber tests, you might encounter something like this:
Background:
Given I am on the new user registration page
Capybara::TimeoutError (Capybara::TimeoutError)
./features/step_definitions/web_steps.rb:20:in `/^(?:|I )am on (.+)$/'
features/user_registration.feature:7:in `Given I am on ...'
Then I should see "Email"
Capybara::TimeoutError (Capybara::TimeoutError)
This happens because Selenium and Capybara use Net::HTTP to know when your Rails app is available. Sadly, you can’t even put the mock activation in a Before block because Capybara won’t start the separate Rails app until the first @javascript test. To get around this we set up our env.rb like so:
require 'artifice'
require Rails.root.join('test', 'support', 'fake_twilio')
Artifice.activate_with(FakeTwilio)
require 'capybara/rails'
require 'capybara/cucumber'
require 'capybara/session'
module Selenium
Net = ::Net.dup
module Net
HTTP = Artifice::NET_HTTP
end
end
class Capybara::Server
Net = ::Net.dup
module Net
HTTP = Artifice::NET_HTTP
end
end
In the case of Artifice, it holds on to the original Net::HTTP as Artifice::NET_HTTP. This block of code puts the original Net::HTTP back but only in the namespaces where it’s needed (Selenium and Capybara). Yet another lovely example of how powerful Ruby is. If you have a cleaner way to do this without resorting to two HTTP libraries, I’d love to hear it.
Making your own Ruby gem
It’s easy to make your own Ruby gem. Even without a library to help you. If you have RubyGems installed you’re already good to go.
First, make a directory for your project. In that directory make gemspec file named after the gem. For example, my_awesome_gem.gemspec. The gemspec file is just Ruby. Here’s a basic example:
Gem::Specification.new do |s|
s.name = 'my_awesome_gem'
s.version = '0.0.1'
s.summary = 'This bit will show up under your gem on rubygems.org'
s.author = 'Mat Schaffer'
s.email = 'mat@schaffer.me'
s.homepage = 'https://github.com/matschaffer/my_awesome_gem'
# These dependencies are only for people who work on this gem
s.add_development_dependency 'rspec'
s.add_development_dependency 'mocha'
# Include everything in the lib folder
s.files = Dir['lib/**/*']
# Supress the warning about no rubyforge project
s.rubyforge_project = 'nowarning'
end
Now just put your code in lib/my_awesome_gem.rb. RubyGems will automatically put your lib directory into the load path when the gem is installed. To test your gem before it’s installed just run your test script using ruby -Ilib my_test_file.rb.
Now build your gem with gem build my_awesome_gem.gemspec and push it to RubyGems.org by running gem push my_awesome_gem-0.0.1.gem. You’ll need to make a RubyGems.org account if you don’t have one. The gem push command will ask you for your account info the first time you push a gem.
As a bonus, if you want to use rake to build and push your gem, just make a Rakefile like this (run rake -T to see what this gives you):
require 'rake/gempackagetask'
spec = Gem::Specification.load(Dir['*.gemspec'].first)
gem = Rake::GemPackageTask.new(spec)
gem.define
desc "Push gem to rubygems.org"
task :push => :gem do
sh "gem push #{gem.package_dir}/#{gem.gem_file}"
end
And if you want to manage your development gems with bundler, just put this in your Gemfile: