the blog

WarningShot - New advanced ‘no more tears’ formula

WarningShot is a project I have been working on for quiet a while and I now feel that it is stable enough to be available to the masses.

WarningShot is a dependency resolution framework with the goal of making staging machines for software as simple as possible, so developers can focus on developing. Another goal of the project is to get rid the process of keeping Wikis on how to set up servers to meet the requirements for an application.

Like a lot of developers I have rake and cap scripts that do all sorts of things for me when I deploy software, like create symlinks for database.yml files, install gems, you name it.  I also have a different wiki page for every application and every type of server role.  Sometimes I forget to cross update stuff and next thing you know the next deployment sucks.

How does WarningShot solve this problem?  Well WarningShot is composed of one or many ‘machine recipes’ or config files (YAML).  Machine recipes are essentially list of requirements and dependencies to make a machine environment be ideal for your software (or just to your liking, I use warningshot to set up computers to my liking, keeping all my computers uniform).  Machine recipes are kept in your source repository and should be updated whenever features are added or removed.  So instead of updating a wiki, you update the config files, this way any version of your application that is release also has a set of specs with it that determine what it would take to properly stage a computer to run it.

You might be saying, ‘well that sounds neat, but what does it look like?’

WarningShot Machine Recipes can be as complicated or as simple as you want.  Each recipe can contain one or more ‘branch.’  A branch is a part of the Dependency Tree that is created when all of the related Machine Recipes are loaded for an application.  Here is a simple recipe to spec out gems that an example application might require.

---
:branch: gem
:environments:
  :production:
    - {name: 'merb-core', version: '>0.9.5'}
    - {name: 'dm-core', version: '>0.9.5'}
    - rack

In the above example I essentially stated that I am dependent on merb v 0.9.5 or greater, datamapper v 0.9.5 or greater and any version of rack when in production mode (there is also a ‘global’ environment that you can set requirements in as well to make them apply to all environments: test, qa, development, production, etc).

Here is a more complex Machine Recipe:

---
- :branch: gem
  :environments:
    :global:
      - {name: 'merb-core', version: '>0.9.5'}
      - {name: 'dm-core', version: '>0.9.5'}
      - rack
- :branch: file
  :environments:
    :global:
      - {source: 'http://example.com/nginx/nginx.conf', target: '/etc/nginx/nginx.conf', md5: '16ec37c499f64fc60e95650b500e30a4'}
- :branch: directory
  :environments:
    :global:
      - /tmp/uploads
      - /mnt/media/images
- :branch: symlink
  :environments:
    :global:
      - {source: '/tmp/uploads', target: './public/uploads', force: true}

The second machine recipe states my app’s gem, file, directory, and symlink dependency (note, when multiple branches are listed they should be prefixed with a hyphen).

So what makes this better than a wiki?  This:

$: sudo warningshot –resolve

A simple one line command and having to remember to set up dependencies becomes a thing of the past.

You can interface with WarningShot from your Cap or Vlad scripts and deploy to a machine that has never been set up and have nothing to worry about. WarningShot will give you statistics and let you know if there was anything it wasn’t able to fix.  Another great place to use WarningShot is to get up and running on new projects.  Instead of a developer spending a few hours reading Wikis on how to set up an application and configuring all the dependencies if WarningShot is installed and the configs are up to date a simple ‘warningshot –resolve’ will set the environment all up.

WarningShot can do a lot of things out of the box, er out of the github, whatever. Currently it supports the following dependency resolvers:

  • File
  • Directory
  • Symlink
  • Gem
  • URL
  • CoreLib
  • Manual
WarningShot can’t fix everything (yet) and that is why there is a ‘ManualResolver’ which is a glorified TODO list. If there is anything that you can’t resolve with WarningShot you can put it in the ManualResolver and after WarningShot fixes what it can it’ll output the TODOS so the developer knows exactly what else needs to be done.  No web page or wiki to hunt down, its all together.
Beside a TODO list the ManualResolver serves as a ‘feature request.’ Anything that can’t be resolved by WarningShot, in my opinion, should be able to be resolved by WarningShot. So if you use the ManualResolver, send me a feature request and tell me what I need to implement or even better join in on the project :).
This post is really just meant as an introduction, stay tuned for more posts about WarningShot in the near future.  If you are interested in using WarningShot and want some more reading check out these wikis.
If you are interested in hacking on it, check out http://github.com/coryodaniel/warningshot or http://warningshot.lighthouseapp.com.

Leave a Reply