Run commands inside Vagrant from outside Vagrant

I’ve been trying to push myself to use Vagrant more for setting up development environments.

It’s fine to have the split between Vagrant and your editor, but it’s the overlapping areas that wear you down. Like when you’re running helpers scripts or applications from your machine.

Here are some examples:

bin/rake -T
bundle install
bin/rspec spec/models/cake_spec.rb

One of my favourites though is an adhoc Vim mapping from Drew Neil of Vimcasts fame:

:map Q :w !bin/rspec spec/models/cakes_spec.rb

(hint: Fill in the path to the current file with CTRL-r %)

And as of right now, how do you run them?

vagrant ssh
cd /vagrant
bundle update rails

Ugh!

So, I wrote a script that converts absolute paths into relative paths and then pipes the command through SSH after cd’ing to the /vagrant folder.

It gets dropped into bin/vrun, then run like so:

bin/vrun bin/rspec /Users/andrew/work/cakehump/spec/cake_spec.rb

It’s a bit clunky, but it’s better than nothing. I’ve no doubt there are improvements, so if you have one, hit me up.

Repeatable and shareable development environments with Vagrant

This is a rough paraphrasing of my CodeCumbria talk “Repeatable and shareable development environments with Vagrant”.

In this post I’m going to cover why having a repeatable and sharable development environment is a good thing.

I’ll be focusing on web development environments, so please adjust your learnings as necessary!

You may consider your development environment and machine to be the same thing. On a fresh install you start a frenzy of apt-geting or brew installing. You make your project folder and then start coding away.

Congratulations, you have likened your machine to a skip. A big jumbled mess of dependencies. It might not feel like it at the time, but there is a better way.

When you have one project, there is no mess. Over time, the unstructured approach to dependencies starts to cause some strain. You have no idea which dependency is in use by which project, and each project has access to every other projects dependencies. Don’t even think about different projects using different versions of the same dependencies!

Setting up a machine is a faff. It’s something you can overlook if it’s a new machine. You’re blinded by the vision of setting up better than last time. But your next reinstall may not be so relaxed - imagine setting up a new machine while in the middle of a tight deadline.

Or having to try and configure a production server without a list of the dependencies you need.

Or bringing a new team member up to speed. A day of installing before they even get into learning about your app.

If you don’t declare project dependencies, you are making it hard for Future You to work on your project. Future You HATES that.

Future You politely requests that you try harder.


One way to raise your game is to use virtual machines. Creating a virtual machine lets you contain that project and its dependencies. No overlap. No leaking.

But virtual machines are slow! I’ve used VirtualBox and IE to do some browser testing and it takes like 10 minutes to start up!

This is true, but virtual machines don’t have to be clunky.

Vagrant builds and starts your virtual machine for you, starting with public base images. Straight off, you don’t have to deal with install disks or ISOs.

It lets you edit files from your machine using your existing code editor. It lets you access your development server as if it was running on your machine.

A key feature of Vagrant is the manifest file that configures your virtual machine. You can share this Vagrantfile by committing it to your source control. You don’t need to hump about large virtual machine images, you just need this text file. Sharable.

Now it’s grand that you can have a virtual machine built for you, but it’s only half the story if you have to install your own dependencies.

Vagrant has built in support to provision boxes - the easiest approach being simple bash scripts. With another short text script, you can completely set up your development environment. Repeatable.

For extra points, Vagrant can build your development environment using Chef or Puppet recipes. These recipes can then go on to build your production server.


Front-loading the hassle can save you effort later.

While the project is at the forefront of your mind, declaring your dependencies is easy.

Setting up your development environment in this way provides documentation for future reference. It defines a development process and helps push consistency across your team.

Vagrant helps you build a virtual machine. Its provisioning support makes it set up your development environment’s dependencies. Sharable. Repeatable.

After writing this I discovered that Kerry Gallagher wrote a step-by-step guide for Vagrant beginners. Check it out!

The state of the local Internet in Cumbria

As an offcomer, I know very few local people and even fewer local businesses. As a web-worker, I turn to the Internet to answer all questions. Finding useful local information here is tough. Lots of effort, with not much result.

