Monday, June 24, 2013

Managing Raspberry Pi with Chef & Bitbucket

The problem:
You have a Pi.
You've overcome that hurdle of thinking up a neat idea.
... but you don't have a means to deploy it to the Pi, and someone keeps coming along to steal the power supply for their Samsung phone.
That, plus your Pi depends on a lot of network configuration or other services to work fully.

The solution:

1) Go and put your Pi next to your Router and ensure both are out of reach. 
Neat cabling often implies secure cabling, so liberal use of zipties will protect your Pi from being beaten out by the collection of hungry smartphones in the house.

2) Make sure you have a passing familiarity with

  • Ruby
  • Bundler
  • Git
  • Bitbucket
  • SSH keys


3) Create a new git repo locally, and a skeleton Chef, Berkshelf setup.
mkdir mypi
cd mypi

# Add bundler
bundle init

# Add some helpful gems
echo 'gem "knife-solo" >> Gemfile
echo 'gem "berkshelf" >> Gemfile

bundle
rbenv rehash
knife solo init
berks init

git add .
git commit -m "Just adding a skeleton"

4) Ensure your SSH keys are on the pi, and go set up your ssh config.
echo "" >> ~/.ssh/config
echo "Host pi.local" >> ~/.ssh/config
echo "User pi" >> ~/.ssh/config

# ssh-keygen if you need to
ssh-copy-id pi@pi.local

5) Finally, start configuring your pi!
echo '{"run_list": [] }' > nodes/pi.local.json
git add nodes/pi.json

bundle exec knife solo prepare pi@pi.local
bundle exec knife solo cook pi@pi.local

5) Go make a pi specific cookbook
cd site-cookbooks
berks cookbook pi
echo 'package "weather-util" do :action install end' >> pi/recipies/default.rb
echo '{"run_list": ["recipe[pi]"] }' > nodes/pi.local.json
git add .
git commit -m "Making some custom pi"
cd ..


6) Run it!
bundle exec knife solo cook -VV pi@pi.local


What just happened?

We added knife-solo, a gem that lets you run chef commands without a chef server.

We made sure our ssh config was right, so we could connect to the machine.

We added berkshelf, a gem to manage chef dependencies/cookbooks (more on this later)

We created nodes/pi.local.json which describes the machine called pi.local. By default, your pi will try to make itself available on this address.

In that recipe, we first gave it an empty run list, but later we added a recipe for your Pi... called... pi.

We added
package "weather-util" do
  action :install
end
to site-cookbooks/pi/recipes/default.rb

... and then updated the nodes/pi.local.json

Finally, we cooked out recipe - the -VV put it into verbose mode.

That installed the 'weather' command onto your pi.

Wouldn't have been easier to do by hand?

Probably, or with Bash scripts + SSH, commititng those to git. What you get from Chef though is more than just bash scripts with a few prebuilt 'test' commands - you can use the entire community of Chef cookbooks to solve a vast majority of your needs.

For example, adding your typically LAMP stack is about as difficult as adding to pi/recipes/default.rb

["mysql", "apache", "php5"].each do |pkg|
  package pkg do
    action :install

  end
end

But then you have to muck around with configuration, starting services, etc.

Instead, I recommend you do something like http://community.opscode.com/cookbooks/apache2

Go do
echo 'cookbook "apache2"'  >> Berksfile
berks install -p cookbooks/

and edit your recipe (pi/recipes/default.rb) to add in

web_app "my_site" do
  server_name node['hostname']
  server_aliases ["pi.local"]
  docroot "/srv/www/my_site"
end

Don't forget to add the relevant depends to the metadata
echo "depends "apache2"' >> site-cookbooks/pi/metadata.rb

And to do the installation steps (remove any previous lines about installing apache you added)
$ cat nodes/pi.local/json

{
  "run_list": ["recipe[apache2::default]", "recipe[pi]"],
  "hostname": "pi.local"
}


and 
bundle exec knife solo cook -VV pi@pi.local

All of a sudden you should have Apache, a named virtualhost, and the contents of "my_site" being served up.

Compare that with manually trying to update a virtualhost, a2ensite it, etc - quite a bit of time can be saved.

More importantly, if you simply add this to git, and publish it to Bitbucket, you instantly have a way to upgrade to a newer server, create a cluster of Pis running your software, or a way to trivially migrate onto the cloud.

Where to from here?

I encourage you to look at cookbooks like newrelic (newrelic is a bad example, as it doesn't have binaries for the pi), so that you can tell if your Pi is up and running when away from the home, as well as things like hamachi - things that let you remotely admin, even behind your home router.

There's plenty of version control cookbooks, allowing you to check out your application from git, or more capistrano like mechanisms.

In general, think of whatever you might need and google "chef opscode (foo) cookbook"

Enhanced by Zemanta

No comments: