GithubHelp home page GithubHelp logo

roundsman's Introduction

Roundsman

This is an attempt to combine the powers of Capistrano and chef-solo.

The only thing you need is SSH access and a supported OS. At this time only Ubuntu is supported.

Introduction

You can skip this if you already know about Capistrano and Chef.

Installing servers can be tedious work. Keeping your configuration in sync can be hard too. Chef is an excellent tool for managing this. It can provision your server from scratch. It can also be run again and again to check and update your configuration if needed.

Capistrano is an excellent tool for deployment. It can deploy your code on multiple machines, with clever defaults, limited downtime and the ability to quickly roll back your deployment if something has gone wrong.

Roundsman aims to integrate Capistrano and Chef. This means that with every deploy, it can check and update your configuration if needed. Are you using a new version of Ruby in your next release? It will automatically install when you deploy! Adding a new machine to your cluster? No problem! Roundsman will go from a bare bones Linux machine to a working server in minutes!

Before you can use Roundsman, you need to know how to use Capistrano and how to write Chef recipes. Here are some resources you might want to check out:

Feeling comfortable you can tackle deploying your application with Capistrano and Chef? Now you can use Roundsman to combine them.

Installing

Roundsman runs on Ruby 1.8.7 and above.

If you're using Bundler, you can add Roundsman to your Gemfile:

# Gemfile

gem 'roundsman', :require => false

Run bundle install to get it.

If you're not using Bundler, you can install Roundsman by hand:

$ gem install roundsman

And "capify" your project:

$ capify .

Next, load Roundsman in Capfile

# Capfile

require 'roundsman/capistrano'

Usage

By default, Roundsman assumes you put your Chef cookbooks inside config/cookbooks. If you don't like this, see the Configuration chapter. But here we're going to use that.

I'm also going to assume that you put all Capistano configuration inside config/deploy.rb. When you have a lot of configuration or use the multistage extension, you might want to place it elsewhere.

After configuring Capistrano and writing and downloading Chef recipes, you can hook them up, with a Capistrano hook. Simply provide provide a run list. Let's say you want to run the default recipe of your own cookbook, called main.

# config/deploy.rb

before "deploy:update_code" do
  roundsman.run_list "recipe[main]"
end

I'm hooking it up before the update_code command, and not before deploy so it will also run when running cap deploy:migrations.

Setting up a webserver usually requires that you have the code already there; otherwise restarting nginx or Apache will fail, because it cannot find your application yet. To remedy that you can make another recipe that will configure your webserver and have it run after deploying your new code:

# config/deploy.rb

after "deploy:create_symlink" do
  roundsman.run_list "recipe[main::webserver]"
end

If you want a recipe to only run on a specific role, you can do so like this:

# config/deploy.rb

namespace :install do
  task :postgres, :roles => [:db] do
    roundsman.run_list "recipe[main::postgres]"
  end
end

before "deploy:update_code", "install:postgres"

Configuration

By default, Roundsman will make a lot of Capistrano's configuration available to chef.

So, you might have these settings:

# config/deploy.rb

set :application, "my-awesome-blog"
set :rails_env, "production"
set :deploy_to, "/var/www/#{application}-#{rails_env}"
set :user, "deployer"

Here's how you can use them inside your recipes:

# config/cookbooks/main/recipes/default.rb

directory File.join(node[:deploy_to], "uploads") do
  owner node[:user]
  owner node[:user]
  recursive true
end

Every configuration option from Capistrano is available in Chef. If your using the passenger_apache2 cookbook for example, you can set the attributes like this:

# config/deploy.rb

set :passenger, :version => "3.0.12", :max_pool_size => 4

There are also a set of configuration options for Roundsman itself. They all have sensible defaults, but you can override them if needed. To read all the default configuration:

$ cap roundsman:configuration

You can also perform a lot of tasks by hand if you need to. Here's how to get information:

$ cap --tasks roundsman

To get more information, use the --explain flag and specify a task name, like this:

$ cap --explain roundsman:install_ruby

How does it work?

What Roundsman does is this:

It will determine if you have the right version of Ruby installed. Your machine might already have an older version of Ruby installed, so if it needs to, it will use ruby-build to install the version of Ruby you need for your application.

Then, it will install check the version of chef-solo and install or upgrade as needed.

It will then copy over the cookbooks from your local machine to your deployment machine. This means that you don't need to commit every change while you're still working on it.

It will create your node.json file based upon your Capistrano configuration and run the recipes needed.

This is all done in Capistrano hooks, using Capistrano methods like run, so you can determine when and how your recipes are run.

Tips

Colors

Capistrano and Chef both give a lot of output. Check out capistrano_colors to colorize your output for better readability.

Vagrant

If you want to test out your configuration locally, you should take a look at Vagrant. It makes managing a VirtualBox a breeze. You can even create a stage just for Vagrant with the Capistrano multistage extension.

Contributing

If you want to help out, please! Create an issue or do a pull request and I will take a look at it.

To get this project up and running, make sure you have VirtualBox, because we use vagrant. Then all you need to do is:

bundle install
rake

roundsman's People

Contributors

arie avatar flamefork avatar iain avatar maxim avatar mikesmullin avatar ryross avatar tk0miya avatar vollnhals avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

roundsman's Issues

Use Ruby apt package instead of compiling from source

Why is there are requirement for 1.9.2-p192?

