toque 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 728adde958810a994d9d16b9d51d2f8cd31ef9dd
4
+ data.tar.gz: f56fb4afebd0bfc9defe5a9e995a4f26a4466f17
5
+ SHA512:
6
+ metadata.gz: 2c689a0d5f297ed1cbd9c4fba502ecf4ab918770afe4eef89c936d1a207dc3593d85e476c5ce127a2e384d1d23d50cb036d4c46c905b0fc938c02cd16ada185f
7
+ data.tar.gz: d13815fc714a02a45cb16a4fb3a783e970b3761910b5387078a3aa8464cf0401104fcc7de1b1b21b5b39716174ad1ca826e4af7b6b9269b9e2a4561ee1c297cd
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ *.iml
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ .idea
8
+ .vagrant
9
+ Gemfile.lock
10
+ InstalledFiles
11
+ _yardoc
12
+ coverage
13
+ doc/
14
+ lib/bundler/man
15
+ pkg
16
+ rdoc
17
+ spec/reports
18
+ test/tmp
19
+ test/version_tmp
20
+ tmp
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 1.9.3
data/Capfile ADDED
@@ -0,0 +1,3 @@
1
+ load 'deploy'
2
+ load 'spec/config/deploy'
3
+ require 'toque'
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in toque.gemspec
4
+ gemspec
5
+
6
+ group :development, :test do
7
+ gem 'rake'
8
+ gem 'rspec'
9
+ gem 'vagrant', '>= 1.0.7'
10
+ gem 'bundler', '~> 1.3'
11
+ gem 'capistrano-spec', github: 'jgraichen/capistrano-spec'
12
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Jan Graichen
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,109 @@
1
+ # Toque - The cap of a Chef
2
+
3
+ [![Build Status](https://travis-ci.org/jgraichen/toque.png?branch=master)](https://travis-ci.org/jgraichen/toque)
4
+
5
+ **Toque** combines the power of *chef-solo* and *capistrano*. It allows you to
6
+ run chef cookbooks with chef-solo as part of your capistrano deploy process.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'toque'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install toque
21
+
22
+ After capifying your project add to your `Capfile`:
23
+
24
+ ```ruby
25
+ require 'toque'
26
+ ```
27
+
28
+ You can install chef by running `cap toque:chef:install` otherwise it will be
29
+ installed on first `run_list` call. **Toque** uses chef omnibus installer to
30
+ install a complete self-contained embedded chef environment.
31
+
32
+ You can specify a specific chef version by setting `:chef_version` to
33
+ something different to `:latest` or `nil`. An already installed version of
34
+ chef will not be upgraded.
35
+
36
+ See `cap toque:config` for more options.
37
+
38
+ ## Usage
39
+
40
+ **Toque** assumes your cookbooks to be in `config/cookbooks` or
41
+ `vendor/cookbooks`. One way is to use `config/cookbooks` for your own
42
+ application cookbook(s) and `vendor/cookbooks` for community cookbooks managed
43
+ by [librarian-chef](https://github.com/applicationsonline/librarian-chef).
44
+
45
+ You can configure *librarian-chef* to use `vendor/cookbooks` as cookbook path:
46
+
47
+ ```bash
48
+ $ librarian-chef config path ./vendor/cookbooks --local
49
+ ```
50
+
51
+ In your deploy configuration you can now run `toque.run_list` with a list of
52
+ recipes you want to execute. You can run chef more then once with different
53
+ list.
54
+
55
+ For example if you want to setup the server before deploying your app run
56
+ your setup recipe right at the start:
57
+
58
+ ```ruby
59
+ before "deploy:update_code" do
60
+ toque.run_list 'recipe[awesome::setup]'
61
+ end
62
+ ```
63
+
64
+ After deploying your app you may need to create a config for your application
65
+ like `database.yml` or redis configuration:
66
+
67
+ after "deploy:create_symlink" do
68
+ toque.run_list 'recipe[awesome::configure]'
69
+ end
70
+
71
+ ## Configuration
72
+
73
+ By default all capistrano options are available in your node configuration:
74
+
75
+ ```ruby
76
+ # config/deploy.rb
77
+
78
+ set :application, 'awesomeium'
79
+ set :deploy_to, "/var/www/#{application}"
80
+ set :user, 'awesomeix'
81
+
82
+ # config/cookbooks/awesome/recipes/configure.rb
83
+
84
+ template File.join(node[:deploy_to], 'config', 'database.yml') do
85
+ source 'database.yml.erb'
86
+ owner node[:user]
87
+ recursive true
88
+ end
89
+ ```
90
+
91
+ ## Thanks
92
+
93
+ Thanks to [roundsman](https://github.com/iain/roundsman) doing even some more
94
+ tasks like installing ruby and chef via rubygems. I've decided to make up
95
+ something new to use omnibus installer right from the start.
96
+
97
+ Also take a look at
98
+ [capistrano-spec](https://github.com/technicalpickles/capistrano-spec) allowing
99
+ some really great capistrano testing.
100
+
101
+ ## Contributing
102
+
103
+ 1. Fork it
104
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
105
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
106
+ 4. Push to the branch (`git push origin my-new-feature`)
107
+ 5. Create new Pull Request
108
+
109
+ You can run a simple vagrant based test by running `bundle exec rspec spec/spec_toque.rb`.
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,99 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant::Config.run do |config|
5
+ # All Vagrant configuration is done here. The most common configuration
6
+ # options are documented and commented below. For a complete reference,
7
+ # please see the online documentation at vagrantup.com.
8
+
9
+ # Every Vagrant virtual environment requires a box to build off of.
10
+ config.vm.box = 'precise32'
11
+
12
+ # The url from where the 'config.vm.box' box will be fetched if it
13
+ # doesn't already exist on the user's system.
14
+ config.vm.box_url = 'http://files.vagrantup.com/precise32.box'
15
+
16
+ # Boot with a GUI so you can see the screen. (Default is headless)
17
+ # config.vm.boot_mode = :gui
18
+
19
+ # Assign this VM to a host-only network IP, allowing you to access it
20
+ # via the IP. Host-only networks can talk to the host machine as well as
21
+ # any other machines on the same network, but cannot be accessed (through this
22
+ # network interface) by any external networks.
23
+ config.vm.network :hostonly, "192.168.33.10"
24
+
25
+ # Assign this VM to a bridged network, allowing you to connect directly to a
26
+ # network using the host's network device. This makes the VM appear as another
27
+ # physical device on your network.
28
+ # config.vm.network :bridged
29
+
30
+ # Forward a port from the guest to the host, which allows for outside
31
+ # computers to access the VM, whereas host only networking does not.
32
+ # config.vm.forward_port 80, 8080
33
+
34
+ # Share an additional folder to the guest VM. The first argument is
35
+ # an identifier, the second is the path on the guest to mount the
36
+ # folder, and the third is the path on the host to the actual folder.
37
+ # config.vm.share_folder "v-data", "/vagrant_data", "../data"
38
+
39
+ # Enable provisioning with Puppet stand alone. Puppet manifests
40
+ # are contained in a directory path relative to this Vagrantfile.
41
+ # You will need to create the manifests directory and a manifest in
42
+ # the file base.pp in the manifests_path directory.
43
+ #
44
+ # An example Puppet manifest to provision the message of the day:
45
+ #
46
+ # # group { "puppet":
47
+ # # ensure => "present",
48
+ # # }
49
+ # #
50
+ # # File { owner => 0, group => 0, mode => 0644 }
51
+ # #
52
+ # # file { '/etc/motd':
53
+ # # content => "Welcome to your Vagrant-built virtual machine!
54
+ # # Managed by Puppet.\n"
55
+ # # }
56
+ #
57
+ # config.vm.provision :puppet do |puppet|
58
+ # puppet.manifests_path = "manifests"
59
+ # puppet.manifest_file = "base.pp"
60
+ # end
61
+
62
+ # Enable provisioning with chef solo, specifying a cookbooks path, roles
63
+ # path, and data_bags path (all relative to this Vagrantfile), and adding
64
+ # some recipes and/or roles.
65
+ #
66
+ # config.vm.provision :chef_solo do |chef|
67
+ # chef.cookbooks_path = "../my-recipes/cookbooks"
68
+ # chef.roles_path = "../my-recipes/roles"
69
+ # chef.data_bags_path = "../my-recipes/data_bags"
70
+ # chef.add_recipe "mysql"
71
+ # chef.add_role "web"
72
+ #
73
+ # # You may also specify custom JSON attributes:
74
+ # chef.json = { :mysql_password => "foo" }
75
+ # end
76
+
77
+ # Enable provisioning with chef server, specifying the chef server URL,
78
+ # and the path to the validation key (relative to this Vagrantfile).
79
+ #
80
+ # The Opscode Platform uses HTTPS. Substitute your organization for
81
+ # ORGNAME in the URL and validation key.
82
+ #
83
+ # If you have your own Chef Server, use the appropriate URL, which may be
84
+ # HTTP instead of HTTPS depending on your configuration. Also change the
85
+ # validation key to validation.pem.
86
+ #
87
+ # config.vm.provision :chef_client do |chef|
88
+ # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
89
+ # chef.validation_key_path = "ORGNAME-validator.pem"
90
+ # end
91
+ #
92
+ # If you're using the Opscode platform, your validator client is
93
+ # ORGNAME-validator, replacing ORGNAME with your organization name.
94
+ #
95
+ # IF you have your own Chef Server, the default validation client name is
96
+ # chef-validator, unless you changed the configuration.
97
+ #
98
+ # chef.validation_client_name = "ORGNAME-validator"
99
+ end
@@ -0,0 +1,18 @@
1
+ require 'capistrano'
2
+
3
+ require 'toque/version'
4
+ require 'toque/helpers'
5
+ require 'toque/tasks'
6
+ require 'toque/chef'
7
+
8
+ module Toque
9
+ def self.load_into(configuration)
10
+ Toque::Helpers.load_into configuration
11
+ Toque::Tasks.load_into configuration
12
+ Toque::Chef.load_into configuration
13
+ end
14
+ end
15
+
16
+ if Capistrano::Configuration.instance
17
+ Toque.load_into Capistrano::Configuration.instance
18
+ end
@@ -0,0 +1,145 @@
1
+ require 'tempfile'
2
+
3
+ module Toque
4
+
5
+ # Tasks and method to interact with chef.
6
+ #
7
+ module Chef
8
+ def self.load_into(configuration)
9
+ configuration.load do
10
+
11
+ namespace :toque do
12
+ namespace :chef do
13
+
14
+ set_default :chef_omnibus_installer_url, 'http://www.opscode.com/chef/install.sh'
15
+ set_default :cookbooks_paths, %w(config/cookbooks vendor/cookbooks)
16
+ set_default :databags_path, 'config/databags'
17
+ set_default :chef_version, :latest
18
+ set_default :chef_debug, false
19
+ set_default :chef_solo, '/opt/chef/bin/chef-solo'
20
+
21
+ # Check if chef-solo installed on remote machine.
22
+ #
23
+ def installed?
24
+ !installed_version.nil?
25
+ end
26
+
27
+ # Return installed chef-solo version.
28
+ #
29
+ def installed_version
30
+ capture("#{chef_solo} -v || true") =~ /Chef: (\d+\.\d+\.\d+)/ ? $1 : nil
31
+ end
32
+
33
+ # Return path to chef solo executable.
34
+ #
35
+ def chef_solo
36
+ fetch(:chef_solo).to_s || 'chef-solo'
37
+ end
38
+
39
+ # Return list of current recipes in run_list.
40
+ #
41
+ def recipes
42
+ Array fetch(:run_list)
43
+ end
44
+
45
+ # Return list of existing cookbook paths.
46
+ #
47
+ def cookbooks_paths
48
+ fetch(:cookbooks_paths).to_a.select { |path| File.exists? path }
49
+ end
50
+
51
+ # Abort if no existing cookbook paths are setted.
52
+ #
53
+ def ensure_cookbooks!
54
+ raise 'No existing cookbook paths found.' if cookbooks_paths.empty?
55
+ end
56
+
57
+ # Return existing databag path or nil if path does not exist.
58
+ #
59
+ def databags_path
60
+ File.exists?((path = fetch(:databags_path))) ? path : nil
61
+ end
62
+
63
+ # Create and return omnibus installer command
64
+ #
65
+ def install_command
66
+ cmd = "#{top.sudo} bash"
67
+ cmd += " -s -- -v #{fetch :chef_version}" unless fetch(:chef_version) == :latest or fetch(:chef_version).nil?
68
+ cmd
69
+ end
70
+
71
+ #
72
+ # Tasks
73
+ #
74
+
75
+ desc 'Install chef via omnibus installed if not preset.'
76
+ task :check do
77
+ install unless installed?
78
+ end
79
+
80
+ desc 'Installs chef using omnibus installer.'
81
+ task :install do
82
+ require_curl
83
+ run "#{top.sudo} true && curl -L #{fetch :chef_omnibus_installer_url} | #{install_command}"
84
+ end
85
+
86
+ namespace :setup do
87
+ desc 'Upload local cookbook to remote server.'
88
+ task :cookbooks do
89
+ pwd!
90
+
91
+ tar = ::Tempfile.new("cookbooks.tar")
92
+ begin
93
+ tar.close
94
+ system "tar -cjf #{tar.path} #{cookbooks_paths.join(' ')} #{databags_path.to_s}"
95
+ upload tar.path, toque.pwd("cookbooks.tar"), :via => :scp
96
+ run "cd #{toque.pwd} && tar -xjf cookbooks.tar"
97
+ ensure
98
+ tar.unlink
99
+ end
100
+ end
101
+
102
+ desc 'Generate and upload chef solo script.'
103
+ task :script do
104
+ pwd!
105
+
106
+ cookbooks = cookbooks_paths.map { |p| %("#{pwd p}") }.join(', ')
107
+ solo = <<-HEREDOC
108
+ file_cache_path "#{pwd! 'cache'}"
109
+ cookbook_path [ #{cookbooks} ]
110
+ data_bag_path "#{pwd databags_path}"
111
+ HEREDOC
112
+ put solo, pwd("node.rb"), :via => :scp
113
+ end
114
+
115
+ desc 'Generate and upload node json configuration.'
116
+ task :configuration do
117
+ pwd!
118
+
119
+ attrs = variables.dup
120
+ attrs[:run_list] = recipes
121
+ put attrs.to_json, pwd("node.json"), :via => :scp
122
+ end
123
+ end
124
+
125
+ desc 'Run list of recipes from `:run_list` option.'
126
+ task :run_list do
127
+ ensure_cookbooks!
128
+
129
+ check
130
+ setup.cookbooks
131
+ setup.script
132
+ setup.configuration
133
+
134
+ logger.info "Now running #{recipes.join(', ')}"
135
+
136
+ sudo "#{chef_solo} -c #{pwd "node.rb"} -j #{pwd "node.json"}#{' -l debug' if fetch(:chef_debug)}"
137
+ end
138
+
139
+ end
140
+ end
141
+
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,69 @@
1
+ module Toque
2
+
3
+ # Toque helpers
4
+ #
5
+ module Helpers
6
+ def self.load_into(configuration)
7
+ configuration.load do
8
+
9
+ namespace :toque do
10
+
11
+ # Set toque default variable.
12
+ #
13
+ def set_default(variable, *args, &block)
14
+ @_toque_variables ||= []
15
+ @_toque_overridden ||= []
16
+ @_toque_variables << variable
17
+ if exists? variable
18
+ @_toque_overridden << variable
19
+ else
20
+ set variable, *args, &block
21
+ end
22
+ end
23
+
24
+ # Return toque remote working directory.
25
+ #
26
+ def pwd(*path)
27
+ File.join(fetch(:toque_pwd).to_s, *path.map(&:to_s))
28
+ end
29
+ set_default :toque_pwd, '/tmp/toque'
30
+
31
+ # Return toque remote working directory. Will be created remotely if not existing.
32
+ #
33
+ def pwd!(*path)
34
+ run "mkdir -p #{pwd = pwd(*path)}"
35
+ pwd
36
+ end
37
+
38
+ # Search if curl is present
39
+ #
40
+ def curl?
41
+ !(capture('curl || true') =~ /not found/)
42
+ end
43
+
44
+ # Install curl if not present
45
+ #
46
+ def require_curl
47
+ sudo 'apt-get install --no-install-recommends -yq curl' unless curl?
48
+ end
49
+
50
+ desc 'List current toque configuration'
51
+ task :config do
52
+ @_toque_variables.sort_by(&:to_s).each do |name|
53
+ display_name = ":#{name},".ljust(30)
54
+ if variables[name].is_a?(Proc)
55
+ value = "<block>"
56
+ else
57
+ value = fetch(name).inspect
58
+ value = "#{value[0..40]}... (truncated)" if value.length > 40
59
+ end
60
+ overridden = @_toque_overridden.include?(name) ? " (overridden)" : ""
61
+ puts "set #{display_name} #{value}#{overridden}"
62
+ end
63
+ end
64
+
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,20 @@
1
+ module Toque
2
+ module Tasks
3
+ def self.load_into(configuration)
4
+ configuration.load do
5
+
6
+ namespace :toque do
7
+
8
+ # Run list of recipes. Install chef if not already preset.
9
+ #
10
+ def run_list(*recipes)
11
+ set :run_list, recipes
12
+ chef.run_list
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,12 @@
1
+ module Toque
2
+ module VERSION
3
+ MAJOR = 1
4
+ MINOR = 0
5
+ PATCH = 0
6
+ STAGE = nil
7
+
8
+ STRING = [MAJOR, MINOR, PATCH, STAGE].reject(&:nil?).join('.')
9
+
10
+ def self.to_s; STRING end
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+
2
+ bash 'Be awesome!' do
3
+ cwd node[:toque_pwd]
4
+ code <<-EOH
5
+ touch awesome
6
+ EOH
7
+ creates "#{node[:toque_pwd]}/awesome"
8
+ end
@@ -0,0 +1,7 @@
1
+
2
+ bash 'Be awesome again!' do
3
+ cwd node[:toque_pwd]
4
+ code <<-EOH
5
+ rm -f awesome
6
+ EOH
7
+ end
@@ -0,0 +1,35 @@
1
+ require 'vagrant'
2
+
3
+ set :application, 'awesomeium'
4
+
5
+ set :repository, '.'
6
+ set :scm, :none # not recommended in production
7
+ set :deploy_via, :copy
8
+
9
+ server '192.168.33.10', :web, :app, :db, :primary => true
10
+
11
+ set :user, 'vagrant'
12
+ set :password, 'vagrant' # not recommended in production
13
+
14
+ set :deploy_to, "/home/#{user}/#{application}"
15
+
16
+ set :use_sudo, false
17
+ default_run_options[:pty] = true
18
+
19
+ # Toque options
20
+ set :cookbooks_paths, %w(spec/config/cookbooks)
21
+
22
+ namespace :vagrant do
23
+ task :up do
24
+ Vagrant::Environment.new.cli 'up'
25
+ end
26
+
27
+ task :destroy do
28
+ Vagrant::Environment.new.cli 'destroy'
29
+ end
30
+ end
31
+
32
+ task :spec do
33
+ toque.run_list "recipe[awesomeium]"
34
+ end
35
+ before 'spec', 'vagrant:up'
@@ -0,0 +1,16 @@
1
+ require 'capistrano-spec'
2
+ require 'toque'
3
+
4
+ Dir[File.expand_path('spec/support/**/*.rb')].each {|f| require f}
5
+
6
+ RSpec.configure do |config|
7
+ config.include Capistrano::Spec::Matchers
8
+ config.include Capistrano::Spec::Helpers
9
+
10
+ config.order = "random"
11
+
12
+ config.expect_with :rspec do |c|
13
+ # Only allow expect syntax
14
+ c.syntax = :expect
15
+ end
16
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+ require 'vagrant'
3
+
4
+ describe Toque do
5
+
6
+ before do
7
+ @vagrant = Vagrant::Environment.new
8
+ @vagrant.cli 'up'
9
+
10
+ @configuration = Capistrano::Configuration.new
11
+ Toque.load_into(@configuration)
12
+
13
+ @configuration.load do
14
+
15
+ server '192.168.33.10', :web, :app, :db, :primary => true
16
+ set :user, 'vagrant'
17
+ set :password, 'vagrant'
18
+
19
+ set :use_sudo, false
20
+ default_run_options[:pty] = true
21
+
22
+ # Toque options
23
+ set :cookbooks_paths, %w(spec/config/cookbooks)
24
+ set :chef_version, '10.24.0'
25
+
26
+ task :awesome! do
27
+ toque.run_list 'recipe[awesomeium]'
28
+ end
29
+
30
+ task :awesome_the_second! do
31
+ toque.run_list 'recipe[awesomeium::second]'
32
+ end
33
+ end
34
+
35
+ @configuration.sudo 'apt-get remove -yq curl'
36
+ @configuration.sudo 'apt-get autoremove -yq'
37
+ end
38
+
39
+ it 'should write an awesome file' do
40
+ @configuration.awesome!
41
+
42
+ # should have installed chef version
43
+ expect(@configuration.capture('/opt/chef/bin/chef-solo -v').strip).to be == 'Chef: 10.24.0'
44
+
45
+ # should have executed cookbook and created an awesome file
46
+ file_exists = @vagrant.primary_vm.channel.sudo 'ls /tmp/toque/awesome'
47
+ expect(file_exists).to be == 0
48
+
49
+ @configuration.awesome_the_second!
50
+
51
+ file_exists = @vagrant.primary_vm.channel.sudo 'ls /tmp/toque/awesome', :error_check => false
52
+ expect(file_exists).to_not be == 0
53
+ end
54
+ end
@@ -0,0 +1,129 @@
1
+ require 'spec_helper'
2
+
3
+ describe Toque::Chef, 'loaded into capistrano' do
4
+ before do
5
+ @configuration = Capistrano::Configuration.new
6
+ @configuration.extend Capistrano::Spec::ConfigurationExtension
7
+ Toque.load_into(@configuration)
8
+ end
9
+
10
+ it 'should define default omnibus installer URL' do
11
+ expect(@configuration.fetch :chef_omnibus_installer_url).to be == 'http://www.opscode.com/chef/install.sh'
12
+ end
13
+
14
+ it "defines toque:chef:install task" do
15
+ expect(@configuration.find_task 'toque:chef:install').to_not be_nil
16
+ end
17
+
18
+ describe '#installed?' do
19
+ it 'detect if chef-solo is not installed' do
20
+ expect(@configuration.toque.chef.installed?).to be_false
21
+ end
22
+
23
+ it 'detect if chef-solo is installed' do
24
+ @configuration.stub_command '/opt/chef/bin/chef-solo -v || true', data: 'Chef: 11.4.0'
25
+ expect(@configuration.toque.chef.installed?).to be_true
26
+ end
27
+ end
28
+
29
+ describe '#installed_version' do
30
+ it 'should fetch installed chef version' do
31
+ @configuration.stub_command '/opt/chef/bin/chef-solo -v || true', data: 'Chef: 11.4.0'
32
+ expect(@configuration.toque.chef.installed_version).to be == '11.4.0'
33
+ end
34
+ end
35
+
36
+ describe '#cookbooks_paths' do
37
+ it 'should return existing cookbook paths' do
38
+ File.stub(:exists?).with('config/cookbooks').and_return true
39
+ File.stub(:exists?).with('vendor/cookbooks').and_return false
40
+
41
+ expect(@configuration.toque.chef.cookbooks_paths).to be == %w(config/cookbooks)
42
+ end
43
+ end
44
+
45
+ describe '#ensure_cookbooks!' do
46
+ it 'should abort if no cookbook path exist' do
47
+ File.stub(:exists?).with('config/cookbooks').and_return false
48
+ File.stub(:exists?).with('vendor/cookbooks').and_return false
49
+
50
+ expect{ @configuration.toque.chef.ensure_cookbooks! }.to raise_error
51
+ end
52
+ end
53
+
54
+ describe '#databags_path' do
55
+ it 'should return path if exists' do
56
+ File.stub(:exists?).with('config/databags').and_return true
57
+
58
+ expect(@configuration.toque.chef.databags_path).to be == 'config/databags'
59
+ end
60
+
61
+ it 'should return nit if path does not exists' do
62
+ File.stub(:exists?).with('config/databags').and_return false
63
+
64
+ expect(@configuration.toque.chef.databags_path).to be_nil
65
+ end
66
+ end
67
+
68
+ describe '#chef_solo' do
69
+ it 'should return path to chef solo executable' do
70
+ expect(@configuration.toque.chef.chef_solo).to be == '/opt/chef/bin/chef-solo'
71
+ end
72
+
73
+ it 'should return path to custom chef solo executable' do
74
+ @configuration.set :chef_solo, 'chef-solo'
75
+ expect(@configuration.toque.chef.chef_solo).to be == 'chef-solo'
76
+ end
77
+ end
78
+
79
+ describe '#upload_cookbooks' do
80
+ before do
81
+ File.stub(:exists?).and_return false
82
+ File.stub(:exists?).with('config/cookbooks').and_return true
83
+ end
84
+
85
+ it 'should create working dir' do
86
+ @configuration.toque.chef.setup.cookbooks
87
+
88
+ expect(@configuration).to have_run 'mkdir -p /tmp/toque'
89
+ end
90
+
91
+ it 'should upload cookbooks' do
92
+ @configuration.toque.chef.setup.cookbooks
93
+
94
+ expect(@configuration).to have_uploaded.to('/tmp/toque/cookbooks.tar')
95
+ end
96
+
97
+ it 'should extract cookbooks on server' do
98
+ @configuration.toque.chef.setup.cookbooks
99
+
100
+ expect(@configuration).to have_run 'cd /tmp/toque && tar -xjf cookbooks.tar'
101
+ end
102
+ end
103
+
104
+ describe 'toque:chef:install' do
105
+
106
+ it 'should install chef using omnibus installer' do
107
+ @configuration.toque.chef.install
108
+ expect(@configuration).to have_run("sudo -p 'sudo password: ' true && curl -L http://www.opscode.com/chef/install.sh | sudo -p 'sudo password: ' bash")
109
+ end
110
+
111
+ context 'with custom installer URL' do
112
+ before { @configuration.set :chef_omnibus_installer_url, 'http://mysrv.tld/inst.sh' }
113
+
114
+ it 'should install chef using custom omnibus installer' do
115
+ @configuration.toque.chef.install
116
+ expect(@configuration).to have_run("sudo -p 'sudo password: ' true && curl -L http://mysrv.tld/inst.sh | sudo -p 'sudo password: ' bash")
117
+ end
118
+ end
119
+
120
+ context 'with specific chef version' do
121
+ before { @configuration.set :chef_version, '10.24.0' }
122
+
123
+ it 'should install chef using custom omnibus installer' do
124
+ @configuration.toque.chef.install
125
+ expect(@configuration).to have_run("sudo -p 'sudo password: ' true && curl -L http://www.opscode.com/chef/install.sh | sudo -p 'sudo password: ' bash -s -- -v 10.24.0")
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe Toque::Helpers, 'loaded into capistrano' do
4
+ before do
5
+ @configuration = Capistrano::Configuration.new
6
+ @configuration.extend Capistrano::Spec::ConfigurationExtension
7
+ Toque.load_into(@configuration)
8
+ end
9
+
10
+ describe '#pwd' do
11
+ it 'return toque working dir' do
12
+ expect(@configuration.toque.pwd).to be == '/tmp/toque'
13
+ end
14
+
15
+ it 'return custom path if set' do
16
+ @configuration.set :toque_pwd, '/tmp/custom_path'
17
+ expect(@configuration.toque.pwd).to be == '/tmp/custom_path'
18
+ end
19
+ end
20
+
21
+ describe '#pwd!' do
22
+ it 'return create remote working dir' do
23
+ @configuration.toque.pwd!
24
+ expect(@configuration).to have_run 'mkdir -p /tmp/toque'
25
+ end
26
+ end
27
+
28
+ describe '#curl?' do
29
+ it 'return true if curl exists' do
30
+ @configuration.stub_command 'curl || true', data: "curl: try 'curl --help' or 'curl --manual' for more information"
31
+ expect(@configuration.toque.curl?).to be_true
32
+ end
33
+
34
+ it 'return false if curl is missing' do
35
+ @configuration.stub_command 'curl || true', data: "sh: command not found"
36
+ expect(@configuration.toque.curl?).to be_false
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'toque/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'toque'
8
+ spec.version = Toque::VERSION
9
+ spec.authors = ['Jan Graichen']
10
+ spec.email = %w(jg@altimos.de)
11
+ spec.description = %q{Toque: Cap of a Chef. Integrate Chef into Capistrano.}
12
+ spec.summary = %q{Toque: Cap of a Chef. Integrate Chef into Capistrano.}
13
+ spec.homepage = 'https://github.com/jgraichen/toque'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = %w(lib)
20
+
21
+ spec.add_dependency 'capistrano'
22
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: toque
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jan Graichen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-04-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capistrano
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: 'Toque: Cap of a Chef. Integrate Chef into Capistrano.'
28
+ email:
29
+ - jg@altimos.de
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - .gitignore
35
+ - .travis.yml
36
+ - Capfile
37
+ - Gemfile
38
+ - LICENSE.txt
39
+ - README.md
40
+ - Rakefile
41
+ - Vagrantfile
42
+ - lib/toque.rb
43
+ - lib/toque/chef.rb
44
+ - lib/toque/helpers.rb
45
+ - lib/toque/tasks.rb
46
+ - lib/toque/version.rb
47
+ - spec/config/cookbooks/awesomeium/recipes/default.rb
48
+ - spec/config/cookbooks/awesomeium/recipes/second.rb
49
+ - spec/config/deploy.rb
50
+ - spec/spec_helper.rb
51
+ - spec/spec_toque.rb
52
+ - spec/toque/chef_spec.rb
53
+ - spec/toque/helpers_spec.rb
54
+ - toque.gemspec
55
+ homepage: https://github.com/jgraichen/toque
56
+ licenses:
57
+ - MIT
58
+ metadata: {}
59
+ post_install_message:
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ requirements: []
74
+ rubyforge_project:
75
+ rubygems_version: 2.0.3
76
+ signing_key:
77
+ specification_version: 4
78
+ summary: 'Toque: Cap of a Chef. Integrate Chef into Capistrano.'
79
+ test_files:
80
+ - spec/config/cookbooks/awesomeium/recipes/default.rb
81
+ - spec/config/cookbooks/awesomeium/recipes/second.rb
82
+ - spec/config/deploy.rb
83
+ - spec/spec_helper.rb
84
+ - spec/spec_toque.rb
85
+ - spec/toque/chef_spec.rb
86
+ - spec/toque/helpers_spec.rb