So what causes the local Internet here to fall short of its potential? The number of good (and more importantly, useful) local sites is low. Thankfully though, the void has been filled by automatically generated directory sites. Thanks to them, the look and feel of the local Internet is cheap and irrelevant. It’s spammy.

So. Two questions, both linked:

1. Why aren’t more small local businesses getting sites built?

Why are local businesses letting themselves be represented by these potentially inaccurate robotic listing sites?

Perhaps there’s a perception that websites don’t offer value for money. Websites aren’t cheap and the whole process is saturated with concepts that aren’t related to the core business of the client. Bandwidth. Servers. Domain names. Content management systems. All businesses, even web businesses want to make money and maximise sales, so projects are scaled up. Clients are up-sold to earn a quick buck. But that’s business, right?

And the big expensive project does not directly generate income. There is no monthly lump sum. It feels like the client has bought a new car that they don’t have permission to drive, rather than the start of an exciting new direction for their company. 

But why spend money on a site that no-one looks at? Roll on, second question.

2. Why wouldn’t the local audience look online for business information?

I don’t believe it’s a question of sophistication. Everyone and their mum has a Facebook account that is kept thoroughly up to date. Smartphone usage is endemic. When I asked Nick Turner (head of digital content at the CN Group) for some insight, he shared that 19% of the visits to the News & Star site were mobiles. That will only rise.

Perhaps the quantity of ‘spam’ listing sites puts people off. Lots of sites that rank highly in Google but offer less than zero value. They waste your valuable time. Perhaps it’s the quality of the real sites. High on noisy SEO optimised content, low on useful information. Worshipping at the altar of SEO.

A solution?

So, how can we fix it? I warn you, this is not a get-rich quick idea. It is a slow burning, long-term idea. The goal is to improve your relationship with your client and their relationship with their customers.

Websites that are fit for purpose.

Websites that can be found and found easily, with well structured content that includes the name of the organisation and describes the client’s business in a way that expresses the character and tone of their business. No SEO bolt-on — let the search engines do their job, naturally.

Build lightweight websites

Begone, complex Content Management System powering pages full of pointless junk for the benefit of Google. The site should have contact details but without a contact form. Telephone number, address, email address. Short. Sharp. Informative. Instead of building the site for the spiders, build it for the audience.

Design should be simple and functional. Avoid fluff that eats into (or inflates) the budget. Lightweight. Tidy. Reign in your client!

They key here is to provide a low-cost entry into website ownership. We don’t want to act as the gatekeepers for their site, we want to be there to help them grow their business through the Internet.

Explain what the Internet is

Help them to understand the Internet. No, put away that ARPANET book, I mean the character of the internet. Why are cat pictures funny? If I have a video I want to share, how do I get it out to the public. How do I talk to my customers?

Instead of driving their online strategy, based off what you think they need, they will be able to suggest their own features. Use your expertise to hone and refine their ideas. The relationship between you will be more balanced. More respectful. And it’ll grow. For a long time.

Prove it’s working

Help them to understand analytics. Give them the ability to collect and interpret the data their website generates. Show them that their customers are more important to their business than website hits. That they don’t need e-commerce to earn money from their site. Lead generation followed by efficient conversion to sales.

It’s about involving the client rather than just building them a site. Work together to build momentum at a pace that both you and your client can cope with.

Start small. Start nano. But aim to grow!

Coming soon: We aren’t starting this adventure with nothing. Harness local assets for your benefit. And theirs.

p.s. I’m @dies_el on twitter, say hello!

An offcomer’s view of the Internet in Cumbria

I have been working online for over a decade. I’ve worked in the North East of England, Glasgow and for the last three years from home for an agency in London. Besides that, I spend a lot of time on the Internet.

I want to blog about how the Internet works, or doesn’t work for Cumbria. But first, a little diversion into why the Internet is a power for good in Cumbria.

Businesses like good transport links. A large chunk of Cumbria isn’t close to a motorway. It isn’t close to anything. Geographically, this puts Cumbria at a disadvantage.

It’s a disadvantage unless you want open space. The fells, the quiet; not everyone wants to work in farming or tourism though.