There is a package on aptitude with 1.9.2p0. I've used this and it works. Compiling from source takes forever.

From http://www.ruby-lang.org/en/downloads/

Debian GNU/Linux uses the apt package manager system. (So does Ubuntu.) You can use it like this:

$ sudo apt-get install ruby1.9.1
Yes, this will install Ruby 1.9.2. It has a ‘library compatibility version’ of 1.9.1, hence the name.

Dependency issues with chef 0.10.8

I'm not exactly sure what has change, it is probably an issue with one of minor-chef version, but I get a dependency-error for the chef-install with 0.10.8:

 * executing "sudo -p 'sudo password: ' gem install chef -v \"~> 0.10.8\" --quiet --no-ri --no-rdoc"
    servers: ["192.168.1.10"]
    [192.168.1.10] executing command
ERROR:  While executing gem ... (Gem::DependencyError)
    Unable to resolve dependencies: chef requires net-ssh (~> 2.2.2); net-ssh-multi requires net-ssh (>= 2.1.4); net-ssh-gateway requires net-ssh (>= 2.6.5)
    command finished in 23491ms
failed: "env RAILS_ENV=production GIT_SSL_NO_VERIFY=true sh -c 'sudo -p '\\''sudo password: '\\'' gem install chef -v \"~> 0.10.8\" --quiet --no-ri --no-rdoc'" on 192.168.1.10

If updated the chef-reference to use 11.4.0&the error is gone. Not sure how much else this breaks, but this seems to be working for now...

Roles are ignored

I have a task similar to this:

namespace :provision do
  task :redis, roles: :redis do
    roundsman.run_list('recipe[redis::server]')
  end
end

And roles like this

role :web, 'web01'
role :app, 'app01'
role :db, 'db01', primary: true
role :redis, 'redis01'

When I run cap provision:redis, I expect it to run recipe[redis::server] only on redis01 host (as per README). Instead, it runs on every host.

  * 01:27:09 == Currently executing `roundsman:chef:chef_solo'
 ** Now running recipe[redis::server]
  * executing "sudo -p 'sudo password: ' chef-solo -c /tmp/roundsman/solo.rb -j /tmp/roundsman/solo.json"
    servers: ["web01", "app01", "db01", "redis01"]
    [db01] executing command
    [web01] executing command
    [redis01] executing command
    [app01] executing command

I made a sanity check by adding this test task.

task :foo, roles: :redis do
  run "echo foo"
end

Running cap foo only ran this task on redis server, as expected.

generate_attributes & remove_procs_from_hash involve a caching of some capistrano variables values

Methods from https://github.com/iain/roundsman/blob/master/lib/roundsman/capistrano.rb attempt to leave capistrano variables (
https://github.com/capistrano/capistrano/blob/master/lib/capistrano/configuration/variables.rb) unaffected but does not actually do this.

For example, after an execution of generate_attributes :releases variable defined at
https://github.com/capistrano/capistrano/blob/master/lib/capistrano/recipes/deploy.rb#L60 is evaluated and cached.

This happens because :releases variable is referenced from :current_releases and :previous_release.

This problem is important when combining chef:default and deploy:cold tasks in another task. deploy:cold updates releases but :releases variable value is already evaluated and cached.

add suport for data_bags

Support for (encrypted) databags would be very nice.
There are some forks out there, but I can't try them.

when I try to install the gems with

bundle install
rake install

I get the following error when running cap -T:

cannot load such file -- roundsman/capistrano (LoadError)

No release should not be required

If a server doesn't need the app deployed on it, it doesn't mean I don't want to run chef on it. How come all tasks in roundsman are tagged with except: { no_release: true}? That makes it impossible to bootstrap, say, a redis server, on which you don't want your app deployed.

care_about_ruby_version doesn't work

https://github.com/iain/roundsman/blob/master/lib/roundsman/capistrano.rb#L95

here

  if installed_version.include?(required_version)
    if fetch(:care_about_ruby_version)
      logger.info "Ruby #{installed_version} matches the required version: #{required_version}."
      return false
    else
      logger.info "Already installed Ruby #{installed_version}, not #{required_version}. Set :care_about_ruby_version if you want to fix this."
      return false
    end
  else
    logger.info "Ruby version mismatch. Installed version: #{installed_version}, required is #{required_version}"
    return true
  end

I had another version of ruby installed
no matter what I set to care_about_ruby_version, install_ruby? will always return true, and roundsman will always install ruby
I think it's illogical.

and maybe it's better in this way

  if fetch(:care_about_ruby_version)
    if installed_version.include?(required_version)
      logger.info "Ruby #{installed_version} matches the required version: #{required_version}."
      return false
    else
      logger.info "Ruby version mismatch. Installed version: #{installed_version}, required is #{required_version}"
      return true
    end
  else
    logger.info "Already installed Ruby #{installed_version}, not #{required_version}. Set :care_about_ruby_version if you want to fix this."
    return false
  end

roundsman_working_directory is not cleaned

When unpacking cookbooks, new cookbook directories are simply copied over existing ones. This means, when changing cookbook versions, old files may remain on the remote machine. In my case, this lead to a hard to find bug, where stuff from a leftover libraries file shadowed some newly introduced definitions.

As a quick fix I added a capistrano task which purges the roundsman_working_directory before each run. Either this should be the default behavior or we need a more sophisticated way of removing old cookbooks before unpacking cookbook.tar.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.