saucier 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in backerman.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,5 @@
1
+ guard 'minitest' do
2
+ watch(%r|^spec/(.*)_spec\.rb|)
3
+ watch(%r{^lib/(.*/)?([^/]+)\.rb$}) { |m| "spec/#{m[2]}_spec.rb" }
4
+ watch(%r|^spec/spec_helper\.rb|) { "spec" }
5
+ end
data/README.md ADDED
@@ -0,0 +1,52 @@
1
+ # saucier
2
+
3
+ saucier is a Capistrano Extension that uses [librarian](https://github.com/applicationsonline/librarian.git "chef-librarian")
4
+ and [chef-solo](https://github.com/opscode/chef "chef") to manage project dependencies and provision servers for your project.
5
+
6
+ Use Capistrano Multistage to manage your servers and environments.
7
+
8
+ Use with [cap-strap](https://github.com/substantial/cap-strap "cap-strap") to bootstrap new servers.
9
+
10
+
11
+ [A sample project using saucier may be found](https://github.com/substantial/saucier-example)
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ gem 'saucier'
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ ## Usage
24
+ Make sure your project has a Cheffile with required chef cookbooks.
25
+
26
+ ###Configuration:
27
+
28
+ * `set :user, "<user that will be executing chef-solo>"` - default: "deploy"
29
+ * `set :group, "<group for deploy user. keep as rvm if using rvm>"` - default: "rvm"
30
+ * `set :chef_deploy_to, "<set path for deploying chef-solo>"` - default: "/etc/chef"
31
+ * `set :chef_ruby, "<ruby you'd like to run librarian and chef-solo>"` - default: "default"
32
+ * `set :chef_gemset, "<gemset for chef>"` - default: "global"
33
+ * `set :chef_solo_config, "<relative path to the chef solo config>"` - default ".chef/solo.rb"
34
+ * `set :chef_node_config, "<relative path to your node config>"` - default ".chef/node.json"
35
+
36
+ ## Testing
37
+
38
+ We're https://github.com/fnichol/minitest-capistrano for testing the capistrano
39
+ configuration.
40
+
41
+ Running Tests:
42
+
43
+ * `rake test` - manually run the tests
44
+ * `bundle exec guard start` - Use guard to watch for changes and run tests automatically.
45
+
46
+ ## Contributing
47
+
48
+ 1. Fork it
49
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
50
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
51
+ 4. Push to the branch (`git push origin my-new-feature`)
52
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs.push "lib"
6
+ t.test_files = FileList['spec/*_spec.rb']
7
+ t.verbose = true
8
+ end
9
+
10
+ task :default => 'test'
@@ -0,0 +1,5 @@
1
+ def _cset(name, *args, &block)
2
+ unless exists?(name)
3
+ set(name, *args, &block)
4
+ end
5
+ end
@@ -0,0 +1,35 @@
1
+ require 'capistrano'
2
+ require 'saucier/helpers'
3
+
4
+ module Capistrano::Saucier
5
+ module Recipes
6
+ module ChefLibrarian
7
+ def self.load_into(configuration)
8
+ configuration.load do
9
+
10
+ _cset(:chef_ruby, "default")
11
+ _cset(:chef_gemset, "global")
12
+
13
+ namespace :chef_librarian do
14
+ task :default do
15
+ chef_librarian.install
16
+ end
17
+
18
+ task :install do
19
+ command = []
20
+ command << ". /etc/profile.d/rvm.sh"
21
+ command << "cd #{current_release}"
22
+ command << "rvm use #{chef_ruby}@#{chef_gemset} --create"
23
+ command << "bundle exec librarian-chef install"
24
+ run command.join(" && ")
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ if instance = Capistrano::Configuration.instance
34
+ Capistrano::Saucier::Recipes::ChefLibrarian.load_into(instance)
35
+ end
@@ -0,0 +1,40 @@
1
+ require 'capistrano'
2
+ require 'saucier/helpers'
3
+
4
+ module Capistrano::Saucier
5
+ module Recipes
6
+ module ChefSolo
7
+ def self.load_into(configuration)
8
+ configuration.load do
9
+ _cset(:chef_ruby, "default")
10
+ _cset(:chef_gemset, "global")
11
+ _cset(:chef_solo_config, ".chef/solo.rb")
12
+ _cset(:chef_node_config, ".chef/node.json")
13
+
14
+ namespace :chef_solo do
15
+ task :default do
16
+ chef_solo.install
17
+ end
18
+
19
+ task :install do
20
+ servers = find_servers_for_task(current_task)
21
+ servers.each do |s|
22
+ node_name = s.options[:node_name] ||= 'chef-node'
23
+ command = []
24
+ command << ". /etc/profile.d/rvm.sh"
25
+ command << "cd #{current_release}"
26
+ command << "rvm use #{chef_ruby}@#{chef_gemset} --create"
27
+ command << "rvmsudo chef-solo -c #{current_release}/#{chef_solo_config} -j #{current_release}/#{chef_node_config} -N #{node_name}"
28
+ run command.join(" && ")
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ if instance = Capistrano::Configuration.instance
39
+ Capistrano::Saucier::Recipes::ChefSolo.load_into(instance)
40
+ end
data/lib/saucier.rb ADDED
@@ -0,0 +1,59 @@
1
+ require 'capistrano'
2
+
3
+ require "saucier/recipes/chef_solo"
4
+ require "saucier/recipes/chef_librarian"
5
+
6
+ module Capistrano::Saucier
7
+ require 'saucier/helpers'
8
+
9
+ def self.load_into(configuration)
10
+ configuration.load do
11
+ _cset(:chef_deploy_to, "/etc/chef")
12
+ _cset(:user, "deploy")
13
+ _cset(:group, "rvm")
14
+
15
+ namespace :provision do
16
+ after 'deploy:setup', 'provision:set_ownership'
17
+ after 'deploy:update_code', 'provision:bundle_install'
18
+
19
+ set :deploy_to, chef_deploy_to
20
+
21
+ task :default do
22
+ transaction do
23
+ deploy.update_code
24
+ chef_librarian.default
25
+ chef_solo.default
26
+ provision.symlink_cookbooks
27
+ end
28
+ end
29
+
30
+ task :setup do
31
+ deploy.setup
32
+ end
33
+
34
+ task :set_ownership do
35
+ sudo "chown -R #{user}:#{group} #{deploy_to}"
36
+ end
37
+
38
+ task :symlink_cookbooks do
39
+ shared_dir = File.join(shared_path, 'cookbooks')
40
+ release_dir = File.join(current_release, 'cookbooks')
41
+ run "mkdir -p #{shared_dir}; ln -s #{shared_dir} #{release_dir}"
42
+ end
43
+
44
+ task :bundle_install do
45
+ command = []
46
+ command << ". /etc/profile.d/rvm.sh"
47
+ command << "cd #{current_release}"
48
+ command << "rvm use #{chef_ruby}@#{chef_gemset} --create"
49
+ command << "bundle install"
50
+ run command.join(" && ")
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ if instance = Capistrano::Configuration.instance
58
+ Capistrano::Saucier.load_into(instance)
59
+ end
data/saucier.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "saucier"
6
+ s.version = "0.0.1"
7
+ s.authors = ["Shaun Dern"]
8
+ s.email = ["shaun@substantial.com"]
9
+ s.homepage = "http://github.com/substantial/saucier"
10
+ s.summary = %q{A Capistrano Extension that uses librarian and chef-solo for provisioning a server.}
11
+ s.description = %q{A Capistrano Extension that uses librarian and chef-solo to track your project cookbook dependencies.
12
+ Use capistrano stages to quickly provision servers for your project. Version control your chef runlist, node configuration
13
+ and cookbook dependencies.
14
+ }
15
+
16
+ s.rubyforge_project = "saucier"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+
23
+ s.add_development_dependency "rake", "~> 0.9.2.2"
24
+ s.add_development_dependency "minitest", "~> 2.12.0"
25
+ s.add_development_dependency "minitest-capistrano", "~> 0.0.8"
26
+ s.add_development_dependency "minitest-colorize", "~> 0.0.4"
27
+ s.add_development_dependency "guard-minitest", "~> 0.5.0"
28
+
29
+ s.add_dependency "capistrano", ">= 2.0.0"
30
+ end
@@ -0,0 +1,45 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
2
+
3
+ describe Capistrano::Saucier::Recipes::ChefLibrarian do
4
+
5
+ load_capistrano_recipe(Capistrano::Saucier::Recipes::ChefLibrarian)
6
+
7
+ describe "tasks" do
8
+ it "has :install" do
9
+ recipe.must_have_task "chef_librarian:install"
10
+ end
11
+
12
+ it "has :default" do
13
+ recipe.must_have_task "chef_librarian:default"
14
+ end
15
+ end
16
+
17
+ describe "default values" do
18
+ it "chef_ruby is 'default'" do
19
+ subject.fetch(:chef_ruby).must_equal "default"
20
+ end
21
+
22
+ it "chef_gemset is 'global'" do
23
+ subject.fetch(:chef_gemset).must_equal "global"
24
+ end
25
+ end
26
+
27
+ describe "task :install" do
28
+ let(:install_command) {
29
+ command = []
30
+ command << ". /etc/profile.d/rvm.sh"
31
+ command << "cd current/release/path"
32
+ command << "rvm use default@global --create"
33
+ command << "bundle exec librarian-chef install"
34
+ command.join(" && ")
35
+ }
36
+ before do
37
+ recipe.set(:current_release) { 'current/release/path' }
38
+ recipe.find_and_execute_task("chef_librarian:install")
39
+ end
40
+
41
+ it "runs librarian-chef install" do
42
+ recipe.must_have_run install_command
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,33 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
2
+
3
+ describe Capistrano::Saucier::Recipes::ChefSolo do
4
+ load_capistrano_recipe(Capistrano::Saucier::Recipes::ChefSolo)
5
+
6
+ describe "tasks" do
7
+ it "has chef:install" do
8
+ recipe.must_have_task "chef_solo:install"
9
+ end
10
+
11
+ it "has chef:default" do
12
+ recipe.must_have_task "chef_solo:default"
13
+ end
14
+ end
15
+
16
+ describe "default values" do
17
+ it "chef_ruby" do
18
+ recipe.fetch(:chef_ruby).must_equal "default"
19
+ end
20
+
21
+ it "chef_gemset" do
22
+ recipe.fetch(:chef_gemset).must_equal "global"
23
+ end
24
+
25
+ it "chef_solo_config" do
26
+ recipe.fetch(:chef_solo_config).must_equal ".chef/solo.rb"
27
+ end
28
+
29
+ it "chef_node_config" do
30
+ recipe.fetch(:chef_node_config).must_equal ".chef/node.json"
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,43 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
2
+
3
+ describe Capistrano::Saucier do
4
+ load_capistrano_recipe(Capistrano::Saucier)
5
+
6
+ describe "variables" do
7
+ it "has a chef_deploy_to" do
8
+ recipe.fetch(:chef_deploy_to).must_equal "/etc/chef"
9
+ end
10
+
11
+ it "sets deploy_to to the chef_deploy_to" do
12
+ recipe.fetch(:deploy_to).must_equal recipe.fetch(:chef_deploy_to)
13
+ end
14
+ end
15
+
16
+ describe "tasks" do
17
+ it "sets ownership" do
18
+ recipe.must_have_task "provision:set_ownership"
19
+ end
20
+
21
+ it "has a task for bundle install" do
22
+ recipe.must_have_task "provision:bundle_install"
23
+ end
24
+
25
+ it "has a task for symlinking cookbooks" do
26
+ recipe.must_have_task "provision:symlink_cookbooks"
27
+ end
28
+
29
+ it "has a setup task" do
30
+ recipe.must_have_task "provision:setup"
31
+ end
32
+ end
33
+
34
+ describe "callbacks" do
35
+ it "bundle installs after update code" do
36
+ recipe.must_have_callback_after "deploy:update_code", "provision:bundle_install"
37
+ end
38
+
39
+ it "sets ownership after setup" do
40
+ recipe.must_have_callback_after "deploy:setup", "provision:set_ownership"
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,26 @@
1
+ require 'capistrano'
2
+
3
+ require 'minitest/autorun'
4
+ require 'minitest/capistrano'
5
+ require 'minitest/colorize'
6
+
7
+ require 'saucier'
8
+
9
+
10
+ def load_capistrano_recipe(recipe)
11
+ before do
12
+ @config = Capistrano::Configuration.new
13
+ @config.extend(MiniTest::Capistrano::ConfigurationExtension)
14
+ @orig_config = Capistrano::Configuration.instance
15
+ Capistrano::Configuration.instance = @config
16
+ recipe.send(:load_into, @config)
17
+ end
18
+
19
+ after do
20
+ Capistrano::Configuration.instance = @orig_config
21
+ end
22
+
23
+ subject {@config}
24
+ let(:recipe) { @config }
25
+ end
26
+
metadata ADDED
@@ -0,0 +1,163 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: saucier
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Shaun Dern
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.9.2.2
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.9.2.2
30
+ - !ruby/object:Gem::Dependency
31
+ name: minitest
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 2.12.0
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 2.12.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: minitest-capistrano
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 0.0.8
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.0.8
62
+ - !ruby/object:Gem::Dependency
63
+ name: minitest-colorize
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 0.0.4
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 0.0.4
78
+ - !ruby/object:Gem::Dependency
79
+ name: guard-minitest
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 0.5.0
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 0.5.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: capistrano
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: 2.0.0
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: 2.0.0
110
+ description: ! "A Capistrano Extension that uses librarian and chef-solo to track
111
+ your project cookbook dependencies.\n Use capistrano stages
112
+ to quickly provision servers for your project. Version control your chef runlist,
113
+ node configuration\n and cookbook dependencies.\n "
114
+ email:
115
+ - shaun@substantial.com
116
+ executables: []
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - .gitignore
121
+ - Gemfile
122
+ - Guardfile
123
+ - README.md
124
+ - Rakefile
125
+ - lib/saucier.rb
126
+ - lib/saucier/helpers.rb
127
+ - lib/saucier/recipes/chef_librarian.rb
128
+ - lib/saucier/recipes/chef_solo.rb
129
+ - saucier.gemspec
130
+ - spec/chef_librarian_spec.rb
131
+ - spec/chef_solo_spec.rb
132
+ - spec/saucier_spec.rb
133
+ - spec/spec_helper.rb
134
+ homepage: http://github.com/substantial/saucier
135
+ licenses: []
136
+ post_install_message:
137
+ rdoc_options: []
138
+ require_paths:
139
+ - lib
140
+ required_ruby_version: !ruby/object:Gem::Requirement
141
+ none: false
142
+ requirements:
143
+ - - ! '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ required_rubygems_version: !ruby/object:Gem::Requirement
147
+ none: false
148
+ requirements:
149
+ - - ! '>='
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ requirements: []
153
+ rubyforge_project: saucier
154
+ rubygems_version: 1.8.22
155
+ signing_key:
156
+ specification_version: 3
157
+ summary: A Capistrano Extension that uses librarian and chef-solo for provisioning
158
+ a server.
159
+ test_files:
160
+ - spec/chef_librarian_spec.rb
161
+ - spec/chef_solo_spec.rb
162
+ - spec/saucier_spec.rb
163
+ - spec/spec_helper.rb