What’s left? Local businesses for local people? You’d have better access to a larger audience if you moved towards one of the larger cities. Why start a business in Whitehaven when you could start one in Carlisle? Why start one in Carlisle when you could start one in Newcastle? 

The Internet does not care about geography. The Internet doesn’t care about motorways or airports or urban sprawls. When you are online, you access the world. By taking advantage of the Internet, the playing field is levelled. Cumbria isn’t at an advantage, but it’s not stacked against us.

Imagine having access to the markets of the world while living in the beautiful county of Cumbria. You can operate a storefront that services the local community while simutaneously providing the very same service to whoever accesses your online presence.

I want to help local businesses use the Internet in a way that works for them and for the villages and towns they’re based in. I want to help teach business owners how to put a little into the Internet and get more back. I want to help local developers further themselves and their communities. I want to reboot the Internet in Cumbria. Join me!

Coming soon: Why the local internet is so terrible in Cumbria and what we can do to start fixing it

p.s. I’m @dies_el on twitter, say hello!

The Garden of the Night

Our protagonist starts in the middle of an ocean on a small sail boat. He doesn’t know how he got there, but he knows he’s alone.

Half starved, the cold wind cuts into him. He takes down his sail and uses it as a blanket. Attaching his lamp to the mast, the blackness of his surroundings are held at bay. For now. Finding a small amount of comfort he falls into an uneasy sleep.

He’s aware of being in a lush paradise. People! There are happy, friendly people here. He meets, he takes fanciful trips around the gardens. He falls in love.

One by one, his friends fall asleep. Everyone is asleep, but he is still awake, afraid to drift off. Even in this dream land he finds loneliness.

Crash! A heavy wave slaps the side of the boat and he’s awake. Back adrift in the ocean. Back in his boat. Back being alone.

http://www.youtube.com/watch?v=NQ5ku4z1pjs

Using a locally developed rubygem with Bundler

I was working with the Embedly API earlier on and thought I’d extract my code into a rubygem (released as tinyembedly, source on github). Preparing the gem was pretty straightforward (thanks to New gem with bundler) however getting the gem back into the ‘host’ application was proving difficult.

The problem I was trying to solve: I wanted to test my gem locally before pushing it out into the real world.

To do that, I thought I’d have to update Bundler to point to my local .gem file.

I added the gem to my Gemfile:

gem :tinyembedly, '0.0.1', :path => ~/dev/tinyembedly/pkg/tinyembedly-0.0.1.gem

Bundler couldn’t find the gem. Strange. After a bit of reading I updated my Gemfile to reference the .gem file folder instead.

gem :tinyembedly, '0.0.1', :path => ~/dev/tinyembedly/pkg/

Now, Bundler was more content, but I just couldn’t get my gem to require. A quick look at the $LOAD_PATH:

$LOAD_PATH.grep(/tiny/)

This revealed that instead of using the .gem file (as I thought) it was expecting :path to point to the unpacked .gem. Duh.

The solution had been staring me in the face. If I wanted to use the locally developed gem (before it had been uploaded to rubygems) I simply installed it, locally, and then added it to my Gemfile:

rake install

Updated my Gemfile:

gem 'tinyembedly', '0.0.1'

This works, because Bundler checks rubygems for the gem and when that fails, checks locally afterward. And with that, all was well. Huff.

Using a Steelseries Kinzu on a Mac (OSX Lion)

This blog post is for all of the mac (Lion) owners who are given (or who buy themselves) a Steelseries Kinzu mouse at Christmas. This writeup may be of use to owners of other gaming mice (with Windows only driver software).

I wanted a mouse for gaming. Being impatient, I headed to the local shops and had a look about. I popped into PC World / Currys but left disappointed with the service [1]. Game were selling a Steelseries Kinzu for a little more than the online price so I picked it up. It’s a seemingly high spec mouse without the cosmetic frills.

Wait, what is a gaming mouse?

For Quake it’s beneficial to have a mouse that polls at 500hz. Secondly, a higher DPI allows for smoother aiming motion. I’m not going to pretend that these are necessary in order to win (I’ll leave that to the people hawking mice), but for a game as high paced and ‘twitchy’ as Quake, I feel like I notice a difference.

But I own a mac!

With a bit of research I came to the conclusion that none of the major companies provided stable drivers or configuration software for OSX. I thought if the rate was set in hardware I might get away with not configuring it.

So, when I returned home with my Steelseries Kinzu, I plugged it in and it felt… suprisingly OK. I had a look at the OSX USB prober, which suggested the mouse was polling at 1000hz. Good news, although I’d read of ‘stability issues’ at that high a rate. When playing Quake, it felt reasonably good, though it would intermittently disconnect and reconnect itself (usually in the middle of a firefight). This wouldn’t do.

I’d also read that a firmware upgrade for the mouse (mice have firmware now? How long was I gone!) resolved a similar issue a user was having on Ubuntu. You need access to a Windows machine that you can install their software on. Through their configuration software you can upgrade your mouse firmware and configure the sampling rate / DPI. These settings are remembered (mice have memory now! How long was I go…) so when you return to your mac, all will be peachy.

But I don’t have a Windows machine

But wait, you have a mac. You don’t have access to a Windows machine. I had to make do with installing the software on a Virtualbox instance (a Windows 7 instance provided by the Internet Explorer for browser testing). Initially the mouse wasn’t accepted as a valid mouse by the software. I shut down the VM and set the USB filter options to cover the Kinzu. When I booted up the VM the mouse wouldn’t move, but running the mouse configuration software again it was detected and installed correctly. Truth be told, I don’t know if the USB filters was the key to getting this working, or whether it just needed a few random reboots to pick up properly. YMMV. Mine certainly did.

So to summarise:

  • If you buy a Steelseries Kinzu mouse, don’t expect any useful help from their under-resourced support team
  • If you have access to a Windows machine, install the mouse software on that to configure your mouse. I found 500hz rid me of my mouse freezing / disconnecting / reconnecting issue.
  • If you don’t have access to a Windows machine, fiddle about with the VM images provided by the Internet Explorer team. It can be done.

Upgrading the firmware on your mouse and lowering the polling rate made this mouse feel spot on.

[1] PC World / Currys Workington were selling ex-display model mice as new with no discount.

Rof playing with his new giant tennis ball. Thanks Uncle Ian.

10 plays
Glasgow snow, full on: 

Added an exposure gradient to the bottom of this pic, I always find it makes snow pictures ‘pop’ a little more.
Also, I think my lens must have some dust specs on it ;) Glasgow snow, full on:

Added an exposure gradient to the bottom of this pic, I always find it makes snow pictures ‘pop’ a little more.

Also, I think my lens must have some dust specs on it ;)

Rails 2.3.9 weirdness in eager loading an ordered has_many :through assocation

Snappy title, eh.

I ran into this bug while trying to update an app to 2.3.9. I know of a workaround but I’m struggling to write a test that reproduces it in the AR source. So until I get around to doing that, heres the weirdness:

class Job < ActiveRecord::Base
  has_many :job_memberships, :dependent => :destroy
  has_many :users, :through => :job_memberships, :order => "users.last_name, users.first_name"
end

(I’m sure you can guess what job_memberships and users look like)

Job.find(165, :include => :users)

Results in:

ActiveRecord::StatementInvalid: Mysql::Error: Unknown column 'users.last_name' in 'order clause':
SELECT `job_memberships`.* FROM `job_memberships` WHERE (`job_memberships`.job_id = 165) ORDER BY
users.last_name, users.first_name

Now a similar bug exists and has been fixed, which lead me to the workaround.

In job.rb, add the :source key to the has_many through definition

  has_many :users, :through => :job_memberships, :order => "users.last_name, users.first_name", :source => :user

… and the eager loading works.

I’ve been so busy trying to write a test that replicates it in the AR test suite that I’ve not actually looked into fixing it, but I suspect like the bug mentioned above it’s in the preload_through_records method in association_preload.rb.

I’ll try again later to write it, but in the mean time this may be useful to someone :)

I'm Andrew Donaldson, a developer working in west Cumbria

view archive